Merge branch 'master' into dev

This commit is contained in:
Nick O'Leary 2021-01-07 10:17:50 +00:00
commit 7913b3cbc2
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
17 changed files with 167 additions and 27 deletions

View File

@ -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:

View File

@ -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

View File

@ -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",

View File

@ -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",

View File

@ -32,7 +32,7 @@
"label" : {
"view" : {
"view" : "Ansicht",
"grid" : "Gitter",
"grid" : "Raster",
"showGrid" : "Raster anzeigen",
"snapGrid" : "Am Raster ausrichten",
"gridSize" : "Rastergröße",

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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 = $('<li><a id="red-ui-header-button-user" class="button hide" href="#"></a></li>')
.prependTo(".red-ui-header-toolbar");

View File

@ -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;
}

View File

@ -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"
},

View File

@ -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",

View File

@ -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"
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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",

View File

@ -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);
});
});

View File

@ -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();
});
});
});