From 11265238db2d47790a5041dd1b69d935ac16c9cf Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Thu, 26 Dec 2019 16:56:31 +0800 Subject: [PATCH 1/5] Implement version check middleware Signed-off-by: Yukai Huang --- app.js | 6 ++++ lib/config/default.js | 3 +- lib/web/middleware/checkVersion.js | 52 ++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 lib/web/middleware/checkVersion.js diff --git a/app.js b/app.js index c884a511..e5c451d3 100644 --- a/app.js +++ b/app.js @@ -25,6 +25,8 @@ var response = require('./lib/response') var models = require('./lib/models') var csp = require('./lib/csp') +const { versionCheckMiddleware } = require('./lib/web/middleware/checkVersion') + function createHttpServer () { if (config.useSSL) { const ca = (function () { @@ -167,6 +169,10 @@ app.use(require('./lib/middleware/checkURIValid')) app.use(require('./lib/middleware/redirectWithoutTrailingSlashes')) app.use(require('./lib/middleware/codiMDVersion')) +if (config.autoVersionCheck) { + app.use(versionCheckMiddleware) +} + // routes need sessions // template files app.set('views', config.viewPath) diff --git a/lib/config/default.js b/lib/config/default.js index 1167cb75..2e76b143 100644 --- a/lib/config/default.js +++ b/lib/config/default.js @@ -178,5 +178,6 @@ module.exports = { // Generated id: "31-good-morning-my-friend---do-you-have-5" // 2nd appearance: "31-good-morning-my-friend---do-you-have-5-1" // 3rd appearance: "31-good-morning-my-friend---do-you-have-5-2" - linkifyHeaderStyle: 'keep-case' + linkifyHeaderStyle: 'keep-case', + autoVersionCheck: true } diff --git a/lib/web/middleware/checkVersion.js b/lib/web/middleware/checkVersion.js new file mode 100644 index 00000000..ade3ff87 --- /dev/null +++ b/lib/web/middleware/checkVersion.js @@ -0,0 +1,52 @@ +'use strict' + +const { promisify } = require('util') + +const request = require('request') + +const logger = require('../../logger') +const config = require('../../config') + +let lastCheckAt +let latest = true +let versionItem = null + +const VERSION_CHECK_ENDPOINT = 'https://evangelion.codimd.dev/' +const CHECK_TIMEOUT = 1000 * 60 * 60 * 24 // 1 day + +const rp = promisify(request) + +exports.versionCheckMiddleware = async function (req, res, next) { + if (lastCheckAt && (lastCheckAt + CHECK_TIMEOUT > Date.now())) { + return next() + } + + // update lastCheckAt whether the check would fail or not + lastCheckAt = Date.now() + + try { + const { statusCode, body: data } = await rp({ + url: `${VERSION_CHECK_ENDPOINT}?v=${config.version}`, + method: 'GET', + json: true + }) + + if (statusCode !== 200 || data.status === 'error') { + logger.error('Version check failed.') + return next() + } + + latest = data.latest + versionItem = latest ? null : data.versionItem + + return next() + } catch (err) { + // ignore and skip version check + logger.error('Version check failed.') + logger.error(err) + return next() + } +} + +exports.versionItem = versionItem +exports.outdated = outdated From 334c81efe74aa833efa3405c24bc210cfd0640cb Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 27 Dec 2019 15:55:00 +0800 Subject: [PATCH 2/5] Save version info in app locals Signed-off-by: Yukai Huang --- app.js | 4 ++++ lib/web/middleware/checkVersion.js | 9 ++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app.js b/app.js index e5c451d3..0e407b66 100644 --- a/app.js +++ b/app.js @@ -206,6 +206,10 @@ app.locals.authProviders = { email: config.isEmailEnable, allowEmailRegister: config.allowEmailRegister } +app.locals.versionInfo = { + latest: true, + versionItem: null +} // Export/Import menu items app.locals.enableDropBoxSave = config.isDropboxEnable diff --git a/lib/web/middleware/checkVersion.js b/lib/web/middleware/checkVersion.js index ade3ff87..db35b06a 100644 --- a/lib/web/middleware/checkVersion.js +++ b/lib/web/middleware/checkVersion.js @@ -8,8 +8,6 @@ const logger = require('../../logger') const config = require('../../config') let lastCheckAt -let latest = true -let versionItem = null const VERSION_CHECK_ENDPOINT = 'https://evangelion.codimd.dev/' const CHECK_TIMEOUT = 1000 * 60 * 60 * 24 // 1 day @@ -36,8 +34,8 @@ exports.versionCheckMiddleware = async function (req, res, next) { return next() } - latest = data.latest - versionItem = latest ? null : data.versionItem + req.app.locals.versionInfo.latest = data.latest + req.app.locals.versionInfo.versionItem = req.app.locals.latest ? null : data.versionItem return next() } catch (err) { @@ -47,6 +45,3 @@ exports.versionCheckMiddleware = async function (req, res, next) { return next() } } - -exports.versionItem = versionItem -exports.outdated = outdated From 8cd9ba2f82bfaf280d361aa60a0bcfc62e2addfc Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Thu, 6 Feb 2020 10:40:51 +0800 Subject: [PATCH 3/5] Log version check info when app is starting Signed-off-by: Yukai Huang --- app.js | 3 ++- lib/web/middleware/checkVersion.js | 37 ++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index 0e407b66..512341d4 100644 --- a/app.js +++ b/app.js @@ -25,7 +25,7 @@ var response = require('./lib/response') var models = require('./lib/models') var csp = require('./lib/csp') -const { versionCheckMiddleware } = require('./lib/web/middleware/checkVersion') +const { versionCheckMiddleware, checkVersion } = require('./lib/web/middleware/checkVersion') function createHttpServer () { if (config.useSSL) { @@ -170,6 +170,7 @@ app.use(require('./lib/middleware/redirectWithoutTrailingSlashes')) app.use(require('./lib/middleware/codiMDVersion')) if (config.autoVersionCheck) { + checkVersion(app) app.use(versionCheckMiddleware) } diff --git a/lib/web/middleware/checkVersion.js b/lib/web/middleware/checkVersion.js index db35b06a..804de4c4 100644 --- a/lib/web/middleware/checkVersion.js +++ b/lib/web/middleware/checkVersion.js @@ -14,9 +14,13 @@ const CHECK_TIMEOUT = 1000 * 60 * 60 * 24 // 1 day const rp = promisify(request) -exports.versionCheckMiddleware = async function (req, res, next) { +exports.checkVersion = checkVersion +/** + * @param {Express.Application|Express.Request} ctx + */ +async function checkVersion (ctx) { if (lastCheckAt && (lastCheckAt + CHECK_TIMEOUT > Date.now())) { - return next() + return } // update lastCheckAt whether the check would fail or not @@ -31,17 +35,36 @@ exports.versionCheckMiddleware = async function (req, res, next) { if (statusCode !== 200 || data.status === 'error') { logger.error('Version check failed.') - return next() + return } - req.app.locals.versionInfo.latest = data.latest - req.app.locals.versionInfo.versionItem = req.app.locals.latest ? null : data.versionItem + let locals = ctx.locals ? ctx.locals : ctx.app.locals - return next() + locals.versionInfo.latest = data.latest + locals.versionInfo.versionItem = data.latest ? null : data.versionItem + + if (!data.latest) { + const { version, link } = data.versionItem + + logger.warn(`Your CodiMD version is out of date! The latest version is ${version}. Please see what's new on ${link}.`) + } + + return } catch (err) { // ignore and skip version check logger.error('Version check failed.') logger.error(err) - return next() + + return } } + +exports.versionCheckMiddleware = function (req, res, next) { + checkVersion(req) + .then(() => { + next() + }) + .catch((err) => { + next() + }) +} From 821295ecd38d22d92d7aa18de5599b4fa86d455d Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Thu, 6 Feb 2020 10:46:48 +0800 Subject: [PATCH 4/5] Fix linting errors Signed-off-by: Yukai Huang --- lib/web/middleware/checkVersion.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/web/middleware/checkVersion.js b/lib/web/middleware/checkVersion.js index 804de4c4..9cd9325e 100644 --- a/lib/web/middleware/checkVersion.js +++ b/lib/web/middleware/checkVersion.js @@ -38,7 +38,7 @@ async function checkVersion (ctx) { return } - let locals = ctx.locals ? ctx.locals : ctx.app.locals + const locals = ctx.locals ? ctx.locals : ctx.app.locals locals.versionInfo.latest = data.latest locals.versionInfo.versionItem = data.latest ? null : data.versionItem @@ -48,14 +48,10 @@ async function checkVersion (ctx) { logger.warn(`Your CodiMD version is out of date! The latest version is ${version}. Please see what's new on ${link}.`) } - - return } catch (err) { // ignore and skip version check logger.error('Version check failed.') logger.error(err) - - return } } @@ -65,6 +61,7 @@ exports.versionCheckMiddleware = function (req, res, next) { next() }) .catch((err) => { + logger.error(err) next() }) } From c26a9f10ca3fbd4e1f84f6928b73cc2c98304e8f Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Fri, 7 Feb 2020 10:55:16 +0800 Subject: [PATCH 5/5] Fix missing environment config for version check Signed-off-by: Yukai Huang --- lib/config/environment.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config/environment.js b/lib/config/environment.js index 3a62985c..8426d82f 100644 --- a/lib/config/environment.js +++ b/lib/config/environment.js @@ -142,5 +142,6 @@ module.exports = { allowPDFExport: toBooleanConfig(process.env.CMD_ALLOW_PDF_EXPORT), openID: toBooleanConfig(process.env.CMD_OPENID), defaultUseHardbreak: toBooleanConfig(process.env.CMD_DEFAULT_USE_HARD_BREAK), - linkifyHeaderStyle: process.env.CMD_LINKIFY_HEADER_STYLE + linkifyHeaderStyle: process.env.CMD_LINKIFY_HEADER_STYLE, + autoVersionCheck: toBooleanConfig(process.env.CMD_AUTO_VERSION_CHECK) }