From be2dd6dc3257dbe5eeb22b8e91e99cca26002ca5 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 9 Aug 2019 16:56:11 +0100 Subject: [PATCH] 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); }