From 14ac6446de3742184ba97b1b2c2113264fb24a6d Mon Sep 17 00:00:00 2001 From: Tyler Eastman Date: Mon, 22 Jul 2019 14:25:52 -0700 Subject: [PATCH 01/23] Handle undefined node._def in edit stack title. --- .../node_modules/@node-red/editor-client/src/js/ui/editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js index 1f4cf0ae9..e8c4b9b63 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js @@ -517,7 +517,7 @@ RED.editor = (function() { } else if (node.type.indexOf("subflow:")===0) { var subflow = RED.nodes.subflow(node.type.substring(8)); label = RED._("subflow.editSubflowInstance",{name:RED.utils.sanitize(subflow.name)}) - } else { + } else if (node._def !== undefined) { if (typeof node._def.paletteLabel !== "undefined") { try { label = RED.utils.sanitize((typeof node._def.paletteLabel === "function" ? node._def.paletteLabel.call(node._def) : node._def.paletteLabel)||""); From 2f5ec8b5bf4a0b1af7d2c806c09a66e1adbb9148 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 26 Jul 2019 17:51:49 +0900 Subject: [PATCH 02/23] Fix inserting new subflow node to existing wire between nodes --- .../@node-red/editor-client/src/js/ui/palette.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js index 28d5af46e..c50af60d0 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js @@ -243,7 +243,6 @@ RED.palette = (function() { RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp")); }); var chart = $("#chart"); - var chartOffset = chart.offset(); var chartSVG = $("#chart>svg").get(0); var activeSpliceLink; var mouseX; @@ -267,8 +266,8 @@ RED.palette = (function() { ui.originalPosition.left = $('#' + e.target.id).offset().left; if (def.inputs > 0 && def.outputs > 0) { - mouseX = ui.position.left-paletteWidth+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft(); - mouseY = ui.position.top-paletteTop+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop(); + mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft(); + mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop(); if (!spliceTimer) { spliceTimer = setTimeout(function() { var nodes = []; From 5ab90b85dae8bfba8e9b2eedd7fd20cc3134faf7 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Thu, 25 Jul 2019 17:18:59 +0100 Subject: [PATCH 03/23] Limit the regex for the /nodes/ api end points fixes #2240 It looks like the regex for the /nodes/... endpoints over matches. I've added `^` to the start to anchor the matches to the start of the URL. --- .../@node-red/editor-api/lib/admin/index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/index.js b/packages/node_modules/@node-red/editor-api/lib/admin/index.js index 32bf010c5..50d7b168f 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/index.js @@ -48,13 +48,13 @@ module.exports = { // Nodes adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler); adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler); - adminApp.get(/\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler); - adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler); - adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler); - adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler); - adminApp.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler); - adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler); - adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler); + adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler); + adminApp.delete(/^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler); + adminApp.get(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.read"),nodes.getSet,apiUtil.errorHandler); + adminApp.put(/^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,needsPermission("nodes.write"),nodes.putSet,apiUtil.errorHandler); // Context adminApp.get("/context/:scope(global)",needsPermission("context.read"),context.get,apiUtil.errorHandler); From b9e97792f348b3698c4cb21ecc63b1a2aff50d12 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 30 Jul 2019 19:52:28 +0900 Subject: [PATCH 04/23] Fix wrong variable name --- CHANGELOG.md | 2 +- packages/node_modules/node-red/settings.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e6de1ce2..b1bdc154c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -677,7 +677,7 @@ Nodes - Initial support of sequence rules for SWITCH node (#1545) - initial support of SORT node (#1500) - Inject node - let once delay be editable (#1541) - - Introduce `nodeMaxMessageBufferLength` setting for msg sequence nodes + - Introduce `nodeMessageBufferMaxLength` setting for msg sequence nodes - Let CSV correct parts if we remove header row. - let default apply if msg.delay not set in override mode. (#1397) - let trigger node be reset by boolean message (#1554) diff --git a/packages/node_modules/node-red/settings.js b/packages/node_modules/node-red/settings.js index a15e533c5..679d24065 100644 --- a/packages/node_modules/node-red/settings.js +++ b/packages/node_modules/node-red/settings.js @@ -55,7 +55,7 @@ module.exports = { // The maximum number of messages nodes will buffer internally as part of their // operation. This applies across a range of nodes that operate on message sequences. // defaults to no limit. A value of 0 also means no limit is applied. - //nodeMaxMessageBufferLength: 0, + //nodeMessageBufferMaxLength: 0, // To disable the option for using local files for storing keys and certificates in the TLS configuration // node, set this to true From 0ad3eceb82f78596841f1b9f4ffcb5c58c279652 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Wed, 31 Jul 2019 16:06:30 +0900 Subject: [PATCH 05/23] Remove unused variables --- packages/node_modules/@node-red/nodes/core/logic/10-switch.html | 1 - packages/node_modules/@node-red/nodes/core/logic/15-change.html | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/logic/10-switch.html b/packages/node_modules/@node-red/nodes/core/logic/10-switch.html index 65e83ca09..3cd3fb032 100644 --- a/packages/node_modules/@node-red/nodes/core/logic/10-switch.html +++ b/packages/node_modules/@node-red/nodes/core/logic/10-switch.html @@ -352,7 +352,6 @@ }, oneditsave: function() { var rules = $("#node-input-rule-container").editableList('items'); - var ruleset; var node = this; node.rules = []; rules.each(function(i) { diff --git a/packages/node_modules/@node-red/nodes/core/logic/15-change.html b/packages/node_modules/@node-red/nodes/core/logic/15-change.html index d60c8c38e..0731fce75 100644 --- a/packages/node_modules/@node-red/nodes/core/logic/15-change.html +++ b/packages/node_modules/@node-red/nodes/core/logic/15-change.html @@ -226,7 +226,6 @@ }, oneditsave: function() { var rules = $("#node-input-rule-container").editableList('items'); - var ruleset; var node = this; node.rules= []; rules.each(function(i) { From fe18df25ba74ff596f846f80234fbfe7945dea9b Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Thu, 1 Aug 2019 20:50:35 +0900 Subject: [PATCH 06/23] Add Japanese translation to delay node --- .../@node-red/nodes/locales/en-US/core/89-delay.html | 12 ++++++------ .../@node-red/nodes/locales/ja/core/89-delay.html | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/core/89-delay.html b/packages/node_modules/@node-red/nodes/locales/en-US/core/89-delay.html index 87deebe2b..d6977a34a 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/core/89-delay.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/core/89-delay.html @@ -22,12 +22,12 @@
Sets the delay, in milliseconds, to be applied to the message. This option only applies if the node is configured to allow the message to override the configured default delay interval.
-
reset
-
If the received message has this property set to any value, all - outstanding messages held by the node are cleared without being sent.
-
flush
-
If the received message has this property set to any value, all - outstanding messages held by the node are sent immediately.
+
reset
+
If the received message has this property set to any value, all + outstanding messages held by the node are cleared without being sent.
+
flush
+
If the received message has this property set to any value, all + outstanding messages held by the node are sent immediately.

Details

When configured to delay messages, the delay interval can be a fixed value, diff --git a/packages/node_modules/@node-red/nodes/locales/ja/core/89-delay.html b/packages/node_modules/@node-red/nodes/locales/ja/core/89-delay.html index 43eda93a7..ed5046f03 100644 --- a/packages/node_modules/@node-red/nodes/locales/ja/core/89-delay.html +++ b/packages/node_modules/@node-red/nodes/locales/ja/core/89-delay.html @@ -22,6 +22,8 @@

メッセージの遅延時間をミリ秒単位で設定します。これはノードの設定でデフォルトの遅延時間を上書きできるようノードを設定した場合にのみ適用します。
reset
受信メッセージでこのプロパティを任意の値に設定すると、ノードが保持する全ての未送信メッセージをクリアします。
+
flush
+
受信メッセージでこのプロパティを任意の値に設定すると、ノードが保持する全ての未送信メッセージを直ちに送信します。

詳細

メッセージを遅延させるように設定する場合、遅延時間は固定値、範囲内の乱数値、メッセージ毎の動的な指定値のいずれかを指定できます。

From 3a6448f727173fed1bc0e4c48e63118d8445ef14 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 2 Aug 2019 13:56:37 +0900 Subject: [PATCH 07/23] Fix splitters in split node --- packages/node_modules/@node-red/nodes/core/logic/17-split.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/nodes/core/logic/17-split.js b/packages/node_modules/@node-red/nodes/core/logic/17-split.js index c644b9e36..869fbaa3d 100644 --- a/packages/node_modules/@node-red/nodes/core/logic/17-split.js +++ b/packages/node_modules/@node-red/nodes/core/logic/17-split.js @@ -42,7 +42,7 @@ module.exports = function(RED) { node.addname = n.addname || ""; try { if (node.spltType === "str") { - this.splt = (n.splt || "\\n").replace(/\\n/,"\n").replace(/\\r/,"\r").replace(/\\t/,"\t").replace(/\\e/,"\e").replace(/\\f/,"\f").replace(/\\0/,"\0"); + this.splt = (n.splt || "\\n").replace(/\\n/g,"\n").replace(/\\r/g,"\r").replace(/\\t/g,"\t").replace(/\\e/g,"\e").replace(/\\f/g,"\f").replace(/\\0/g,"\0"); } else if (node.spltType === "bin") { var spltArray = JSON.parse(n.splt); if (Array.isArray(spltArray)) { From 9d66ca4a498a9ef3ccb940ac8c80a66f100f7484 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Mon, 5 Aug 2019 19:03:30 +0900 Subject: [PATCH 08/23] Fix duplicated tooltip --- .../@node-red/editor-client/src/js/ui/tab-context.js | 2 +- .../@node-red/nodes/core/core/lib/debug/debug-utils.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js index b62ad13c3..916fa711f 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js @@ -37,7 +37,7 @@ RED.sidebar.context = (function() { // '').appendTo(content); var footerToolbar = $('
'+ - // ' ' + + // ' ' + '
'); diff --git a/packages/node_modules/@node-red/nodes/core/core/lib/debug/debug-utils.js b/packages/node_modules/@node-red/nodes/core/core/lib/debug/debug-utils.js index edc349507..980f18790 100644 --- a/packages/node_modules/@node-red/nodes/core/core/lib/debug/debug-utils.js +++ b/packages/node_modules/@node-red/nodes/core/core/lib/debug/debug-utils.js @@ -42,14 +42,14 @@ RED.debug = (function() { var content = $("
").css({"position":"relative","height":"100%"}); var toolbar = $('').appendTo(content); + '
').appendTo(content); var footerToolbar = $('
'+ // ''+ // 'list'+ // 'table '+ // ''+ - ' ' + + ' ' + '
'); messageList = $('
').appendTo(content); From 15b99c574980357eb3414da6533a7f0cf0ef1295 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 6 Aug 2019 19:24:45 +0900 Subject: [PATCH 09/23] Use appropriate the version of Node.js --- packages/node_modules/@node-red/runtime/lib/index.js | 2 +- packages/node_modules/node-red/lib/red.js | 6 +++--- packages/node_modules/node-red/red.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 58b7df986..66bff6ff2 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -129,7 +129,7 @@ function start() { log.info(log._("runtime.version",{component:"Node.js ",version:process.version})); if (settings.UNSUPPORTED_VERSION) { log.error("*****************************************************************"); - log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=4"})+" *"); + log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=8.9.0"})+" *"); log.error("*****************************************************************"); events.emit("runtime-event",{id:"runtime-unsupported-version",payload:{type:"error",text:"notification.errors.unsupportedVersion"},retain:true}); } diff --git a/packages/node_modules/node-red/lib/red.js b/packages/node_modules/node-red/lib/red.js index 2a04df578..4d7269518 100644 --- a/packages/node_modules/node-red/lib/red.js +++ b/packages/node_modules/node-red/lib/red.js @@ -27,9 +27,9 @@ var apiEnabled = false; function checkVersion(userSettings) { var semver = require('semver'); - if (!semver.satisfies(process.version,">=4.8.0")) { + if (!semver.satisfies(process.version,">=8.9.0")) { // TODO: in the future, make this a hard error. - // var e = new Error("Unsupported version of node.js"); + // var e = new Error("Unsupported version of Node.js"); // e.code = "unsupported_version"; // throw e; userSettings.UNSUPPORTED_VERSION = process.version; @@ -39,7 +39,7 @@ function checkVersion(userSettings) { * This module provides the full Node-RED application, with both the runtime * and editor components built in. * - * The API this module exposes allows it to be embedded within another node.js + * The API this module exposes allows it to be embedded within another Node.js * application. * * @namespace node-red diff --git a/packages/node_modules/node-red/red.js b/packages/node_modules/node-red/red.js index 337eb44e8..040f2db53 100755 --- a/packages/node_modules/node-red/red.js +++ b/packages/node_modules/node-red/red.js @@ -197,8 +197,8 @@ try { RED.init(server,settings); } catch(err) { if (err.code == "unsupported_version") { - console.log("Unsupported version of node.js:",process.version); - console.log("Node-RED requires node.js v4 or later"); + console.log("Unsupported version of Node.js:",process.version); + console.log("Node-RED requires Node.js v8.9.0 or later"); } else if (err.code == "not_built") { console.log("Node-RED has not been built. See README.md for details"); } else { From fe91295704fcc313139256b3b673031d6e9720fa Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 6 Aug 2019 19:27:46 +0900 Subject: [PATCH 10/23] Replace node.js with Node.js --- .github/ISSUE_TEMPLATE.md | 2 +- .github/ISSUE_TEMPLATE/--bug_report.md | 2 +- CONTRIBUTING.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 5d4d87bb7..07efaf18e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -28,7 +28,7 @@ To help us understand the issue, please fill-in as much of the following informa ### Please tell us about your environment: - [ ] Node-RED version: -- [ ] node.js version: +- [ ] Node.js version: - [ ] npm version: - [ ] Platform/OS: - [ ] Browser: diff --git a/.github/ISSUE_TEMPLATE/--bug_report.md b/.github/ISSUE_TEMPLATE/--bug_report.md index ff13e2ace..63923455e 100644 --- a/.github/ISSUE_TEMPLATE/--bug_report.md +++ b/.github/ISSUE_TEMPLATE/--bug_report.md @@ -33,7 +33,7 @@ To help us understand the issue, please fill-in as much of the following informa ### Please tell us about your environment: - [ ] Node-RED version: -- [ ] node.js version: +- [ ] Node.js version: - [ ] npm version: - [ ] Platform/OS: - [ ] Browser: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 33a2f582f..f0f4096c5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ relevant nodes, press Ctrl-E and copy the flow data from the Export dialog. At a minimum, please include: - Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly. - - Version of node.js - what does `node -v` say? + - Version of Node.js - what does `node -v` say? ## Feature requests From fde85481666c7da333599d1d07c3b643ce59d536 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 6 Aug 2019 19:30:05 +0900 Subject: [PATCH 11/23] Remove handling for unused error code --- packages/node_modules/node-red/red.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/node_modules/node-red/red.js b/packages/node_modules/node-red/red.js index 040f2db53..94cebdfaa 100755 --- a/packages/node_modules/node-red/red.js +++ b/packages/node_modules/node-red/red.js @@ -199,8 +199,6 @@ try { if (err.code == "unsupported_version") { console.log("Unsupported version of Node.js:",process.version); console.log("Node-RED requires Node.js v8.9.0 or later"); - } else if (err.code == "not_built") { - console.log("Node-RED has not been built. See README.md for details"); } else { console.log("Failed to start server:"); if (err.stack) { From 2505ac3f9815a57a45cd3065ff678475cc6c57ae Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 6 Aug 2019 19:57:39 +0900 Subject: [PATCH 12/23] Update Japanese message catalog --- .../editor-client/locales/ja/editor.json | 28 +++++++++++++------ .../@node-red/nodes/locales/ja/messages.json | 11 ++++++-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index 770c75589..9d6ceaf6a 100755 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -80,7 +80,7 @@ "projects-new": "新規", "projects-open": "開く", "projects-settings": "設定", - "showNodeLabelDefault": "追加したノードのラベルを表示する" + "showNodeLabelDefault": "追加したノードのラベルを表示" } }, "actions": { @@ -351,7 +351,8 @@ "pasteNode": "ノードを貼り付け", "undoChange": "変更操作を戻す", "searchBox": "ノードを検索", - "managePalette": "パレットの管理" + "managePalette": "パレットの管理", + "actionList": "動作一覧" }, "library": { "library": "ライブラリ", @@ -527,11 +528,13 @@ "none": "選択されていません", "refresh": "読み込みのため更新してください", "empty": "データが存在しません", - "node": "Node", - "flow": "Flow", - "global": "Global", + "node": "ノード", + "flow": "フロー", + "global": "グローバル", "deleteConfirm": "データを削除しても良いですか?", - "autoRefresh": "自動更新" + "autoRefresh": "自動更新", + "refrsh": "更新", + "delete": "削除" }, "palette": { "name": "パレットの管理", @@ -736,7 +739,16 @@ }, "jsonEditor": { "title": "JSONエディタ", - "format": "JSONフォーマット" + "format": "JSONフォーマット", + "rawMode": "JSONを編集", + "uiMode": "ビジュアルエディタ", + "insertAbove": "上に挿入", + "insertBelow": "下に挿入", + "addItem": "要素を追加", + "copyPath": "要素のパスをコピー", + "expandItems": "要素を展開", + "collapseItems": "要素を折り畳む", + "duplicate": "複製" }, "markdownEditor": { "title": "マークダウンエディタ", @@ -930,7 +942,7 @@ "appearance": "外観", "env": "環境変数" }, - "languages" : { + "languages": { "de": "ドイツ語", "en-US": "英語", "ja": "日本語", diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json index ef899908e..1f244d824 100755 --- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json @@ -7,7 +7,8 @@ "username": "ユーザ名", "password": "パスワード", "property": "プロパティ", - "selectNodes": "ノードを選択..." + "selectNodes": "ノードを選択...", + "expand": "展開" }, "status": { "connected": "接続済", @@ -137,7 +138,10 @@ "debugNodes": "debugノード", "clearLog": "ログを削除", "filterLog": "ログのフィルタリング", - "openWindow": "新しいウィンドウで開く" + "openWindow": "新しいウィンドウで開く", + "copyPath": "パスをコピー", + "copyPayload": "値をコピー", + "pinPath": "展開を固定" }, "messageMenu": { "collapseAll": "全パスを折りたたむ", @@ -615,7 +619,8 @@ "tail": "tail", "index": "index between", "exp": "JSONata式", - "else": "その他" + "else": "その他", + "hask": "has key" }, "errors": { "invalid-expr": "不正な表現: __error__", From 542cf3147dedaabb05a619b862e50066b3655786 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 6 Aug 2019 15:12:13 +0100 Subject: [PATCH 13/23] Support displaying falsey node status values Fixes #2246 --- packages/node_modules/@node-red/editor-client/src/js/ui/view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index 16883d28a..0db014d46 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -3056,7 +3056,7 @@ RED.view = (function() { } thisNode.selectAll(".node_status").style(style); } - if (d.status.text) { + if (d.status.hasOwnProperty('text')) { thisNode.selectAll(".node_status_label").text(d.status.text); } else { thisNode.selectAll(".node_status_label").text(""); From 6c3913785d8fde78037013002ddea4479bfa0dbb Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 6 Aug 2019 15:21:57 +0100 Subject: [PATCH 14/23] Add error event handler to ssh-keygen child_process Fixes #2255 --- .../lib/storage/localfilesystem/projects/ssh/keygen.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js index 218144c12..5555f841b 100644 --- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js +++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js @@ -51,6 +51,12 @@ function runSshKeygenCommand(args,cwd,env) { resolve(stdout); } }); + child.error('error', function(err) { + if (/ENOENT/.test(err.toString())) { + err.code = "command_not_found"; + } + reject(err); + }); }); } From 9b938f6515e82fcc6a242f2e9967ba148f286814 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 6 Aug 2019 15:55:25 +0100 Subject: [PATCH 15/23] Fix default value handling on context array access Fixes #2252 --- .../node_modules/@node-red/runtime/lib/nodes/context/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js b/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js index f8de26070..322fa2868 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js @@ -234,7 +234,7 @@ function createContext(id,seed,parent) { if (err.code === "INVALID_EXPR") { throw err; } - value[0] = undefined; + values[0] = undefined; } } } else { @@ -246,7 +246,7 @@ function createContext(id,seed,parent) { if (err.code === "INVALID_EXPR") { throw err; } - value[i] = undefined; + values[i] = undefined; } } } From 6e3fa974ba361e1bf32620d5b7dcb109d1f86c85 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 6 Aug 2019 16:32:46 +0100 Subject: [PATCH 16/23] Remove all ui test dependencies from package.json Given chromedriver was already an extra dependency that needed to be manually installed, I have now moved all of the webdriver.io dependencies out as well. A new script has been added to install all of the ui test dependencies. The Grunt file has been updated on how it checks for the missing deps. --- Gruntfile.js | 20 ++++++++++++++------ package.json | 5 ----- scripts/install-ui-test-dependencies.sh | 7 +++++++ 3 files changed, 21 insertions(+), 11 deletions(-) create mode 100755 scripts/install-ui-test-dependencies.sh diff --git a/Gruntfile.js b/Gruntfile.js index 8b7b85a25..66ebf4f38 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -496,7 +496,9 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-chmod'); grunt.loadNpmTasks('grunt-jsonlint'); grunt.loadNpmTasks('grunt-mocha-istanbul'); - grunt.loadNpmTasks('grunt-webdriver'); + if (fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { + grunt.loadNpmTasks('grunt-webdriver'); + } grunt.loadNpmTasks('grunt-jsdoc'); grunt.loadNpmTasks('grunt-jsdoc-to-markdown'); grunt.loadNpmTasks('grunt-npm-command'); @@ -555,8 +557,8 @@ module.exports = function(grunt) { }); grunt.registerTask('verifyUiTestDependencies', function() { - if (!fs.existsSync(path.join("node_modules", "chromedriver"))) { - grunt.fail.fatal('You need to run "npm install chromedriver@2" before running UI test.'); + if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { + grunt.fail.fatal('You need to install the UI test dependencies first.\nUse the script in "scripts/install-ui-test-dependencies.sh"'); return false; } }); @@ -579,9 +581,15 @@ module.exports = function(grunt) { 'Runs code style check on editor code', ['jshint:editor']); - grunt.registerTask('test-ui', - 'Builds editor content then runs unit tests on editor ui', - ['verifyUiTestDependencies','build','jshint:editor','webdriver:all']); + if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { + grunt.registerTask('test-ui', + 'Builds editor content then runs unit tests on editor ui', + ['verifyUiTestDependencies']); + } else { + grunt.registerTask('test-ui', + 'Builds editor content then runs unit tests on editor ui', + ['verifyUiTestDependencies','build','jshint:editor','webdriver:all']); + } grunt.registerTask('test-nodes', 'Runs unit tests on core nodes', diff --git a/package.json b/package.json index 92bc8020d..e0997ce16 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,6 @@ "grunt-npm-command": "~0.1.2", "grunt-sass": "~2.0.0", "grunt-simple-mocha": "~0.4.1", - "grunt-webdriver": "^2.0.3", "http-proxy": "^1.16.2", "istanbul": "0.4.5", "minami": "1.2.3", @@ -105,10 +104,6 @@ "sinon": "1.17.7", "stoppable": "^1.1.0", "supertest": "3.4.2", - "wdio-chromedriver-service": "^0.1.5", - "wdio-mocha-framework": "^0.6.4", - "wdio-spec-reporter": "^0.1.5", - "webdriverio": "^4.14.1", "node-red-node-test-helper": "^0.2.3", "jsdoc-nr-template": "node-red/jsdoc-nr-template" }, diff --git a/scripts/install-ui-test-dependencies.sh b/scripts/install-ui-test-dependencies.sh new file mode 100755 index 000000000..0148633be --- /dev/null +++ b/scripts/install-ui-test-dependencies.sh @@ -0,0 +1,7 @@ +npm install --no-save \ + grunt-webdriver@^2.0.3 \ + wdio-chromedriver-service@^0.1.5 \ + wdio-mocha-framework@^0.6.4 \ + wdio-spec-reporter@^0.1.5 \ + webdriverio@^4.14.1 \ + chromedriver@2 From 77a913f8584f5cb113d7688c983435c38d79c067 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 6 Aug 2019 16:34:43 +0100 Subject: [PATCH 17/23] Add Node 12 to full build matrix on Travis Having removed the ui test dependencies out of package.json we can remove the 'allow failures' flag from the node 12 build. Given how close Node 12 is to being LTS, we really need to pay proper attention to it. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14236730a..a101eecb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,5 +9,3 @@ matrix: before_script: - npm install -g istanbul coveralls - node_js: "8" - allow_failures: - - node_js: "12" From defa9a227066a160bb907083c67724d386f95f01 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 6 Aug 2019 17:12:40 +0100 Subject: [PATCH 18/23] Fix ssh-keygen error handling --- .../runtime/lib/storage/localfilesystem/projects/ssh/keygen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js index 5555f841b..cb739643b 100644 --- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js +++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/ssh/keygen.js @@ -51,7 +51,7 @@ function runSshKeygenCommand(args,cwd,env) { resolve(stdout); } }); - child.error('error', function(err) { + child.on('error', function(err) { if (/ENOENT/.test(err.toString())) { err.code = "command_not_found"; } From be2dd6dc3257dbe5eeb22b8e91e99cca26002ca5 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 9 Aug 2019 16:56:11 +0100 Subject: [PATCH 19/23] Add req back to audit log events and extend to Projects api --- .../@node-red/editor-api/lib/admin/context.js | 6 +- .../@node-red/editor-api/lib/admin/flow.js | 12 ++- .../@node-red/editor-api/lib/admin/flows.js | 6 +- .../@node-red/editor-api/lib/admin/nodes.js | 30 ++++--- .../editor-api/lib/editor/projects.js | 90 ++++++++++++------- .../@node-red/editor-api/lib/util.js | 7 ++ .../@node-red/runtime/lib/api/context.js | 22 ++--- .../@node-red/runtime/lib/api/flows.js | 37 ++++---- .../@node-red/runtime/lib/api/library.js | 14 +-- .../@node-red/runtime/lib/api/nodes.js | 71 +++++++++------ .../@node-red/runtime/lib/api/projects.js | 53 ++++++++++- .../@node-red/runtime/lib/api/settings.js | 13 ++- .../node_modules/@node-red/util/lib/log.js | 2 +- 13 files changed, 249 insertions(+), 114 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/context.js b/packages/node_modules/@node-red/editor-api/lib/admin/context.js index 6a2efd82d..54bfd9f85 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/context.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/context.js @@ -30,7 +30,8 @@ module.exports = { scope: req.params.scope, id: req.params.id, key: req.params[0], - store: req.query['store'] + store: req.query['store'], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.context.getValue(opts).then(function(result) { res.json(result); @@ -45,7 +46,8 @@ module.exports = { scope: req.params.scope, id: req.params.id, key: req.params[0], - store: req.query['store'] + store: req.query['store'], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.context.delete(opts).then(function(result) { res.status(204).end(); diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/flow.js b/packages/node_modules/@node-red/editor-api/lib/admin/flow.js index 5ba5d7a04..98ae997ff 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/flow.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/flow.js @@ -24,7 +24,8 @@ module.exports = { get: function(req,res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.flows.getFlow(opts).then(function(result) { return res.json(result); @@ -35,7 +36,8 @@ module.exports = { post: function(req,res) { var opts = { user: req.user, - flow: req.body + flow: req.body, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.flows.addFlow(opts).then(function(id) { return res.json({id:id}); @@ -47,7 +49,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - flow: req.body + flow: req.body, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.flows.updateFlow(opts).then(function(id) { return res.json({id:id}); @@ -58,7 +61,8 @@ module.exports = { delete: function(req,res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.flows.deleteFlow(opts).then(function() { res.status(204).end(); diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/flows.js b/packages/node_modules/@node-red/editor-api/lib/admin/flows.js index ccad8718f..11b30e446 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/flows.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/flows.js @@ -27,7 +27,8 @@ module.exports = { return res.status(400).json({code:"invalid_api_version", message:"Invalid API Version requested"}); } var opts = { - user: req.user + user: req.user, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.flows.getFlows(opts).then(function(result) { if (version === "v1") { @@ -46,7 +47,8 @@ module.exports = { } var opts = { user: req.user, - deploymentType: req.get("Node-RED-Deployment-Type")||"full" + deploymentType: req.get("Node-RED-Deployment-Type")||"full", + req: apiUtils.getRequestLogObject(req) } if (opts.deploymentType !== 'reload') { diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js b/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js index 59a137587..2787a5c36 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/nodes.js @@ -24,7 +24,8 @@ module.exports = { }, getAll: function(req,res) { var opts = { - user: req.user + user: req.user, + req: apiUtils.getRequestLogObject(req) } if (req.get("accept") == "application/json") { runtimeAPI.nodes.getNodeList(opts).then(function(list) { @@ -42,7 +43,8 @@ module.exports = { var opts = { user: req.user, module: req.body.module, - version: req.body.version + version: req.body.version, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.addModule(opts).then(function(info) { res.json(info); @@ -54,7 +56,8 @@ module.exports = { delete: function(req,res) { var opts = { user: req.user, - module: req.params[0] + module: req.params[0], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.removeModule(opts).then(function() { res.status(204).end(); @@ -66,7 +69,8 @@ module.exports = { getSet: function(req,res) { var opts = { user: req.user, - id: req.params[0] + "/" + req.params[2] + id: req.params[0] + "/" + req.params[2], + req: apiUtils.getRequestLogObject(req) } if (req.get("accept") === "application/json") { runtimeAPI.nodes.getNodeInfo(opts).then(function(result) { @@ -87,7 +91,8 @@ module.exports = { getModule: function(req,res) { var opts = { user: req.user, - module: req.params[0] + module: req.params[0], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.getModuleInfo(opts).then(function(result) { res.send(result); @@ -106,7 +111,8 @@ module.exports = { var opts = { user: req.user, id: req.params[0] + "/" + req.params[2], - enabled: body.enabled + enabled: body.enabled, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.setNodeSetState(opts).then(function(result) { res.send(result); @@ -125,7 +131,8 @@ module.exports = { var opts = { user: req.user, module: req.params[0], - enabled: body.enabled + enabled: body.enabled, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.setModuleState(opts).then(function(result) { res.send(result); @@ -139,7 +146,8 @@ module.exports = { var opts = { user: req.user, module: req.params[0], - lang: req.query.lng + lang: req.query.lng, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.getModuleCatalog(opts).then(function(result) { res.json(result); @@ -152,7 +160,8 @@ module.exports = { getModuleCatalogs: function(req,res) { var opts = { user: req.user, - lang: req.query.lng + lang: req.query.lng, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.getModuleCatalogs(opts).then(function(result) { res.json(result); @@ -164,7 +173,8 @@ module.exports = { getIcons: function(req,res) { var opts = { - user: req.user + user: req.user, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.nodes.getIconList(opts).then(function(list) { res.json(list); diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/projects.js b/packages/node_modules/@node-red/editor-api/lib/editor/projects.js index ff7fc5e85..0849c8ff8 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/projects.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/projects.js @@ -22,7 +22,8 @@ var needsPermission = require("../auth").needsPermission; function listProjects(req,res) { var opts = { - user: req.user + user: req.user, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.listProjects(opts).then(function(result) { res.json(result); @@ -33,7 +34,8 @@ function listProjects(req,res) { function getProject(req,res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getProject(opts).then(function(data) { if (data) { @@ -49,7 +51,8 @@ function getProjectStatus(req,res) { var opts = { user: req.user, id: req.params.id, - remote: req.query.remote + remote: req.query.remote, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getStatus(opts).then(function(data){ if (data) { @@ -64,7 +67,8 @@ function getProjectStatus(req,res) { function getProjectRemotes(req,res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getRemotes(opts).then(function(data) { res.json(data); @@ -98,7 +102,8 @@ module.exports = { app.post("/", needsPermission("projects.write"), function(req,res) { var opts = { user: req.user, - project: req.body + project: req.body, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.createProject(opts).then(function(result) { res.json(result); @@ -112,7 +117,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - project: req.body + project: req.body, + req: apiUtils.getRequestLogObject(req) } if (req.body.active) { @@ -150,7 +156,8 @@ module.exports = { app.delete("/:id", needsPermission("projects.write"), function(req,res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.deleteProject(opts).then(function() { res.status(204).end(); @@ -168,7 +175,8 @@ module.exports = { app.get("/:id/files", needsPermission("projects.read"), function(req,res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getFiles(opts).then(function(data) { res.json(data); @@ -185,7 +193,8 @@ module.exports = { user: req.user, id: req.params.id, path: req.params[0], - tree: req.params.treeish + tree: req.params.treeish, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getFile(opts).then(function(data) { res.json({content:data}); @@ -199,7 +208,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - path: req.params[0] + path: req.params[0], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.revertFile(opts).then(function() { @@ -214,7 +224,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - path: req.params[0] + path: req.params[0], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.stageFile(opts).then(function() { getProjectStatus(req,res); @@ -228,7 +239,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - path: req.body.files + path: req.body.files, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.stageFile(opts).then(function() { getProjectStatus(req,res); @@ -242,7 +254,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - message: req.body.message + message: req.body.message, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.commit(opts).then(function() { getProjectStatus(req,res); @@ -256,7 +269,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - path: req.params[0] + path: req.params[0], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.unstageFile(opts).then(function() { getProjectStatus(req,res); @@ -269,7 +283,8 @@ module.exports = { app.delete("/:id/stage", needsPermission("projects.write"), function(req, res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.unstageFile(opts).then(function() { getProjectStatus(req,res); @@ -284,7 +299,8 @@ module.exports = { user: req.user, id: req.params.id, path: req.params[0], - type: req.params.type + type: req.params.type, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getFileDiff(opts).then(function(data) { res.json({ @@ -301,7 +317,8 @@ module.exports = { user: req.user, id: req.params.id, limit: req.query.limit || 20, - before: req.query.before + before: req.query.before, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getCommits(opts).then(function(data) { res.json(data); @@ -315,7 +332,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - sha: req.params.sha + sha: req.params.sha, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getCommit(opts).then(function(data) { res.json({commit:data}); @@ -330,7 +348,8 @@ module.exports = { user: req.user, id: req.params.id, remote: req.params[0], - track: req.query.u + track: req.query.u, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.push(opts).then(function(data) { res.status(204).end(); @@ -346,7 +365,8 @@ module.exports = { id: req.params.id, remote: req.params[0], track: req.query.setUpstream, - allowUnrelatedHistories: req.query.allowUnrelatedHistories + allowUnrelatedHistories: req.query.allowUnrelatedHistories, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.pull(opts).then(function(data) { res.status(204).end(); @@ -359,7 +379,8 @@ module.exports = { app.delete("/:id/merge", needsPermission("projects.write"), function(req, res) { var opts = { user: req.user, - id: req.params.id + id: req.params.id, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.abortMerge(opts).then(function() { res.status(204).end(); @@ -374,7 +395,8 @@ module.exports = { user: req.user, id: req.params.id, path: req.params[0], - resolution: req.body.resolutions + resolution: req.body.resolutions, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.resolveMerge(opts).then(function() { res.status(204).end(); @@ -388,7 +410,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - remote: false + remote: false, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getBranches(opts).then(function(data) { res.json(data); @@ -403,7 +426,8 @@ module.exports = { user: req.user, id: req.params.id, branch: req.params.branchName, - force: !!req.query.force + force: !!req.query.force, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.deleteBranch(opts).then(function(data) { res.status(204).end(); @@ -417,7 +441,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - remote: true + remote: true, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getBranches(opts).then(function(data) { res.json(data); @@ -431,7 +456,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - branch: req.params[0] + branch: req.params[0], + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.getBranchStatus(opts).then(function(data) { res.json(data); @@ -446,7 +472,8 @@ module.exports = { user: req.user, id: req.params.id, branch: req.body.name, - create: req.body.create + create: req.body.create, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.setBranch(opts).then(function(data) { res.json(data); @@ -463,7 +490,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - remote: req.body + remote: req.body, + req: apiUtils.getRequestLogObject(req) } if (/^https?:\/\/[^/]+@/i.test(req.body.url)) { res.status(400).json({error:"unexpected_error", message:"Git http url must not include username/password"}); @@ -481,7 +509,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - remote: req.params.remoteName + remote: req.params.remoteName, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.removeRemote(opts).then(function(data) { getProjectRemotes(req,res); @@ -497,7 +526,8 @@ module.exports = { var opts = { user: req.user, id: req.params.id, - remote: remote + remote: remote, + req: apiUtils.getRequestLogObject(req) } runtimeAPI.projects.updateRemote(opts).then(function() { res.status(204).end(); diff --git a/packages/node_modules/@node-red/editor-api/lib/util.js b/packages/node_modules/@node-red/editor-api/lib/util.js index 1984bd5f1..0cef96bbb 100644 --- a/packages/node_modules/@node-red/editor-api/lib/util.js +++ b/packages/node_modules/@node-red/editor-api/lib/util.js @@ -47,5 +47,12 @@ module.exports = { code: err.code||"unexpected_error", message: err.message||err.toString() }); + }, + getRequestLogObject: function(req) { + return { + user: req.user, + path: req.path, + ip: (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined + } } } diff --git a/packages/node_modules/@node-red/runtime/lib/api/context.js b/packages/node_modules/@node-red/runtime/lib/api/context.js index 0b2fefcc9..f69349a62 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/context.js +++ b/packages/node_modules/@node-red/runtime/lib/api/context.js @@ -67,7 +67,7 @@ var api = module.exports = { * @param {String} opts.id - the id of the context * @param {String} opts.store - the context store * @param {String} opts.key - the context key - + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node information * @memberof @node-red/runtime_context */ @@ -81,7 +81,7 @@ var api = module.exports = { var availableStores = runtime.nodes.listContextStores(); //{ default: 'default', stores: [ 'default', 'file' ] } if (store && availableStores.stores.indexOf(store) === -1) { - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -106,7 +106,7 @@ var api = module.exports = { if (store !== availableStores.default) { encoded.store = store; } - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}, opts.req); resolve(encoded); }); return; @@ -127,7 +127,7 @@ var api = module.exports = { // TODO: proper error reporting if (!errorReported) { errorReported = true; - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"unexpected_error"}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"unexpected_error"}, opts.req); var err = new Error(); err.code = "unexpected_error"; err.status = 400; @@ -139,7 +139,7 @@ var api = module.exports = { c--; if (c === 0) { if (!errorReported) { - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key},opts.req); resolve(result); } } @@ -147,7 +147,7 @@ var api = module.exports = { }) } } else { - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key},opts.req); resolve({}); } }) @@ -161,7 +161,7 @@ var api = module.exports = { * @param {String} opts.id - the id of the context * @param {String} opts.store - the context store * @param {String} opts.key - the context key - + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node information * @memberof @node-red/runtime_context */ @@ -175,7 +175,7 @@ var api = module.exports = { var availableStores = runtime.nodes.listContextStores(); //{ default: 'default', stores: [ 'default', 'file' ] } if (store && availableStores.stores.indexOf(store) === -1) { - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"},opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -196,13 +196,13 @@ var api = module.exports = { if (key) { store = store || availableStores.default; ctx.set(key,undefined,store,function(err) { - runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key}); + runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key},opts.req); resolve(); }); return; } else { // TODO: support deleting whole context - runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"}); + runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"},opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -243,7 +243,7 @@ var api = module.exports = { // }) } } else { - runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key}); + runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key},opts.req); resolve(); } diff --git a/packages/node_modules/@node-red/runtime/lib/api/flows.js b/packages/node_modules/@node-red/runtime/lib/api/flows.js index 735e295fc..1e6e72dc7 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/flows.js +++ b/packages/node_modules/@node-red/runtime/lib/api/flows.js @@ -43,12 +43,13 @@ var api = module.exports = { * Gets the current flow configuration * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the active flow configuration * @memberof @node-red/runtime_flows */ getFlows: function(opts) { return new Promise(function(resolve,reject) { - runtime.log.audit({event: "flows.get"}/*,req*/); + runtime.log.audit({event: "flows.get"}, opts.req); return resolve(runtime.nodes.getFlows()); }); }, @@ -56,6 +57,7 @@ var api = module.exports = { * Sets the current flow configuration * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the active flow configuration * @memberof @node-red/runtime_flows */ @@ -64,7 +66,7 @@ var api = module.exports = { var flows = opts.flows; var deploymentType = opts.deploymentType||"full"; - runtime.log.audit({event: "flows.set",type:deploymentType}/*,req*/); + runtime.log.audit({event: "flows.set",type:deploymentType}, opts.req); var apiPromise; if (deploymentType === 'reload') { @@ -98,6 +100,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {Object} opts.flow - the flow to add + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the id of the added flow * @memberof @node-red/runtime_flows */ @@ -105,10 +108,10 @@ var api = module.exports = { return new Promise(function(resolve,reject) { var flow = opts.flow; runtime.nodes.addFlow(flow).then(function(id) { - runtime.log.audit({event: "flow.add",id:id}); + runtime.log.audit({event: "flow.add",id:id}, opts.req); return resolve(id); }).catch(function(err) { - runtime.log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); }) @@ -122,6 +125,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {Object} opts.id - the id of the flow to retrieve + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the active flow configuration * @memberof @node-red/runtime_flows */ @@ -129,10 +133,10 @@ var api = module.exports = { return new Promise(function (resolve,reject) { var flow = runtime.nodes.getFlow(opts.id); if (flow) { - runtime.log.audit({event: "flow.get",id:opts.id}); + runtime.log.audit({event: "flow.get",id:opts.id}, opts.req); return resolve(flow); } else { - runtime.log.audit({event: "flow.get",id:opts.id,error:"not_found"}); + runtime.log.audit({event: "flow.get",id:opts.id,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -147,6 +151,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {Object} opts.id - the id of the flow to update * @param {Object} opts.flow - the flow configuration + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the id of the updated flow * @memberof @node-red/runtime_flows */ @@ -156,22 +161,22 @@ var api = module.exports = { var id = opts.id; try { runtime.nodes.updateFlow(id,flow).then(function() { - runtime.log.audit({event: "flow.update",id:id}); + runtime.log.audit({event: "flow.update",id:id}, opts.req); return resolve(id); }).catch(function(err) { - runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); }) } catch(err) { if (err.code === 404) { - runtime.log.audit({event: "flow.update",id:id,error:"not_found"}); + runtime.log.audit({event: "flow.update",id:id,error:"not_found"}, opts.req); // TODO: this swap around of .code and .status isn't ideal err.status = 404; err.code = "not_found"; return reject(err); } else { - runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); } @@ -184,6 +189,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {Object} opts.id - the id of the flow to delete + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves if successful * @memberof @node-red/runtime_flows */ @@ -192,22 +198,22 @@ var api = module.exports = { var id = opts.id; try { runtime.nodes.removeFlow(id).then(function() { - runtime.log.audit({event: "flow.remove",id:id}); + runtime.log.audit({event: "flow.remove",id:id}, opts.req); return resolve(); }).catch(function(err) { - runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); }); } catch(err) { if (err.code === 404) { - runtime.log.audit({event: "flow.remove",id:id,error:"not_found"}); + runtime.log.audit({event: "flow.remove",id:id,error:"not_found"}, opts.req); // TODO: this swap around of .code and .status isn't ideal err.status = 404; err.code = "not_found"; return reject(err); } else { - runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); } @@ -221,12 +227,13 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.type - the node type to return the credential information for * @param {String} opts.id - the node id + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the safe credentials * @memberof @node-red/runtime_flows */ getNodeCredentials: function(opts) { return new Promise(function(resolve,reject) { - runtime.log.audit({event: "credentials.get",type:opts.type,id:opts.id}); + runtime.log.audit({event: "credentials.get",type:opts.type,id:opts.id}, opts.req); var credentials = runtime.nodes.getCredentials(opts.id); if (!credentials) { return resolve({}); diff --git a/packages/node_modules/@node-red/runtime/lib/api/library.js b/packages/node_modules/@node-red/runtime/lib/api/library.js index 31037858b..f252d3264 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/library.js +++ b/packages/node_modules/@node-red/runtime/lib/api/library.js @@ -32,13 +32,14 @@ var api = module.exports = { * @param {String} opts.library - the library * @param {String} opts.type - the type of entry * @param {String} opts.path - the path of the entry + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_library */ getEntry: function(opts) { return new Promise(function(resolve,reject) { runtime.library.getEntry(opts.library,opts.type,opts.path).then(function(result) { - runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path}); + runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path}, opts.req); return resolve(result); }).catch(function(err) { if (err) { @@ -51,10 +52,10 @@ var api = module.exports = { } else { err.status = 400; } - runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path,error:err.code}); + runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path,error:err.code}, opts.req); return reject(err); } - runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,error:"not_found"}); + runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,error:"not_found"}, opts.req); var error = new Error(); error.code = "not_found"; error.status = 404; @@ -72,22 +73,23 @@ var api = module.exports = { * @param {String} opts.path - the path of the entry * @param {Object} opts.meta - any meta data associated with the entry * @param {String} opts.body - the body of the entry + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_library */ saveEntry: function(opts) { return new Promise(function(resolve,reject) { runtime.library.saveEntry(opts.library,opts.type,opts.path,opts.meta,opts.body).then(function() { - runtime.log.audit({event: "library.set",type:opts.type,path:opts.path}); + runtime.log.audit({event: "library.set",type:opts.type,path:opts.path}, opts.req); return resolve(); }).catch(function(err) { runtime.log.warn(runtime.log._("api.library.error-save-entry",{path:opts.path,message:err.toString()})); if (err.code === 'forbidden') { - runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"forbidden"}); + runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"forbidden"}, opts.req); err.status = 403; return reject(err); } - runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"unexpected_error",message:err.toString()}, opts.req); var error = new Error(); error.status = 400; return reject(error); diff --git a/packages/node_modules/@node-red/runtime/lib/api/nodes.js b/packages/node_modules/@node-red/runtime/lib/api/nodes.js index ca67acc17..ee4d3bc1a 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/nodes.js +++ b/packages/node_modules/@node-red/runtime/lib/api/nodes.js @@ -48,6 +48,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the node set to return + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node information * @memberof @node-red/runtime_nodes */ @@ -56,11 +57,11 @@ var api = module.exports = { var id = opts.id; var result = runtime.nodes.getNodeInfo(id); if (result) { - runtime.log.audit({event: "nodes.info.get",id:id}); + runtime.log.audit({event: "nodes.info.get",id:id}, opts.req); delete result.loaded; return resolve(result); } else { - runtime.log.audit({event: "nodes.info.get",id:id,error:"not_found"}); + runtime.log.audit({event: "nodes.info.get",id:id,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -73,12 +74,13 @@ var api = module.exports = { * Gets the list of node modules installed in the runtime * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the list of node modules * @memberof @node-red/runtime_nodes */ getNodeList: function(opts) { return new Promise(function(resolve,reject) { - runtime.log.audit({event: "nodes.list.get"}); + runtime.log.audit({event: "nodes.list.get"}, opts.req); return resolve(runtime.nodes.getNodeList()); }) }, @@ -89,6 +91,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the node set to return * @param {String} opts.lang - the locale language to return + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node html content * @memberof @node-red/runtime_nodes */ @@ -98,10 +101,10 @@ var api = module.exports = { var lang = opts.lang; var result = runtime.nodes.getNodeConfig(id,lang); if (result) { - runtime.log.audit({event: "nodes.config.get",id:id}); + runtime.log.audit({event: "nodes.config.get",id:id}, opts.req); return resolve(result); } else { - runtime.log.audit({event: "nodes.config.get",id:id,error:"not_found"}); + runtime.log.audit({event: "nodes.config.get",id:id,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -114,12 +117,13 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.lang - the locale language to return + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node html content * @memberof @node-red/runtime_nodes */ getNodeConfigs: function(opts) { return new Promise(function(resolve,reject) { - runtime.log.audit({event: "nodes.configs.get"}); + runtime.log.audit({event: "nodes.configs.get"}, opts.req); return resolve(runtime.nodes.getNodeConfigs(opts.lang)); }); }, @@ -129,6 +133,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.module - the id of the module to return + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node module info * @memberof @node-red/runtime_nodes */ @@ -136,10 +141,10 @@ var api = module.exports = { return new Promise(function(resolve,reject) { var result = runtime.nodes.getModuleInfo(opts.module); if (result) { - runtime.log.audit({event: "nodes.module.get",id:opts.module}); + runtime.log.audit({event: "nodes.module.get",id:opts.module}, opts.req); return resolve(result); } else { - runtime.log.audit({event: "nodes.module.get",id:opts.module,error:"not_found"}); + runtime.log.audit({event: "nodes.module.get",id:opts.module,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -154,13 +159,14 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.module - the id of the module to install * @param {String} opts.version - (optional) the version of the module to install + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the node module info * @memberof @node-red/runtime_nodes */ addModule: function(opts) { return new Promise(function(resolve,reject) { if (!runtime.settings.available()) { - runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}); + runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}, opts.req); var err = new Error("Settings unavailable"); err.code = "settings_unavailable"; err.status = 400; @@ -170,7 +176,7 @@ var api = module.exports = { var existingModule = runtime.nodes.getModuleInfo(opts.module); if (existingModule) { if (!opts.version || existingModule.version === opts.version) { - runtime.log.audit({event: "nodes.install",module:opts.module, version:opts.version, error:"module_already_loaded"}); + runtime.log.audit({event: "nodes.install",module:opts.module, version:opts.version, error:"module_already_loaded"}, opts.req); var err = new Error("Module already loaded"); err.code = "module_already_loaded"; err.status = 400; @@ -178,24 +184,24 @@ var api = module.exports = { } } runtime.nodes.installModule(opts.module,opts.version).then(function(info) { - runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version}); + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version}, opts.req); return resolve(info); }).catch(function(err) { if (err.code === 404) { - runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:"not_found"}); + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:"not_found"}, opts.req); // TODO: code/status err.status = 404; } else if (err.code) { err.status = 400; - runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code}); + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code}, opts.req); } else { err.status = 400; - runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code||"unexpected_error",message:err.toString()}, opts.req); } return reject(err); }) } else { - runtime.log.audit({event: "nodes.install",module:opts.module,error:"invalid_request"}); + runtime.log.audit({event: "nodes.install",module:opts.module,error:"invalid_request"}, opts.req); var err = new Error("Invalid request"); err.code = "invalid_request"; err.status = 400; @@ -209,13 +215,14 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.module - the id of the module to remove + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_nodes */ removeModule: function(opts) { return new Promise(function(resolve,reject) { if (!runtime.settings.available()) { - runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}); + runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}, opts.req); var err = new Error("Settings unavailable"); err.code = "settings_unavailable"; err.status = 400; @@ -223,7 +230,7 @@ var api = module.exports = { } var module = runtime.nodes.getModuleInfo(opts.module); if (!module) { - runtime.log.audit({event: "nodes.remove",module:opts.module,error:"not_found"}); + runtime.log.audit({event: "nodes.remove",module:opts.module,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -231,15 +238,15 @@ var api = module.exports = { } try { runtime.nodes.uninstallModule(opts.module).then(function() { - runtime.log.audit({event: "nodes.remove",module:opts.module}); + runtime.log.audit({event: "nodes.remove",module:opts.module}, opts.req); resolve(); }).catch(function(err) { err.status = 400; - runtime.log.audit({event: "nodes.remove",module:opts.module,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "nodes.remove",module:opts.module,error:err.code||"unexpected_error",message:err.toString()}, opts.req); return reject(err); }) } catch(error) { - runtime.log.audit({event: "nodes.remove",module:opts.module,error:error.code||"unexpected_error",message:error.toString()}); + runtime.log.audit({event: "nodes.remove",module:opts.module,error:error.code||"unexpected_error",message:error.toString()}, opts.req); error.status = 400; return reject(error); } @@ -252,6 +259,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.module - the id of the module to enable or disable * @param {String} opts.enabled - whether the module should be enabled or disabled + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the module info object * @memberof @node-red/runtime_nodes */ @@ -259,7 +267,7 @@ var api = module.exports = { var mod = opts.module; return new Promise(function(resolve,reject) { if (!runtime.settings.available()) { - runtime.log.audit({event: "nodes.module.set",error:"settings_unavailable"}); + runtime.log.audit({event: "nodes.module.set",error:"settings_unavailable"}, opts.req); var err = new Error("Settings unavailable"); err.code = "settings_unavailable"; err.status = 400; @@ -268,7 +276,7 @@ var api = module.exports = { try { var module = runtime.nodes.getModuleInfo(mod); if (!module) { - runtime.log.audit({event: "nodes.module.set",module:mod,error:"not_found"}); + runtime.log.audit({event: "nodes.module.set",module:mod,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -287,7 +295,7 @@ var api = module.exports = { return reject(err); }); } catch(error) { - runtime.log.audit({event: "nodes.module.set",module:mod,enabled:opts.enabled,error:error.code||"unexpected_error",message:error.toString()}); + runtime.log.audit({event: "nodes.module.set",module:mod,enabled:opts.enabled,error:error.code||"unexpected_error",message:error.toString()}, opts.req); error.status = 400; return reject(error); } @@ -300,13 +308,14 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the node-set to enable or disable * @param {String} opts.enabled - whether the module should be enabled or disabled + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the module info object * @memberof @node-red/runtime_nodes */ setNodeSetState: function(opts) { return new Promise(function(resolve,reject) { if (!runtime.settings.available()) { - runtime.log.audit({event: "nodes.info.set",error:"settings_unavailable"}); + runtime.log.audit({event: "nodes.info.set",error:"settings_unavailable"}, opts.req); var err = new Error("Settings unavailable"); err.code = "settings_unavailable"; err.status = 400; @@ -318,7 +327,7 @@ var api = module.exports = { try { var node = runtime.nodes.getNodeInfo(id); if (!node) { - runtime.log.audit({event: "nodes.info.set",id:id,error:"not_found"}); + runtime.log.audit({event: "nodes.info.set",id:id,error:"not_found"}, opts.req); var err = new Error(); err.code = "not_found"; err.status = 404; @@ -326,16 +335,16 @@ var api = module.exports = { } else { delete node.loaded; putNode(node,enabled).then(function(result) { - runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled}); + runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled}, opts.req); return resolve(result); }).catch(function(err) { - runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); }); } } catch(error) { - runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:error.code||"unexpected_error",message:error.toString()}); + runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:error.code||"unexpected_error",message:error.toString()}, opts.req); error.status = 400; return reject(error); } @@ -347,6 +356,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {User} opts.lang - the i18n language to return. If not set, uses runtime default (en-US) + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the message catalogs * @memberof @node-red/runtime_nodes */ @@ -376,6 +386,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {User} opts.module - the module * @param {User} opts.lang - the i18n language to return. If not set, uses runtime default (en-US) + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the message catalog * @memberof @node-red/runtime_nodes */ @@ -397,12 +408,13 @@ var api = module.exports = { * Gets the list of all icons available in the modules installed within the runtime * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the list of all icons * @memberof @node-red/runtime_nodes */ getIconList: function(opts) { return new Promise(function(resolve,reject) { - runtime.log.audit({event: "nodes.icons.get"}); + runtime.log.audit({event: "nodes.icons.get"}, opts.req); return resolve(runtime.nodes.getNodeIcons()); }); @@ -413,6 +425,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.module - the id of the module requesting the icon * @param {String} opts.icon - the name of the icon + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the icon file as a Buffer or null if no icon available * @memberof @node-red/runtime_nodes */ diff --git a/packages/node_modules/@node-red/runtime/lib/api/projects.js b/packages/node_modules/@node-red/runtime/lib/api/projects.js index 27aef8c7b..53a0e64f3 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/projects.js +++ b/packages/node_modules/@node-red/runtime/lib/api/projects.js @@ -27,11 +27,12 @@ var api = module.exports = { available: function(opts) { return Promise.resolve(!!runtime.storage.projects); }, - /** * List projects known to the runtime * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ @@ -56,10 +57,12 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {Object} opts.project - the project information + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ createProject: function(opts) { + runtime.log.audit({event: "projects.create",name:opts.project.name}, opts.req); return runtime.storage.projects.createProject(opts.user, opts.project) }, @@ -69,11 +72,13 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project to initialise * @param {Object} opts.project - the project information + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ initialiseProject: function(opts) { // Initialised set when creating default files for an empty repo + runtime.log.audit({event: "projects.initialise",id:opts.id}, opts.req); return runtime.storage.projects.initialiseProject(opts.user, opts.id, opts.project) }, @@ -81,6 +86,7 @@ var api = module.exports = { * Gets the active project * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the active project * @memberof @node-red/runtime_projects */ @@ -93,11 +99,13 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project to activate + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ setActiveProject: function(opts) { var currentProject = runtime.storage.projects.getActiveProject(opts.user); + runtime.log.audit({event: "projects.set",id:opts.id}, opts.req); if (!currentProject || opts.id !== currentProject.name) { return runtime.storage.projects.setActiveProject(opts.user, opts.id); } else { @@ -110,6 +118,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project to get + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the project metadata * @memberof @node-red/runtime_projects */ @@ -123,10 +132,12 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project to update * @param {Object} opts.project - the project information + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ updateProject: function(opts) { + runtime.log.audit({event: "projects.update",id:opts.id}, opts.req); return runtime.storage.projects.updateProject(opts.user, opts.id, opts.project); }, @@ -135,10 +146,12 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project to update + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ deleteProject: function(opts) { + runtime.log.audit({event: "projects.delete",id:opts.id}, opts.req); return runtime.storage.projects.deleteProject(opts.user, opts.id); }, @@ -148,6 +161,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {Boolean} opts.remote - whether to include status of remote repos + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the project status * @memberof @node-red/runtime_projects */ @@ -161,6 +175,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {Boolean} opts.remote - whether to return remote branches (true) or local (false) + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - a list of the local branches * @memberof @node-red/runtime_projects */ @@ -174,6 +189,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String} opts.branch - the name of the branch + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the status of the branch * @memberof @node-red/runtime_projects */ @@ -188,10 +204,12 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.branch - the name of the branch * @param {Boolean} opts.create - whether to create the branch if it doesn't exist + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ setBranch: function(opts) { + runtime.log.audit({event: "projects.branch.set",id:opts.id, branch: opts.branch, create:opts.create}, opts.req); return runtime.storage.projects.setBranch(opts.user, opts.id, opts.branch, opts.create) }, @@ -202,10 +220,12 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.branch - the name of the branch * @param {Boolean} opts.force - whether to force delete + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ deleteBranch: function(opts) { + runtime.log.audit({event: "projects.branch.delete",id:opts.id, branch: opts.branch, force:opts.force}, opts.req); return runtime.storage.projects.deleteBranch(opts.user, opts.id, opts.branch, false, opts.force); }, @@ -215,10 +235,12 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String} opts.message - the message to associate with the commit + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ commit: function(opts) { + runtime.log.audit({event: "projects.commit",id:opts.id}, opts.req); return runtime.storage.projects.commit(opts.user, opts.id,{message: opts.message}); }, @@ -228,6 +250,7 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String} opts.sha - the sha of the commit to return + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the commit details * @memberof @node-red/runtime_projects */ @@ -242,6 +265,7 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.limit - limit how many to return * @param {String} opts.before - id of the commit to work back from + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - an array of commits * @memberof @node-red/runtime_projects */ @@ -257,10 +281,12 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ abortMerge: function(opts) { + runtime.log.audit({event: "projects.merge.abort",id:opts.id}, opts.req); return runtime.storage.projects.abortMerge(opts.user, opts.id); }, @@ -271,10 +297,12 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.path - the path of the file being merged * @param {String} opts.resolutions - how to resolve the merge conflict + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ resolveMerge: function(opts) { + runtime.log.audit({event: "projects.merge.resolve",id:opts.id, file:opts.path}, opts.req); return runtime.storage.projects.resolveMerge(opts.user, opts.id, opts.path, opts.resolution); }, @@ -283,6 +311,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the file listing * @memberof @node-red/runtime_projects */ @@ -297,6 +326,7 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.path - the path of the file * @param {String} opts.tree - the version control tree to use + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the content of the file * @memberof @node-red/runtime_projects */ @@ -310,10 +340,12 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String|Array} opts.path - the path of the file, or an array of paths + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ stageFile: function(opts) { + runtime.log.audit({event: "projects.file.stage",id:opts.id, file:opts.path}, opts.req); return runtime.storage.projects.stageFile(opts.user, opts.id, opts.path); }, @@ -323,10 +355,12 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String} opts.path - the path of the file. If not set, all staged files are unstaged + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ unstageFile: function(opts) { + runtime.log.audit({event: "projects.file.unstage",id:opts.id, file:opts.path}, opts.req); return runtime.storage.projects.unstageFile(opts.user, opts.id, opts.path); }, @@ -336,10 +370,12 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String} opts.path - the path of the file + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ revertFile: function(opts) { + runtime.log.audit({event: "projects.file.revert",id:opts.id, file:opts.path}, opts.req); return runtime.storage.projects.revertFile(opts.user, opts.id,opts.path) }, @@ -350,6 +386,7 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.path - the path of the file * @param {String} opts.type - the type of diff + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the requested diff * @memberof @node-red/runtime_projects */ @@ -362,6 +399,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - a list of project remotes * @memberof @node-red/runtime_projects */ @@ -378,10 +416,12 @@ var api = module.exports = { * @param {Object} opts.remote - the remote metadata * @param {String} opts.remote.name - the name of the remote * @param {String} opts.remote.url - the url of the remote + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ addRemote: function(opts) { + runtime.log.audit({event: "projects.remote.add",id:opts.id, remote:opts.remote.name}, opts.req); return runtime.storage.projects.addRemote(opts.user, opts.id, opts.remote) }, @@ -391,10 +431,12 @@ var api = module.exports = { * @param {User} opts.user - the user calling the api * @param {String} opts.id - the id of the project * @param {String} opts.remote - the name of the remote + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ removeRemote: function(opts) { + runtime.log.audit({event: "projects.remote.delete",id:opts.id, remote:opts.remote}, opts.req); return runtime.storage.projects.removeRemote(opts.user, opts.id, opts.remote); }, @@ -405,10 +447,12 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {Object} opts.remote - the remote metadata * @param {String} opts.remote.name - the name of the remote + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ updateRemote: function(opts) { + runtime.log.audit({event: "projects.remote.update",id:opts.id, remote:opts.remote.name}, opts.req); return runtime.storage.projects.updateRemote(opts.user, opts.id, opts.remote.name, opts.remote) }, @@ -416,10 +460,15 @@ var api = module.exports = { * Pull changes from the remote * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {String} opts.remote - the remote to pull + * @param {Boolean} opts.track - whether to track this remote + * @param {Boolean} opts.allowUnrelatedHistories - + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ pull: function(opts) { + runtime.log.audit({event: "projects.pull",id:opts.id, remote: opts.remote, track:opts.track}, opts.req); return runtime.storage.projects.pull(opts.user, opts.id, opts.remote, opts.track, opts.allowUnrelatedHistories); }, @@ -430,10 +479,12 @@ var api = module.exports = { * @param {String} opts.id - the id of the project * @param {String} opts.remote - the name of the remote * @param {String} opts.track - whether to set the remote as the upstream + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when complete * @memberof @node-red/runtime_projects */ push: function(opts) { + runtime.log.audit({event: "projects.push",id:opts.id, remote: opts.remote, track:opts.track}, opts.req); return runtime.storage.projects.push(opts.user, opts.id, opts.remote, opts.track); } diff --git a/packages/node_modules/@node-red/runtime/lib/api/settings.js b/packages/node_modules/@node-red/runtime/lib/api/settings.js index 3ae83d0cf..96bb6c973 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/settings.js +++ b/packages/node_modules/@node-red/runtime/lib/api/settings.js @@ -60,6 +60,7 @@ var api = module.exports = { * Gets the runtime settings object * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the runtime settings * @memberof @node-red/runtime_settings */ @@ -125,6 +126,7 @@ var api = module.exports = { * Gets an individual user's settings object * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the user settings * @memberof @node-red/runtime_settings */ @@ -143,6 +145,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {Object} opts.settings - the updates to the user settings + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the user settings * @memberof @node-red/runtime_settings */ @@ -158,16 +161,16 @@ var api = module.exports = { currentSettings = extend(currentSettings, opts.settings); try { runtime.settings.setUserSettings(username, currentSettings).then(function() { - runtime.log.audit({event: "settings.update",username:username}); + runtime.log.audit({event: "settings.update",username:username}, opts.req); return resolve(); }).catch(function(err) { - runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); }); } catch(err) { runtime.log.warn(runtime.log._("settings.user-not-available",{message:runtime.log._("settings.not-available")})); - runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}); + runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}, opts.req); err.status = 400; return reject(err); } @@ -178,6 +181,7 @@ var api = module.exports = { * Gets a list of a user's ssh keys * @param {Object} opts * @param {User} opts.user - the user calling the api + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the user's ssh keys * @memberof @node-red/runtime_settings */ @@ -198,6 +202,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {User} opts.id - the id of the key to return + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the user's ssh public key * @memberof @node-red/runtime_settings */ @@ -229,6 +234,7 @@ var api = module.exports = { * @param {User} opts.password - (optional) the password for the key pair * @param {User} opts.comment - (option) a comment to associate with the key pair * @param {User} opts.size - (optional) the size of the key. Default: 2048 + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - the id of the generated key * @memberof @node-red/runtime_settings */ @@ -249,6 +255,7 @@ var api = module.exports = { * @param {Object} opts * @param {User} opts.user - the user calling the api * @param {User} opts.id - the id of the key to delete + * @param {Object} opts.req - the request to log (optional) * @return {Promise} - resolves when deleted * @memberof @node-red/runtime_settings */ diff --git a/packages/node_modules/@node-red/util/lib/log.js b/packages/node_modules/@node-red/util/lib/log.js index abce5fa99..155863802 100644 --- a/packages/node_modules/@node-red/util/lib/log.js +++ b/packages/node_modules/@node-red/util/lib/log.js @@ -214,7 +214,7 @@ var log = module.exports = { if (req) { msg.user = req.user; msg.path = req.path; - msg.ip = (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined; + msg.ip = req.ip || (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined; } log.log(msg); } From 16440072fb5f7ae7c3acd75d70358f1c07679d1a Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 9 Aug 2019 17:09:03 +0100 Subject: [PATCH 20/23] Add audit log to project spec tests --- .../@node-red/runtime/lib/api/projects.js | 2 +- .../runtime/lib/api/projects_spec.js | 120 +++++++++++++----- 2 files changed, 91 insertions(+), 31 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/api/projects.js b/packages/node_modules/@node-red/runtime/lib/api/projects.js index 53a0e64f3..d792f3765 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/projects.js +++ b/packages/node_modules/@node-red/runtime/lib/api/projects.js @@ -62,7 +62,7 @@ var api = module.exports = { * @memberof @node-red/runtime_projects */ createProject: function(opts) { - runtime.log.audit({event: "projects.create",name:opts.project.name}, opts.req); + runtime.log.audit({event: "projects.create",name:opts.project?opts.project.name:"missing-name"}, opts.req); return runtime.storage.projects.createProject(opts.user, opts.project) }, diff --git a/test/unit/@node-red/runtime/lib/api/projects_spec.js b/test/unit/@node-red/runtime/lib/api/projects_spec.js index c8f0c25c8..2fe7ca221 100644 --- a/test/unit/@node-red/runtime/lib/api/projects_spec.js +++ b/test/unit/@node-red/runtime/lib/api/projects_spec.js @@ -57,7 +57,9 @@ describe("runtime-api/settings", function() { }); describe("listProjects", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { listProjects: sinon.spy(function(user) { if (user === "error") { var err = new Error("error"); @@ -105,7 +107,9 @@ describe("runtime-api/settings", function() { }); describe("createProject", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { createProject: sinon.spy(function(user,project) { if (user === "error") { var err = new Error("error"); @@ -138,7 +142,9 @@ describe("runtime-api/settings", function() { }); }); describe("initialiseProject", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { initialiseProject: sinon.spy(function(user,id,project) { if (user === "error") { var err = new Error("error"); @@ -172,7 +178,9 @@ describe("runtime-api/settings", function() { }); describe("getActiveProject", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getActiveProject: sinon.spy(function(user) { if (user === "error") { var err = new Error("error"); @@ -209,7 +217,9 @@ describe("runtime-api/settings", function() { var activeProject; var runtime; beforeEach(function() { - runtime = {storage: {projects: { + runtime = { + log: mockLog(), + storage: {projects: { getActiveProject: sinon.spy(function() { return activeProject;}), setActiveProject: sinon.spy(function(user,id) { if (user === "error") { @@ -258,7 +268,9 @@ describe("runtime-api/settings", function() { }); describe("getProject", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getProject: sinon.spy(function(user,id) { if (user === "error") { var err = new Error("error"); @@ -291,7 +303,9 @@ describe("runtime-api/settings", function() { }); }); describe("updateProject", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { updateProject: sinon.spy(function(user,id,project) { if (user === "error") { var err = new Error("error"); @@ -325,7 +339,9 @@ describe("runtime-api/settings", function() { }); describe("deleteProject", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { deleteProject: sinon.spy(function(user,id) { if (user === "error") { var err = new Error("error"); @@ -359,7 +375,9 @@ describe("runtime-api/settings", function() { }); describe("getStatus", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getStatus: sinon.spy(function(user,id,remote) { if (user === "error") { var err = new Error("error"); @@ -392,7 +410,9 @@ describe("runtime-api/settings", function() { }); }); describe("getBranches", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getBranches: sinon.spy(function(user,id,remote) { if (user === "error") { var err = new Error("error"); @@ -425,7 +445,9 @@ describe("runtime-api/settings", function() { }); }); describe("getBranchStatus", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getBranchStatus: sinon.spy(function(user,id,branch) { if (user === "error") { var err = new Error("error"); @@ -459,7 +481,9 @@ describe("runtime-api/settings", function() { }); describe("setBranch", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { setBranch: sinon.spy(function(user,id,branch,create) { if (user === "error") { var err = new Error("error"); @@ -493,7 +517,9 @@ describe("runtime-api/settings", function() { }); describe("deleteBranch", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { deleteBranch: sinon.spy(function(user,id,branch,something,force) { if (user === "error") { var err = new Error("error"); @@ -527,7 +553,9 @@ describe("runtime-api/settings", function() { }); describe("commit", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { commit: sinon.spy(function(user,id,message) { if (user === "error") { var err = new Error("error"); @@ -560,7 +588,9 @@ describe("runtime-api/settings", function() { }); }); describe("getCommit", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getCommit: sinon.spy(function(user,id,sha) { if (user === "error") { var err = new Error("error"); @@ -594,7 +624,9 @@ describe("runtime-api/settings", function() { }); describe("getCommits", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getCommits: sinon.spy(function(user,id,options) { if (user === "error") { var err = new Error("error"); @@ -634,7 +666,9 @@ describe("runtime-api/settings", function() { }); describe("abortMerge", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { abortMerge: sinon.spy(function(user,id) { if (user === "error") { var err = new Error("error"); @@ -668,7 +702,9 @@ describe("runtime-api/settings", function() { }); describe("resolveMerge", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { resolveMerge: sinon.spy(function(user,id,path,resolution) { if (user === "error") { var err = new Error("error"); @@ -702,7 +738,9 @@ describe("runtime-api/settings", function() { }); describe("getFiles", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getFiles: sinon.spy(function(user,id) { if (user === "error") { var err = new Error("error"); @@ -736,7 +774,9 @@ describe("runtime-api/settings", function() { }); describe("getFile", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getFile: sinon.spy(function(user,id,path,tree) { if (user === "error") { var err = new Error("error"); @@ -770,7 +810,9 @@ describe("runtime-api/settings", function() { }); describe("stageFile", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { stageFile: sinon.spy(function(user,id,path) { if (user === "error") { var err = new Error("error"); @@ -803,7 +845,9 @@ describe("runtime-api/settings", function() { }); }); describe("unstageFile", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { unstageFile: sinon.spy(function(user,id,path) { if (user === "error") { var err = new Error("error"); @@ -837,7 +881,9 @@ describe("runtime-api/settings", function() { }); describe("revertFile", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { revertFile: sinon.spy(function(user,id,path) { if (user === "error") { var err = new Error("error"); @@ -871,7 +917,9 @@ describe("runtime-api/settings", function() { }); describe("getFileDiff", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getFileDiff: sinon.spy(function(user,id,path,type) { if (user === "error") { var err = new Error("error"); @@ -905,7 +953,9 @@ describe("runtime-api/settings", function() { }); describe("getRemotes", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { getRemotes: sinon.spy(function(user,id) { if (user === "error") { var err = new Error("error"); @@ -939,7 +989,9 @@ describe("runtime-api/settings", function() { }); describe("addRemote", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { addRemote: sinon.spy(function(user,id,remote) { if (user === "error") { var err = new Error("error"); @@ -973,7 +1025,9 @@ describe("runtime-api/settings", function() { }); describe("removeRemote", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { removeRemote: sinon.spy(function(user,id,remote) { if (user === "error") { var err = new Error("error"); @@ -1007,7 +1061,9 @@ describe("runtime-api/settings", function() { }); describe("updateRemote", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { updateRemote: sinon.spy(function(user,id,name,remote) { if (user === "error") { var err = new Error("error"); @@ -1040,7 +1096,9 @@ describe("runtime-api/settings", function() { }); }); describe("pull", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { pull: sinon.spy(function(user,id,remote,track,allowUnrelatedHistories) { if (user === "error") { var err = new Error("error"); @@ -1073,7 +1131,9 @@ describe("runtime-api/settings", function() { }); }); describe("push", function() { - var runtime = {storage: {projects: { + var runtime = { + log: mockLog(), + storage: {projects: { push: sinon.spy(function(user,id,remote,track) { if (user === "error") { var err = new Error("error"); From e2db958510d853a20c25bc3172e3622e9d2c73e1 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 9 Aug 2019 17:27:32 +0100 Subject: [PATCH 21/23] Fix up admin nodes test for audit log changes --- test/unit/@node-red/editor-api/lib/admin/nodes_spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js b/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js index 6fbbeff67..ef98fb677 100644 --- a/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js +++ b/test/unit/@node-red/editor-api/lib/admin/nodes_spec.js @@ -441,7 +441,7 @@ describe("api/admin/nodes", function() { nodes.init({ nodes:{ getModuleCatalog: function(opts) { - return Promise.resolve(opts); + return Promise.resolve({a:123}); } } }); @@ -452,7 +452,7 @@ describe("api/admin/nodes", function() { if (err) { throw err; } - res.body.should.eql({ module: 'module/set' }); + res.body.should.eql({a:123}); done(); }); }); From 7b5a41c3ff8f2cfde007c53628881090c64abbe0 Mon Sep 17 00:00:00 2001 From: Hiroyasu Nishiyama Date: Mon, 12 Aug 2019 13:49:34 +0900 Subject: [PATCH 22/23] fix subflow category change on palette --- .../@node-red/editor-client/src/js/ui/palette.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js index 359d0dead..8948017b6 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js @@ -415,7 +415,7 @@ RED.palette = (function() { createCategory(newCategory,category,category,"node-red"); var currentCategoryNode = paletteNode.closest(".red-ui-palette-category"); - var newCategoryNode = $("#palette-"+category); + var newCategoryNode = $("#red-ui-palette-"+category); newCategoryNode.append(paletteNode); if (newCategoryNode.find(".red-ui-palette-node").length === 1) { categoryContainers[category].open(); @@ -428,9 +428,6 @@ RED.palette = (function() { currentCategoryNode.find("i").toggleClass("expanded"); } } - - - } }); } From e5255b0c7c83cc2e36e8699553d379472c60fb46 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 12 Aug 2019 14:36:26 +0100 Subject: [PATCH 23/23] Ensure 2nd arg to node.error is an object Fixes #2228 --- packages/node_modules/@node-red/runtime/lib/nodes/Node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/Node.js b/packages/node_modules/@node-red/runtime/lib/nodes/Node.js index b1003d717..d4e1ae00f 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/Node.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/Node.js @@ -272,7 +272,7 @@ Node.prototype.error = function(logMessage,msg) { logMessage = logMessage || ""; } var handled = false; - if (msg) { + if (msg && typeof msg === 'object') { handled = this._flow.handleError(this,logMessage,msg); } if (!handled) {