mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add clientid/username/password to MQTT nodes
Alternative implementation, closes #42 The username/password as not stored in the main flow file for security reasons; they are stored in the adjacent credentials file. This does mean an extra step to importing an MQTT node, as the user has to manually edit it to re-add username and password if needed.
This commit is contained in:
parent
796080471d
commit
7040aaa179
@ -30,8 +30,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/x-red" data-help-name="mqtt in">
|
<script type="text/x-red" data-help-name="mqtt in">
|
||||||
<p>MQTT input node. Connects to the specified broker and subscribes to the specified topic. The topic may contain MQTT wildcards.</p>
|
<p>MQTT input node. Connects to a broker and subscribes to the specified topic. The topic may contain MQTT wildcards.</p>
|
||||||
<p>Outputs an object called <b>msg</b> containing <b>msg.topic, msg.payload, msg.qos</b> and <b>msg.retain</b>. <b>msg.payload</b> is a String.</p>
|
<p>Outputs an object called <b>msg</b> containing <b>msg.topic, msg.payload, msg.qos</b> and <b>msg.retain</b>.</p>
|
||||||
|
<p><b>msg.payload</b> is a String.</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -105,6 +106,18 @@
|
|||||||
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
||||||
<input type="text" id="node-config-input-port" placeholder="Port" style="width:45px">
|
<input type="text" id="node-config-input-port" placeholder="Port" style="width:45px">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-config-input-clientid"><i class="icon-tag"></i> Client ID</label>
|
||||||
|
<input type="text" id="node-config-input-clientid" placeholder="Leave blank for auto generated">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-config-input-user"><i class="icon-user"></i> Username</label>
|
||||||
|
<input type="text" id="node-config-input-user">
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-config-input-pass"><i class="icon-lock"></i> Password</label>
|
||||||
|
<input type="password" id="node-config-input-pass">
|
||||||
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@ -112,10 +125,49 @@
|
|||||||
category: 'config',
|
category: 'config',
|
||||||
defaults: {
|
defaults: {
|
||||||
broker: {value:"localhost",required:true},
|
broker: {value:"localhost",required:true},
|
||||||
port: {value:1883,required:true,validate:RED.validators.number()}
|
port: {value:1883,required:true,validate:RED.validators.number()},
|
||||||
|
clientid: { value:"" }
|
||||||
|
//user -> credentials
|
||||||
|
//pass -> credentials
|
||||||
|
|
||||||
},
|
},
|
||||||
label: function() {
|
label: function() {
|
||||||
return this.broker+":"+this.port;
|
return this.broker+":"+this.port;
|
||||||
|
},
|
||||||
|
oneditprepare: function() {
|
||||||
|
$.getJSON('mqtt-broker/'+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: 'mqtt-broker/'+this.id,
|
||||||
|
type: 'POST',
|
||||||
|
data: credentials,
|
||||||
|
success:function(result){}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
ondelete: function() {
|
||||||
|
$.ajax({
|
||||||
|
url: 'mqtt-broker/'+this.id,
|
||||||
|
type: 'DELETE',
|
||||||
|
success: function(result) {}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -22,9 +22,54 @@ function MQTTBrokerNode(n) {
|
|||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
this.broker = n.broker;
|
this.broker = n.broker;
|
||||||
this.port = n.port;
|
this.port = n.port;
|
||||||
|
this.clientid = n.clientid;
|
||||||
|
var credentials = RED.nodes.getCredentials(n.id);
|
||||||
|
if (credentials) {
|
||||||
|
this.username = credentials.user;
|
||||||
|
this.password = credentials.password;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RED.nodes.registerType("mqtt-broker",MQTTBrokerNode);
|
RED.nodes.registerType("mqtt-broker",MQTTBrokerNode);
|
||||||
|
|
||||||
|
var querystring = require('querystring');
|
||||||
|
|
||||||
|
RED.app.get('/mqtt-broker/: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('/mqtt-broker/:id',function(req,res) {
|
||||||
|
RED.nodes.deleteCredentials(req.params.id);
|
||||||
|
res.send(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
RED.app.post('/mqtt-broker/: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 MQTTInNode(n) {
|
function MQTTInNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
@ -32,7 +77,7 @@ function MQTTInNode(n) {
|
|||||||
this.broker = n.broker;
|
this.broker = n.broker;
|
||||||
this.brokerConfig = RED.nodes.getNode(this.broker);
|
this.brokerConfig = RED.nodes.getNode(this.broker);
|
||||||
if (this.brokerConfig) {
|
if (this.brokerConfig) {
|
||||||
this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port);
|
this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password);
|
||||||
var node = this;
|
var node = this;
|
||||||
this.client.subscribe(this.topic,2,function(topic,payload,qos,retain) {
|
this.client.subscribe(this.topic,2,function(topic,payload,qos,retain) {
|
||||||
var msg = {topic:topic,payload:payload,qos:qos,retain:retain};
|
var msg = {topic:topic,payload:payload,qos:qos,retain:retain};
|
||||||
@ -65,7 +110,7 @@ function MQTTOutNode(n) {
|
|||||||
this.brokerConfig = RED.nodes.getNode(this.broker);
|
this.brokerConfig = RED.nodes.getNode(this.broker);
|
||||||
|
|
||||||
if (this.brokerConfig) {
|
if (this.brokerConfig) {
|
||||||
this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port);
|
this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password);
|
||||||
this.on("input",function(msg) {
|
this.on("input",function(msg) {
|
||||||
if (msg != null) {
|
if (msg != null) {
|
||||||
if (this.topic) {
|
if (this.topic) {
|
||||||
|
@ -25,13 +25,16 @@ function matchTopic(ts,t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get: function(broker,port) {
|
get: function(broker,port,clientid,username,password) {
|
||||||
var id = broker+":"+port;
|
var id = "["+(username||"")+":"+(password||"")+"]["+(clientid||"")+"]@"+broker+":"+port;
|
||||||
if (!connections[id]) {
|
if (!connections[id]) {
|
||||||
connections[id] = function() {
|
connections[id] = function() {
|
||||||
var client = mqtt.createClient(port,broker);
|
var client = mqtt.createClient(port,broker);
|
||||||
client.setMaxListeners(0);
|
client.setMaxListeners(0);
|
||||||
var options = {keepalive:15,clientId:'mqtt_' + (1+Math.random()*4294967295).toString(16)};
|
var options = {keepalive:15};
|
||||||
|
options.clientId = clientid || 'mqtt_' + (1+Math.random()*4294967295).toString(16);
|
||||||
|
options.username = username;
|
||||||
|
options.password = password;
|
||||||
var queue = [];
|
var queue = [];
|
||||||
var subscriptions = [];
|
var subscriptions = [];
|
||||||
var connecting = false;
|
var connecting = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user