diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ed34b9fad..b7239546c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,5 +1,6 @@
name: PublishDockerImage
-
+env:
+ ACTIONS_ALLOW_UNSECURE_COMMANDS: true
on:
release:
types: [published]
@@ -27,8 +28,6 @@ jobs:
with:
node-version: '12'
- run: node ./node-red/.github/scripts/update-node-red-docker.js
- env:
- ACTIONS_ALLOW_UNSECURE_COMMANDS: true
- name: Create Docker Pull Request
uses: peter-evans/create-pull-request@v2
with:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c12019755..fdbb4ada9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,25 @@
+### 1.2.7: Maintenance Release
+
+Editor
+
+ - Ensure subflow-scoped config nodes do not get moved on import Fixes #2789
+ - Allow TypedInput to be disabled (#2752) @bartbutenaers
+ - Allow userMenu to be explicitly enabled (#2805) @tfmf
+ - Improvements to DE translation (#2192) @ketzu
+
+
+Runtime
+
+ - Handle `undefined` error passed to node.error (#2781) @johnwang71
+ - Disable nyc coverage reporting on older node versions
+ - Improve Editor API unit test coverage (#2777) @aaronmyatt
+
+
+Nodes
+
+ - Trigger: ensure timestamp option sends .now() at point of sending
+
+
### 1.2.6: Maintenance Release
diff --git a/package.json b/package.json
index b1981d8cc..cddf1f76e 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
],
"dependencies": {
"ajv": "6.12.6",
- "async-mutex": "0.2.4",
+ "async-mutex": "0.2.6",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
@@ -38,7 +38,7 @@
"cookie-parser": "1.4.5",
"cors": "2.8.5",
"cron": "1.7.2",
- "denque": "1.4.1",
+ "denque": "1.5.0",
"express": "4.17.1",
"express-session": "1.17.1",
"fs-extra": "8.1.0",
@@ -54,11 +54,11 @@
"lodash.clonedeep": "^4.5.0",
"media-typer": "1.1.0",
"memorystore": "1.6.4",
- "mime": "2.4.6",
+ "mime": "2.4.7",
"moment-timezone": "0.5.32",
"mqtt": "4.2.6",
"multer": "1.4.2",
- "mustache": "4.0.1",
+ "mustache": "4.1.0",
"node-red-admin": "^0.2.6",
"node-red-node-rbe": "^0.2.9",
"node-red-node-sentiment": "^0.1.6",
@@ -73,7 +73,7 @@
"request": "2.88.0",
"semver": "6.3.0",
"tar": "6.0.5",
- "uglify-js": "3.11.6",
+ "uglify-js": "3.12.4",
"ws": "6.2.1",
"xml2js": "0.4.23"
},
@@ -81,7 +81,7 @@
"bcrypt": "3.0.8"
},
"devDependencies": {
- "dompurify": "2.2.2",
+ "dompurify": "2.2.6",
"grunt": "1.3.0",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.3.2",
@@ -103,7 +103,7 @@
"grunt-simple-nyc": "^3.0.1",
"http-proxy": "1.18.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
- "marked": "1.2.5",
+ "marked": "1.2.7",
"minami": "1.2.3",
"mocha": "^5.2.0",
"node-red-node-test-helper": "^0.2.5",
diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json
index 516532e37..0b9ebb224 100644
--- a/packages/node_modules/@node-red/editor-api/package.json
+++ b/packages/node_modules/@node-red/editor-api/package.json
@@ -25,9 +25,9 @@
"express-session": "1.17.1",
"express": "4.17.1",
"memorystore": "1.6.4",
- "mime": "2.4.6",
+ "mime": "2.4.7",
"multer": "1.4.2",
- "mustache": "4.0.1",
+ "mustache": "4.1.0",
"oauth2orize": "1.11.0",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
diff --git a/packages/node_modules/@node-red/editor-client/locales/de/editor.json b/packages/node_modules/@node-red/editor-client/locales/de/editor.json
index 0c8dd42eb..7c408d742 100755
--- a/packages/node_modules/@node-red/editor-client/locales/de/editor.json
+++ b/packages/node_modules/@node-red/editor-client/locales/de/editor.json
@@ -32,7 +32,7 @@
"label" : {
"view" : {
"view" : "Ansicht",
- "grid" : "Gitter",
+ "grid" : "Raster",
"showGrid" : "Raster anzeigen",
"snapGrid" : "Am Raster ausrichten",
"gridSize" : "Rastergröße",
diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
index ddeea65e6..0d664ce3c 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
@@ -1360,7 +1360,7 @@ RED.nodes = (function() {
}
}
} else {
- if (n.z && !workspaces[n.z]) {
+ if (n.z && !workspaces[n.z] && !subflow_map[n.z]) {
n.z = activeWorkspace;
}
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
index fa1e68cca..332f41fa9 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
@@ -965,6 +965,18 @@
},
hide: function() {
this.uiSelect.hide();
+ },
+ disable: function(val) {
+ if(val === true) {
+ this.uiSelect.attr("disabled", "disabled");
+ } else if (val === false) {
+ this.uiSelect.attr("disabled", null); //remove attr
+ } else {
+ this.uiSelect.attr("disabled", val); //user value
+ }
+ },
+ disabled: function() {
+ return this.uiSelect.attr("disabled");
}
});
})(jQuery);
diff --git a/packages/node_modules/@node-red/editor-client/src/js/user.js b/packages/node_modules/@node-red/editor-client/src/js/user.js
index dd0ff8f90..bd7339285 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/user.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/user.js
@@ -219,7 +219,7 @@ RED.user = (function() {
function init() {
if (RED.settings.user) {
- if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) {
+ if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu") || RED.settings.editorTheme.userMenu) {
var userMenu = $('
')
.prependTo(".red-ui-header-toolbar");
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss
index fb3e331ee..14cb3f70e 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss
@@ -26,6 +26,14 @@
box-sizing: border-box;
overflow:visible;
position: relative;
+ &[disabled] {
+ input, button {
+ background: $secondary-background-inactive;
+ pointer-events: none;
+ cursor: not-allowed;
+ }
+ }
+
.red-ui-typedInput-input-wrap {
flex-grow: 1;
}
diff --git a/packages/node_modules/@node-red/nodes/locales/de/messages.json b/packages/node_modules/@node-red/nodes/locales/de/messages.json
index 7d9bd3523..fe1e1dfc1 100755
--- a/packages/node_modules/@node-red/nodes/locales/de/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/de/messages.json
@@ -583,11 +583,11 @@
"regex" : "Reguläre Ausdrücke verwenden"
},
"action" : {
- "set" : "Festlegen",
+ "set" : "Setze",
"change" : "Ändern",
"delete" : "Löschen",
"move" : "Bewegen",
- "to" : "bis",
+ "to" : "auf",
"search" : "Suchen nach",
"replace" : "Ersetzen durch"
},
diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json
index 07c107af7..b3e510f9a 100644
--- a/packages/node_modules/@node-red/nodes/package.json
+++ b/packages/node_modules/@node-red/nodes/package.json
@@ -23,7 +23,7 @@
"cookie": "0.4.1",
"cors": "2.8.5",
"cron": "1.7.2",
- "denque": "1.4.1",
+ "denque": "1.5.0",
"fs-extra": "8.1.0",
"fs.notify": "0.0.4",
"hash-sum": "2.0.0",
@@ -33,7 +33,7 @@
"media-typer": "1.1.0",
"mqtt": "4.2.6",
"multer": "1.4.2",
- "mustache": "4.0.1",
+ "mustache": "4.1.0",
"on-headers": "1.0.2",
"raw-body": "2.4.1",
"request": "2.88.0",
diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json
index 3d517421c..c2c533633 100644
--- a/packages/node_modules/@node-red/registry/package.json
+++ b/packages/node_modules/@node-red/registry/package.json
@@ -19,6 +19,6 @@
"@node-red/util": "1.3.0-beta.1",
"semver": "6.3.0",
"tar": "6.0.5",
- "uglify-js": "3.11.6"
+ "uglify-js": "3.12.4"
}
}
diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js
index a4791e084..307da6d62 100644
--- a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js
+++ b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js
@@ -470,8 +470,8 @@ class Flow {
}
// console.log("HE",logMessage);
var count = 1;
- if (msg && msg.hasOwnProperty("error") && msg.error !== null) {
- if (msg.error.hasOwnProperty("source") && msg.error.source !== null) {
+ if (msg && msg.hasOwnProperty("error") && msg.error) {
+ if (msg.error.hasOwnProperty("source") && msg.error.source) {
if (msg.error.source.id === node.id) {
count = msg.error.source.count+1;
if (count === 10) {
diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js b/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js
index da15ecfe4..87facdc23 100644
--- a/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js
+++ b/packages/node_modules/@node-red/runtime/lib/flows/Subflow.js
@@ -112,8 +112,8 @@ class Subflow extends Flow {
this.node_map = node_map;
this.path = parent.path+"/"+(subflowInstance._alias||subflowInstance.id);
- this.templateCredentials = credentials.get(subflowDef.id);
- this.instanceCredentials = credentials.get(this.id);
+ this.templateCredentials = credentials.get(subflowDef.id) || {};
+ this.instanceCredentials = credentials.get(this.id) || {};
var env = [];
if (this.subflowDef.env) {
diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json
index 1a549e0c6..cd828c50b 100644
--- a/packages/node_modules/@node-red/runtime/package.json
+++ b/packages/node_modules/@node-red/runtime/package.json
@@ -18,7 +18,7 @@
"dependencies": {
"@node-red/registry": "1.3.0-beta.1",
"@node-red/util": "1.3.0-beta.1",
- "async-mutex": "0.2.4",
+ "async-mutex": "0.2.6",
"clone": "2.1.2",
"express": "4.17.1",
"fs-extra": "8.1.0",
diff --git a/test/unit/@node-red/editor-api/lib/editor/theme_spec.js b/test/unit/@node-red/editor-api/lib/editor/theme_spec.js
index 55006f71b..5c8123d61 100644
--- a/test/unit/@node-red/editor-api/lib/editor/theme_spec.js
+++ b/test/unit/@node-red/editor-api/lib/editor/theme_spec.js
@@ -142,4 +142,19 @@ describe("api/editor/theme", function () {
settings.projects.should.have.a.property("enabled", false);
});
+ it("test explicit userMenu set to true in theme setting", function () {
+ theme.init({
+ editorTheme: {
+ userMenu: true,
+ }
+ });
+
+ theme.app();
+
+ var settings = theme.settings();
+ settings.should.have.a.property("userMenu");
+ settings.userMenu.should.be.eql(true);
+
+ });
+
});
diff --git a/test/unit/@node-red/editor-api/lib/index_spec.js b/test/unit/@node-red/editor-api/lib/index_spec.js
index ec846cf65..28928181b 100644
--- a/test/unit/@node-red/editor-api/lib/index_spec.js
+++ b/test/unit/@node-red/editor-api/lib/index_spec.js
@@ -18,10 +18,9 @@ var should = require("should");
var sinon = require("sinon");
var request = require("supertest");
var express = require("express");
-var fs = require("fs");
-var path = require("path");
var NR_TEST_UTILS = require("nr-test-utils");
+const auth = require("basic-auth");
var api = NR_TEST_UTILS.require("@node-red/editor-api");
@@ -95,4 +94,89 @@ describe("api/index", function() {
request(api.httpAdmin).get("/auth/login").expect(200).end(done)
})
});
+
+ describe('initialises api with admin middleware', function(done) {
+ it('ignores non-function values',function(done) {
+ api.init({ httpAdminRoot: true, httpAdminMiddleware: undefined },{},{},{});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'testMiddleware')
+ should(middlewareFound).be.empty();
+ done();
+ });
+
+ it('only accepts functions as middleware',function(done) {
+ const testMiddleware = function(req, res, next){ next(); };
+ api.init({ httpAdminRoot: true, httpAdminMiddleware: testMiddleware },{},{},{});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'testMiddleware')
+ should(middlewareFound).be.length(1);
+ done();
+ });
+ });
+
+ describe('initialises api with authentication enabled', function(done) {
+
+ it('enables an oauth/openID based authentication mechanism',function(done) {
+ const stub = sinon.stub(apiAuth, 'genericStrategy', function(){});
+ const adminAuth = { type: 'strategy', strategy: {} }
+ api.init({ httpAdminRoot: true, adminAuth },{},{},{});
+ should(stub.called).be.ok();
+ stub.restore();
+ done();
+ });
+
+ it('enables password protection',function(done) {
+ const adminAuth = { type: 'credentials' }
+ api.init({ httpAdminRoot: true, adminAuth },{},{},{});
+
+ // is the name ("initialize") of the passport middleware present
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'initialize')
+ should(middlewareFound).be.length(1);
+ done();
+ });
+
+ });
+
+ describe('initialises api with custom cors config', function (done) {
+ const httpAdminCors = {
+ origin: "*",
+ methods: "GET,PUT,POST,DELETE"
+ };
+
+ it('uses default cors middleware when user settings absent', function(done){
+ api.init({ httpAdminRoot: true }, {}, {}, {});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'corsMiddleware')
+ should(middlewareFound).be.length(1);
+ done();
+ })
+
+ it('enables custom cors middleware when settings present', function(done){
+ api.init({ httpAdminRoot: true, httpAdminCors }, {}, {}, {});
+ const middlewareFound = api.httpAdmin._router.stack.filter((layer) => layer.name === 'corsMiddleware')
+ should(middlewareFound).be.length(2);
+ done();
+ })
+ });
+
+ describe('editor start', function (done) {
+
+ it('cannot be started when editor is disabled', function (done) {
+ const stub = sinon.stub(apiEditor, 'start', function () {
+ return Promise.resolve(true);
+ });
+ api.init({ httpAdminRoot: true, disableEditor: true }, {}, {}, {});
+ should(api.start()).resolvedWith(true);
+ stub.restore();
+ done();
+ });
+
+ it('can be started when editor enabled', function (done) {
+ const stub = sinon.stub(apiEditor, 'start');
+ api.init({ httpAdminRoot: true, disableEditor: false }, {}, {}, {});
+ api.start();
+ should(stub.called).be.true();
+ stub.restore();
+ done();
+ });
+
+ });
+
});