From 57359d1659e2404291c9acd216119dc0ec191228 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 22 May 2023 10:54:37 +0100 Subject: [PATCH] Ensure express server options are applied consistently Fixes #4169 --- .../@node-red/editor-api/lib/admin/index.js | 15 ++------------- .../@node-red/editor-api/lib/editor/index.js | 7 ++++--- .../editor-api/lib/editor/projects.js | 7 ++++--- .../editor-api/lib/editor/settings.js | 4 ++-- .../@node-red/editor-api/lib/editor/sshkeys.js | 6 ++++-- .../@node-red/editor-api/lib/editor/theme.js | 15 +++++++++++++-- .../@node-red/editor-api/lib/index.js | 18 +++++------------- .../@node-red/editor-api/lib/util.js | 17 ++++++++++++++--- .../@node-red/runtime/lib/index.js | 9 +++++++++ .../editor-api/lib/editor/index_spec.js | 2 ++ .../editor-api/lib/editor/settings_spec.js | 4 ++-- .../editor-api/lib/editor/sshkeys_spec.js | 2 +- 12 files changed, 62 insertions(+), 44 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/index.js b/packages/node_modules/@node-red/editor-api/lib/admin/index.js index 8406fa8e9..26eabe65b 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/index.js @@ -14,8 +14,6 @@ * limitations under the License. **/ -var express = require("express"); - var nodes = require("./nodes"); var flows = require("./flows"); var flow = require("./flow"); @@ -37,18 +35,9 @@ module.exports = { plugins.init(runtimeAPI); diagnostics.init(settings, runtimeAPI); - var needsPermission = auth.needsPermission; - - var adminApp = express(); - - var defaultServerSettings = { - "x-powered-by": false - } - var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{}); - for (var eOption in serverSettings) { - adminApp.set(eOption, serverSettings[eOption]); - } + const needsPermission = auth.needsPermission; + const adminApp = apiUtil.createExpressApp(settings) // Flows adminApp.get("/flows",needsPermission("flows.read"),flows.get,apiUtil.errorHandler); diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/index.js b/packages/node_modules/@node-red/editor-api/lib/editor/index.js index f210d90fe..42be1f270 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/index.js @@ -46,14 +46,15 @@ module.exports = { runtimeAPI = _runtimeAPI; needsPermission = auth.needsPermission; if (!settings.disableEditor) { - info.init(runtimeAPI); + info.init(settings, runtimeAPI); comms.init(server,settings,runtimeAPI); var ui = require("./ui"); ui.init(runtimeAPI); - var editorApp = express(); + const editorApp = apiUtil.createExpressApp(settings) + if (settings.requireHttps === true) { editorApp.enable('trust proxy'); editorApp.use(function (req, res, next) { @@ -86,7 +87,7 @@ module.exports = { //Projects var projects = require("./projects"); - projects.init(runtimeAPI); + projects.init(settings, runtimeAPI); editorApp.use("/projects",projects.app()); // Locales diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/projects.js b/packages/node_modules/@node-red/editor-api/lib/editor/projects.js index ad505a46e..5d1b2ff26 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/projects.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/projects.js @@ -14,9 +14,9 @@ * limitations under the License. **/ -var express = require("express"); var apiUtils = require("../util"); +var settings; var runtimeAPI; var needsPermission = require("../auth").needsPermission; @@ -77,11 +77,12 @@ function getProjectRemotes(req,res) { }) } module.exports = { - init: function(_runtimeAPI) { + init: function(_settings, _runtimeAPI) { + settings = _settings; runtimeAPI = _runtimeAPI; }, app: function() { - var app = express(); + var app = apiUtils.createExpressApp(settings) app.use(function(req,res,next) { runtimeAPI.projects.available().then(function(available) { diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/settings.js b/packages/node_modules/@node-red/editor-api/lib/editor/settings.js index 5fa2476e1..200ddf2c2 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/settings.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/settings.js @@ -18,9 +18,9 @@ var runtimeAPI; var sshkeys = require("./sshkeys"); module.exports = { - init: function(_runtimeAPI) { + init: function(settings, _runtimeAPI) { runtimeAPI = _runtimeAPI; - sshkeys.init(runtimeAPI); + sshkeys.init(settings, runtimeAPI); }, userSettings: function(req, res) { var opts = { diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js b/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js index 6d1c62e11..08097571f 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js @@ -17,13 +17,15 @@ var apiUtils = require("../util"); var express = require("express"); var runtimeAPI; +var settings; module.exports = { - init: function(_runtimeAPI) { + init: function(_settings, _runtimeAPI) { runtimeAPI = _runtimeAPI; + settings = _settings; }, app: function() { - var app = express(); + const app = apiUtils.createExpressApp(settings); // List all SSH keys app.get("/", function(req,res) { diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/theme.js b/packages/node_modules/@node-red/editor-api/lib/editor/theme.js index c21a7e6e7..b3f6ef922 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/theme.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/theme.js @@ -19,6 +19,7 @@ var util = require("util"); var path = require("path"); var fs = require("fs"); var clone = require("clone"); +const apiUtil = require("../util") var defaultContext = { page: { @@ -40,6 +41,7 @@ var defaultContext = { vendorMonaco: "" } }; +var settings; var theme = null; var themeContext = clone(defaultContext); @@ -92,7 +94,8 @@ function serveFilesFromTheme(themeValue, themeApp, directory, baseDirectory) { } module.exports = { - init: function(settings, _runtimeAPI) { + init: function(_settings, _runtimeAPI) { + settings = _settings; runtimeAPI = _runtimeAPI; themeContext = clone(defaultContext); if (process.env.NODE_ENV == "development") { @@ -113,7 +116,15 @@ module.exports = { var url; themeSettings = {}; - themeApp = express(); + themeApp = apiUtil.createExpressApp(settings); + + const defaultServerSettings = { + "x-powered-by": false + } + const serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{}); + for (const eOption in serverSettings) { + themeApp.set(eOption, serverSettings[eOption]); + } if (theme.page) { diff --git a/packages/node_modules/@node-red/editor-api/lib/index.js b/packages/node_modules/@node-red/editor-api/lib/index.js index 56f52a222..d9f34eafd 100644 --- a/packages/node_modules/@node-red/editor-api/lib/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/index.js @@ -37,7 +37,6 @@ var adminApp; var server; var editor; - /** * Initialise the module. * @param {Object} settings The runtime settings @@ -49,7 +48,7 @@ var editor; function init(settings,_server,storage,runtimeAPI) { server = _server; if (settings.httpAdminRoot !== false) { - adminApp = express(); + adminApp = apiUtil.createExpressApp(settings); var cors = require('cors'); var corsHandler = cors({ @@ -64,14 +63,6 @@ function init(settings,_server,storage,runtimeAPI) { } } - var defaultServerSettings = { - "x-powered-by": false - } - var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{}); - for (var eOption in serverSettings) { - adminApp.set(eOption, serverSettings[eOption]); - } - auth.init(settings,storage); var maxApiRequestSize = settings.apiMaxLength || '5mb'; @@ -136,10 +127,11 @@ async function stop() { editor.stop(); } } + module.exports = { - init: init, - start: start, - stop: stop, + init, + start, + stop, /** * @memberof @node-red/editor-api diff --git a/packages/node_modules/@node-red/editor-api/lib/util.js b/packages/node_modules/@node-red/editor-api/lib/util.js index 621fd9e33..f1420235a 100644 --- a/packages/node_modules/@node-red/editor-api/lib/util.js +++ b/packages/node_modules/@node-red/editor-api/lib/util.js @@ -14,10 +14,9 @@ * limitations under the License. **/ +const express = require("express"); -var log = require("@node-red/util").log; // TODO: separate module -var i18n = require("@node-red/util").i18n; // TODO: separate module - +const { log, i18n } = require("@node-red/util"); module.exports = { errorHandler: function(err,req,res,next) { @@ -64,5 +63,17 @@ module.exports = { path: req.path, ip: (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined } + }, + createExpressApp: function(settings) { + const app = express(); + + const defaultServerSettings = { + "x-powered-by": false + } + const serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{}); + for (let eOption in serverSettings) { + app.set(eOption, serverSettings[eOption]); + } + return app } } diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index a886cd2ca..74f03c55c 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -89,6 +89,15 @@ function init(userSettings,httpServer,_adminApi) { nodeApp = express(); adminApp = express(); + const defaultServerSettings = { + "x-powered-by": false + } + const serverSettings = Object.assign({},defaultServerSettings,userSettings.httpServerOptions||{}); + for (let eOption in serverSettings) { + nodeApp.set(eOption, serverSettings[eOption]); + adminApp.set(eOption, serverSettings[eOption]); + } + if (_adminApi) { adminApi = _adminApi; diff --git a/test/unit/@node-red/editor-api/lib/editor/index_spec.js b/test/unit/@node-red/editor-api/lib/editor/index_spec.js index 8ed4d88f3..2c11acbc3 100644 --- a/test/unit/@node-red/editor-api/lib/editor/index_spec.js +++ b/test/unit/@node-red/editor-api/lib/editor/index_spec.js @@ -61,12 +61,14 @@ describe("api/editor/index", function() { sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/"+m),"init").callsFake(function(){}); }); sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme"),"app").callsFake(function(){ return express()}); + sinon.stub(NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/settings"),"sshkeys").callsFake(function(){ return express()}); }); after(function() { mockList.forEach(function(m) { NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/"+m).init.restore(); }) NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/theme").app.restore(); + NR_TEST_UTILS.require("@node-red/editor-api/lib/editor/settings").sshkeys.restore(); auth.needsPermission.restore(); log.error.restore(); }); diff --git a/test/unit/@node-red/editor-api/lib/editor/settings_spec.js b/test/unit/@node-red/editor-api/lib/editor/settings_spec.js index 171dca564..19f72977a 100644 --- a/test/unit/@node-red/editor-api/lib/editor/settings_spec.js +++ b/test/unit/@node-red/editor-api/lib/editor/settings_spec.js @@ -41,7 +41,7 @@ describe("api/editor/settings", function() { }); it('returns the user settings', function(done) { - info.init({ + info.init({}, { settings: { getUserSettings: function(opts) { if (opts.user !== "fred") { @@ -67,7 +67,7 @@ describe("api/editor/settings", function() { }); it('updates the user settings', function(done) { var update; - info.init({ + info.init({}, { settings: { updateUserSettings: function(opts) { if (opts.user !== "fred") { diff --git a/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js b/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js index 1647cd99d..75e8063f6 100644 --- a/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js +++ b/test/unit/@node-red/editor-api/lib/editor/sshkeys_spec.js @@ -34,7 +34,7 @@ describe("api/editor/sshkeys", function() { } } before(function() { - sshkeys.init(mockRuntime); + sshkeys.init({}, mockRuntime); app = express(); app.use(bodyParser.json()); app.use("/settings/user/keys", sshkeys.app());