From 39b849ded8ca84065deb375e51eb9797828eb420 Mon Sep 17 00:00:00 2001 From: Nicholas O'Leary Date: Fri, 22 Nov 2013 20:34:57 +0000 Subject: [PATCH] Move Mysql node credentials to credentials file We must not store passwords in the regular flows file as this gets exchanged with the browser regularly and would leave things vulnerable. The credentials mechanism is there to all a write-once-don't-need-to-read approach that allows the runtime access to the credentials without exposing them to the browser. --- storage/mysql/68-mysql.html | 40 ++++++++++++++++++++++++-- storage/mysql/68-mysql.js | 56 +++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/storage/mysql/68-mysql.html b/storage/mysql/68-mysql.html index 29187b1b..a68e642b 100644 --- a/storage/mysql/68-mysql.html +++ b/storage/mysql/68-mysql.html @@ -43,13 +43,49 @@ defaults: { host: {value:"127.0.0.1",required:true}, port: {value:"3306",required:true}, - user: {value:"",required:true}, - pass: {value:"",required:true}, + //user: {value:"",required:true}, + //pass: {value:"",required:true}, db: {value:"",required:true} }, label: function() { return this.db; + }, + oneditprepare: function() { + $.getJSON('MySQLdatabase/'+this.id,function(data) { + if (data.user) { + $('#node-config-input-user').val(data.user); + } + if (data.hasPassword) { + $('#node-config-input-pass').val('__PWRD__'); + } else { + $('#node-config-input-pass').val(''); + } + + }); + }, + oneditsave: function() { + var newUser = $('#node-config-input-user').val(); + var newPass = $('#node-config-input-pass').val(); + var credentials = {}; + credentials.user = newUser; + if (newPass != '__PWRD__') { + credentials.password = newPass; + } + $.ajax({ + url: 'MySQLdatabase/'+this.id, + type: 'POST', + data: credentials, + success:function(result){} + }); + }, + ondelete: function() { + $.ajax({ + url: 'MySQLdatabase/'+this.id, + type: 'DELETE', + success: function(result) {} + }); } + }); diff --git a/storage/mysql/68-mysql.js b/storage/mysql/68-mysql.js index 7d1564fd..312ab31e 100644 --- a/storage/mysql/68-mysql.js +++ b/storage/mysql/68-mysql.js @@ -17,13 +17,65 @@ var RED = require(process.env.NODE_RED_HOME+"/red/red"); var reconnect = RED.settings.mysqlReconnectTime || 30000; var mysqldb = require('mysql'); +var querystring = require('querystring'); + +RED.app.get('/MySQLdatabase/:id',function(req,res) { + var credentials = RED.nodes.getCredentials(req.params.id); + if (credentials) { + res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")})); + } else { + res.send(JSON.stringify({})); + } +}); + +RED.app.delete('/MySQLdatabase/:id',function(req,res) { + RED.nodes.deleteCredentials(req.params.id); + res.send(200); +}); + +RED.app.post('/MySQLdatabase/:id',function(req,res) { + var body = ""; + req.on('data', function(chunk) { + body+=chunk; + }); + req.on('end', function(){ + var newCreds = querystring.parse(body); + var credentials = RED.nodes.getCredentials(req.params.id)||{}; + if (newCreds.user == null || newCreds.user == "") { + delete credentials.user; + } else { + credentials.user = newCreds.user; + } + if (newCreds.password == "") { + delete credentials.password; + } else { + credentials.password = newCreds.password||credentials.password; + } + RED.nodes.addCredentials(req.params.id,credentials); + res.send(200); + }); +}); + function MySQLNode(n) { RED.nodes.createNode(this,n); this.host = n.host; this.port = n.port; - this.user = n.user; - this.password = n.pass; + if (n.user) { + var credentials = {}; + credentials.user = n.user; + credentials.password = n.pass; + RED.nodes.addCredentials(n.id,credentials); + this.user = n.user; + this.password = n.pass; + } else { + var credentials = RED.nodes.getCredentials(n.id); + if (credentials) { + this.user = credentials.user; + this.password = credentials.password; + } + } + this.dbname = n.db; var node = this;