diff --git a/editor/js/main.js b/editor/js/main.js index 04270f7be..f97374b0e 100644 --- a/editor/js/main.js +++ b/editor/js/main.js @@ -179,13 +179,25 @@ ] } } else if (msg.error === "credentials_load_failed") { - if (RED.user.hasPermission("projects.write")) { + if (RED.settings.theme("projects.enabled",false)) { + // projects enabled + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: "Setup credentials", + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.showCredentialsPrompt(); + } + } + ] + } + } else { options.buttons = [ { - text: "Setup credentials", + text: "Close", click: function() { persistentNotifications[notificationId].hideNotification(); - RED.projects.showCredentialsPrompt(); } } ] diff --git a/red/api/editor/locales/en-US/editor.json b/red/api/editor/locales/en-US/editor.json index 882e2808d..189dbaba7 100644 --- a/red/api/editor/locales/en-US/editor.json +++ b/red/api/editor/locales/en-US/editor.json @@ -91,6 +91,7 @@ "missing-types": "
Flows stopped due to missing node types.
", "restartRequired": "Node-RED must be restarted to enable upgraded modules", "credentials_load_failed": "Flows stopped as the credentials could not be decrypted.
The flow credential file is encrypted, but the project's encryption key is missing or invalid.
", + "credentials_load_failed_reset":"Credentials could not be decrypted
The flow credential file is encrypted, but the project's encryption key is missing or invalid.
The flow credential file will be reset on the next deployment. Any existing flow credentials will be cleared.
", "missing_flow_file": "Project flow file not found.
The project is not configured with a flow file.
", "project_empty": "The project is empty.
Do you want to create a default set of project files?
Otherwise, you will have to manually add files to the project outside of the editor.
Project '__project__' not found.
", diff --git a/red/runtime/nodes/flows/index.js b/red/runtime/nodes/flows/index.js index a8cea3822..54f8092e6 100644 --- a/red/runtime/nodes/flows/index.js +++ b/red/runtime/nodes/flows/index.js @@ -37,6 +37,7 @@ var activeFlowConfig = null; var activeFlows = {}; var started = false; +var credentialsPendingReset = false; var activeNodesToFlow = {}; var subflowInstanceNodeMap = {}; @@ -70,21 +71,31 @@ function init(runtime) { } function loadFlows() { - return storage.getFlows().then(function(config) { + var config; + return storage.getFlows().then(function(_config) { + config = _config; log.debug("loaded flow revision: "+config.rev); return credentials.load(config.credentials).then(function() { events.emit("runtime-event",{id:"runtime-state",retain:true}); return config; }); }).catch(function(err) { - activeConfig = null; - events.emit("runtime-event",{id:"runtime-state",payload:{type:"warning",error:err.code,project:err.project,text:"notification.warnings."+err.code},retain:true}); - if (err.code === "project_not_found") { - log.warn(log._("storage.localfilesystem.projects.project-not-found",{project:err.project})); - } else { + if (err.code === "credentials_load_failed" && !storage.projects) { + // project disabled, credential load failed + credentialsPendingReset = true; log.warn(log._("nodes.flows.error",{message:err.toString()})); + events.emit("runtime-event",{id:"runtime-state",payload:{type:"warning",error:err.code,text:"notification.warnings.credentials_load_failed_reset"},retain:true}); + return config; + } else { + activeConfig = null; + events.emit("runtime-event",{id:"runtime-state",payload:{type:"warning",error:err.code,project:err.project,text:"notification.warnings."+err.code},retain:true}); + if (err.code === "project_not_found") { + log.warn(log._("storage.localfilesystem.projects.project-not-found",{project:err.project})); + } else { + log.warn(log._("nodes.flows.error",{message:err.toString()})); + } + throw err; } - throw err; }); } function load(forceStart) { @@ -317,7 +328,12 @@ function start(type,diff,muteLog) { } } events.emit("nodes-started"); - events.emit("runtime-event",{id:"runtime-state",retain:true}); + + if (credentialsPendingReset === true) { + credentialsPendingReset = false; + } else { + events.emit("runtime-event",{id:"runtime-state",retain:true}); + } if (!muteLog) { if (type !== "full") {