feat: host key verification UI components#92
Merged
billchurch merged 17 commits intomainfrom Feb 26, 2026
Merged
Conversation
Implement localStorage-backed SSH host key store that supports TOFU (Trust On First Use) verification in the browser. Provides lookup, store, remove, import/export, and manual key addition with validation of SSH algorithms and base64 key data.
Add SolidJS signals for tracking host key verification state including status, source, fingerprint info, config, and modal open/close state for prompt and mismatch dialogs.
Modal for unknown host key verification with TOFU flow. Displays host, algorithm, SHA-256 fingerprint, and optional checkbox to save the key to the browser client-side store.
Hard block modal for host key mismatches. Shows expected vs received fingerprints, refuses the connection, and provides guidance based on whether the mismatch was detected by the server or client store.
Simple rejection notice modal for when a connection is refused by host key policy. Displays the reason and directs the user to contact their administrator.
Status bar icon with popover showing host key verification details. Displays a green shield for verified hosts or amber shield for alerts, with click-to-expand details showing host, algorithm, fingerprint, and verification source.
Use bracket notation for index signature properties to comply with noPropertyAccessFromIndexSignature, and add explicit type assertions for array element access under noUncheckedIndexedAccess.
Add expandable section for managing client-side SSH host keys with: - List of stored keys showing host, algorithm, and SHA-256 fingerprint - Delete button per key entry - Add Key form for manually entering OpenSSH public keys - Export keys to JSON file download - Import keys from JSON file upload Section only appears when client store is enabled in host key config.
Wire up client-side handling for server host key verification events: - Add hostkey:verify/verified/mismatch/alert/rejected to ServerToClientEvents - Add hostkey:verify-response to ClientToServerEvents - Add hostKeyVerification to PermissionsPayload - Implement all event handlers in socket service with client store lookup - Add rejected state signals to terminal store - Reset host key state on disconnect
Integrate host key verification UI into the main application: - Add HostKeyPromptModal with accept/reject handlers and client store save - Add HostKeyMismatchModal with dismiss-to-login flow - Add HostKeyRejectedModal for server policy rejections - Add HostKeyStatusIndicator to bottom status bar - Import socket signal and host key store for emit/save operations
- Fix mismatch modal showing placeholder instead of actual stored fingerprint by returning storedKey from lookup and computing SHA-256 via SubtleCrypto - Change closeOnBackdropClick to false on prompt modal to prevent accidental rejection - Default rememberKey checkbox to true (TOFU model) - Add click-outside-to-close and Escape key handling to status indicator popover
The <For> list was driven by hostKeyStore.getAll(), a plain localStorage read that is not reactive in SolidJS. After deletion the list never re-rendered, and refreshFingerprints() replaced the fingerprints map without the deleted key, causing the fallback 'Computing...' text. Add a reactive storedKeys signal, update it synchronously on delete, and prune the fingerprints map in place so remaining entries keep their already-computed fingerprints without an async recompute.
- Consume hostKeyVerification from the /ssh/config HTTP response in loadServerAuthMethods and set the hostKeyVerifyConfig signal immediately. This makes the Trusted Host Keys settings section visible before any socket connection, enabling key import on fresh browsers. - Make session-related PermissionsPayload fields optional to support partial pre-auth permissions events from the server.
Add 31-test suite for client-side TOFU host key store (lookup, store, remove, import/export, resilience). Add config-hostkey tests for server config consumption. Fix extensionless import in config.ts, remove 13 unnecessary TransferId type assertions (S4325), flip 2 negated ternary conditions (S7735) in sftp-service.ts.
…atch) Apply npm audit fix to address 4 vulnerabilities in dev dependencies: - rollup 4.57.1 → 4.59.0 (HIGH: arbitrary file write GHSA-mw96-cpmx-2vgc) - basic-ftp 5.1.0 → 5.2.0 (CRITICAL: path traversal GHSA-5rq4-664w-9x2c) - ajv/minimatch transitive deps updated (MODERATE/HIGH: ReDoS) Update SECURITY.md review dates.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the client-side UI for SSH host key verification, complementing the server-side feature in webssh2. Provides browser-based host key prompting, status display, and localStorage-based key persistence.
Key changes:
host-key-store.ts— localStorage-backed store with lookup (returning discriminated union for trusted/mismatch/unknown), save, delete, and clear operationshostkey:verify,hostkey:verified,hostkey:mismatch,hostkey:alert,hostkey:rejectedevents with SHA-256 fingerprint computation via SubtleCryptoTesting
Test plan
npm run check:allpassesnpm run buildproduces clean output