Skip to content

fix(v2): SSO buttons no longer vanish on a transient providers-fetch blip#681

Merged
lilyshen0722 merged 1 commit into
mainfrom
fix/oauth-buttons-resilient
Jul 13, 2026
Merged

fix(v2): SSO buttons no longer vanish on a transient providers-fetch blip#681
lilyshen0722 merged 1 commit into
mainfrom
fix/oauth-buttons-resilient

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Root cause of the recurring "I can't see the SSO option, sometimes after a while I can" reports. V2OAuthButtons did:

axios.get('/api/auth/oauth/providers')
  .then(res => setProviders(res.data?.providers ?? []))
  .catch(() => setProviders([]));   // ANY failure → empty
if (!providers.length) return null; // empty → nothing, no retry

So a single failed/slow fetch — a deploy blip, a spot reclaim, or the user's own network hiccup — set providers to empty and hid the buttons with no retry, until a manual reload ("after a while I can see it"). It turned every brief transient into a sticky, visible broken-login state, and it's specifically the SSO buttons because they're the only login element gated on a fragile fetch. (The underlying backend blips themselves are separately fixed by #676/#679; this is the frontend amplifier.)

Fix:

  • Seed state from a localStorage last-known-good cache → repeat visitors see buttons instantly, and a transient failure falls back to the cached list instead of blanking.
  • Retry the fetch 3× with backoff.
  • Only clear on a successful empty response (genuine self-hosted-without-OAuth) — never on a network error.
  • Cancel the pending retry timer on unmount (no stray request after navigating away).

Tests: added fall-back-to-cache-on-failure and retry-until-recovery; 6/6 in V2OAuth.test.tsx, 40/40 v2 suite green.

Zero-downtime deployable.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MnRCAFgjrrGZxo9VRCmCm9

…blip

Root cause of the intermittent 'SSO options disappear, then come back
after a while' reports: V2OAuthButtons set providers=[] on ANY fetch
failure and rendered null when empty, with no retry. So any one-second
transient — a deploy blip, a spot reclaim, or the user's own wifi —
blanked the OAuth buttons until a manual page reload.

Fix: seed from a localStorage last-known-good cache (repeat visitors see
buttons instantly), retry the fetch 3x with backoff, and only clear on a
*successful* empty response (genuine self-hosted no-OAuth) — never on a
network error. Also cancel the pending retry timer on unmount (no stray
request after navigating away; also fixes cross-test timer bleed).

Tests: fall-back-to-cache-on-failure + retry-until-recovery, 6/6 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MnRCAFgjrrGZxo9VRCmCm9
@lilyshen0722
lilyshen0722 merged commit 268b70b into main Jul 13, 2026
11 checks passed
@lilyshen0722
lilyshen0722 deleted the fix/oauth-buttons-resilient branch July 13, 2026 08:17
lilyshen0722 added a commit that referenced this pull request Jul 13, 2026
…e bundles) (#682)

index.html was served with NO Cache-Control header, so browsers applied
heuristic caching and could serve a stale copy pointing at an old hashed
bundle — stranding users on pre-deploy code until their cache expired.
This is why shipped fixes (e.g. the SSO-button fix #681) appeared not to
land: the browser kept loading the old bundle.

Serve index.html with 'no-cache, no-store, must-revalidate' so it's
always revalidated, and mark the hashed (immutable) assets 'immutable'
so they still cache hard. Vite emits a fresh index every build that
names the current bundles; the index must always be re-fetched to learn
them. nginx -t validated.


Claude-Session: https://claude.ai/code/session_01MnRCAFgjrrGZxo9VRCmCm9

Co-authored-by: Sam Xu <xcjsam@g.ucla.edu>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

2 participants