From bd2f7cef495b87050ec3f126e7425095078440b2 Mon Sep 17 00:00:00 2001 From: WilliButz Date: Wed, 5 Sep 2018 19:49:01 +0200 Subject: [PATCH 1/7] lib/models/revision.js: make independent of exec-path Previously calling `app.js` from another directory than the base directory of CodiMD would result in an error being thrown because `lib/workers/dmpWorker.js` could not be found. This change makes the function call independent of the path CodiMD is started from. Signed-off-by: WilliButz --- lib/models/revision.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/models/revision.js b/lib/models/revision.js index 8bc95cb..4ee080d 100644 --- a/lib/models/revision.js +++ b/lib/models/revision.js @@ -5,6 +5,7 @@ var async = require('async') var moment = require('moment') var childProcess = require('child_process') var shortId = require('shortid') +var path = require('path') // core var config = require('../config') @@ -14,7 +15,7 @@ var dmpWorker = createDmpWorker() var dmpCallbackCache = {} function createDmpWorker () { - var worker = childProcess.fork('./lib/workers/dmpWorker.js', { + var worker = childProcess.fork(path.resolve(__dirname, '../workers/dmpWorker.js'), { stdio: 'ignore' }) if (config.debug) logger.info('dmp worker process started') From e48852e0e2de4441b5ef84dc9bb16be8ba9c01d8 Mon Sep 17 00:00:00 2001 From: WilliButz Date: Wed, 5 Sep 2018 19:50:46 +0200 Subject: [PATCH 2/7] lib/config: add environment variable to set config file Previously it was assumed that `config.json` would be placed in the same directory as the rest of CodiMD without any optional override. This allows to override the path to the `config.json` by setting `CMD_CONFIG_FILE` to the canonical path of the desired config file. Signed-off-by: WilliButz --- lib/config/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config/index.js b/lib/config/index.js index 26f0ae9..76c8bbf 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -23,7 +23,8 @@ const packageConfig = { minimumCompatibleVersion: '0.5.0' } -const configFilePath = path.join(appRootPath, 'config.json') +const configFilePath = path.resolve(appRootPath, process.env.CMD_CONFIG_FILE || +'config.json') const fileConfig = fs.existsSync(configFilePath) ? require(configFilePath)[env] : undefined let config = require('./default') From 556783ffad2e26c490c0d9d9520d7ee13a750dbb Mon Sep 17 00:00:00 2001 From: WilliButz Date: Wed, 5 Sep 2018 19:56:41 +0200 Subject: [PATCH 3/7] lib/config: use `path.resolve` instead of `path.join` While paths like `tmpPath` could previously be configured, they were all interpreted relative to `appRootPath` because of `path.join`. Now the configurable paths can be canonical and therefore independent of the `appRootPath`. Signed-off-by: WilliButz --- lib/config/index.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/config/index.js b/lib/config/index.js index 76c8bbf..59db861 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -174,20 +174,20 @@ config.sslCAPath.forEach(function (capath, i, array) { array[i] = path.resolve(appRootPath, capath) }) -config.sslCertPath = path.join(appRootPath, config.sslCertPath) -config.sslKeyPath = path.join(appRootPath, config.sslKeyPath) -config.dhParamPath = path.join(appRootPath, config.dhParamPath) +config.sslCertPath = path.resolve(appRootPath, config.sslCertPath) +config.sslKeyPath = path.resolve(appRootPath, config.sslKeyPath) +config.dhParamPath = path.resolve(appRootPath, config.dhParamPath) -config.tmpPath = path.join(appRootPath, config.tmpPath) -config.defaultNotePath = path.join(appRootPath, config.defaultNotePath) -config.docsPath = path.join(appRootPath, config.docsPath) -config.indexPath = path.join(appRootPath, config.indexPath) -config.codimdPath = path.join(appRootPath, config.codimdPath) -config.errorPath = path.join(appRootPath, config.errorPath) -config.prettyPath = path.join(appRootPath, config.prettyPath) -config.slidePath = path.join(appRootPath, config.slidePath) -config.constantsPath = path.join(appRootPath, config.constantsPath) -config.uploadsPath = path.join(appRootPath, config.uploadsPath) +config.tmpPath = path.resolve(appRootPath, config.tmpPath) +config.defaultNotePath = path.resolve(appRootPath, config.defaultNotePath) +config.docsPath = path.resolve(appRootPath, config.docsPath) +config.indexPath = path.resolve(appRootPath, config.indexPath) +config.codimdPath = path.resolve(appRootPath, config.codimdPath) +config.errorPath = path.resolve(appRootPath, config.errorPath) +config.prettyPath = path.resolve(appRootPath, config.prettyPath) +config.slidePath = path.resolve(appRootPath, config.slidePath) +config.constantsPath = path.resolve(appRootPath, config.constantsPath) +config.uploadsPath = path.resolve(appRootPath, config.uploadsPath) // make config readonly config = deepFreeze(config) From 12cd74727065079905cb385119d7a2db35276cca Mon Sep 17 00:00:00 2001 From: WilliButz Date: Wed, 26 Sep 2018 20:40:28 +0200 Subject: [PATCH 4/7] imageRouter/filesystem: make callback path-independent Images are now properly served when `config.uploadsPath` differs from its default value. Signed-off-by: WilliButz --- lib/web/imageRouter/filesystem.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/web/imageRouter/filesystem.js b/lib/web/imageRouter/filesystem.js index 4bf82b3..8c432b0 100644 --- a/lib/web/imageRouter/filesystem.js +++ b/lib/web/imageRouter/filesystem.js @@ -1,5 +1,6 @@ 'use strict' const url = require('url') +const path = require('path') const config = require('../../config') const logger = require('../../logger') @@ -15,5 +16,5 @@ exports.uploadImage = function (imagePath, callback) { return } - callback(null, url.resolve(config.serverURL + '/', imagePath.match(/public\/(.+)$/)[1])) + callback(null, url.resolve(config.serverURL + '/uploads/', path.basename(imagePath))) } From 825ee4e66e79271c39631f2b9eb059caa8f17bfc Mon Sep 17 00:00:00 2001 From: WilliButz Date: Wed, 26 Sep 2018 17:18:33 +0200 Subject: [PATCH 5/7] app.js: add missing routes for configurable paths Signed-off-by: WilliButz --- app.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app.js b/app.js index ab37bff..76ff664 100644 --- a/app.js +++ b/app.js @@ -126,6 +126,9 @@ app.use(i18n.init) // routes without sessions // static files app.use('/', express.static(path.join(__dirname, '/public'), { maxAge: config.staticCacheTime })) +app.use('/docs', express.static(path.resolve(__dirname, config.docsPath), { maxAge: config.staticCacheTime })) +app.use('/uploads', express.static(path.resolve(__dirname, config.uploadsPath), { maxAge: config.staticCacheTime })) +app.use('/default.md', express.static(path.resolve(__dirname, config.defaultNotePath), { maxAge: config.staticCacheTime })) // session app.use(session({ From bb80bc2292d2841776e8bfd6285f96194d990284 Mon Sep 17 00:00:00 2001 From: Claudius Date: Mon, 10 Sep 2018 22:35:38 +0200 Subject: [PATCH 6/7] removing superfluous config parameters for template files Signed-off-by: Claudius --- app.js | 2 +- lib/config/default.js | 7 +------ lib/config/index.js | 10 ++-------- lib/response.js | 12 ++++++------ lib/web/statusRouter.js | 2 +- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/app.js b/app.js index 76ff664..d6d607b 100644 --- a/app.js +++ b/app.js @@ -170,7 +170,7 @@ app.use(require('./lib/web/middleware/codiMDVersion')) // routes need sessions // template files -app.set('views', path.join(__dirname, '/public/views')) +app.set('views', config.viewPath) // set render engine app.engine('ejs', ejs.renderFile) // set view engine diff --git a/lib/config/default.js b/lib/config/default.js index 6096bce..5d10ad2 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -38,15 +38,10 @@ module.exports = { sslCAPath: '', dhParamPath: '', // other path + viewPath: './public/views', tmpPath: './tmp', defaultNotePath: './public/default.md', docsPath: './public/docs', - indexPath: './public/views/index.ejs', - codimdPath: './public/views/codimd.ejs', - errorPath: './public/views/error.ejs', - prettyPath: './public/views/pretty.ejs', - slidePath: './public/views/slide.ejs', - constantsPath: './public/js/lib/common/constant.ejs', uploadsPath: './public/uploads', // session sessionName: 'connect.sid', diff --git a/lib/config/index.js b/lib/config/index.js index 59db861..7d059c5 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -9,7 +9,7 @@ const deepFreeze = require('deep-freeze') const {Environment, Permission} = require('./enum') const logger = require('../logger') -const appRootPath = path.join(__dirname, '../../') +const appRootPath = path.resolve(__dirname, '../../') const env = process.env.NODE_ENV || Environment.development const debugConfig = { debug: (env === Environment.development) @@ -177,16 +177,10 @@ config.sslCAPath.forEach(function (capath, i, array) { config.sslCertPath = path.resolve(appRootPath, config.sslCertPath) config.sslKeyPath = path.resolve(appRootPath, config.sslKeyPath) config.dhParamPath = path.resolve(appRootPath, config.dhParamPath) - +config.viewPath = path.resolve(appRootPath, config.viewPath) config.tmpPath = path.resolve(appRootPath, config.tmpPath) config.defaultNotePath = path.resolve(appRootPath, config.defaultNotePath) config.docsPath = path.resolve(appRootPath, config.docsPath) -config.indexPath = path.resolve(appRootPath, config.indexPath) -config.codimdPath = path.resolve(appRootPath, config.codimdPath) -config.errorPath = path.resolve(appRootPath, config.errorPath) -config.prettyPath = path.resolve(appRootPath, config.prettyPath) -config.slidePath = path.resolve(appRootPath, config.slidePath) -config.constantsPath = path.resolve(appRootPath, config.constantsPath) config.uploadsPath = path.resolve(appRootPath, config.uploadsPath) // make config readonly diff --git a/lib/response.js b/lib/response.js index 295f91d..8862304 100644 --- a/lib/response.js +++ b/lib/response.js @@ -51,7 +51,7 @@ var response = { } function responseError (res, code, detail, msg) { - res.status(code).render(config.errorPath, { + res.status(code).render('error.ejs', { url: config.serverURL, title: code + ' ' + detail + ' ' + msg, code: code, @@ -101,11 +101,11 @@ function showIndex (req, res, next) { }).then(function (user) { if (user) { data.deleteToken = user.deleteToken - res.render(config.indexPath, data) + res.render('index.ejs', data) } }) } else { - res.render(config.indexPath, data) + res.render('index.ejs', data) } } @@ -119,7 +119,7 @@ function responseCodiMD (res, note) { 'Cache-Control': 'private', // only cache by client 'X-Robots-Tag': 'noindex, nofollow' // prevent crawling }) - res.render(config.codimdPath, { + res.render('codimd.ejs', { url: config.serverURL, title: title, useCDN: config.useCDN, @@ -275,7 +275,7 @@ function renderPublish (data, res) { res.set({ 'Cache-Control': 'private' // only cache by client }) - res.render(config.prettyPath, data) + res.render('pretty.ejs', data) } function actionPublish (req, res, note) { @@ -657,7 +657,7 @@ function renderPublishSlide (data, res) { res.set({ 'Cache-Control': 'private' // only cache by client }) - res.render(config.slidePath, data) + res.render('slide.ejs', data) } module.exports = response diff --git a/lib/web/statusRouter.js b/lib/web/statusRouter.js index 7ecf383..fb2609e 100644 --- a/lib/web/statusRouter.js +++ b/lib/web/statusRouter.js @@ -105,5 +105,5 @@ statusRouter.get('/config', function (req, res) { 'X-Robots-Tag': 'noindex, nofollow', // prevent crawling 'Content-Type': 'application/javascript' }) - res.render(config.constantsPath, data) + res.render('../js/lib/common/constant.ejs', data) }) From 61e240192e3ab7e02cb59115e10343da03f18951 Mon Sep 17 00:00:00 2001 From: WilliButz Date: Thu, 27 Sep 2018 12:08:29 +0200 Subject: [PATCH 7/7] README: add note about configurable paths Signed-off-by: WilliButz --- README.md | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ecdc8c7..e111b4c 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,7 @@ There are some config settings you need to change in the files below. | --------- | ------ | ----------- | | `NODE_ENV` | `production` or `development` | set current environment (will apply corresponding settings in the `config.json`) | | `DEBUG` | `true` or `false` | set debug mode; show more logs | +| `CMD_CONFIG_FILE` | `/path/to/config.json` | optional override for the path to CodiMD's config file | | `CMD_DOMAIN` | `codimd.org` | domain name | | `CMD_URL_PATH` | `codimd` | sub URL path, like `www.example.com/` | | `CMD_HOST` | `localhost` | host to listen on | @@ -277,19 +278,15 @@ There are some config settings you need to change in the files below. | `defaultPermission` | `freely`, `editable`, `limited`, `locked`, `protected` or `private` | set notes default permission (only applied on signed users) | | `dbURL` | `mysql://localhost:3306/database` | set the db URL; if set, then db config (below) won't be applied | | `db` | `{ "dialect": "sqlite", "storage": "./db.codimd.sqlite" }` | set the db configs, [see more here](http://sequelize.readthedocs.org/en/latest/api/sequelize/) | -| `sslKeyPath` | `./cert/client.key` | SSL key path (only need when you set `useSSL`) | -| `sslCertPath` | `./cert/codimd_io.crt` | SSL cert path (only need when you set `useSSL`) | -| `sslCAPath` | `['./cert/COMODORSAAddTrustCA.crt']` | SSL ca chain (only need when you set `useSSL`) | -| `dhParamPath` | `./cert/dhparam.pem` | SSL dhparam path (only need when you set `useSSL`) | -| `tmpPath` | `./tmp/` | temp directory path | -| `defaultNotePath` | `./public/default.md` | default note file path | -| `docsPath` | `./public/docs` | docs directory path | -| `indexPath` | `./public/views/index.ejs` | index template file path | -| `hackmdPath` | `./public/views/hackmd.ejs` | hackmd template file path | -| `errorPath` | `./public/views/error.ejs` | error template file path | -| `prettyPath` | `./public/views/pretty.ejs` | pretty template file path | -| `slidePath` | `./public/views/slide.hbs` | slide template file path | -| `uploadsPath` | `./public/uploads` | uploads directory - needs to be persistent when you use imageUploadType `filesystem` | +| `sslKeyPath` | `./cert/client.key` | SSL key path1 (only need when you set `useSSL`) | +| `sslCertPath` | `./cert/codimd_io.crt` | SSL cert path1 (only need when you set `useSSL`) | +| `sslCAPath` | `['./cert/COMODORSAAddTrustCA.crt']` | SSL ca chain1 (only need when you set `useSSL`) | +| `dhParamPath` | `./cert/dhparam.pem` | SSL dhparam path1 (only need when you set `useSSL`) | +| `tmpPath` | `./tmp/` | temp directory path1 | +| `defaultNotePath` | `./public/default.md` | default note file path1 | +| `docsPath` | `./public/docs` | docs directory path1 | +| `viewPath` | `./public/views` | template directory path1 | +| `uploadsPath` | `./public/uploads` | uploads directory1 - needs to be persistent when you use imageUploadType `filesystem` | | `sessionName` | `connect.sid` | cookie session name | | `sessionSecret` | `secret` | cookie session secret | | `sessionLife` | `14 * 24 * 60 * 60 * 1000` | cookie session life | @@ -305,6 +302,8 @@ There are some config settings you need to change in the files below. | `s3` | `{ "accessKeyId": "YOUR_S3_ACCESS_KEY_ID", "secretAccessKey": "YOUR_S3_ACCESS_KEY", "region": "YOUR_S3_REGION" }` | When `imageuploadtype` be set to `s3`, you would also need to setup this key, check our [S3 Image Upload Guide](docs/guides/s3-image-upload.md) | | `s3bucket` | `YOUR_S3_BUCKET_NAME` | bucket name when `imageUploadType` is set to `s3` or `minio` | +1: relative paths are based on CodiMD's base directory + ## Third-party integration API key settings | service | settings location | description |