feat: SSH key file browser — Browse button to load keys from disk
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m54s
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 2m54s
Adds a file picker next to the Private Key textarea in the credential dialog. Users can browse for key files (.pem, .key, id_rsa, id_ed25519, etc.) instead of copy-pasting PEM content. Uses standard FileReader API — no additional Tauri plugins needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4a0c2c9790
commit
f825692ecc
@ -270,10 +270,27 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">Private Key (PEM)</label>
|
<label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">Private Key (PEM)</label>
|
||||||
|
<div class="flex gap-2 mb-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="px-3 py-1.5 text-xs rounded bg-[#21262d] border border-[#30363d] text-[var(--wraith-text-secondary)] hover:text-[var(--wraith-text-primary)] hover:border-[var(--wraith-accent-blue)] transition-colors cursor-pointer"
|
||||||
|
@click="browseKeyFile"
|
||||||
|
>
|
||||||
|
Browse...
|
||||||
|
</button>
|
||||||
|
<span v-if="keyFileName" class="text-xs text-[var(--wraith-text-muted)] self-center truncate">{{ keyFileName }}</span>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
ref="keyFileInputRef"
|
||||||
|
type="file"
|
||||||
|
class="hidden"
|
||||||
|
accept=".pem,.key,.pub,.id_rsa,.id_ed25519,.id_ecdsa,.ppk"
|
||||||
|
@change="loadKeyFile"
|
||||||
|
/>
|
||||||
<textarea
|
<textarea
|
||||||
v-model="newCred.privateKeyPEM"
|
v-model="newCred.privateKeyPEM"
|
||||||
rows="5"
|
rows="5"
|
||||||
placeholder="-----BEGIN OPENSSH PRIVATE KEY----- ... -----END OPENSSH PRIVATE KEY-----"
|
placeholder="Paste key or use Browse to load from file"
|
||||||
class="w-full px-3 py-2 text-sm rounded bg-[#161b22] border border-[#30363d] text-[var(--wraith-text-primary)] placeholder-[var(--wraith-text-muted)] outline-none focus:border-[var(--wraith-accent-blue)] transition-colors resize-none font-mono"
|
class="w-full px-3 py-2 text-sm rounded bg-[#161b22] border border-[#30363d] text-[var(--wraith-text-primary)] placeholder-[var(--wraith-text-muted)] outline-none focus:border-[var(--wraith-accent-blue)] transition-colors resize-none font-mono"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
/>
|
/>
|
||||||
@ -385,6 +402,25 @@ const newCred = ref<NewCredForm>({
|
|||||||
passphrase: "",
|
passphrase: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// SSH key file picker
|
||||||
|
const keyFileInputRef = ref<HTMLInputElement | null>(null);
|
||||||
|
const keyFileName = ref("");
|
||||||
|
|
||||||
|
function browseKeyFile(): void {
|
||||||
|
keyFileInputRef.value?.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadKeyFile(event: Event): void {
|
||||||
|
const file = (event.target as HTMLInputElement).files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
keyFileName.value = file.name;
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
newCred.value.privateKeyPEM = (reader.result as string).trim();
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
}
|
||||||
|
|
||||||
const form = ref<ConnectionForm>({
|
const form = ref<ConnectionForm>({
|
||||||
name: "",
|
name: "",
|
||||||
hostname: "",
|
hostname: "",
|
||||||
@ -431,6 +467,7 @@ function setProtocol(protocol: "ssh" | "rdp"): void {
|
|||||||
function resetNewCredForm(): void {
|
function resetNewCredForm(): void {
|
||||||
newCred.value = { name: "", username: "", password: "", privateKeyPEM: "", passphrase: "" };
|
newCred.value = { name: "", username: "", password: "", privateKeyPEM: "", passphrase: "" };
|
||||||
newCredError.value = "";
|
newCredError.value = "";
|
||||||
|
keyFileName.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteSelectedCredential(): Promise<void> {
|
async function deleteSelectedCredential(): Promise<void> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user