Repository navigation
fix(app): handle one-time pairing links across the GUI - #53257
Merged
Merged
Conversation
Pairing link first with a password fallback in the connect screen and the Add/Edit server dialog, one redeem path with specific errors, re-pairing signed-out servers from Home and Settings, and a desktop Pairing page that lists every reachable address and gets codes from the window's server client.
…and keep the chosen pairing address A server's controller kept the password it started with, so changing a working server's password left it on the old one. Controllers now rebuild when the listed connection's address or password changes, and callers holding an older connection get the current one. Pairing keeps the first address when its token works there, a scanned QR code fills in a readable link, ServerRef no longer starts a controller just to read builtin, and the docs no longer name the removed pairing.info.
… pair button for a typed custom address A retried link with the same code keeps an address the user edited. The server dialog closes before its continuation opens the next dialog. The pairing page counts a valid custom address while it is typed.
…ettle custom address edits The chosen pairing address is preferred only when its own redeem attempt answered, so an unreachable local address no longer delays pairing by five seconds. An unchanged save on a signed-out server checks its credentials instead of closing. The custom address comes from the field alone, and typing it no longer moves the field. SDK examples name the remaining Pairing methods.
|
Hey, doing pairing on windows with only Desktop app installed makes using $oc = "C:\Users\<user>\AppData\Local\Programs\@opencode-aidesktop\resources\opencode-cli.exe"and then & $oc service set hostname 0.0.0.0Probably this should be mentioned in the pairing section or just add opencode bin to PATH on Desktop install |
Member
Author
|
Thanks for the comment. A few things. I want to make it a button to do this nicely for you, and also for the built-in terminal, just like add the built-in CLI to path. So, yeah, a couple things to improve, but yeah, just gonna make it better overall |
3 of 6 tasks
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.
#50970 and #50972 replaced password pairing with one-time
/auth/connect/<code>links. The connect screen handled the new links, but the rest of the GUI did not: the Add server dialog treated a link as a server address, desktop had no way to redeem one, and a server whose 30-day session expired showed a red dot and no action. This PR fixes the app and GUI side only. It needs no server or protocol changes.flowchart LR Link["Pasted or scanned link<br/>http(s)://host/auth/connect/code"] --> Redeem["useRedeemPairing()"] Redeem -->|200 token| Save["Save url + token as password"] Redeem -->|401| Expired["Link expired or already used"] Redeem -->|network error| Mixed{"https page,<br/>http server?"} Mixed -->|yes| MixedMsg["Use an HTTPS address"] Mixed -->|no| Unreachable["Could not reach host"] Redeem -->|"/connect#… (old server)"| Legacy["Update OpenCode on the server"]opencode service get password). If you paste a bare address into the link field, the form switches to the password view with the address filled in.servers/connect/redeem.ts). The connect screen, the dialog and the QR scanner all use it, so they all show the same specific errors. Before, every failure said "expired", even when the server was unreachable and the code still worked. A redeemed token is kept, so if the connection check fails, a retry does not spend the link again.localhost:4096with a link that names127.0.0.1:4096(asopencode pairprints), the app updates the existing entry instead of adding a duplicate.127.0.0.1, the page explains why and showsopencode service set hostname 0.0.0.0with a copy button, instead of a disabled button.expires_in, and a New code action, which also appears next to the error when getting a code fails. The link now refreshes when the code expires, not every 60 s.Connect screen
Before
After: pairing link first
After: Use password
Connect screen: pasted link to a server that cannot be reached
Before
After
Connect screen over plain http
Before
After
Add server dialog
Before: a pasted pairing link is treated as an address
After: pairing link first
After: added
After: Use password
Signed-out server (expired session or changed password)
Before
After
After: Authenticate opens the edit dialog
After: paste a new link and save
Desktop Settings → Pairing: server listens only on this computer
Before
After
Desktop Settings → Pairing: details dialog
Before
After
After: custom address
After: invalid custom address
Scanner failure
QrScanner sends decoder failures (anything but "no QR code in this frame") only to
console.log, so a blocked decoder worker (the CSP bug fixed in #53278) left a live preview that never scanned.scanner.tsxnow shows an error for them. Checked in Chromium with a fake camera: withworker-srcremoved the message appears; with it allowed, 15 s of frames without a code show nothing.Pairing page without the main process
Pairing's main entry existed to read the sidecar's credentials for
server.info()andserver.pair(). The window'sServerRefis already authenticated for the sidecar (wireRendererHeadersadds the credentials in main), so:ctx.servers.get(id)returns a listed server's liveServerRef(sdk/host-apis.ts, wired to the host's existingserver(id)inruntime/extension/host-apis.tsx).builtin). The link and QR code render from it and no longer wait for main.PairingIpc keeps only the display sleep blocker. The keep-screen-active row, and its settings search entry, show only while main is active.servers/connect) stays in the app:ConnectServerScreenrenders before extensions mount when signed out on the web.DialogServeralready redeems pasted links on submit through the sameuseRedeemPairing.WithoutMainProcessstory issues a code with main inactive.Pairing dialog with main inactive
Rebased on #53588 (every pairing address in QR codes)
pairingLinkreads both links and the{"code","urls"}QR payload.redeemPairingLinktries every address in parallel, as feat(cli): include every pairing address in QR codes #53588 does, and still tells the outcomes apart: "expired" only when a server answered 401, otherwise "unreachable". The mixed-content message shows only when every address is plain HTTP from an HTTPS page.