SSH: Change the input box type for Private Key field from textarea to file.

This commit is contained in:
NI
2019-08-29 21:27:43 +08:00
parent b1e77f70ba
commit 6d349f133e
3 changed files with 90 additions and 12 deletions

View File

@@ -323,13 +323,14 @@ const initialFieldDef = {
}, },
"Private Key": { "Private Key": {
name: "Private Key", name: "Private Key",
description: "Like the one inside ~/.ssh/id_rsa, can't be encrypted", description:
type: "textarea", "Like the one inside ~/.ssh/id_rsa, can&apos;t be encrypted<br /><br />" +
"To decrypt the Private Key, use command: <i>" +
"openssl rsa -in /path/to/encrypted_private_key -out " +
"/path/to/decrypted_private_key</i>",
type: "textfile",
value: "", value: "",
example: example: "",
"-----BEGIN RSA PRIVATE KEY-----\r\n" +
"..... yBQZobkBQ50QqhDivQz4i1Pb33Z0Znjnzjoid4 ....\r\n" +
"-----END RSA PRIVATE KEY-----",
verify(d) { verify(d) {
if (d.length <= 0) { if (d.length <= 0) {
throw new Error("Private Key must be specified"); throw new Error("Private Key must be specified");
@@ -341,7 +342,29 @@ const initialFieldDef = {
); );
} }
return "We'll login with this private key"; let lines = d.split("\n");
for (let i in lines) {
if (lines[i].indexOf("-") === 0) {
continue;
}
if (lines[i].indexOf("Proc-Type: 4,ENCRYPTED") === 0) {
throw new Error("Cannot use encrypted Private Key file");
}
if (lines[i].indexOf(":") > 0) {
continue;
}
if (lines[i].indexOf("MII") < 0) {
throw new Error("Cannot use encrypted Private Key file");
}
break;
}
return "We'll login with this Private Key";
} }
}, },
Authentication: { Authentication: {
@@ -691,15 +714,15 @@ class Wizard {
async stepCredentialPrompt(rd, sd, config) { async stepCredentialPrompt(rd, sd, config) {
let self = this, let self = this,
fieldName = ""; fields = [];
switch (config.auth) { switch (config.auth) {
case AUTHMETHOD_PASSPHRASE: case AUTHMETHOD_PASSPHRASE:
fieldName = "Passphrase"; fields = [{ name: "Passphrase" }];
break; break;
case AUTHMETHOD_PRIVATE_KEY: case AUTHMETHOD_PRIVATE_KEY:
fieldName = "Private Key"; fields = [{ name: "Private Key" }];
break; break;
default: default:
@@ -713,7 +736,7 @@ class Wizard {
"Please input your credential", "Please input your credential",
"Login", "Login",
r => { r => {
let vv = r[fieldName.toLowerCase()]; let vv = r[fields[0].name.toLowerCase()];
sd.send( sd.send(
CLIENT_CONNECT_RESPOND_CREDENTIAL, CLIENT_CONNECT_RESPOND_CREDENTIAL,
@@ -732,7 +755,7 @@ class Wizard {
) )
); );
}, },
command.fields(initialFieldDef, [{ name: fieldName }]) command.fields(initialFieldDef, fields)
); );
} }
} }

View File

@@ -413,6 +413,7 @@ body {
} }
.form1 > fieldset .field > input[type="text"], .form1 > fieldset .field > input[type="text"],
.form1 > fieldset .field > input[type="file"],
.form1 > fieldset .field > input[type="email"], .form1 > fieldset .field > input[type="email"],
.form1 > fieldset .field > input[type="number"], .form1 > fieldset .field > input[type="number"],
.form1 > fieldset .field > input[type="search"], .form1 > fieldset .field > input[type="search"],
@@ -455,6 +456,7 @@ body {
} }
.form1 > fieldset .field.error > input[type="text"], .form1 > fieldset .field.error > input[type="text"],
.form1 > fieldset .field.error > input[type="file"],
.form1 > fieldset .field.error > input[type="email"], .form1 > fieldset .field.error > input[type="email"],
.form1 > fieldset .field.error > input[type="number"], .form1 > fieldset .field.error > input[type="number"],
.form1 > fieldset .field.error > input[type="search"], .form1 > fieldset .field.error > input[type="search"],

View File

@@ -114,6 +114,29 @@
@change="verify(key, field, true)" @change="verify(key, field, true)"
></textarea> ></textarea>
<input
v-if="field.field.type === 'textfile'"
type="file"
autocomplete="off"
:placeholder="field.field.example"
:name="field.field.name + '-file'"
:autofocus="field.autofocus"
@change="importFile($event.target, field)"
/>
<input
v-if="field.field.type === 'textfile'"
v-model="field.field.value"
v-focus="field.autofocus"
type="text"
autocomplete="off"
:name="field.field.name"
:placeholder="field.field.example"
:autofocus="field.autofocus"
style="display: none"
@input="verify(key, field, false)"
@change="verify(key, field, true)"
/>
<div v-if="field.field.type === 'textdata'" class="textinfo"> <div v-if="field.field.type === 'textdata'" class="textinfo">
<div class="info">{{ field.field.value }}</div> <div class="info">{{ field.field.value }}</div>
</div> </div>
@@ -387,6 +410,36 @@ export default {
event.target.style.height = ""; event.target.style.height = "";
event.target.style.height = event.target.scrollHeight + "px"; event.target.style.height = event.target.scrollHeight + "px";
}, },
importFile(el, field) {
if (el.files.length <= 0) {
return;
}
el.disabled = "disabled";
let r = new FileReader();
r.onload = () => {
let s = el.nextSibling;
for (;;) {
if (s.tagName !== "INPUT") {
s = s.nextSibling;
continue;
}
field.field.value = r.result;
s.dispatchEvent(new Event("change"));
break;
}
el.disabled = "";
};
r.readAsText(el.files[0], "utf-8");
},
verify(key, field, force) { verify(key, field, force) {
try { try {
field.message = "" + field.field.verify(field.field.value); field.message = "" + field.field.verify(field.field.value);