Show the device code in the sign-in dialog - #39
Merged
Merged
Conversation
Sign-in is broken in 3.5.0 for anyone who signs in from inside the app. The browser opens to github.com/login/device, which asks for a code, and the application never shows one. There are two sign-in surfaces. The welcome flow renders through ui/lib/sign-in.tsx and AuthenticationForm, which #26 taught to display the code. The dialog - the one reached by re-authenticating, which is what happens when a token is invalidated - renders through ui/sign-in/sign-in.tsx and was missed. It ignored state.deviceFlow entirely and printed the old copy promising a redirect back to GitHub Desktop, which no longer happens. A user's log shows it exactly: "initializing OAuth device flow", then "opening in browser: https://github.com/login/device", then nothing until the abandoned poll dies minutes later. The request was always fine. The code was fetched, stored in state, and never rendered. Visible in the published bundle: "device-flow-user-code" and "Enter this code at" each appear once, for the welcome flow, and the dialog's misleading redirect sentence appears alongside them. After this change they appear twice and the redirect sentence is gone, confirmed by building. The styles were scoped to .sign-in-form, the welcome form's class, so even once the dialog rendered the code it would have been unstyled. They are now unscoped, because the code is shown from two places. The standing copy is also corrected where it still described the redirect flow, including on the existing-account warning step that reuses it.
Cam8863
approved these changes
Aug 28, 2026
Merged
guys-inc-ops Bot
added a commit
that referenced
this pull request
Aug 28, 2026
Ships the sign-in fix from #39. 3.5.0 could not be signed into from inside the application: the device code was fetched and never rendered by the re-authentication dialog, so the browser opened asking for a code that was nowhere on screen. Also stops the notes generator publishing "TODO". Empty sections rendered a placeholder that existed as a prompt for whoever edited the draft release by hand; we publish without that pass, so a patch release fixing one thing would have shipped a literal "## Improved / TODO" to users. Empty sections are now omitted. Verified that 3.4.9-linux1 still renders its ten upstream issue links with no placeholders. Co-authored-by: guys-inc-ops[bot] <321481384+guys-inc-ops[bot]@users.noreply.github.com>
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.
Sign-in is broken in 3.5.0 for anyone signing in from inside the app. Fixes the report from
dampmeme64.What happens
The browser opens to
github.com/login/device, which asks for a code, and the application never shows one. From the user's log:The request was always fine — the browser only opens because it succeeded. The code was fetched, put into state, and never rendered.
Root cause: two sign-in surfaces, one updated
Welcome / first-run renders through
ui/lib/sign-in.tsx→AuthenticationForm. feat(auth): sign in with the OAuth device flow, stop shipping a client secret #26 taught this one to display the code. It works.The dialog —
ui/sign-in/sign-in.tsx, reached by re-authenticating, which is what happens when a token is invalidated — was missed.renderAuthenticationStepignoredstate.deviceFlowentirely and printed the pre-device-flow copy:That is now false. Nothing redirects back, and the code you need is never shown.
This is why the pre-release GUI sign-in test passed: it exercised first-run, and the user hit re-authentication.
Visible in the published 3.5.0 bundle —
device-flow-user-codeandEnter this code ateach appear once (the welcome flow), alongside the dialog's redirect sentence.The fix
renderAuthenticationStepnow renders the code whenstate.deviceFlowis set, using the same markup as the welcome form.The stylesheet needed changing too:
_device-flow.scsswas scoped to.sign-in-form, the welcome form's class, so even once the dialog rendered the code it would have been unstyled. Now unscoped, with a comment saying why — it is shown from two places.The standing copy is corrected where it still described the redirect flow, which also affects the existing-account warning step that reuses it.
Verified by building, not by inference
I got this wrong twice before landing it — first blaming CORS, then a renderer/main-process split — because I reasoned from
curland specs instead of running things. So this one is checked against the compiled output:device-flow-user-codeEnter this code attsc,eslint,prettierclean.yarn compile:prodexits 0.Follow-up worth doing separately
Nothing in CI renders a component or launches the app, which is why 1032 passing tests, CodeQL, and the build-secret scan all cleared a build no one could sign into. The secret scan even greps for
login/device/codeand found it — proving the string compiled, not that a user could reach it. A component test asserting "a sign-in state carrying a device code renders that code", run against both surfaces, would have caught this in milliseconds.