Skip to content

app sign-ins confirm the account, so sign out then sign in can pick another one - #16661

Merged
lucasr1b merged 1 commit into
mainfrom
sign-in-after-sign-out
Oct 2, 2026
Merged

lucasr1b merged 1 commit into
mainfrom
sign-in-after-sign-out

Conversation

@lucasr1b

@lucasr1b lucasr1b commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

follow-up to #16364, from Austin: signing out in the app and signing in again lands straight back in the same account. the app's sign-out only signs the app out; the browser's cmux.com session stays (on purpose, the same as Slack or Figma desktop), so the sign-in page sees a signed-in browser and continues. only Switch Account asked for the chooser.

now any sign-in started by the Mac app shows the account chooser when the browser is already signed in: "continue as you" in one click, or use another account. so sign out, sign in, chooser.

  • the page decides from the return target, not prompt: after-sign-in with the app's callback and that attempt's cmux_auth_state (signInIsForApp). that survives detours where prompt gets dropped, like a cancelled Google sign-in going through the auth-error page's "back to sign in".
  • an account signed in on the page just now (password, code, passkey) is never asked again, so the chooser no longer flashes while the sign-in redirects. this also fixes that flash for Switch Account.
  • unchanged: sign-ins started on cmux.com, OAuth landings (cmux_continue), restricted accounts (onboarding first), and the in-app pricing webview, whose callback has no attempt state and gets after-sign-in's own confirmation as before.

web only, so it ships with the web deploy and applies to the app builds people already have.

Testing

  • bun test tests/sign-in-entry.test.ts tests/after-sign-in-route.test.ts tests/app-pricing-page.test.tsx tests/account-sessions.test.ts: 99 pass. new tests cover the app rule, the just-signed-in guard, and signInIsForApp for app, web, pricing and malformed targets.
  • bun run typecheck, eslint and the oxlint complexity check clean.
  • end to end against the dev sign-in project with a local web server and headless chromium, 10/10: signed-out app sign-in opens the form and a password sign-in goes straight to the app callback with no chooser flash; signed in, an app sign-in shows the chooser with the account and "use a different account"; continuing hands back to the app (after-sign-in 307s to the cmux-dev-*://auth-callback); the auth-error page's back link still shows the chooser; a web sign-in while signed in still continues; the pricing webview target still skips it.
  • a subagent review found no loops or dead ends. its findings (the auth-error detour, the chooser flash, the pricing webview asking twice, stale comments) are all handled above.
  • not checked live: a tagged app build end to end, and a real Google round trip.

Changelog

Fixed: Signing in again after signing out of the app now asks which account to use instead of signing back in to the same one

Demo Video

  • Video URL or attachment: none, web routing change covered by the e2e above

Checklist

  • Behavior changes have added or updated tests, or Testing says why not
  • UI, settings, menu, schema, help-text or user-facing docs change: no new strings, the chooser already exists in all 20 locales
  • Reviewed with a subagent before merge

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Signing in again after signing out of the Mac app now shows the account chooser instead of returning to the same account.

  • The chooser decision comes from the app's return target (after-sign-in with cmux_auth_state) rather than prompt, so it works even after detours like a cancelled Google sign-in.
  • An account signed in just now on the page is never asked again, so the chooser doesn't flash during redirects (also fixes that for Switch Account).

Written for commit 11fc4a0. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Sign-In
    • App-directed sign-ins now show an account chooser to people who were already signed in when the sign-in page opened.
    • People who sign in during that visit can continue without seeing the chooser again. OAuth returns also continue without an extra account-selection step.
    • Existing account-selection prompts and onboarding for restricted accounts remain unchanged.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (2)
.github/review-bot-rules/test-determinism.md — configured
.github/review-bot-rules/source-control-artifacts.md — configured

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: d6b86a21-8a25-4482-ba4e-cc2cbb80d54e

📥 Commits

Reviewing files that changed from the base of the PR and between b10f7e2 and 11fc4a0.

📒 Files selected for processing (3)
  • web/app/handler/cmux-sign-in.tsx
  • web/app/handler/sign-in-entry.ts
  • web/tests/sign-in-entry.test.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.


📝 Walkthrough

Walkthrough

The sign-in handler now identifies app-directed return targets and passes that status, along with initial sign-in state, to entry selection. Signed-in app sign-ins select an account unless the user just signed in on the page or is returning from OAuth.

Changes

App sign-in account selection

Layer / File(s) Summary
Detect app return targets
web/app/handler/sign-in-entry.ts, web/tests/sign-in-entry.test.ts
signInIsForApp recognizes after-sign-in return URLs with a native callback containing cmux_auth_state. Tests cover relative and absolute URLs, handoff parameters, and rejected targets.
Select sign-in entry
web/app/handler/sign-in-entry.ts, web/app/handler/cmux-sign-in.tsx, web/tests/sign-in-entry.test.ts
CmuxSignIn passes app-target status and whether the user signed in on the page to signInEntry. Entry selection continues OAuth returns and newly signed-in accounts, and directs restricted accounts to onboarding.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 11fc4

No actionable issue is established that prevents merging. The existing-session hard-reload behavior remains unverified.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 11fc4

The change generally adds account confirmation for app sign-ins, while keeping separate checks on where session credentials can be returned. No credential-return bypass was established. Some uncertainty remains about distinguishing a completed sign-in from other session changes and recovering from a failed account switch.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The directly affected boundary is selection of the browser-authenticated account whose session credentials are returned to a native callback. The inspected change does not add tenant-wide authority or a new credential destination; installed callback ownership and production configuration remain outside the established evidence.

Trust Boundaries and Controls

  • observed — A crafted return target can influence app classification without passing callback authorization. Credential delivery separately requires an allowed callback host, path, and scheme, or the signed pricing-return check. These controls constrain the apparent classification-to-credential attack path independently of chooser behavior.

Resilience and Maintainability Implications

  • inferred — If a restored, concurrently changed, or partially activated session produces a non-null user after an initially signed-out render, the new presence-based exception can select continuation. The switching hold and success-path identity check are counterevidence, but SDK behavior determines whether failure recovery can expose this conditional path. It is an unresolved contract question, not an established bypass.
  • observed — The existing handoff initiator generates a random nonce, and tests verify cookie expiry, clearing after successful return, and manual fallback on nonce mismatch. These observations do not establish atomic one-time consumption, cancellation invalidation, or native-client rejection of stale attempts; no PR-induced weakening of those properties was established.

Hardening Proposals

  • proposed — Consider tying the continuation exception to an explicit page-owned completion event and verified account identity, with a recovery state that prevents automatic continuation after a failed switch. Lifecycle validation should distinguish restoration, concurrent session changes, and partial activation from successful page sign-in.
🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (24 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary behavior change: app sign-ins now allow the user to choose another account after signing out. It is concise and specific.
Description check ✅ Passed The description is complete and relevant. It explains the problem, behavior, implementation approach, preserved behavior, tests run, end-to-end validation, known verification limits, changelog entry, …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Cloud Persistent Session And Early Input ✅ Passed PASS: The PR changes only web sign-in routing and its tests (cmux-sign-in.tsx, sign-in-entry.ts, and sign-in-entry.test.ts). The diff adds account-selection state and app return-target detection…
Cmux Swift Actor Isolation ✅ Passed PASS: The pull request changes only two web TypeScript/TSX files and one TypeScript test file. The authoritative diff contains no Swift files or Swift code, so it introduces no Swift 6 actor-isolation…
Cmux Swift Blocking Runtime ✅ Passed The authoritative PR diff changes only three web TypeScript/TSX files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. It introduces no p…
Cmux Browser Automation Off-Main ✅ Passed The check is not applicable. The PR changes only web sign-in TypeScript/TSX files and sign-in tests. The diff does not modify Sources/TerminalController.swift, ControlCommandExecutionPolicy.swift,…
Cmux Expensive Synchronous Load ✅ Passed The custom check applies only to production Swift changes. The review-scoped diff changes three web files only: two TypeScript files and one TSX file. It contains no Swift paths or Swift production co…
Cmux Cache Substitution Correctness ✅ Passed The diff does not replace a fresh authoritative read in a persistence, history, undo, or snapshot path. It adds openedSignedIn as a transient React state value for sign-in entry selection and derive…
Cmux No Hacky Sleeps ✅ Passed PASS. The PR changes only sign-in state and URL classification. The production additions use React state, branching, and URL parsing. The diff introduces no sleep, timer, polling, fixed delay, backoff…
Cmux Algorithmic Complexity ✅ Passed The production diff adds only constant-time branching in signInEntry and one signInIsForApp URL/query inspection per render. It adds no scalable collection scans, nested scans, sorting/filtering i…
Cmux Swift Concurrency ✅ Passed PASS: The review-scoped diff changes only three TypeScript/TSX files under web/ and changes no Swift code. Therefore, it does not introduce or expand any Swift legacy async pattern covered by this che…
Cmux Swift @Concurrent ✅ Passed The pull request changes only three web TypeScript/TSX files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. The authoritative diff cont…
Cmux Swift Package Boundaries ✅ Passed The review-scoped diff changes only three web TypeScript/TSX files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. It contains no Swift …
Cmux Swiftpm Lockfiles ✅ Passed The pull request changes only three web TypeScript/TSX files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. It changes no SwiftPM packa…
Cmux Swift Logging ✅ Passed The pull request changes only TypeScript/TSX files under web/ and a TypeScript test file. The authoritative diff contains no Swift files and adds or materially changes no logging statements. The Swift…
Cmux User-Facing Error Privacy ✅ Passed The production diff changes sign-in routing only. It adds boolean state detection and selects the existing account chooser; it does not add or change user-facing error text, alerts, API error bodies, …
Cmux Full Internationalization ✅ Passed The pull request changes sign-in routing state and adds tests only. The production diff adds no user-facing text, message keys, metadata, changelog content, locale files, or string-catalog entries. Th…
Cmux Swiftui State Layout ✅ Passed The pull request changes only three web TypeScript/TSX files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. The diff contains no SwiftU…
Cmux Architecture Rethink ✅ Passed PASS: The custom check applies to Swift architecture changes. The authoritative PR diff changes only three TypeScript/TSX files and adds no Swift files. Therefore, the Swift-specific architectural fai…
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The pull request changes only three web TypeScript/TSX files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. The authoritative diff cont…
Cmux Source Artifacts ✅ Passed All three changed paths are intentional TypeScript/TSX source or test files: web/app/handler/cmux-sign-in.tsx, web/app/handler/sign-in-entry.ts, and web/tests/sign-in-entry.test.ts. The diff add…
Cmux No Test Or Debug Seam In Production Source ✅ Passed PASS: The pull request changes only three web TypeScript/TSX files. The review-scoped diff contains no Swift file under a production Sources/ path, so it cannot introduce a prohibited test or debug …
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lucasr1b
lucasr1b merged commit aa6f57e into main Oct 2, 2026
69 of 70 checks passed
@lucasr1b
lucasr1b deleted the sign-in-after-sign-out branch October 2, 2026 03:49
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Merge receipt for 11fc4a08ed: every check was green at merge (18 verified; 18 skipped by policy). Full suite runs on main after merge.

rustybret pushed a commit to rustybret/bmux that referenced this pull request Oct 2, 2026
541c735 fix(remote): reject unknown Eternal Terminal equals options (manaflow-ai#15987)
ecb963b fix(cli): reject trailing remotes list/remove arguments (manaflow-ai#15978)
17a8a94 ci: pass the frame pacing fling count as an argument (manaflow-ai#16617)
aa6f57e app sign-ins confirm the account, so sign out then sign in can pick another one (manaflow-ai#16661)
4adc8e4 Fix updater readiness wait reset loop (manaflow-ai#16664)
6f77178 Keep only Invite in Cloud sidebar header (manaflow-ai#16636)
72f2915 notify: add --desktop flag to post to the panel without a native banner (manaflow-ai#14688)
4ba0d8a Expose per-surface prompt and unread state to custom sidebars (manaflow-ai#11142)
b3da20c Allow browser drags across Cloud workspaces (manaflow-ai#16390)
6529dfd Stop retrying Cloud terminals on stale replay daemons (manaflow-ai#16327)
b10f7e2 test: create the requested cwd in the stale-reported split test (manaflow-ai#16653)
9b5b35f Fix Computer Use onboarding readiness after permissions are granted (manaflow-ai#14281)
c45da7e Merge pull request manaflow-ai#16623 from manaflow-ai/fix-ios-cloudvpn-appstore-signing
6e67724 fix: close CloudVPN profile and identity gaps
7e9d6ab fix: sign CloudVPN in App Store exports
1984d1e test: cover App Store CloudVPN signing

# Conflicts:
#	.github/workflows/cmux-next-frame-pacing.yml
#	.github/workflows/ios-app-store.yml
#	.github/workflows/ios-appstore-upload.yml
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