Skip to content

fix(identity): let a stuck at-launch sign-in copy its link - #2453

Merged
ngthuydiem merged 2 commits into
mainfrom
fix/sign-in-link-fallback
Nov 13, 2026
Merged

ngthuydiem merged 2 commits into
mainfrom
fix/sign-in-link-fallback

Conversation

@ngthuydiem

@ngthuydiem ngthuydiem commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Why

In at-launch organization builds, someone can get stuck on Signing you in to … when the browser never shows the sign-in page. Retrying with Open the sign-in page again goes through the same handoff, and the screen never shows the URL, so there's no way forward except Cancel or Not now.

On macOS, tauri-plugin-opener runs /usr/bin/open and waits for it to exit. A failed launch already maps to browser-unavailable. So the stuck screen means one of two things: open reported success, or it is still waiting on a hung browser. In the second case, login() stays blocked inside begin_federated while it holds the sign-in operation lock, so retries queue up behind it.

What

  • Copy sign-in link: login() keeps the authorization URL it opened next to the pending callback in State.callback. A new federated_identity_sign_in_link command returns it while the attempt is pending, and it is cleared wherever the callback is. The signing-in screen gets a Copy sign-in link button that uses writeClipboardText. It shows a status line on success and the usual alert on failure.
  • Bounded launch: login() registers the callback and its link before it opens the browser, so Copy sign-in link works during the launch wait too. open_within runs the opener on its own thread and waits up to 5s. A reported failure clears the callback and returns browser-unavailable. A launch that is still pending after 5s lets the attempt go on, so retries aren't stuck behind it.
  • Wiring for the new command: build.rs, capabilities/default.json (main webview only), lib.rs, and the permission isolation test.
  • One line in docs/buzz-help.md.

The URL now crosses IPC. It carries the S256 handoff challenge and the loopback return_to. The handoff secret and the returned code stay native, and the begin_federated doc comment now says so.

Screenshots

Signing-in screen, from tests/fixtures/launch-sign-in.html (after: Copy clicked).

Light Dark
Before Before, light Before, dark
After After, light After, dark

Tests

  • federated_identity::tests: an open failure stops sign-in, while a hung open does not. The link is readable while pending and gone after cancel.
  • LaunchSignIn.test.tsx: the copy button shows the alert when no link is available, then copies the link and shows the status line.
  • Local runs: pnpm check, Vitest for src/features/federated-identity and IdentitySettings, cargo clippy --all-targets -D warnings, cargo fmt --check. Full cargo test passes except two tests that SIGSEGV on this machine: converts_tiled_heic_without_cropping and onboarding_snapshot_is_kept_until_next_launch_restore. I confirmed the same segfaults on an earlier base (67175637a), so they aren't from this change.

Deferred

  • Not yet exercised in a packaged at-launch build, and no human test yet (checklist steps 2–3).
  • The 5s wait still runs synchronously inside the async login(). Before this change that wait had no limit.

🤖 Generated with Claude Code

@ngthuydiem

Copy link
Copy Markdown
Contributor Author

🤖 Test evidence at 8eb513374. These are unit and component tests only; the packaged app has not been run yet.

$ cargo test --lib federated_identity::tests::
test federated_identity::tests::cancel_releases_the_native_callback_before_a_replacement_login ... ok
test federated_identity::tests::a_reported_browser_failure_stops_sign_in_but_a_hung_browser_does_not ... ok
test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 833 filtered out; finished in 2.01s

$ vitest run src/features/federated-identity/LaunchSignIn.test.tsx -t "copies the sign-in link"
 ✓ src/features/federated-identity/LaunchSignIn.test.tsx > copies the sign-in link when the browser didn't open 78ms
      Tests  1 passed | 15 skipped (16)

@ngthuydiem
ngthuydiem marked this pull request as ready for review November 4, 2026 19:26
@ngthuydiem
ngthuydiem requested a review from a team as a code owner November 4, 2026 19:26

@joahg joahg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Read the sign-in link plumbing and the bounded open. The link is only the authorization URL (S256 challenge and loopback return_to), the command is allowlisted for the main webview only, and it is cleared with the callback. Looks safe.

@ngthuydiem
ngthuydiem force-pushed the fix/sign-in-link-fallback branch from 51fc48b to 932ea46 Compare November 6, 2026 20:10
@tellaho

tellaho commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

🤖 Design review at 932ea46f2f. Intent: let someone finish organization sign-in by copying its link when the browser handoff stalls.

Must-fix: make Copy ready before offering it. With a hung browser, someone can click Copy sign-in link during the five-second launch wait and receive “Couldn’t copy the sign-in link. Try again.” The screen already enables Copy, but native only stores the link after that wait. Make the URL available before enabling Copy, or keep the shared Button pending until it is available; normal preparation should not produce a recovery error.

Evidence: enabled action and null-link error, link stored after the opener returns. This conflicts with the design guide’s available-action and state guidance. Verify the copy action while the opener is held pending.

Limits: source review only; no screenshots supplied, tests run, or packaged sign-in/clipboard, keyboard, screen-reader, theme, width, long-name or enlarged-text checks performed.

@tellaho

tellaho commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

🤖 Could you add a screenshot or short video of the change to the PR? Design uses these for faster reviews.

ngthuydiem and others added 2 commits November 13, 2026 09:59
If the browser never shows the sign-in page, the at-launch screen stays on
"Signing you in" with no way forward. Add "Copy sign-in link" so the page
can be opened by hand, and stop a hung macOS `open` from holding sign-in:
the launch runs on its own thread and the attempt goes on after 5s. A
reported launch failure still ends the attempt with browser-unavailable.

Co-authored-by: Fizz <6be7be23ec5bba868f3e1db5ec86013d76bd1a293dce5b435a192158fec13641@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Diem Nguyen <[email protected]>
Co-authored-by: Fizz <6be7be23ec5bba868f3e1db5ec86013d76bd1a293dce5b435a192158fec13641@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Diem Nguyen <[email protected]>
@ngthuydiem
ngthuydiem force-pushed the fix/sign-in-link-fallback branch from 932ea46 to 808e1d9 Compare November 13, 2026 18:01
@ngthuydiem

Copy link
Copy Markdown
Contributor Author

🤖 Addressed in 808e1d990 (rebased on main):

  • Copy ready before it's offered: login() now stores the callback and its link before it opens the browser (mod.rs), so Copy sign-in link returns the link during the 5s launch wait instead of the error. If the launch reports failure, it clears the callback and ends with browser-unavailable as before.
  • Screenshots: before/after, light and dark, are now in the description.

Limits: there's no mock opener in the native tests, so the "copy while the opener is held" case isn't covered by an automated test. The order is in the code, and open_within's hung and failed cases are tested. Not yet tried in a packaged build.

@ngthuydiem
ngthuydiem merged commit 9555708 into main Nov 13, 2026
127 of 129 checks passed
@ngthuydiem
ngthuydiem deleted the fix/sign-in-link-fallback branch November 13, 2026 23:50
wpfleger96 added a commit that referenced this pull request Nov 14, 2026
…y-unreads

* origin/main: (24 commits)
  [1/2] feat(agents): add a recommended agent setup (core) (#3344)
  test(browser): survive the live-stream restart a page-clock jump causes (#3442)
  chore(renovate): hold rusqlite below 0.41 for mesh-llm (#3438)
  test(browser): serve the diffs and CLI reload fixtures outside the navigation budget (#3445)
  test(browser): play the draft clip at rate 0 instead of looping it before the Play click (#3446)
  fix(status): reopen a status whose preset deadlines coincide as Today (#3449)
  fix(messages): tolerate a cancelled reaction-name chunk load (#3450)
  fix(pairing): tolerate /proc/net/tcp rows printed twice or missed (#3451)
  test(browser): wait on the signal each test asserts in local-agent-activity and message-navigation (#3444)
  Expose native channel headings to Solo sources (#3523)
  test(browser-host): run the 100,000-channel broker scale check alone in the measurements lane (#3447)
  fix(solo): keep every contributed destination action (#3516)
  fix(identity): report an issuer that keeps rate-limiting an agent as a limit (#2365)
  fix(identity): let a stuck at-launch sign-in copy its link (#2453)
  fix(profiles): open avatar previews on hover in compact density (#3510)
  feat(solo): smooth chat recency reordering (#3502)
  Reject self-mentions that cannot wake another session (#3513)
  feat(status): offer don't clear for every status (#3515)
  Let plugin panels name their tab with panels.useTabTitle (#3251)
  fix(agents): report a conversation wake that fails before its turn starts (#2192)
  ...

# Conflicts:
#	tests/browser/message-management.spec.mjs
wpfleger96 added a commit that referenced this pull request Nov 14, 2026
* origin/main: (27 commits)
  [2/2] feat(agents): offer Automatic (Recommended) in Create agent and Identity (#3345)
  fix(solo): preserve and resume unsent chat drafts (#3525)
  fix(builderlab): give refused app sign-ins and Identity links a route to Organization sign-in (#3078)
  fix(agents): say why Import an agent can't import here, and link Manage plugins (#3073)
  [1/2] feat(agents): add a recommended agent setup (core) (#3344)
  test(browser): survive the live-stream restart a page-clock jump causes (#3442)
  chore(renovate): hold rusqlite below 0.41 for mesh-llm (#3438)
  test(browser): serve the diffs and CLI reload fixtures outside the navigation budget (#3445)
  test(browser): play the draft clip at rate 0 instead of looping it before the Play click (#3446)
  fix(status): reopen a status whose preset deadlines coincide as Today (#3449)
  fix(messages): tolerate a cancelled reaction-name chunk load (#3450)
  fix(pairing): tolerate /proc/net/tcp rows printed twice or missed (#3451)
  test(browser): wait on the signal each test asserts in local-agent-activity and message-navigation (#3444)
  Expose native channel headings to Solo sources (#3523)
  test(browser-host): run the 100,000-channel broker scale check alone in the measurements lane (#3447)
  fix(solo): keep every contributed destination action (#3516)
  fix(identity): report an issuer that keeps rate-limiting an agent as a limit (#2365)
  fix(identity): let a stuck at-launch sign-in copy its link (#2453)
  fix(profiles): open avatar previews on hover in compact density (#3510)
  feat(solo): smooth chat recency reordering (#3502)
  ...

# Conflicts:
#	src-tauri/src/federated_identity/agent/tests.rs
#	src-tauri/src/federated_identity/mod.rs
#	src-tauri/src/federated_identity/protocol.rs
joahg added a commit to joahg/buzz-app that referenced this pull request Nov 14, 2026
* origin/main: (133 commits)
  Expose ordinary chats without workspace headings (block#3530)
  [2/2] feat(agents): offer Automatic (Recommended) in Create agent and Identity (block#3345)
  fix(solo): preserve and resume unsent chat drafts (block#3525)
  fix(builderlab): give refused app sign-ins and Identity links a route to Organization sign-in (block#3078)
  fix(agents): say why Import an agent can't import here, and link Manage plugins (block#3073)
  [1/2] feat(agents): add a recommended agent setup (core) (block#3344)
  test(browser): survive the live-stream restart a page-clock jump causes (block#3442)
  chore(renovate): hold rusqlite below 0.41 for mesh-llm (block#3438)
  test(browser): serve the diffs and CLI reload fixtures outside the navigation budget (block#3445)
  test(browser): play the draft clip at rate 0 instead of looping it before the Play click (block#3446)
  fix(status): reopen a status whose preset deadlines coincide as Today (block#3449)
  fix(messages): tolerate a cancelled reaction-name chunk load (block#3450)
  fix(pairing): tolerate /proc/net/tcp rows printed twice or missed (block#3451)
  test(browser): wait on the signal each test asserts in local-agent-activity and message-navigation (block#3444)
  Expose native channel headings to Solo sources (block#3523)
  test(browser-host): run the 100,000-channel broker scale check alone in the measurements lane (block#3447)
  fix(solo): keep every contributed destination action (block#3516)
  fix(identity): report an issuer that keeps rate-limiting an agent as a limit (block#2365)
  fix(identity): let a stuck at-launch sign-in copy its link (block#2453)
  fix(profiles): open avatar previews on hover in compact density (block#3510)
  ...

Signed-off-by: Joah Gerstenberg <[email protected]>

# Conflicts:
#	src/bundled/codex/prompt.test.ts
#	src/bundled/goose/runtime.ts
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.

3 participants