Repository navigation
fix(ssh): the SSH password dialog no longer closes itself and comes back - #28883
Conversation
A host that drops an unanswered login no longer replaces the open prompt with a new one, a background dial no longer replaces a connection whose reconnect is asking the user, one Cancel closes every open prompt for that host, and a paired client's automatic connect stays automatic. Co-Authored-By: Claude <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ⬇️ Low Merge Risk: 🔵 Low · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
a92d9913-b9ff-47c9-bdee-97232cac82f4
⛔ Files ignored due to path filters: 1
src/shared/rpc-contract/rpc-params-catalog.generated.tsis excluded by!**/*.generated.*
📒 Files selected for processing: 13
src/main/ipc/ssh-passphrase.test.tssrc/main/ipc/ssh-passphrase.tssrc/main/runtime/rpc/methods/ssh.test.tssrc/main/runtime/rpc/methods/ssh.tssrc/main/ssh/ssh-connection-manager-sign-in-reuse.test.tssrc/main/ssh/ssh-connection-manager.test.tssrc/main/ssh/ssh-connection-manager.tssrc/main/ssh/ssh-connection.tssrc/main/ssh/ssh-credential-prompt-login-grace-wire.test.tssrc/main/ssh/ssh-target-registry.tssrc/renderer/src/web/preload-api/web-terminal-api.tssrc/renderer/src/web/web-preload-api-ssh.test.tssrc/shared/rpc-contract/ssh-params.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
…ed by a background dial Co-Authored-By: Claude <noreply@anthropic.com>
…ack (#28883) * fix(ssh): the SSH password dialog no longer closes itself and comes back A host that drops an unanswered login no longer replaces the open prompt with a new one, a background dial no longer replaces a connection whose reconnect is asking the user, one Cancel closes every open prompt for that host, and a paired client's automatic connect stays automatic. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): a typed password its reconnect has yet to use is not replaced by a background dial Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: m4air <m4air@Mac.localdomain> Co-authored-by: Claude <noreply@anthropic.com> (cherry picked from commit d5324c9) (cherry picked from commit 4fef196f6de24bcbf5d6a401e31f01b8cd255b86)
ELI5
On a password host, the SSH password dialog could close by itself while the user was still about to type, then open again right away. That could keep repeating. Now the dialog stays open until the user answers or cancels. One answer or one Cancel settles it.
What Changed
Before: a user left the password dialog open for a while, or the app retried in the background. The dialog vanished and a new one appeared. This is the "dismiss + reappears" loop a user reported again on 1.4.225. #28402 already handled a Cancel. It did not cover a dialog that closed itself, because a self-closed dialog never counts as a Cancel.
After: the open dialog is the one the user answers. What the user types signs in. A Cancel stops all automatic sign-in attempts until the user clicks Reconnect.
Mechanism. The fix covers four ways one dialog could be replaced by another:
ssh-connection.ts). sshd drops a login nobody answers within its grace time. That is 120 s by default and often 30 to 60 s. The dropped socket counted as a network error, so the connection retried. The retry closed the open dialog and opened a new one. Now, if the startup fails while a password prompt is open, the attempt waits for the user's answer:A new wire test against a real ssh2 server reproduces this. It failed before the change (2 prompts) and passes after it (1 prompt).
ssh-connection-manager.ts). Status checks and tunnels callconnect(). When the existing connection was in its own reconnect,connect()tore it down, which closed its dialog, and dialed again, which opened another. Now a connection counts as "already in progress", the same as a first connect, in two cases:The dialog is modal, so any connect that arrives while it is open is a background one.
ssh-passphrase.ts). Before, a Cancel answered only the front prompt, and the next one for the same host opened straight away. Now a Cancel closes every open prompt for that host.ssh.connectRPC). The RPC dropped theautomaticflag. A web client's startup restore therefore counted as a user Reconnect, which lifted the host's Cancel.automaticis now an optional RPC field, and the web client passes it through. Old servers ignore the field. Old clients send nothing, which keeps today's "explicit" behavior.Why
connect(). The dialog is modal, so nobody can click Reconnect while it is open. A connection waiting on the user is a fact the connection already knows. That makes it the single check point, so any future background caller gets the same treatment.user@hostcan use different keys. Blocking both from one Cancel would break a target that signs in with a key and never prompts.I checked the 1.4.225 hand-port of #28402 against main for every file it touched. It matches. The dropped WSL lines are unrelated to the decline.
Linked Issue
STA-10477 (follow-up)
Visual Proof
N/A. The existing dialog is reused. The change is that it no longer closes itself and reopens.
Testing
src/main/ssh/ssh-credential-prompt-login-grace-wire.test.ts: a real ssh2 server drops the first login while the password prompt is open. Before the change it showed 2 prompts. After it shows 1 prompt, the typed password signs in, and a Cancel ends the attempt asauth-failed.src/main/ssh/ssh-connection-manager.test.ts: a backgroundconnect()leaves a connection whose reconnect is asking the user alone.src/main/ipc/ssh-passphrase.test.ts: one Cancel closes the other open prompts for that host only.src/main/runtime/rpc/methods/ssh.test.tsandsrc/renderer/src/web/web-preload-api-ssh.test.ts:automaticreaches the host's connect.src/main/ssh/ssh-connection-manager-sign-in-reuse.test.tsis updated. A dial during the open prompt is now refused, and a re-asked password is still not handed on.End to end, built app. The app ran hidden (
ORCA_BACKGROUND_LAUNCH=1) with an isolated profile and was driven over CDP. The host was a local password-only SSH server with a 20 s login grace:Passed:
pnpm tc:node,pnpm tc:web,pnpm test src/main/ssh src/main/ipc src/renderer/src/web, andpnpm run check:code-quality:changed.I manually tested these changes locally
Automated tests added/updated, or explained why not below
AI Disclosure
Review
Agent skill upstream boundary
Notes
automaticis a new optional field, so it is safe in both directions.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)