@node-red/nodes 2.1.5 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright JS Foundation and other contributors, http://js.foundation
1
+ Copyright OpenJS Foundation and other contributors, https://openjsf.org/
2
2
 
3
3
  Apache License
4
4
  Version 2.0, January 2004
@@ -234,7 +234,7 @@
234
234
  }
235
235
  } else if (v[i].vt === "jsonata") {
236
236
  try{jsonata(v[i].v);}catch(e){return false;}
237
- } else if ([i].vt === "json") {
237
+ } else if (v[i].vt === "json") {
238
238
  try{JSON.parse(v[i].v);}catch(e){return false;}
239
239
  }
240
240
  }
@@ -75,16 +75,12 @@ module.exports = function(RED) {
75
75
  node.repeaterSetup = function () {
76
76
  if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
77
77
  this.repeat = this.repeat * 1000;
78
- if (RED.settings.verbose) {
79
- this.log(RED._("inject.repeat", this));
80
- }
78
+ this.debug(RED._("inject.repeat", this));
81
79
  this.interval_id = setInterval(function() {
82
80
  node.emit("input", {});
83
81
  }, this.repeat);
84
82
  } else if (this.crontab) {
85
- if (RED.settings.verbose) {
86
- this.log(RED._("inject.crontab", this));
87
- }
83
+ this.debug(RED._("inject.crontab", this));
88
84
  this.cronjob = scheduleTask(this.crontab,() => { node.emit("input", {})});
89
85
  }
90
86
  };
@@ -148,10 +144,8 @@ module.exports = function(RED) {
148
144
  }
149
145
  if (this.interval_id != null) {
150
146
  clearInterval(this.interval_id);
151
- if (RED.settings.verbose) { this.log(RED._("inject.stopped")); }
152
147
  } else if (this.cronjob != null) {
153
148
  this.cronjob.stop();
154
- if (RED.settings.verbose) { this.log(RED._("inject.stopped")); }
155
149
  delete this.cronjob;
156
150
  }
157
151
  };
@@ -7,6 +7,7 @@ module.exports = function(RED) {
7
7
  var debuglength = RED.settings.debugMaxLength || 1000;
8
8
  var useColors = RED.settings.debugUseColors || false;
9
9
  util.inspect.styles.boolean = "red";
10
+ const { hasOwnProperty } = Object.prototype;
10
11
 
11
12
  function DebugNode(n) {
12
13
  var hasEditExpression = (n.targetType === "jsonata");
@@ -107,7 +108,7 @@ module.exports = function(RED) {
107
108
  }
108
109
  })
109
110
  this.on("input", function(msg, send, done) {
110
- if (msg.hasOwnProperty("status") && msg.status.hasOwnProperty("source") && msg.status.source.hasOwnProperty("id") && (msg.status.source.id === node.id)) {
111
+ if (hasOwnProperty.call(msg, "status") && hasOwnProperty.call(msg.status, "source") && hasOwnProperty.call(msg.status.source, "id") && (msg.status.source.id === node.id)) {
111
112
  done();
112
113
  return;
113
114
  }
@@ -118,17 +119,17 @@ module.exports = function(RED) {
118
119
  var st = (typeof output === 'string') ? output : util.inspect(output);
119
120
  var fill = "grey";
120
121
  var shape = "dot";
121
- if (typeof output === 'object' && output.hasOwnProperty("fill") && output.hasOwnProperty("shape") && output.hasOwnProperty("text")) {
122
+ if (typeof output === 'object' && hasOwnProperty.call(output, "fill") && hasOwnProperty.call(output, "shape") && hasOwnProperty.call(output, "text")) {
122
123
  fill = output.fill;
123
124
  shape = output.shape;
124
125
  st = output.text;
125
126
  }
126
127
  if (node.statusType === "auto") {
127
- if (msg.hasOwnProperty("error")) {
128
+ if (hasOwnProperty.call(msg, "error")) {
128
129
  fill = "red";
129
130
  st = msg.error.message;
130
131
  }
131
- if (msg.hasOwnProperty("status")) {
132
+ if (hasOwnProperty.call(msg, "status")) {
132
133
  fill = msg.status.fill || "grey";
133
134
  shape = msg.status.shape || "ring";
134
135
  st = msg.status.text || "";
@@ -194,7 +195,7 @@ module.exports = function(RED) {
194
195
 
195
196
  function sendDebug(msg) {
196
197
  // don't put blank errors in sidebar (but do add to logs)
197
- //if ((msg.msg === "") && (msg.hasOwnProperty("level")) && (msg.level === 20)) { return; }
198
+ //if ((msg.msg === "") && (hasOwnProperty.call(msg, "level")) && (msg.level === 20)) { return; }
198
199
  msg = RED.util.encodeObject(msg,{maxLength:debuglength});
199
200
  RED.comms.publish("debug",msg);
200
201
  }
@@ -112,6 +112,7 @@ module.exports = function(RED) {
112
112
  "var node = {"+
113
113
  "id:__node__.id,"+
114
114
  "name:__node__.name,"+
115
+ "path:__node__.path,"+
115
116
  "outputCount:__node__.outputCount,"+
116
117
  "log:__node__.log,"+
117
118
  "error:__node__.error,"+
@@ -163,6 +164,7 @@ module.exports = function(RED) {
163
164
  __node__: {
164
165
  id: node.id,
165
166
  name: node.name,
167
+ path: node._path,
166
168
  outputCount: node.outputs,
167
169
  log: function() {
168
170
  node.log.apply(node, arguments);
@@ -344,6 +346,7 @@ module.exports = function(RED) {
344
346
  var node = {
345
347
  id:__node__.id,
346
348
  name:__node__.name,
349
+ path:__node__.path,
347
350
  outputCount:__node__.outputCount,
348
351
  log:__node__.log,
349
352
  error:__node__.error,
@@ -366,6 +369,7 @@ module.exports = function(RED) {
366
369
  var node = {
367
370
  id:__node__.id,
368
371
  name:__node__.name,
372
+ path:__node__.path,
369
373
  outputCount:__node__.outputCount,
370
374
  log:__node__.log,
371
375
  error:__node__.error,
@@ -114,7 +114,8 @@
114
114
  timeout: {value:"5", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
115
115
  timeoutUnits: {value:"seconds"},
116
116
  rate: {value:"1", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
117
- nbRateUnits: {value:"1", required:false, validate:RED.validators.regex(/\d+|/)},
117
+ nbRateUnits: {value:"1", required:false,
118
+ validate:function(v) { return v === undefined || (RED.validators.number(v) && (v >= 0)); }},
118
119
  rateUnits: {value: "second"},
119
120
  randomFirst: {value:"1", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
120
121
  randomLast: {value:"5", required:true, validate:function(v) { return RED.validators.number(v) && (v >= 0); }},
@@ -86,7 +86,7 @@ module.exports = function(RED) {
86
86
  });
87
87
  var cmd = arg.shift();
88
88
  /* istanbul ignore else */
89
- if (RED.settings.verbose) { node.log(cmd+" ["+arg+"]"); }
89
+ node.debug(cmd+" ["+arg+"]");
90
90
  child = spawn(cmd,arg,node.spawnOpt);
91
91
  node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid});
92
92
  var unknownCommand = (child.pid === undefined);
@@ -136,7 +136,7 @@ module.exports = function(RED) {
136
136
  }
137
137
  else {
138
138
  /* istanbul ignore else */
139
- if (RED.settings.verbose) { node.log(arg); }
139
+ node.debug(arg);
140
140
  child = exec(arg, node.execOpt, function (error, stdout, stderr) {
141
141
  var msg2, msg3;
142
142
  delete msg.payload;
@@ -155,7 +155,7 @@ module.exports = function(RED) {
155
155
  if (error.signal) { msg3.payload.signal = error.signal; }
156
156
  if (error.code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); }
157
157
  else { node.status({fill:"red",shape:"dot",text:"error:"+error.code}); }
158
- if (RED.settings.verbose) { node.log('error:' + error); }
158
+ node.debug('error:' + error);
159
159
  }
160
160
  else if (node.oldrc === "false") {
161
161
  msg3 = RED.util.cloneMessage(msg);
@@ -288,7 +288,7 @@ module.exports = function(RED) {
288
288
  //TODO: delete msg.responseTopic - to prevent it being resent?
289
289
  }
290
290
  }
291
- topicOK = topicOK && !/[\+#]/.test(msg.topic);
291
+ topicOK = topicOK && !/[\+#\b\f\n\r\t\v\0]/.test(msg.topic);
292
292
 
293
293
  if (topicOK) {
294
294
  node.brokerConn.publish(msg, done); // send the message
@@ -730,12 +730,18 @@ module.exports = function(RED) {
730
730
  node.client.on("reconnect", function() {
731
731
  setStatusConnecting(node, true);
732
732
  });
733
- //TODO: what to do with this event? Anything? Necessary?
733
+ //Broker Disconnect - V5 event
734
734
  node.client.on("disconnect", function(packet) {
735
735
  //Emitted after receiving disconnect packet from broker. MQTT 5.0 feature.
736
- var rc = packet && packet.properties && packet.properties.reasonString;
737
- var rc = packet && packet.properties && packet.reasonCode;
738
- //TODO: If keeping this event, do we use these? log these?
736
+ const rc = (packet && packet.properties && packet.reasonCode) || packet.reasonCode;
737
+ const rs = packet && packet.properties && packet.properties.reasonString || "";
738
+ const details = {
739
+ broker: (node.clientid?node.clientid+"@":"")+node.brokerurl,
740
+ reasonCode: rc,
741
+ reasonString: rs
742
+ }
743
+ node.log(RED._("mqtt.state.broker-disconnected", details));
744
+ setStatusDisconnected(node, true);
739
745
  });
740
746
  // Register disconnect handlers
741
747
  node.client.on('close', function () {
@@ -264,7 +264,7 @@ in your Node-RED user directory (${RED.settings.userDir}).
264
264
  if (opts.headers.hasOwnProperty('cookie')) {
265
265
  var cookies = cookie.parse(opts.headers.cookie, {decode:String});
266
266
  for (var name in cookies) {
267
- opts.cookieJar.setCookie(cookie.serialize(name, cookies[name], {encode:String}), url, {ignoreError: true});
267
+ opts.cookieJar.setCookieSync(cookie.serialize(name, cookies[name], {encode:String}), url, {ignoreError: true});
268
268
  }
269
269
  delete opts.headers.cookie;
270
270
  }
@@ -277,13 +277,13 @@ in your Node-RED user directory (${RED.settings.userDir}).
277
277
  } else if (typeof msg.cookies[name] === 'object') {
278
278
  if(msg.cookies[name].encode === false){
279
279
  // If the encode option is false, the value is not encoded.
280
- opts.cookieJar.setCookie(cookie.serialize(name, msg.cookies[name].value, {encode: String}), url, {ignoreError: true});
280
+ opts.cookieJar.setCookieSync(cookie.serialize(name, msg.cookies[name].value, {encode: String}), url, {ignoreError: true});
281
281
  } else {
282
282
  // The value is encoded by encodeURIComponent().
283
- opts.cookieJar.setCookie(cookie.serialize(name, msg.cookies[name].value), url, {ignoreError: true});
283
+ opts.cookieJar.setCookieSync(cookie.serialize(name, msg.cookies[name].value), url, {ignoreError: true});
284
284
  }
285
285
  } else {
286
- opts.cookieJar.setCookie(cookie.serialize(name, msg.cookies[name]), url, {ignoreError: true});
286
+ opts.cookieJar.setCookieSync(cookie.serialize(name, msg.cookies[name]), url, {ignoreError: true});
287
287
  }
288
288
  }
289
289
  }
@@ -177,7 +177,8 @@
177
177
  path: {value:"",required:true,validate:RED.validators.regex(/^((?!\/debug\/ws).)*$/)},
178
178
  tls: {type:"tls-config",required: false},
179
179
  wholemsg: {value:"false"},
180
- hb: {value: "", validate: RED.validators.number(/*blank allowed*/true) }
180
+ hb: {value: "", validate: RED.validators.number(/*blank allowed*/true) },
181
+ subprotocol: {value:"",required: false}
181
182
  },
182
183
  inputs:0,
183
184
  outputs:0,
@@ -265,7 +266,10 @@
265
266
  <label for="node-config-input-tls" data-i18n="httpin.tls-config"></label>
266
267
  <input type="text" id="node-config-input-tls">
267
268
  </div>
268
-
269
+ <div class="form-row">
270
+ <label for="node-config-input-subprotocol"><i class="fa fa-tag"></i> <span data-i18n="websocket.label.subprotocol"></span></label>
271
+ <input type="text" id="node-config-input-subprotocol">
272
+ </div>
269
273
  <div class="form-row">
270
274
  <label for="node-config-input-wholemsg" data-i18n="websocket.sendrec"></label>
271
275
  <select type="text" id="node-config-input-wholemsg" style="width: 70%;">
@@ -46,6 +46,12 @@ module.exports = function(RED) {
46
46
 
47
47
  // Store local copies of the node configuration (as defined in the .html)
48
48
  node.path = n.path;
49
+ if (typeof n.subprotocol === "string") {
50
+ // Split the string on comma and trim each result
51
+ node.subprotocol = n.subprotocol.split(",").map(v => v.trim())
52
+ } else {
53
+ node.subprotocol = [];
54
+ }
49
55
  node.wholemsg = (n.wholemsg === "true");
50
56
 
51
57
  node._inputNodes = []; // collection of nodes that want to receive events
@@ -92,7 +98,7 @@ module.exports = function(RED) {
92
98
  tlsNode.addTLSOptions(options);
93
99
  }
94
100
  }
95
- var socket = new ws(node.path,options);
101
+ var socket = new ws(node.path,node.subprotocol,options);
96
102
  socket.setMaxListeners(0);
97
103
  node.server = socket; // keep for closing
98
104
  handleConnection(socket);
@@ -23,9 +23,17 @@
23
23
  </select>
24
24
  <span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width:65px">
25
25
  </div>
26
- <div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;">
26
+ <div class="form-row hidden" id="node-input-host-row" style="padding-left:110px;">
27
27
  <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" placeholder="localhost" style="width: 60%;">
28
28
  </div>
29
+ <div class="form-row" id="node-input-tls-enable">
30
+ <label> </label>
31
+ <input type="checkbox" id="node-input-usetls" style="display: inline-block; width:auto; vertical-align:top;">
32
+ <label for="node-input-usetls" style="width:auto" data-i18n="httpin.use-tls"></label>
33
+ <div id="node-row-tls" class="hide">
34
+ <label style="width:auto; margin-left:20px; margin-right:10px;" for="node-input-tls"><span data-i18n="httpin.tls-config"></span></label><input type="text" style="width: 300px" id="node-input-tls">
35
+ </div>
36
+ </div>
29
37
 
30
38
  <div class="form-row">
31
39
  <label><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.output"></span></label>
@@ -42,7 +50,7 @@
42
50
  </div>
43
51
 
44
52
  <div id="node-row-newline" class="form-row hidden" style="padding-left:110px;">
45
- <span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;">
53
+ <span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;" data-i18n="[placeholder]tcpin.label.optional">
46
54
  </div>
47
55
 
48
56
  <div class="form-row">
@@ -58,17 +66,18 @@
58
66
  <script type="text/javascript">
59
67
  RED.nodes.registerType('tcp in',{
60
68
  category: 'network',
61
- color:"Silver",
69
+ color: "Silver",
62
70
  defaults: {
63
71
  name: {value:""},
64
- server: {value:"server",required:true},
65
- host: {value:"",validate:function(v) { return (this.server == "server")||v.length > 0;} },
66
- port: {value:"",required:true,validate:RED.validators.number()},
72
+ server: {value:"server", required:true},
73
+ host: {value:"", validate:function(v) { return (this.server == "server")||v.length > 0;} },
74
+ port: {value:"", required:true, validate:RED.validators.number()},
67
75
  datamode:{value:"stream"},
68
76
  datatype:{value:"buffer"},
69
77
  newline:{value:""},
70
78
  topic: {value:""},
71
- base64: {/*deprecated*/ value:false,required:true}
79
+ base64: {/*deprecated*/ value:false, required:true},
80
+ tls: {type:"tls-config", value:'', required:false}
72
81
  },
73
82
  inputs:0,
74
83
  outputs:1,
@@ -77,7 +86,7 @@
77
86
  return this.name || "tcp:"+(this.host?this.host+":":"")+this.port;
78
87
  },
79
88
  labelStyle: function() {
80
- return this.name?"node_label_italic":"";
89
+ return this.name ? "node_label_italic" : "";
81
90
  },
82
91
  oneditprepare: function() {
83
92
  var updateOptions = function() {
@@ -103,6 +112,27 @@
103
112
  $("#node-input-server").change(updateOptions);
104
113
  $("#node-input-datatype").change(updateOptions);
105
114
  $("#node-input-datamode").change(updateOptions);
115
+ function updateTLSOptions() {
116
+ if ($("#node-input-usetls").is(':checked')) {
117
+ $("#node-row-tls").show();
118
+ } else {
119
+ $("#node-row-tls").hide();
120
+ }
121
+ }
122
+ if (this.tls) {
123
+ $('#node-input-usetls').prop('checked', true);
124
+ } else {
125
+ $('#node-input-usetls').prop('checked', false);
126
+ }
127
+ updateTLSOptions();
128
+ $("#node-input-usetls").on("click",function() {
129
+ updateTLSOptions();
130
+ });
131
+ },
132
+ oneditsave: function() {
133
+ if (!$("#node-input-usetls").is(':checked')) {
134
+ $("#node-input-tls").val("_ADD_");
135
+ }
106
136
  }
107
137
  });
108
138
  </script>
@@ -123,6 +153,15 @@
123
153
  <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" style="width: 60%;">
124
154
  </div>
125
155
 
156
+ <div class="form-row" id="node-input-tls-enable">
157
+ <label> </label>
158
+ <input type="checkbox" id="node-input-usetls" style="display: inline-block; width: auto; vertical-align: top;">
159
+ <label for="node-input-usetls" style="width: auto" data-i18n="httpin.use-tls"></label>
160
+ <div id="node-row-tls" class="hide">
161
+ <label style="width: auto; margin-left: 20px; margin-right: 10px;" for="node-input-tls"><span data-i18n="httpin.tls-config"></span></label><input type="text" style="width: 300px" id="node-input-tls">
162
+ </div>
163
+ </div>
164
+
126
165
  <div class="form-row hidden" id="node-input-end-row">
127
166
  <label>&nbsp;</label>
128
167
  <input type="checkbox" id="node-input-end" style="display: inline-block; width: auto; vertical-align: top;">
@@ -144,14 +183,15 @@
144
183
  <script type="text/javascript">
145
184
  RED.nodes.registerType('tcp out',{
146
185
  category: 'network',
147
- color:"Silver",
186
+ color: "Silver",
148
187
  defaults: {
188
+ name: {value:""},
149
189
  host: {value:"",validate:function(v) { return (this.beserver != "client")||v.length > 0;} },
150
190
  port: {value:"",validate:function(v) { return (this.beserver == "reply")||RED.validators.number()(v); } },
151
- beserver: {value:"client",required:true},
152
- base64: {value:false,required:true},
153
- end: {value:false,required:true},
154
- name: {value:""}
191
+ beserver: {value:"client", required:true},
192
+ base64: {value:false, required:true},
193
+ end: {value:false, required:true},
194
+ tls: {type:"tls-config", value:'', required:false}
155
195
  },
156
196
  inputs:1,
157
197
  outputs:0,
@@ -170,18 +210,42 @@
170
210
  $("#node-input-port-row").hide();
171
211
  $("#node-input-host-row").hide();
172
212
  $("#node-input-end-row").hide();
213
+ $("#node-input-tls-enable").hide();
173
214
  } else if (sockettype == "client"){
174
215
  $("#node-input-port-row").show();
175
216
  $("#node-input-host-row").show();
176
217
  $("#node-input-end-row").show();
218
+ $("#node-input-tls-enable").show();
177
219
  } else {
178
220
  $("#node-input-port-row").show();
179
221
  $("#node-input-host-row").hide();
180
222
  $("#node-input-end-row").show();
223
+ $("#node-input-tls-enable").show();
181
224
  }
182
225
  };
183
226
  updateOptions();
184
227
  $("#node-input-beserver").change(updateOptions);
228
+ function updateTLSOptions() {
229
+ if ($("#node-input-usetls").is(':checked')) {
230
+ $("#node-row-tls").show();
231
+ } else {
232
+ $("#node-row-tls").hide();
233
+ }
234
+ }
235
+ if (this.tls) {
236
+ $('#node-input-usetls').prop('checked', true);
237
+ } else {
238
+ $('#node-input-usetls').prop('checked', false);
239
+ }
240
+ updateTLSOptions();
241
+ $("#node-input-usetls").on("click",function() {
242
+ updateTLSOptions();
243
+ });
244
+ },
245
+ oneditsave: function() {
246
+ if (!$("#node-input-usetls").is(':checked')) {
247
+ $("#node-input-tls").val("_ADD_");
248
+ }
185
249
  }
186
250
  });
187
251
  </script>
@@ -194,15 +258,23 @@
194
258
  <span data-i18n="tcpin.label.port"></span>
195
259
  <input type="text" id="node-input-port" style="width:60px">
196
260
  </div>
261
+ <div class="form-row" id="node-input-tls-enable">
262
+ <label> </label>
263
+ <input type="checkbox" id="node-input-usetls" style="display: inline-block; width: auto; vertical-align: top;">
264
+ <label for="node-input-usetls" style="width: auto" data-i18n="httpin.use-tls"></label>
265
+ <div id="node-row-tls" class="hide">
266
+ <label style="width: auto; margin-left: 20px; margin-right: 10px;" for="node-input-tls"><span data-i18n="httpin.tls-config"></span></label><input type="text" style="width: 300px" id="node-input-tls">
267
+ </div>
268
+ </div>
197
269
  <div class="form-row">
198
- <label for="node-input-out"><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.return"></span></label>
270
+ <label for="node-input-ret"><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.return"></span></label>
199
271
  <select type="text" id="node-input-ret" style="width:54%;">
200
272
  <option value="buffer" data-i18n="tcpin.output.buffer"></option>
201
273
  <option value="string" data-i18n="tcpin.output.string"></option>
202
274
  </select>
203
275
  </div>
204
276
  <div class="form-row">
205
- <label for="node-input-out"> </label>
277
+ <label for="node-input-out"><i class="fa fa-sign-out fa-rotate-90"></i> <span data-i18n="tcpin.label.close"></span></label>
206
278
  <select type="text" id="node-input-out" style="width:54%;">
207
279
  <option value="time" data-i18n="tcpin.return.timeout"></option>
208
280
  <option value="char" data-i18n="tcpin.return.character"></option>
@@ -213,6 +285,9 @@
213
285
  <input type="text" id="node-input-splitc" style="width:50px;">
214
286
  <span id="node-units"></span>
215
287
  </div>
288
+ <div id="node-row-newline" class="form-row hidden" style="padding-left:162px;">
289
+ <span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;" data-i18n="[placeholder]tcpin.label.optional">
290
+ </div>
216
291
  <div class="form-row">
217
292
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
218
293
  <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
@@ -222,14 +297,16 @@
222
297
  <script type="text/javascript">
223
298
  RED.nodes.registerType('tcp request',{
224
299
  category: 'network',
225
- color:"Silver",
300
+ color: "Silver",
226
301
  defaults: {
302
+ name: {value:""},
227
303
  server: {value:""},
228
- port: {value:"",validate:RED.validators.regex(/^(\d*|)$/)},
229
- out: {value:"time",required:true},
304
+ port: {value:"", validate:RED.validators.regex(/^(\d*|)$/)},
305
+ out: {value:"time", required:true},
230
306
  ret: {value:"buffer"},
231
- splitc: {value:"0",required:true},
232
- name: {value:""}
307
+ splitc: {value:"0", required:true},
308
+ newline: {value:""},
309
+ tls: {type:"tls-config", value:'', required:false}
233
310
  },
234
311
  inputs:1,
235
312
  outputs:1,
@@ -246,6 +323,14 @@
246
323
  $("#node-input-ret").val("buffer");
247
324
  this.ret = "buffer";
248
325
  }
326
+ $("#node-input-ret").on("change", function() {
327
+ if ($("#node-input-ret").val() === "string" && $("#node-input-out").val() === "sit") { $("#node-row-newline").show(); }
328
+ else { $("#node-row-newline").hide(); }
329
+ });
330
+ $("#node-input-out").on("change", function() {
331
+ if ($("#node-input-ret").val() === "string" && $("#node-input-out").val() === "sit") { $("#node-row-newline").show(); }
332
+ else { $("#node-row-newline").hide(); }
333
+ });
249
334
  $("#node-input-out").on('focus', function () { previous = this.value; }).on("change", function() {
250
335
  $("#node-input-splitc").show();
251
336
  if (previous === null) { previous = $("#node-input-out").val(); }
@@ -272,6 +357,27 @@
272
357
  $("#node-input-splitc").hide();
273
358
  }
274
359
  });
360
+ function updateTLSOptions() {
361
+ if ($("#node-input-usetls").is(':checked')) {
362
+ $("#node-row-tls").show();
363
+ } else {
364
+ $("#node-row-tls").hide();
365
+ }
366
+ }
367
+ if (this.tls) {
368
+ $('#node-input-usetls').prop('checked', true);
369
+ } else {
370
+ $('#node-input-usetls').prop('checked', false);
371
+ }
372
+ updateTLSOptions();
373
+ $("#node-input-usetls").on("click",function() {
374
+ updateTLSOptions();
375
+ });
376
+ },
377
+ oneditsave: function() {
378
+ if (!$("#node-input-usetls").is(':checked')) {
379
+ $("#node-input-tls").val("_ADD_");
380
+ }
275
381
  }
276
382
  });
277
383
  </script>
@@ -16,13 +16,46 @@
16
16
 
17
17
  module.exports = function(RED) {
18
18
  "use strict";
19
- var reconnectTime = RED.settings.socketReconnectTime||10000;
20
- var socketTimeout = RED.settings.socketTimeout||null;
19
+ let reconnectTime = RED.settings.socketReconnectTime || 10000;
20
+ let socketTimeout = RED.settings.socketTimeout || null;
21
21
  const msgQueueSize = RED.settings.tcpMsgQueueSize || 1000;
22
22
  const Denque = require('denque');
23
- var net = require('net');
23
+ const net = require('net');
24
+ const tls = require('tls');
25
+
26
+ let connectionPool = {};
27
+
28
+ function normalizeConnectArgs(listArgs) {
29
+ const args = net._normalizeArgs(listArgs);
30
+ const options = args[0];
31
+ const cb = args[1];
32
+
33
+ // If args[0] was options, then normalize dealt with it.
34
+ // If args[0] is port, or args[0], args[1] is host, port, we need to
35
+ // find the options and merge them in, normalize's options has only
36
+ // the host/port/path args that it knows about, not the tls options.
37
+ // This means that options.host overrides a host arg.
38
+ if (listArgs[1] !== null && typeof listArgs[1] === 'object') {
39
+ ObjectAssign(options, listArgs[1]);
40
+ } else if (listArgs[2] !== null && typeof listArgs[2] === 'object') {
41
+ ObjectAssign(options, listArgs[2]);
42
+ }
43
+
44
+ return cb ? [options, cb] : [options];
45
+ }
24
46
 
25
- var connectionPool = {};
47
+ function getAllowUnauthorized() {
48
+ const allowUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0';
49
+
50
+ if (allowUnauthorized) {
51
+ process.emitWarning(
52
+ 'Setting the NODE_TLS_REJECT_UNAUTHORIZED ' +
53
+ 'environment variable to \'0\' makes TLS connections ' +
54
+ 'and HTTPS requests insecure by disabling ' +
55
+ 'certificate verification.');
56
+ }
57
+ return allowUnauthorized;
58
+ }
26
59
 
27
60
  /**
28
61
  * Enqueue `item` in `queue`
@@ -53,13 +86,14 @@ module.exports = function(RED) {
53
86
  this.topic = n.topic;
54
87
  this.stream = (!n.datamode||n.datamode=='stream'); /* stream,single*/
55
88
  this.datatype = n.datatype||'buffer'; /* buffer,utf8,base64 */
56
- this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r");
89
+ this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r").replace("\\t","\t");
57
90
  this.base64 = n.base64;
58
91
  this.server = (typeof n.server == 'boolean')?n.server:(n.server == "server");
59
92
  this.closing = false;
60
93
  this.connected = false;
61
94
  var node = this;
62
95
  var count = 0;
96
+ if (n.tls) { var tlsNode = RED.nodes.getNode(n.tls); }
63
97
 
64
98
  if (!node.server) {
65
99
  var buffer = null;
@@ -70,13 +104,25 @@ module.exports = function(RED) {
70
104
  node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port}));
71
105
  node.status({fill:"grey",shape:"dot",text:"common.status.connecting"});
72
106
  var id = RED.util.generateId();
73
- client = net.connect(node.port, node.host, function() {
74
- buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
75
- node.connected = true;
76
- node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
77
- node.status({fill:"green",shape:"dot",text:"common.status.connected",_session:{type:"tcp",id:id}});
78
- });
79
- client.setKeepAlive(true,120000);
107
+ var connOpts = {host: node.host};
108
+ if (n.tls) {
109
+ var connOpts = tlsNode.addTLSOptions({host: node.host});
110
+ client = tls.connect(node.port, connOpts, function() {
111
+ buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
112
+ node.connected = true;
113
+ node.log(RED._("status.connected", {host: node.host, port: node.port}));
114
+ node.status({fill:"green",shape:"dot",text:"common.status.connected",_session:{type:"tcp",id:id}});
115
+ });
116
+ }
117
+ else {
118
+ client = net.connect(node.port, node.host, function() {
119
+ buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
120
+ node.connected = true;
121
+ node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
122
+ node.status({fill:"green",shape:"dot",text:"common.status.connected",_session:{type:"tcp",id:id}});
123
+ });
124
+ }
125
+ client.setKeepAlive(true, 120000);
80
126
  connectionPool[id] = client;
81
127
 
82
128
  client.on('data', function (data) {
@@ -89,7 +135,7 @@ module.exports = function(RED) {
89
135
  buffer = buffer+data;
90
136
  var parts = buffer.split(node.newline);
91
137
  for (var i = 0; i<parts.length-1; i+=1) {
92
- msg = {topic:node.topic, payload:parts[i]};
138
+ msg = {topic:node.topic, payload:parts[i] + node.newline.trimEnd()};
93
139
  msg._session = {type:"tcp",id:id};
94
140
  node.send(msg);
95
141
  }
@@ -150,7 +196,13 @@ module.exports = function(RED) {
150
196
  });
151
197
  }
152
198
  else {
153
- var server = net.createServer(function (socket) {
199
+ let srv = net;
200
+ let connOpts;
201
+ if (n.tls) {
202
+ srv = tls;
203
+ connOpts = tlsNode.addTLSOptions({});
204
+ }
205
+ var server = srv.createServer(connOpts, function (socket) {
154
206
  socket.setKeepAlive(true,120000);
155
207
  if (socketTimeout !== null) { socket.setTimeout(socketTimeout); }
156
208
  var id = RED.util.generateId();
@@ -177,7 +229,7 @@ module.exports = function(RED) {
177
229
  buffer = buffer+data;
178
230
  var parts = buffer.split(node.newline);
179
231
  for (var i = 0; i<parts.length-1; i+=1) {
180
- msg = {topic:node.topic, payload:parts[i], ip:socket.remoteAddress, port:socket.remotePort};
232
+ msg = {topic:node.topic, payload:parts[i] + node.newline.trimEnd(), ip:socket.remoteAddress, port:socket.remotePort};
181
233
  msg._session = {type:"tcp",id:id};
182
234
  node.send(msg);
183
235
  }
@@ -269,8 +321,9 @@ module.exports = function(RED) {
269
321
  this.closing = false;
270
322
  this.connected = false;
271
323
  var node = this;
324
+ if (n.tls) { var tlsNode = RED.nodes.getNode(n.tls); }
272
325
 
273
- if (!node.beserver||node.beserver=="client") {
326
+ if (!node.beserver || node.beserver == "client") {
274
327
  var reconnectTimeout;
275
328
  var client = null;
276
329
  var end = false;
@@ -278,11 +331,24 @@ module.exports = function(RED) {
278
331
  var setupTcpClient = function() {
279
332
  node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port}));
280
333
  node.status({fill:"grey",shape:"dot",text:"common.status.connecting"});
281
- client = net.connect(node.port, node.host, function() {
282
- node.connected = true;
283
- node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
284
- node.status({fill:"green",shape:"dot",text:"common.status.connected"});
285
- });
334
+ if (n.tls) {
335
+ // connOpts = tlsNode.addTLSOptions(connOpts);
336
+ // client = tls.connect(connOpts, function() {
337
+ var connOpts = tlsNode.addTLSOptions({host: node.host});
338
+ client = tls.connect(node.port, connOpts, function() {
339
+ // buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
340
+ node.connected = true;
341
+ node.log(RED._("status.connected", {host: node.host, port: node.port}));
342
+ node.status({fill:"green",shape:"dot",text:"common.status.connected"});
343
+ });
344
+ }
345
+ else {
346
+ client = net.connect(node.port, node.host, function() {
347
+ node.connected = true;
348
+ node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
349
+ node.status({fill:"green",shape:"dot",text:"common.status.connected"});
350
+ });
351
+ }
286
352
  client.setKeepAlive(true,120000);
287
353
  client.on('error', function (err) {
288
354
  node.log(RED._("tcpin.errors.error",{error:err.toString()}));
@@ -368,7 +434,13 @@ module.exports = function(RED) {
368
434
  else {
369
435
  var connectedSockets = [];
370
436
  node.status({text:RED._("tcpin.status.connections",{count:0})});
371
- var server = net.createServer(function (socket) {
437
+ let srv = net;
438
+ let connOpts;
439
+ if (n.tls) {
440
+ srv = tls;
441
+ connOpts = tlsNode.addTLSOptions({});
442
+ }
443
+ var server = srv.createServer(connOpts, function (socket) {
372
444
  socket.setKeepAlive(true,120000);
373
445
  if (socketTimeout !== null) { socket.setTimeout(socketTimeout); }
374
446
  node.log(RED._("tcpin.status.connection-from",{host:socket.remoteAddress, port:socket.remotePort}));
@@ -445,7 +517,11 @@ module.exports = function(RED) {
445
517
  this.port = Number(n.port);
446
518
  this.out = n.out;
447
519
  this.ret = n.ret || "buffer";
520
+ this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r").replace("\\t","\t");
448
521
  this.splitc = n.splitc;
522
+ if (n.tls) {
523
+ var tlsNode = RED.nodes.getNode(n.tls);
524
+ }
449
525
 
450
526
  if (this.out === "immed") { this.splitc = -1; this.out = "time"; }
451
527
  if (this.out !== "char") { this.splitc = Number(this.splitc); }
@@ -500,12 +576,48 @@ module.exports = function(RED) {
500
576
  }
501
577
  else { buf = Buffer.alloc(65536); } // set it to 64k... hopefully big enough for most TCP packets.... but only hopefully
502
578
 
503
- clients[connection_id].client = net.Socket();
579
+ var connOpts = {host:host, port:port};
580
+ if (n.tls) {
581
+ connOpts = tlsNode.addTLSOptions(connOpts);
582
+ const allowUnauthorized = getAllowUnauthorized();
583
+
584
+ let options = {
585
+ rejectUnauthorized: !allowUnauthorized,
586
+ ciphers: tls.DEFAULT_CIPHERS,
587
+ checkServerIdentity: tls.checkServerIdentity,
588
+ minDHSize: 1024,
589
+ ...connOpts
590
+ };
591
+
592
+ if (!options.keepAlive) { options.singleUse = true; }
593
+
594
+ const context = options.secureContext || tls.createSecureContext(options);
595
+
596
+ clients[connection_id].client = new tls.TLSSocket(options.socket, {
597
+ allowHalfOpen: options.allowHalfOpen,
598
+ pipe: !!options.path,
599
+ secureContext: context,
600
+ isServer: false,
601
+ requestCert: false, // true,
602
+ rejectUnauthorized: false, // options.rejectUnauthorized !== false,
603
+ session: options.session,
604
+ ALPNProtocols: options.ALPNProtocols,
605
+ requestOCSP: options.requestOCSP,
606
+ enableTrace: options.enableTrace,
607
+ pskCallback: options.pskCallback,
608
+ highWaterMark: options.highWaterMark,
609
+ onread: options.onread,
610
+ signal: options.signal,
611
+ });
612
+ }
613
+ else {
614
+ clients[connection_id].client = net.Socket();
615
+ }
504
616
  if (socketTimeout !== null) { clients[connection_id].client.setTimeout(socketTimeout);}
505
617
 
506
618
  if (host && port) {
507
619
  clients[connection_id].connecting = true;
508
- clients[connection_id].client.connect(port, host, function() {
620
+ clients[connection_id].client.connect(connOpts, function() {
509
621
  //node.log(RED._("tcpin.errors.client-connected"));
510
622
  node.status({fill:"green",shape:"dot",text:"common.status.connected"});
511
623
  if (clients[connection_id] && clients[connection_id].client) {
@@ -528,17 +640,32 @@ module.exports = function(RED) {
528
640
  else {
529
641
  node.warn(RED._("tcpin.errors.no-host"));
530
642
  }
531
-
643
+ var chunk = "";
532
644
  clients[connection_id].client.on('data', function(data) {
533
645
  if (node.out === "sit") { // if we are staying connected just send the buffer
534
646
  if (clients[connection_id]) {
535
647
  const msg = clients[connection_id].lastMsg || {};
536
648
  msg.payload = RED.util.cloneMessage(data);
537
649
  if (node.ret === "string") {
538
- try { msg.payload = msg.payload.toString(); }
539
- catch(e) { node.error("Failed to create string", msg); }
650
+ try {
651
+ if (node.newline && node.newline !== "" ) {
652
+ chunk += msg.payload.toString();
653
+ let parts = chunk.split(node.newline);
654
+ for (var p=0; p<parts.length-1; p+=1) {
655
+ let m = RED.util.cloneMessage(msg);
656
+ m.payload = parts[p] + node.newline.trimEnd();
657
+ nodeSend(m);
658
+ }
659
+ chunk = parts[parts.length-1];
660
+ }
661
+ else {
662
+ msg.payload = msg.payload.toString();
663
+ nodeSend(msg);
664
+ }
665
+ }
666
+ catch(e) { node.error(RED._("tcpin.errors.bad-string"), msg); }
540
667
  }
541
- nodeSend(msg);
668
+ else { nodeSend(msg); }
542
669
  }
543
670
  }
544
671
  // else if (node.splitc === 0) {
@@ -675,7 +802,13 @@ module.exports = function(RED) {
675
802
  //node.warn(RED._("tcpin.errors.connect-timeout"));
676
803
  if (clients[connection_id].client) {
677
804
  clients[connection_id].connecting = true;
678
- clients[connection_id].client.connect(port, host, function() {
805
+
806
+ var connOpts = {host:host, port:port};
807
+ if (n.tls) {
808
+ connOpts = tlsNode.addTLSOptions(connOpts);
809
+ }
810
+
811
+ clients[connection_id].client.connect(connOpts, function() {
679
812
  clients[connection_id].connected = true;
680
813
  clients[connection_id].connecting = false;
681
814
  node.status({fill:"green",shape:"dot",text:"common.status.connected"});
@@ -49,7 +49,11 @@ module.exports = function(RED) {
49
49
  }
50
50
  var value = RED.util.getMessageProperty(msg,node.property);
51
51
  if (value !== undefined) {
52
- if (typeof value === "string") {
52
+ if (typeof value === "string" || Buffer.isBuffer(value)) {
53
+ // if (Buffer.isBuffer(value) && node.action !== "obj") {
54
+ // node.warn(RED._("json.errors.dropped")); done();
55
+ // }
56
+ // else
53
57
  if (node.action === "" || node.action === "obj") {
54
58
  try {
55
59
  RED.util.setMessageProperty(msg,node.property,JSON.parse(value));
@@ -71,9 +71,7 @@ module.exports = function(RED) {
71
71
  node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg);
72
72
  }
73
73
  else {
74
- if (RED.settings.verbose) {
75
- node.log(RED._("file.status.deletedfile",{file:filename}));
76
- }
74
+ node.debug(RED._("file.status.deletedfile",{file:filename}));
77
75
  nodeSend(msg);
78
76
  }
79
77
  done();
@@ -499,7 +499,8 @@
499
499
  "label": {
500
500
  "type": "Typ",
501
501
  "path": "Pfad",
502
- "url": "URL"
502
+ "url": "URL",
503
+ "subprotocol": "Subprotokoll"
503
504
  },
504
505
  "listenon": "Lauschen (listen on)",
505
506
  "connectto": "Verbinden mit",
@@ -442,7 +442,8 @@
442
442
  "state": {
443
443
  "connected": "Connected to broker: __broker__",
444
444
  "disconnected": "Disconnected from broker: __broker__",
445
- "connect-failed": "Connection failed to broker: __broker__"
445
+ "connect-failed": "Connection failed to broker: __broker__",
446
+ "broker-disconnected": "Broker __broker__ disconnected client: __reasonCode__ __reasonString__"
446
447
  },
447
448
  "retain": "Retain",
448
449
  "output": {
@@ -530,7 +531,8 @@
530
531
  "label": {
531
532
  "type": "Type",
532
533
  "path": "Path",
533
- "url": "URL"
534
+ "url": "URL",
535
+ "subprotocol": "Subprotocol"
534
536
  },
535
537
  "listenon": "Listen on",
536
538
  "connectto": "Connect to",
@@ -579,7 +581,9 @@
579
581
  "server": "Server",
580
582
  "return": "Return",
581
583
  "ms": "ms",
582
- "chars": "chars"
584
+ "chars": "chars",
585
+ "close": "Close",
586
+ "optional": "(optional)"
583
587
  },
584
588
  "type": {
585
589
  "listen": "Listen on",
@@ -596,7 +600,7 @@
596
600
  "return": {
597
601
  "timeout": "after a fixed timeout of",
598
602
  "character": "when character received is",
599
- "number": "a fixed number of chars",
603
+ "number": "after a fixed number of characters",
600
604
  "never": "never - keep connection open",
601
605
  "immed": "immediately - don't wait for reply"
602
606
  },
@@ -616,11 +620,11 @@
616
620
  "timeout": "timeout closed socket port __port__",
617
621
  "cannot-listen": "unable to listen on port __port__, error: __error__",
618
622
  "error": "error: __error__",
619
-
620
623
  "socket-error": "socket error from __host__:__port__",
621
624
  "no-host": "Host and/or port not set",
622
625
  "connect-timeout": "connect timeout",
623
- "connect-fail": "connect failed"
626
+ "connect-fail": "connect failed",
627
+ "bad-string": "failed to convert to string"
624
628
  }
625
629
  },
626
630
  "udp": {
@@ -291,8 +291,8 @@
291
291
  "hour": "時間",
292
292
  "days": "日",
293
293
  "day": "日",
294
- "between": "頻度",
295
- "and": "回/",
294
+ "between": "範囲",
295
+ "and": "",
296
296
  "rate": "流量",
297
297
  "msgper": "メッセージ/",
298
298
  "queuemsg": "中間メッセージをキューに追加",
@@ -442,7 +442,8 @@
442
442
  "state": {
443
443
  "connected": "ブローカへ接続しました: __broker__",
444
444
  "disconnected": "ブローカから切断されました: __broker__",
445
- "connect-failed": "ブローカへの接続に失敗しました: __broker__"
445
+ "connect-failed": "ブローカへの接続に失敗しました: __broker__",
446
+ "broker-disconnected": "ブローカ __broker__ がクライアントを切断しました: __reasonCode__ __reasonString__"
446
447
  },
447
448
  "retain": "保持",
448
449
  "output": {
@@ -530,7 +531,8 @@
530
531
  "label": {
531
532
  "type": "種類",
532
533
  "path": "パス",
533
- "url": "URL"
534
+ "url": "URL",
535
+ "subprotocol": "サブプロトコル"
534
536
  },
535
537
  "listenon": "待ち受け",
536
538
  "connectto": "接続",
@@ -579,7 +581,9 @@
579
581
  "server": "サーバ",
580
582
  "return": "戻り値",
581
583
  "ms": "ミリ秒",
582
- "chars": "文字"
584
+ "chars": "文字",
585
+ "close": "終了",
586
+ "optional": "(任意)"
583
587
  },
584
588
  "type": {
585
589
  "listen": "待ち受け",
@@ -618,7 +622,8 @@
618
622
  "socket-error": "__host__:__port__ にてソケットのエラーが生じました",
619
623
  "no-host": "ホスト名またはポートが設定されていません",
620
624
  "connect-timeout": "接続がタイムアウトしました",
621
- "connect-fail": "接続に失敗しました"
625
+ "connect-fail": "接続に失敗しました",
626
+ "bad-string": "文字列への変換に失敗しました"
622
627
  }
623
628
  },
624
629
  "udp": {
@@ -433,7 +433,8 @@
433
433
  "label": {
434
434
  "type": "종류",
435
435
  "path": "패스",
436
- "url": "URL"
436
+ "url": "URL",
437
+ "subprotocol": "서브 프로토콜"
437
438
  },
438
439
  "listenon": "대기",
439
440
  "connectto": "접속",
@@ -461,7 +461,8 @@
461
461
  "label": {
462
462
  "type": "Тип",
463
463
  "path": "Путь",
464
- "url": "URL"
464
+ "url": "URL",
465
+ "subprotocol": "Подпротокол"
465
466
  },
466
467
  "listenon": "Слушать на ...",
467
468
  "connectto": "Присоединиться к ...",
@@ -454,7 +454,8 @@
454
454
  "label": {
455
455
  "type": "类型",
456
456
  "path": "路径",
457
- "url": "URL"
457
+ "url": "URL",
458
+ "subprotocol": "子协议"
458
459
  },
459
460
  "listenon": "监听",
460
461
  "connectto": "连接",
@@ -458,7 +458,8 @@
458
458
  "label": {
459
459
  "type": "類型",
460
460
  "path": "路徑",
461
- "url": "URL"
461
+ "url": "URL",
462
+ "subprotocol": "子协议"
462
463
  },
463
464
  "listenon": "監聽",
464
465
  "connectto": "連接",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/nodes",
3
- "version": "2.1.5",
3
+ "version": "2.2.1",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,12 +17,12 @@
17
17
  "dependencies": {
18
18
  "acorn": "8.7.0",
19
19
  "acorn-walk": "8.2.0",
20
- "ajv": "8.8.2",
20
+ "ajv": "8.10.0",
21
21
  "body-parser": "1.19.1",
22
22
  "cheerio": "1.0.0-rc.10",
23
23
  "content-type": "1.0.4",
24
24
  "cookie-parser": "1.4.6",
25
- "cookie": "0.4.1",
25
+ "cookie": "0.4.2",
26
26
  "cors": "2.8.5",
27
27
  "cronosjs": "1.7.1",
28
28
  "denque": "2.0.1",
@@ -36,14 +36,14 @@
36
36
  "is-utf8": "0.2.1",
37
37
  "js-yaml": "3.14.1",
38
38
  "media-typer": "1.1.0",
39
- "mqtt": "4.3.4",
40
- "multer": "1.4.3",
39
+ "mqtt": "4.3.5",
40
+ "multer": "1.4.4",
41
41
  "mustache": "4.2.0",
42
42
  "on-headers": "1.0.2",
43
- "raw-body": "2.4.2",
43
+ "raw-body": "2.4.3",
44
44
  "tough-cookie": "4.0.0",
45
45
  "uuid": "8.3.2",
46
- "ws": "7.5.1",
46
+ "ws": "7.5.6",
47
47
  "xml2js": "0.4.23",
48
48
  "iconv-lite": "0.6.3"
49
49
  }