Fix 1.36.9: email login hands back to the waiting tab, top bar refreshes after sign-in #87

Merged
pyaniz merged 1 commit from staging into main 2026-10-24 10:39:35 -05:00
Owner

Type: Fix (patch) - VERSION 1.36.8 -> 1.36.9.

The link authenticated the tab it was opened in while the tab that asked for it kept waiting. The waiting tab did have a watcher (BroadcastChannel + /auth/me polling), but it polled only while visible, never asked again when brought back to the foreground, used a hard reload, and gave no hint when the link points at a different address than the one the tab is on. Now:

  • The link tab announces the login and waits ~1.5 s for an ack. The waiting tab answers after confirming its own session (/auth/me), carries on into the app, and the link tab shows "You are signed in. Return to the tab where you asked for the link" (tries window.close(), offers Continue in this tab instead). With no waiting tab it carries on as before.
  • Waiting tab: checks on the broadcast, a 2.5 s poll that is no longer paused while hidden, visibilitychange, focus and pageshow, plus an I opened the link button. Transport is BroadcastChannel and the storage event (shared/utils/authEvents.ts).
  • /auth/config now returns public_url; the login page warns when it differs from the current origin (links would sign in another site, a tab can never follow that).
  • Redirects after login are in-app navigations (state already updated) instead of full reloads.

Bug 2: top bar not refreshing

  • AuthContext.login() is now the single place that finishes a sign-in: sets the user, completes it from /auth/me, and tells the other tabs. The group wizard's sign-in only wrote localStorage and never updated the app (the likeliest cause of the stale top bar); the Discord callback now uses login() too.
  • AuthContext re-syncs on login/logout events from other tabs and when a tab returns to view (throttled to once per 10 s); logout also broadcasts.
  • GroupContext reloads groups whenever the logged-in user changes.

Not covered (by design)

The session is only issued to the browser that opens the link (same rule as the Telegram flow). If the email app opens the link in a different browser, an installed app or another device, the waiting tab cannot follow; a server-side hand-over would let anyone who tricks you into clicking a link sign in their own browser as you, so I did not add one.

Testing

  • npm run build passes. Not exercised in a browser: please test on staging with two tabs of one browser (request the link in tab 1, open it from the email), then once with the link opened in another browser; and sign in through the group wizard and check the top bar.

🤖 Generated with Claude Code

**Type:** Fix (patch) - VERSION 1.36.8 -> 1.36.9. ## Bug 1: email magic link The link authenticated the tab it was opened in while the tab that asked for it kept waiting. The waiting tab did have a watcher (BroadcastChannel + `/auth/me` polling), but it polled only while visible, never asked again when brought back to the foreground, used a hard reload, and gave no hint when the link points at a different address than the one the tab is on. Now: - The link tab announces the login and waits ~1.5 s for an **ack**. The waiting tab answers after confirming its own session (`/auth/me`), carries on into the app, and the link tab shows "You are signed in. Return to the tab where you asked for the link" (tries `window.close()`, offers *Continue in this tab instead*). With no waiting tab it carries on as before. - Waiting tab: checks on the broadcast, a 2.5 s poll that is no longer paused while hidden, `visibilitychange`, `focus` and `pageshow`, plus an **I opened the link** button. Transport is BroadcastChannel **and** the `storage` event (`shared/utils/authEvents.ts`). - `/auth/config` now returns `public_url`; the login page warns when it differs from the current origin (links would sign in another site, a tab can never follow that). - Redirects after login are in-app navigations (state already updated) instead of full reloads. ## Bug 2: top bar not refreshing - `AuthContext.login()` is now the single place that finishes a sign-in: sets the user, completes it from `/auth/me`, and tells the other tabs. The **group wizard's sign-in only wrote localStorage** and never updated the app (the likeliest cause of the stale top bar); the Discord callback now uses `login()` too. - `AuthContext` re-syncs on `login`/`logout` events from other tabs and when a tab returns to view (throttled to once per 10 s); logout also broadcasts. - `GroupContext` reloads groups whenever the logged-in user changes. ## Not covered (by design) The session is only issued to the browser that opens the link (same rule as the Telegram flow). If the email app opens the link in a different browser, an installed app or another device, the waiting tab cannot follow; a server-side hand-over would let anyone who tricks you into clicking a link sign in their own browser as you, so I did not add one. ## Testing - `npm run build` passes. **Not exercised in a browser**: please test on staging with two tabs of one browser (request the link in tab 1, open it from the email), then once with the link opened in another browser; and sign in through the group wizard and check the top bar. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Fix: email magic link hands back to the waiting tab; top bar and groups refresh after any sign-in (1.36.9)
All checks were successful
Build and Publish Containers / build-and-push (push) Successful in 41s
Mirror to GitHub / mirror (push) Successful in 24s
dc0e1f3473
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
pyaniz merged commit d81766e4aa into main 2026-10-24 10:39:35 -05:00
Sign in to join this conversation.
No description provided.