Skip to content

fix(auth): unify first-run setup into one browser handoff (BUG-1843) - #739

Merged
xarmian merged 1 commit into
mainfrom
fix/first-run-cli-auth-handoff
Jun 21, 2026
Merged

fix(auth): unify first-run setup into one browser handoff (BUG-1843)#739
xarmian merged 1 commit into
mainfrom
fix/first-run-cli-auth-handoff

Conversation

@xarmian

@xarmian xarmian commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Problem (BUG-1843)

On a fresh, locally-hosted instance, first-run setup was two disconnected browser handoffs. The operator opened the /setup link, created the admin account, and the page dropped them on the console — while the CLI only then printed a second "authorize the CLI" URL back in the terminal, which a user who'd moved to the browser never saw. The result: ctrl-C out of the wedged pad init, re-run, and only the second run reached the approval page.

Fix — one browser handoff

The CLI mints the pending CLI auth session up front and hands /setup a validated next=/auth/cli/<code> target. Account creation now flows straight into the approval page (where the just-bootstrapped admin is already authenticated), one click finishes login, and the CLI polls that pre-created session and connects. No return-to-terminal gap.

  • internal/cli/bootstrap.go — thread next into the /setup URL (query before the #token fragment, URL-escaped); raise bootstrapPollTimeout to 20m to match the setup session TTL.
  • cmd/pad/main.go — extract pollAndSaveCLIAuth; runBrowserSetup pre-creates the session and polls it; pad workspace init drives local setup inline instead of erroring.
  • cmd/pad/init.gopad init routes through the unified handoff.
  • internal/store + internal/server — grant a setup-specific 20m CLI auth session TTL when UserCount()==0 so the combined create-account + approve window can't expire mid-flow; normal pad auth login keeps the 5m default.
  • web/src/routes/setup/+page.svelte — honor a validated local next redirect (open-redirect guarded), preserved across the token-fragment scrub.

Verification

  • New unit tests lock the next-before-#token URL ordering.
  • internal/cli / cmd/pad / internal/store / internal/server suites pass; web build clean.
  • Live end-to-end run on an isolated instance confirmed the server-side chain: pre-created session → bootstrap cookie → approve → token.
  • Reviewed via Codex loop (3 rounds → CLEAN); fixes for both the session-TTL and CLI-poll-timeout ceilings came out of that loop.

https://claude.ai/code/session_01KmxkPxLksjf1pmrZDpsnTJ

On a fresh instance, `pad init` / `pad auth setup` created the admin
account in the browser and dropped the operator on the console, then
printed a SECOND "authorize the CLI" URL back in the terminal that a
user who'd moved to the browser never saw — forcing a ctrl-C + re-run.

Collapse it into a single browser tab: the CLI mints the pending CLI
auth session up front and hands /setup a validated `next=/auth/cli/<code>`
target, so account creation flows straight into the approval page where
the just-bootstrapped admin approves in one click and the CLI connects.

- internal/cli/bootstrap.go: thread `next` into the /setup URL (query
  before the #token fragment); raise bootstrapPollTimeout to 20m to
  match the setup session TTL.
- cmd/pad/main.go: extract pollAndSaveCLIAuth; runBrowserSetup pre-creates
  the session and polls it; `pad workspace init` drives local setup inline.
- cmd/pad/init.go: `pad init` routes through the unified handoff.
- internal/store + internal/server: grant a setup-specific 20m CLI auth
  session TTL when UserCount==0 so the combined create-account + approve
  window can't expire mid-flow; normal logins keep the 5m default.
- web/src/routes/setup: honor a validated local `next` redirect (open-
  redirect guarded), preserved across the token-fragment scrub.

Reviewed via Codex loop (3 rounds → clean).

Claude-Session: https://claude.ai/code/session_01KmxkPxLksjf1pmrZDpsnTJ
@xarmian
xarmian merged commit 22d901c into main Jun 21, 2026
4 checks passed
@xarmian
xarmian deleted the fix/first-run-cli-auth-handoff branch June 21, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant