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": {
name: "Private Key",
description: "Like the one inside ~/.ssh/id_rsa, can't be encrypted",
type: "textarea",
description:
"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: "",
example:
"-----BEGIN RSA PRIVATE KEY-----\r\n" +
"..... yBQZobkBQ50QqhDivQz4i1Pb33Z0Znjnzjoid4 ....\r\n" +
"-----END RSA PRIVATE KEY-----",
example: "",
verify(d) {
if (d.length <= 0) {
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: {
@@ -691,15 +714,15 @@ class Wizard {
async stepCredentialPrompt(rd, sd, config) {
let self = this,
fieldName = "";
fields = [];
switch (config.auth) {
case AUTHMETHOD_PASSPHRASE:
fieldName = "Passphrase";
fields = [{ name: "Passphrase" }];
break;
case AUTHMETHOD_PRIVATE_KEY:
fieldName = "Private Key";
fields = [{ name: "Private Key" }];
break;
default:
@@ -713,7 +736,7 @@ class Wizard {
"Please input your credential",
"Login",
r => {
let vv = r[fieldName.toLowerCase()];
let vv = r[fields[0].name.toLowerCase()];
sd.send(
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="file"],
.form1 > fieldset .field > input[type="email"],
.form1 > fieldset .field > input[type="number"],
.form1 > fieldset .field > input[type="search"],
@@ -455,6 +456,7 @@ body {
}
.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="number"],
.form1 > fieldset .field.error > input[type="search"],

View File

@@ -114,6 +114,29 @@
@change="verify(key, field, true)"
></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 class="info">{{ field.field.value }}</div>
</div>
@@ -387,6 +410,36 @@ export default {
event.target.style.height = "";
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) {
try {
field.message = "" + field.field.verify(field.field.value);