feat(desktop): remote-host mode + OS-store client-cert mTLS (D-1/D-2)
- remote-hosts.ts + DesktopPrefs (remoteHosts/selectedHostId, immutable, back-compat) + tray host-picker. - will-navigate lock is now dynamic to the selected remote origin, fails closed on null (no open-redirect). - select-client-certificate handler: event.preventDefault() first, pick by issuer CN, non-silent missing-cert dialog + cert-less callback -> clean nginx rejection (Chromium sources certs from OS store). Verified: npm run typecheck exit 0; pure-helper assertions pass.
This commit is contained in:
@@ -21,6 +21,22 @@ export type DesktopClaudeStatus = 'working' | 'waiting' | 'idle' | 'unknown' | '
|
||||
/** Approval gate kind, mirrored from backend PermissionGate (src/types.ts:101). */
|
||||
export type DesktopPermissionGate = 'tool' | 'plan'
|
||||
|
||||
/**
|
||||
* A remote web-terminal host reachable over the mTLS reverse tunnel
|
||||
* (Track C-Desktop, PLAN_NATIVE_TUNNEL §"C-Desktop / D-1"). `url` is the https
|
||||
* origin the BrowserWindow loads, e.g. `https://t1.terminal.yaojia.wang/`; the
|
||||
* device client certificate (D-2, sourced from the OS keychain) is the only auth
|
||||
* gate. `id` is a stable opaque handle used by the tray host-picker + prefs.
|
||||
*/
|
||||
export interface RemoteHost {
|
||||
/** Stable opaque id (uuid); the tray/prefs key, never shown to the user. */
|
||||
readonly id: string
|
||||
/** Human label shown in the tray host-picker. */
|
||||
readonly name: string
|
||||
/** The https origin URL to load, normalized to `https://<host>/`. */
|
||||
readonly url: string
|
||||
}
|
||||
|
||||
/**
|
||||
* User preferences, persisted as JSON in the app's userData dir (hand-rolled
|
||||
* store — matches the project's minimal-deps convention; no electron-store).
|
||||
@@ -38,6 +54,10 @@ export interface DesktopPrefs {
|
||||
readonly notifyOnApproval: boolean
|
||||
/** Fire a native notification when a session's Claude status changes. */
|
||||
readonly notifyOnStatusChange: boolean
|
||||
/** Configured remote tunnel hosts (D-1); empty on a fresh install. */
|
||||
readonly remoteHosts: readonly RemoteHost[]
|
||||
/** Selected host id, or null → "This machine (local)" (the embedded server). */
|
||||
readonly selectedHostId: string | null
|
||||
}
|
||||
|
||||
/** Handle returned by the embedded server, for lifecycle + window wiring. */
|
||||
|
||||
Reference in New Issue
Block a user