fix: route provider-tagged browser sign-ins directly to the provider's OAuth - #51
Conversation
…s OAuth A provider choice in the CLI now always opens the console signup entry (/signup?provider=...&redirect=<consent>), which auto-starts that provider's OAuth and returns to the consent screen — instead of the consent URL, whose auth middleware bounces an unauthenticated browser to the generic sign-in page. Provider-tagged flows also get the longer browser-wait budget, since the provider round-trip applies whether or not the account is new. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
LGTM: verified at head 873e295 — the regression fix checks out against the nominal console source: /signup?provider= auto-forwards to that provider's OAuth and preserves ?redirect= across the round-trip (the consent page sits behind auth middleware, which is exactly what this routes around); signupEntry-only and untagged flows are byte-identical to base; the redirect percent-encoding was execution-verified to round-trip exactly; typecheck/lint/build clean and 275/275 tests pass locally; CI 3/3 green; and both merge orders vs #49 are safe.
Two optional nits, take or leave:
- test/onboarding-run.test.ts:185 —
assert.ok(timeoutMs > 0)is a pretty loose assertion; pinning equality to the plain timeout would say more. The ordering check at :163 already covers the part that matters, so this is cosmetic. - test/onboarding-run.test.ts:177 — the throwaway
's'/'c'state/challenge args in the timeout comparison read a little opaque; a short comment or named values would help the next reader.
Generated by Claude Code
There was a problem hiding this comment.
Auto-approved: Claude reviewed this PR and posted an LGTM verdict (see its review). A repo admin enabled this via the auto-approve workflow.
Generated by Claude Code
Part of the 2026-08-19 user-testing feedback on CLI sign-in: picking Google or GitHub must land the browser directly on that provider's OAuth flow, never on the generic sign-in page.
Stack position: PR 2 of 3 from the 2026-08-19 user-testing feedback, based on main, independent of its siblings: cli#49 (per-provider login picker — the paired PR that threads
providerfromauth login) and cli#53 (terms/privacy notice at account creation). Known follow-up once this and cli#53 are both in:oauthSignup's "Pick "Google" there" note (sibling-ownedsignup.ts) becomes slightly stale since the signup page auto-starts the provider — one-line copy fix after merge.Context
The console's OAuth consent page (
apps/console/app/pages/oauth/[id].vuein nominal) runs behind auth middleware, so when the CLI opens the consent URL in a signed-out browser, the user is bounced to the generic/loginpage — the "signin page" flagged in testing. The console signup page already solves this: it accepts?provider=google|githuband auto-forwards straight to that provider's OAuth, keeps the CLI's consent URL alive in?redirect=across the provider round-trip, and (for a browser that is already signed in) skips the provider hop and redirects straight to consent. Its provider login composables are shared with the sign-in page, so an existing account routed through the signup entry simply signs in. Until now the CLI only used that entry whensignupEntrywas set (theauth signupGoogle/GitHub path); a provider-tagged plain sign-in still opened the bare consent URL. This became user-visible once #45 madeauth login's browser option the single sign-in entry point.What this PR does
buildBrowserFlowUrlsroutes the browser through the console signup entry wheneveroptions.provideris set — with or withoutsignupEntry— carryingredirect(the consent path + query),provider, the installref, and the onboarding run id exactly as the signup path does today.SIGNUP_BROWSER_TIMEOUT_MS), since the provider round-trip applies whether or not the account is new.signupEntrywithoutprovider, and the no-options consent flow, are byte-for-byte unchanged; the stderr copy still says "sign in" unlesssignupEntryis set.BrowserFlowOptionsand the timeout constant updated to describe the new semantics.End-to-end, the
auth loginpicker passesprovidervia the paired sibling PR (PR 1 of 3); merging in either order is safe —auth signup's Google/GitHub options already exercise this exact URL shape today.Verification
npm run typecheck— pass;npm run lint— pass;npm run test— 275/275 pass (3 new).{provider: 'google'}alone →openUrlis/signupwithprovider=google,ref, andredirect=<consent path+query>, and a longer timeout than the plain flow;{signupEntry: true}without provider → same/signupshape, noproviderparam, same long timeout; no options →openUrl === authUrlon/oauth/<client-id>.🤖 Generated with Claude Code