mirror of https://github.com/node-red/node-red.git
UI to upload certificates and keys for TLS, and send them to node red in configuration properties to store them in credentials file
by default upload buttons will be shown unless a cert or key path is already set added new settings flag called 'tlsDisableLocalFiles' to disable UI for local paths for cloud hosted NRpull/1171/head
parent
bfcd795687
commit
2bde07561f
|
@ -15,17 +15,42 @@
|
|||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="tls-config">
|
||||
<div class="form-row" class="hide" id="node-config-row-uselocalfiles">
|
||||
<input type="checkbox" id="node-config-input-uselocalfiles" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-config-input-uselocalfiles" style="width: 70%;"><span data-i18n="tls.label.use-local-files"></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width: 120px;" for="node-config-input-cert"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.cert"></span></label>
|
||||
<input style="width: 60%;" type="text" id="node-config-input-cert" data-i18n="[placeholder]tls.placeholder.cert">
|
||||
<label style="width: 120px;"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.cert"></span></label>
|
||||
<span class="tls-config-input-data">
|
||||
<label class="btn ui-button" style="width: 85px; padding: 3px 0px;" for="node-config-input-certfile"><i class="fa fa-upload"></i> <span data-i18n="tls.label.upload"></span></label>
|
||||
<input class="hide" type="file" id="node-config-input-certfile">
|
||||
<span id="tls-config-certname" style="width: 180px; overflow: hidden; line-height:34px; height:34px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;"> </span>
|
||||
</span>
|
||||
<input type="hidden" id="node-config-input-certname">
|
||||
<input type="hidden" id="node-config-input-certdata">
|
||||
<input class="hide tls-config-input-path" style="width: 60%;" type="text" id="node-config-input-cert" data-i18n="[placeholder]tls.placeholder.cert">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width: 120px;" for="node-config-input-key"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.key"></span></label>
|
||||
<input style="width: 60%;" type="text" id="node-config-input-key" data-i18n="[placeholder]tls.placeholder.key">
|
||||
<span class="tls-config-input-data">
|
||||
<label class="btn" style="width: 85px; padding: 3px 0px;" for="node-config-input-keyfile"><i class="fa fa-upload"></i> <span data-i18n="tls.label.upload"></span></label>
|
||||
<input class="hide" type="file" id="node-config-input-keyfile">
|
||||
<span id="tls-config-keyname" style="width: 180px; overflow: hidden; line-height:34px; height:34px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;"> </span>
|
||||
</span>
|
||||
<input type="hidden" id="node-config-input-keyname">
|
||||
<input type="hidden" id="node-config-input-keydata">
|
||||
<input class="hide tls-config-input-path" style="width: 60%;" type="text" id="node-config-input-key" data-i18n="[placeholder]tls.placeholder.key">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label style="width: 120px;" for="node-config-input-ca"><i class="fa fa-file-text-o"></i> <span data-i18n="tls.label.ca"></span></label>
|
||||
<input style="width: 60%;" type="text" id="node-config-input-ca" data-i18n="[placeholder]tls.placeholder.ca">
|
||||
<span class="tls-config-input-data">
|
||||
<label class="btn" style="width: 85px; padding: 3px 0px;" for="node-config-input-cafile"><i class="fa fa-upload"></i> <span data-i18n="tls.label.upload"></span></label>
|
||||
<input class="hide" type="file" title=" " id="node-config-input-cafile">
|
||||
<span id="tls-config-caname" style="width: 180px; overflow: hidden; line-height:34px; height:34px; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle;"> </span>
|
||||
</span>
|
||||
<input type="hidden" id="node-config-input-caname">
|
||||
<input type="hidden" id="node-config-input-cadata">
|
||||
<input class="hide tls-config-input-path" style="width: 60%;" type="text" id="node-config-input-ca" data-i18n="[placeholder]tls.placeholder.ca">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="checkbox" id="node-config-input-verifyservercert" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
|
@ -61,13 +86,85 @@
|
|||
return currentCert === '' || v != '';
|
||||
}},
|
||||
ca: {value:""},
|
||||
certname: {value:""},
|
||||
keyname: {value:""},
|
||||
caname: {value:""},
|
||||
uselocalfiles: {value:true},
|
||||
verifyservercert: {value: true}
|
||||
},
|
||||
credentials: {
|
||||
certdata: {type:"text"},
|
||||
keydata: {type:"text"},
|
||||
cadata: {type:"text"}
|
||||
},
|
||||
label: function() {
|
||||
return this.name || this._("tls.tls");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
function updateFileUpload() {
|
||||
if ($("#node-config-input-uselocalfiles").is(':checked')) {
|
||||
$(".tls-config-input-path").show();
|
||||
$(".tls-config-input-data").hide();
|
||||
} else {
|
||||
$(".tls-config-input-data").show();
|
||||
$(".tls-config-input-path").hide();
|
||||
}
|
||||
}
|
||||
$("#node-config-input-uselocalfiles").on("click",function() {
|
||||
updateFileUpload();
|
||||
});
|
||||
function saveFile(property, file) {
|
||||
var dataInputId = "#node-config-input-"+property+"data";
|
||||
var filenameInputId = "#node-config-input-"+property+"name";
|
||||
var filename = file.name;
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
$("#tls-config-"+property+"name").text(filename);
|
||||
$(filenameInputId).val(filename);
|
||||
$(dataInputId).val(event.target.result);
|
||||
}
|
||||
reader.readAsText(file,"UTF-8");
|
||||
}
|
||||
$("#node-config-input-certfile" ).change(function() {
|
||||
saveFile("cert", this.files[0]);
|
||||
});
|
||||
$("#node-config-input-keyfile" ).change(function() {
|
||||
saveFile("key", this.files[0]);
|
||||
});
|
||||
$("#node-config-input-cafile" ).change(function() {
|
||||
saveFile("ca", this.files[0]);
|
||||
});
|
||||
if (RED.settings.tlsDisableLocalFiles) {
|
||||
$("#node-config-row-uselocalfiles").hide();
|
||||
} else {
|
||||
$("#node-config-row-uselocalfiles").show();
|
||||
}
|
||||
// in case paths were set from old TLS config
|
||||
if(this.cert || this.key || this.ca) {
|
||||
this.uselocalfiles = true;
|
||||
$("#node-config-input-uselocalfiles").prop('checked',true);
|
||||
}
|
||||
$("#tls-config-certname").text(this.certname);
|
||||
$("#tls-config-keyname").text(this.keyname);
|
||||
$("#tls-config-caname").text(this.caname);
|
||||
updateFileUpload();
|
||||
},
|
||||
oneditsave: function() {
|
||||
if ($("#node-config-input-uselocalfiles").is(':checked')) {
|
||||
$("#node-config-input-cadata").val("");
|
||||
$("#node-config-input-caname").val("");
|
||||
$("#node-config-input-certdata").val("");
|
||||
$("#node-config-input-certname").val("");
|
||||
$("#node-config-input-keydata").val("");
|
||||
$("#node-config-input-keyname").val("");
|
||||
} else {
|
||||
$("#node-config-input-ca").val("");
|
||||
$("#node-config-input-cert").val("");
|
||||
$("#node-config-input-key").val("");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -21,34 +21,65 @@ module.exports = function(RED) {
|
|||
function TLSConfig(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.valid = true;
|
||||
this.verifyservercert = n.verifyservercert;
|
||||
var certPath = n.cert.trim();
|
||||
var keyPath = n.key.trim();
|
||||
var caPath = n.ca.trim();
|
||||
|
||||
if ( (certPath.length > 0) !== (keyPath.length > 0)) {
|
||||
this.valid = false;
|
||||
this.error(RED._("tls.error.missing-file"));
|
||||
return;
|
||||
}
|
||||
this.verifyservercert = n.verifyservercert;
|
||||
if ((certPath.length > 0) || (keyPath.length > 0)) {
|
||||
|
||||
try {
|
||||
if (certPath) {
|
||||
this.cert = fs.readFileSync(certPath);
|
||||
if ( (certPath.length > 0) !== (keyPath.length > 0)) {
|
||||
this.valid = false;
|
||||
this.error(RED._("tls.error.missing-file"));
|
||||
return;
|
||||
}
|
||||
if (keyPath) {
|
||||
this.key = fs.readFileSync(keyPath);
|
||||
|
||||
try {
|
||||
if (certPath) {
|
||||
this.cert = fs.readFileSync(certPath);
|
||||
}
|
||||
if (keyPath) {
|
||||
this.key = fs.readFileSync(keyPath);
|
||||
}
|
||||
if (caPath) {
|
||||
this.ca = fs.readFileSync(caPath);
|
||||
}
|
||||
} catch(err) {
|
||||
this.valid = false;
|
||||
this.error(err.toString());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (this.credentials) {
|
||||
var certData = this.credentials.certdata || "";
|
||||
var keyData = this.credentials.keydata || "";
|
||||
var caData = this.credentials.cadata || "";
|
||||
|
||||
if ((certData.length > 0) !== (keyData.length > 0)) {
|
||||
this.valid = false;
|
||||
this.error(RED._("tls.error.missing-file"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (certData) {
|
||||
this.cert = certData;
|
||||
}
|
||||
if (keyData) {
|
||||
this.key = keyData;
|
||||
}
|
||||
if (caData) {
|
||||
this.ca = caData;
|
||||
}
|
||||
}
|
||||
if (caPath) {
|
||||
this.ca = fs.readFileSync(caPath);
|
||||
}
|
||||
} catch(err) {
|
||||
this.valid = false;
|
||||
this.error(err.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("tls-config",TLSConfig);
|
||||
RED.nodes.registerType("tls-config", TLSConfig, {
|
||||
credentials: {
|
||||
certdata: {type:"text"},
|
||||
keydata: {type:"text"},
|
||||
cadata: {type:"text"}
|
||||
}
|
||||
});
|
||||
|
||||
TLSConfig.prototype.addTLSOptions = function(opts) {
|
||||
if (this.valid) {
|
||||
|
|
|
@ -126,6 +126,8 @@
|
|||
"tls": {
|
||||
"tls": "TLS configuration",
|
||||
"label": {
|
||||
"use-local-files": "Use key and certificates from local files",
|
||||
"upload": "Upload",
|
||||
"cert": "Certificate",
|
||||
"key": "Private Key",
|
||||
"ca": "CA Certificate",
|
||||
|
|
|
@ -43,6 +43,10 @@ module.exports = {
|
|||
safeSettings.flowFilePretty = settings.flowFilePretty;
|
||||
}
|
||||
|
||||
if (settings.tlsDisableLocalFiles) {
|
||||
safeSettings.tlsDisableLocalFiles = settings.tlsDisableLocalFiles;
|
||||
}
|
||||
|
||||
if (!runtime.nodes.paletteEditorEnabled()) {
|
||||
safeSettings.editorTheme = safeSettings.editorTheme || {};
|
||||
safeSettings.editorTheme.palette = safeSettings.editorTheme.palette || {};
|
||||
|
|
|
@ -47,6 +47,10 @@ module.exports = {
|
|||
// The maximum length, in characters, of any message sent to the debug sidebar tab
|
||||
debugMaxLength: 1000,
|
||||
|
||||
// To disable the option for using local files for storing keys and certificates in the TLS configuration
|
||||
// node, set this to true
|
||||
//tlsDisableLocalFiles:true,
|
||||
|
||||
// Colourise the console output of the debug node
|
||||
//debugUseColors: true,
|
||||
|
||||
|
|
Loading…
Reference in New Issue