Save SSH passwords in Windows Credential Manager and auto-type at prompt

This commit is contained in:
megaproxy 2026-05-25 20:08:31 +01:00
parent 872fb0e80e
commit 1c243b3f3f
11 changed files with 538 additions and 38 deletions

View file

@ -15,9 +15,13 @@ export type SpawnSpec =
identityFile?: string;
jumpHost?: string;
extraArgs?: string[];
/** Backend uses this to look up a saved password from keyring at
* spawn time. Never echoed back to the frontend. */
hostId?: string;
};
/** One saved SSH host. Mirrors the Rust `SshHost` struct. */
/** One saved SSH host. Mirrors the Rust `SshHost` struct (plus the
* `hasPassword` flag that the backend sets when listing). */
export interface SshHost {
id: string;
label: string;
@ -27,6 +31,10 @@ export interface SshHost {
identityFile?: string;
jumpHost?: string;
extraArgs?: string[];
/** True iff a credential is stored under this host's id in the system
* keyring. Set by the backend on `list_ssh_hosts`; the field is
* ignored on `save_ssh_hosts` (use the password commands below). */
hasPassword?: boolean;
}
export const listDistros = (): Promise<string[]> => invoke("list_distros");
@ -70,3 +78,15 @@ export const listSshHosts = (): Promise<SshHost[]> => invoke("list_ssh_hosts");
export const saveSshHosts = (hosts: SshHost[]): Promise<void> =>
invoke("save_ssh_hosts", { hosts });
/** Store / replace the saved password for this host id. Plaintext is
* IPC'd to the Rust side (in-process, no disk hop) and immediately
* written to Windows Credential Manager (DPAPI). */
export const setHostPassword = (hostId: string, password: string): Promise<void> =>
invoke("set_host_password", { hostId, password });
export const deleteHostPassword = (hostId: string): Promise<void> =>
invoke("delete_host_password", { hostId });
export const hasHostPassword = (hostId: string): Promise<boolean> =>
invoke("has_host_password", { hostId });