useVaultState hydrates knownHosts asynchronously — its init awaits the
decryption of hosts, keys, identities and proxyProfiles before reading
knownHosts from localStorage. The state is briefly [] at boot even when
localStorage has saved entries.
The host-key verifier introduced in bce33f34 reads the renderer's
knownHosts state at connect time. Any SSH connect that fires inside
that hydration window (manual click or auto-restored session) sees an
empty trust list, marks every host as unknown, and prompts again. The
fix accepted by the user is saved to localStorage, but next restart
the same race repeats, giving the impression that fingerprints are
never persisted.
Use the existing getEffectiveKnownHosts helper at the two sites that
feed the SSH connect path (VaultView + TerminalLayerMount). The helper
falls back to localStorage while state is still settling, mirroring
the same pattern already applied to sync payloads (App.tsx:479).
Memoised on the knownHosts state so the prop reference is stable and
the TerminalLayer/VaultView React.memo equality checks still hold.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
14
App.tsx
14
App.tsx
@@ -300,6 +300,16 @@ function App({ settings }: { settings: SettingsState }) {
|
||||
keysRef.current = keys;
|
||||
const knownHostsRef = useRef(knownHosts);
|
||||
knownHostsRef.current = knownHosts;
|
||||
// Bridge the gap while useVaultState hydrates: its async init awaits
|
||||
// hosts/keys/identities/proxyProfiles decryption before reading knownHosts,
|
||||
// so the state is briefly [] at boot even when localStorage has entries.
|
||||
// Any SSH connect during that window (manual click or restored session)
|
||||
// would otherwise see no trusted hosts and prompt for fingerprint
|
||||
// re-confirmation. Mirrors the same fallback already used by sync payloads.
|
||||
const effectiveKnownHosts = useMemo(
|
||||
() => getEffectiveKnownHosts(knownHosts) ?? [],
|
||||
[knownHosts],
|
||||
);
|
||||
|
||||
const {
|
||||
sessions,
|
||||
@@ -1996,7 +2006,7 @@ function App({ settings }: { settings: SettingsState }) {
|
||||
snippets={snippets}
|
||||
snippetPackages={snippetPackages}
|
||||
customGroups={customGroups}
|
||||
knownHosts={knownHosts}
|
||||
knownHosts={effectiveKnownHosts}
|
||||
shellHistory={shellHistory}
|
||||
connectionLogs={connectionLogs}
|
||||
managedSources={managedSources}
|
||||
@@ -2069,7 +2079,7 @@ function App({ settings }: { settings: SettingsState }) {
|
||||
snippetPackages={snippetPackages}
|
||||
sessions={sessions}
|
||||
workspaces={workspaces}
|
||||
knownHosts={knownHosts}
|
||||
knownHosts={effectiveKnownHosts}
|
||||
draggingSessionId={draggingSessionId}
|
||||
terminalTheme={currentTerminalTheme}
|
||||
followAppTerminalTheme={followAppTerminalTheme}
|
||||
|
||||
Reference in New Issue
Block a user