2014-11-04 12:34:49 +01:00
|
|
|
/**
|
2017-01-11 16:24:33 +01:00
|
|
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
2014-11-04 12:34:49 +01:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
**/
|
|
|
|
|
2019-01-28 15:40:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This module provides an Express application to serve the Node-RED editor.
|
|
|
|
*
|
|
|
|
* It implements the Node-RED HTTP Admin API the Editor uses to interact
|
|
|
|
* with the Node-RED runtime.
|
|
|
|
*
|
|
|
|
* @namespace @node-red/editor-api
|
|
|
|
*/
|
|
|
|
|
2014-11-04 12:34:49 +01:00
|
|
|
var express = require("express");
|
2015-07-15 23:43:24 +02:00
|
|
|
var bodyParser = require("body-parser");
|
2014-11-04 12:34:49 +01:00
|
|
|
var util = require('util');
|
2014-11-06 23:59:48 +01:00
|
|
|
var passport = require('passport');
|
2016-05-31 15:55:03 +02:00
|
|
|
var cors = require('cors');
|
2014-11-04 12:34:49 +01:00
|
|
|
|
2014-11-06 23:59:48 +01:00
|
|
|
var auth = require("./auth");
|
2017-08-22 23:26:29 +02:00
|
|
|
var apiUtil = require("./util");
|
2014-11-04 12:34:49 +01:00
|
|
|
|
2015-11-11 23:11:02 +01:00
|
|
|
var adminApp;
|
2015-11-24 23:38:42 +01:00
|
|
|
var server;
|
2017-08-22 23:26:29 +02:00
|
|
|
var editor;
|
2016-03-12 01:03:50 +01:00
|
|
|
|
2019-01-28 15:40:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialise the module.
|
|
|
|
* @param {Object} settings The runtime settings
|
2019-10-21 17:35:35 +02:00
|
|
|
* @param {HTTPServer} _server An instance of HTTP Server
|
2019-01-28 15:40:24 +01:00
|
|
|
* @param {Storage} storage An instance of Node-RED Storage
|
|
|
|
* @param {Runtime} runtimeAPI An instance of Node-RED Runtime
|
|
|
|
* @memberof @node-red/editor-api
|
|
|
|
*/
|
2018-12-01 00:01:09 +01:00
|
|
|
function init(settings,_server,storage,runtimeAPI) {
|
2015-11-24 23:38:42 +01:00
|
|
|
server = _server;
|
2015-11-11 23:11:02 +01:00
|
|
|
if (settings.httpAdminRoot !== false) {
|
|
|
|
adminApp = express();
|
2018-05-14 15:32:58 +02:00
|
|
|
|
|
|
|
var cors = require('cors');
|
|
|
|
var corsHandler = cors({
|
|
|
|
origin: "*",
|
|
|
|
methods: "GET,PUT,POST,DELETE"
|
|
|
|
});
|
|
|
|
adminApp.use(corsHandler);
|
|
|
|
|
2020-05-05 19:13:21 +02:00
|
|
|
if (settings.httpAdminMiddleware) {
|
2020-12-22 23:28:33 +01:00
|
|
|
if (typeof settings.httpAdminMiddleware === "function" || Array.isArray(settings.httpAdminMiddleware)) {
|
|
|
|
adminApp.use(settings.httpAdminMiddleware);
|
2020-05-05 19:13:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-08 22:17:42 +02:00
|
|
|
var defaultServerSettings = {
|
|
|
|
"x-powered-by": false
|
|
|
|
}
|
|
|
|
var serverSettings = Object.assign({},defaultServerSettings,settings.httpServerOptions||{});
|
|
|
|
for (var eOption in serverSettings) {
|
|
|
|
adminApp.set(eOption, serverSettings[eOption]);
|
|
|
|
}
|
|
|
|
|
2018-04-23 12:21:02 +02:00
|
|
|
auth.init(settings,storage);
|
2015-11-11 23:11:02 +01:00
|
|
|
|
2016-10-10 11:14:08 +02:00
|
|
|
var maxApiRequestSize = settings.apiMaxLength || '5mb';
|
2015-11-11 23:11:02 +01:00
|
|
|
adminApp.use(bodyParser.json({limit:maxApiRequestSize}));
|
|
|
|
adminApp.use(bodyParser.urlencoded({limit:maxApiRequestSize,extended:true}));
|
|
|
|
|
2017-08-22 23:26:29 +02:00
|
|
|
adminApp.get("/auth/login",auth.login,apiUtil.errorHandler);
|
2015-11-11 23:11:02 +01:00
|
|
|
if (settings.adminAuth) {
|
2017-04-21 22:54:48 +02:00
|
|
|
if (settings.adminAuth.type === "strategy") {
|
|
|
|
auth.genericStrategy(adminApp,settings.adminAuth.strategy);
|
2017-04-12 11:09:03 +02:00
|
|
|
} else if (settings.adminAuth.type === "credentials") {
|
|
|
|
adminApp.use(passport.initialize());
|
|
|
|
adminApp.post("/auth/token",
|
|
|
|
auth.ensureClientSecret,
|
|
|
|
auth.authenticateClient,
|
|
|
|
auth.getToken,
|
|
|
|
auth.errorHandler
|
|
|
|
);
|
2022-01-12 14:26:18 +01:00
|
|
|
} else if (settings.adminAuth.tokens) {
|
|
|
|
adminApp.use(passport.initialize());
|
2017-04-12 11:09:03 +02:00
|
|
|
}
|
2017-08-22 23:26:29 +02:00
|
|
|
adminApp.post("/auth/revoke",auth.needsPermission(""),auth.revoke,apiUtil.errorHandler);
|
2015-11-11 23:11:02 +01:00
|
|
|
}
|
2018-01-16 12:21:54 +01:00
|
|
|
|
2017-12-04 12:42:44 +01:00
|
|
|
// Editor
|
|
|
|
if (!settings.disableEditor) {
|
|
|
|
editor = require("./editor");
|
2018-04-23 12:21:02 +02:00
|
|
|
var editorApp = editor.init(server, settings, runtimeAPI);
|
2017-12-04 12:42:44 +01:00
|
|
|
adminApp.use(editorApp);
|
|
|
|
}
|
2017-08-22 23:26:29 +02:00
|
|
|
|
2016-05-31 15:55:03 +02:00
|
|
|
if (settings.httpAdminCors) {
|
|
|
|
var corsHandler = cors(settings.httpAdminCors);
|
|
|
|
adminApp.use(corsHandler);
|
|
|
|
}
|
2014-11-06 23:59:48 +01:00
|
|
|
|
2020-07-31 16:26:21 +02:00
|
|
|
var adminApiApp = require("./admin").init(settings, runtimeAPI);
|
2017-08-22 23:26:29 +02:00
|
|
|
adminApp.use(adminApiApp);
|
|
|
|
} else {
|
|
|
|
adminApp = null;
|
2015-11-11 23:11:02 +01:00
|
|
|
}
|
2014-11-04 12:34:49 +01:00
|
|
|
}
|
2019-01-28 15:40:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Start the module.
|
|
|
|
* @return {Promise} resolves when the application is ready to handle requests
|
|
|
|
* @memberof @node-red/editor-api
|
|
|
|
*/
|
2020-11-30 15:38:48 +01:00
|
|
|
async function start() {
|
2017-08-22 23:26:29 +02:00
|
|
|
if (editor) {
|
|
|
|
return editor.start();
|
|
|
|
}
|
2015-11-12 10:03:03 +01:00
|
|
|
}
|
2019-01-28 15:40:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the module.
|
|
|
|
* @return {Promise} resolves when the application is stopped
|
|
|
|
* @memberof @node-red/editor-api
|
|
|
|
*/
|
2020-11-30 15:38:48 +01:00
|
|
|
async function stop() {
|
2017-08-22 23:26:29 +02:00
|
|
|
if (editor) {
|
|
|
|
editor.stop();
|
|
|
|
}
|
2015-11-12 10:03:03 +01:00
|
|
|
}
|
2014-11-04 12:34:49 +01:00
|
|
|
module.exports = {
|
2015-11-11 23:11:02 +01:00
|
|
|
init: init,
|
2015-11-12 10:03:03 +01:00
|
|
|
start: start,
|
|
|
|
stop: stop,
|
2019-01-28 15:40:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @memberof @node-red/editor-api
|
|
|
|
* @mixes @node-red/editor-api_auth
|
|
|
|
*/
|
2015-11-11 23:11:02 +01:00
|
|
|
auth: {
|
|
|
|
needsPermission: auth.needsPermission
|
|
|
|
},
|
2019-01-28 15:40:24 +01:00
|
|
|
/**
|
|
|
|
* The Express app used to serve the Node-RED Editor
|
|
|
|
* @type ExpressApplication
|
|
|
|
* @memberof @node-red/editor-api
|
|
|
|
*/
|
2018-12-04 16:59:43 +01:00
|
|
|
get httpAdmin() { return adminApp; }
|
2014-11-06 11:00:25 +01:00
|
|
|
};
|