1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Handle subflow modules that contain subflows

This commit is contained in:
Nick O'Leary 2021-04-28 21:49:32 +01:00
parent ad316ffd37
commit 7df1a03b4b
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
3 changed files with 51 additions and 47 deletions

View File

@ -95,6 +95,9 @@ function createNode(flow,config) {
} else if (nodeTypeConstructor) { } else if (nodeTypeConstructor) {
// console.log(nodeTypeConstructor) // console.log(nodeTypeConstructor)
var subflowConfig = parseConfig([nodeTypeConstructor.subflow].concat(nodeTypeConstructor.subflow.flow)); var subflowConfig = parseConfig([nodeTypeConstructor.subflow].concat(nodeTypeConstructor.subflow.flow));
var subflowInstanceConfig = subflowConfig.subflows[nodeTypeConstructor.subflow.id];
delete subflowConfig.subflows[nodeTypeConstructor.subflow.id];
subflowInstanceConfig.subflows = subflowConfig.subflows;
var instanceConfig = clone(config); var instanceConfig = clone(config);
instanceConfig.env = clone(nodeTypeConstructor.subflow.env); instanceConfig.env = clone(nodeTypeConstructor.subflow.env);
@ -124,7 +127,7 @@ function createNode(flow,config) {
nodeTypeConstructor.type, nodeTypeConstructor.type,
flow, flow,
flow.global, flow.global,
subflowConfig.subflows[nodeTypeConstructor.subflow.id], subflowInstanceConfig,
instanceConfig instanceConfig
); );
subflow.start(); subflow.start();

View File

@ -343,7 +343,11 @@ var api = module.exports = {
if (newCreds) { if (newCreds) {
delete node.credentials; delete node.credentials;
var savedCredentials = credentialCache[nodeID] || {}; var savedCredentials = credentialCache[nodeID] || {};
if (/^subflow(:|$)/.test(nodeType)) { // Need to check the type of constructor for this node.
// - Function : regular node
// - !Function: subflow module
if (/^subflow(:|$)/.test(nodeType) || typeof runtime.nodes.getType(nodeType) !== 'function') {
for (cred in newCreds) { for (cred in newCreds) {
if (newCreds.hasOwnProperty(cred)) { if (newCreds.hasOwnProperty(cred)) {
if (newCreds[cred] === "__PWRD__") { if (newCreds[cred] === "__PWRD__") {

View File

@ -36,102 +36,96 @@ describe('red/runtime/nodes/credentials', function() {
index.clearRegistry(); index.clearRegistry();
}); });
it('loads provided credentials',function(done) { it('loads provided credentials',function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings
}); });
credentials.load({"a":{"b":1,"c":2}}).then(function() { return credentials.load({"a":{"b":1,"c":2}}).then(function() {
credentials.get("a").should.have.property('b',1); credentials.get("a").should.have.property('b',1);
credentials.get("a").should.have.property('c',2); credentials.get("a").should.have.property('c',2);
done();
}); });
}); });
it('adds a new credential',function(done) { it('adds a new credential',function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings
}); });
credentials.load({"a":{"b":1,"c":2}}).then(function() { return credentials.load({"a":{"b":1,"c":2}}).then(function() {
credentials.dirty().should.be.false(); credentials.dirty().should.be.false();
should.not.exist(credentials.get("b")); should.not.exist(credentials.get("b"));
credentials.add("b",{"foo":"bar"}).then(function() { return credentials.add("b",{"foo":"bar"}).then(function() {
credentials.get("b").should.have.property("foo","bar"); credentials.get("b").should.have.property("foo","bar");
credentials.dirty().should.be.true(); credentials.dirty().should.be.true();
done();
}); });
}); });
}); });
it('deletes an existing credential',function(done) { it('deletes an existing credential',function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings
}); });
credentials.load({"a":{"b":1,"c":2}}).then(function() { return credentials.load({"a":{"b":1,"c":2}}).then(function() {
credentials.dirty().should.be.false(); credentials.dirty().should.be.false();
credentials.delete("a"); credentials.delete("a");
should.not.exist(credentials.get("a")); should.not.exist(credentials.get("a"));
credentials.dirty().should.be.true(); credentials.dirty().should.be.true();
done();
}); });
}); });
it('exports the credentials, clearing dirty flag', function(done) { it('exports the credentials, clearing dirty flag', function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings
}); });
var creds = {"a":{"b":1,"c":2}}; var creds = {"a":{"b":1,"c":2}};
credentials.load(creds).then(function() { return credentials.load(creds).then(function() {
credentials.add("b",{"foo":"bar"}).then(function() { return credentials.add("b",{"foo":"bar"})
}).then(function() {
credentials.dirty().should.be.true(); credentials.dirty().should.be.true();
credentials.export().then(function(exported) { return credentials.export().then(function(exported) {
exported.should.eql(creds); exported.should.eql(creds);
credentials.dirty().should.be.false(); credentials.dirty().should.be.false();
done();
}) })
}); });
});
}) })
describe("#clean",function() { describe("#clean",function() {
it("removes credentials of unknown nodes",function(done) { it("removes credentials of unknown nodes",function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings,
nodes: { getType: () => function(){} }
}); });
var creds = {"a":{"b":1,"c":2},"b":{"d":3}}; var creds = {"a":{"b":1,"c":2},"b":{"d":3}};
credentials.load(creds).then(function() { return credentials.load(creds).then(function() {
credentials.dirty().should.be.false(); credentials.dirty().should.be.false();
should.exist(credentials.get("a")); should.exist(credentials.get("a"));
should.exist(credentials.get("b")); should.exist(credentials.get("b"));
credentials.clean([{id:"b"}]).then(function() { return credentials.clean([{id:"b"}]).then(function() {
credentials.dirty().should.be.true(); credentials.dirty().should.be.true();
should.not.exist(credentials.get("a")); should.not.exist(credentials.get("a"));
should.exist(credentials.get("b")); should.exist(credentials.get("b"));
done();
}); });
}); });
}); });
it("extracts credentials of known nodes",function(done) { it("extracts credentials of known nodes",function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings,
nodes: { getType: () => function(){} }
}); });
credentials.register("testNode",{"b":"text","c":"password"}) credentials.register("testNode",{"b":"text","c":"password"})
var creds = {"a":{"b":1,"c":2}}; var creds = {"a":{"b":1,"c":2}};
var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}]; var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}];
credentials.load(creds).then(function() { return credentials.load(creds).then(function() {
credentials.dirty().should.be.false(); credentials.dirty().should.be.false();
credentials.clean(newConfig).then(function() { return credentials.clean(newConfig).then(function() {
credentials.dirty().should.be.true(); credentials.dirty().should.be.true();
credentials.get("a").should.have.property('b',"newBValue"); credentials.get("a").should.have.property('b',"newBValue");
credentials.get("a").should.have.property('c',"newCValue"); credentials.get("a").should.have.property('c',"newCValue");
should.not.exist(newConfig[0].credentials); should.not.exist(newConfig[0].credentials);
done();
}); });
}); });
}); });
@ -139,12 +133,13 @@ describe('red/runtime/nodes/credentials', function() {
}); });
it('warns if a node has no credential definition', function(done) { it('warns if a node has no credential definition', function() {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings,
nodes: { getType: () => function(){} }
}); });
credentials.load({}).then(function() { return credentials.load({}).then(function() {
var node = {id:"node",type:"test",credentials:{ var node = {id:"node",type:"test",credentials:{
user1:"newUser", user1:"newUser",
password1:"newPassword" password1:"newPassword"
@ -154,14 +149,14 @@ describe('red/runtime/nodes/credentials', function() {
log.warn.called.should.be.true(); log.warn.called.should.be.true();
should.not.exist(node.credentials); should.not.exist(node.credentials);
log.warn.restore(); log.warn.restore();
done();
}); });
}) })
it('extract credential updates in the provided node', function(done) { it('extract credential updates in the provided node', function(done) {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings,
nodes: { getType: () => function(){} }
}); });
var defintion = { var defintion = {
user1:{type:"text"}, user1:{type:"text"},
@ -205,7 +200,8 @@ describe('red/runtime/nodes/credentials', function() {
it('extract ignores node without credentials', function(done) { it('extract ignores node without credentials', function(done) {
credentials.init({ credentials.init({
log: log, log: log,
settings: encryptionDisabledSettings settings: encryptionDisabledSettings,
nodes: { getType: () => function(){} }
}); });
credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() { credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() {
var node = {id:"node",type:"test"}; var node = {id:"node",type:"test"};
@ -233,7 +229,8 @@ describe('red/runtime/nodes/credentials', function() {
delete settings[key]; delete settings[key];
return Promise.resolve(); return Promise.resolve();
} }
} },
nodes: { getType: () => function(){} }
} }
it('migrates to encrypted and generates default key', function(done) { it('migrates to encrypted and generates default key', function(done) {
settings = {}; settings = {};
@ -341,7 +338,7 @@ describe('red/runtime/nodes/credentials', function() {
}); });
}); });
}); });
it('migrates from default key to user key', function(done) { it('migrates from default key to user key', function() {
settings = { settings = {
_credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a", _credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a",
credentialSecret: "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccddddddddddddeeeee" credentialSecret: "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccddddddddddddeeeee"
@ -349,21 +346,20 @@ describe('red/runtime/nodes/credentials', function() {
// {"node":{user1:"abc",password1:"123"}} // {"node":{user1:"abc",password1:"123"}}
var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"};
credentials.init(runtime); credentials.init(runtime);
credentials.load(cryptedFlows).then(function() { return credentials.load(cryptedFlows).then(function() {
credentials.dirty().should.be.true(); credentials.dirty().should.be.true();
should.exist(credentials.get("node")); should.exist(credentials.get("node"));
credentials.export().then(function(result) { return credentials.export().then(function(result) {
result.should.have.a.property("$"); result.should.have.a.property("$");
settings.should.not.have.a.property("_credentialSecret"); settings.should.not.have.a.property("_credentialSecret");
// reset everything - but with _credentialSecret still set // reset everything - but with _credentialSecret still set
credentials.init(runtime); credentials.init(runtime);
// load the freshly encrypted version // load the freshly encrypted version
credentials.load(result).then(function() { return credentials.load(result).then(function() {
should.exist(credentials.get("node")); should.exist(credentials.get("node"));
credentials.get("node").should.have.a.property("user1","abc"); credentials.get("node").should.have.a.property("user1","abc");
credentials.get("node").should.have.a.property("password1","123"); credentials.get("node").should.have.a.property("password1","123");
done();
}) })
}); });
}); });
@ -459,7 +455,8 @@ describe('red/runtime/nodes/credentials', function() {
set: function(key,value) { set: function(key,value) {
throw new Error(); throw new Error();
} }
} },
nodes: { getType: () => function(){} }
} }
// {"node":{user1:"abc",password1:"123"}} // {"node":{user1:"abc",password1:"123"}}
credentials.init(runtime); credentials.init(runtime);