Skip to content

fix(web): stop rewriting the OAuth state so Google login works again - #1187

Merged
jbojcic1 merged 1 commit into
livefrom
fix/google-login-oauth-state-live
Sep 25, 2026
Merged

jbojcic1 merged 1 commit into
livefrom
fix/google-login-oauth-state-live

Conversation

@ditto-agent

Copy link
Copy Markdown
Contributor

Cherry-pick of #1186 (commit 0911d33) onto live for prod. The only adaptation is the pre-SDK osInitiateGoogleAuth call in auth.ts.

Problem

Google login and signup fail on next.agi.cash and agi.cash with 400 Bad Request from the Open Secret enclave at /auth/google/callback (shown as "Failed to authenticate with Google. Please try again.").

initiateGoogleAuth decoded the enclave's OAuth state (base64url JSON, no padding), added a sessionId so the callback route could restore the deep link, and re-encoded it with @stablelib/base64, which pads with =. The enclave decodes the returned state with a strict no-padding decoder and then compares it with its stored copy, so any = fails the login.

This worked by accident: the rewritten JSON was 141 bytes (a multiple of 3), so no padding was ever emitted. On 2026-09-21 the enclave started to include redirect_url in the state (Maple repo, services/opensecret/docs/oauth-callbacks.md, which also says clients must return the state unchanged). The rewritten JSON became 193 bytes, the encoder added =, and every Google login broke.

Verified live against the enclave with a bogus code: the unchanged state and the rewritten state without padding both pass the state check (and fail later at Google with 500), while the app's actual rewritten state gets 400 Bad Request.

Fix

  • Return the enclave's auth URL untouched.
  • Keep the deep-link stash in sessionStorage, but key it by the SHA-256 of the verbatim state (the value Google echoes back) instead of a generated session id threaded through the state.
  • The callback route looks the stash up by the state from the URL.

Notes

  • @stablelib/base64 is no longer used by web-wallet (the SDK and e2e still use it). The dependency entry can go in a follow-up.
  • The same fix goes to live in a separate PR (cherry-pick).

Test plan

  • bun run fix:all, bun run typecheck
  • New unit test oauth-login-session-storage.test.ts
  • Google login on next.agi.cash after deploy, including a deep link (/login?redirectTo=... with a token hash)

🤖 Generated with Claude Code

The enclave issues the OAuth `state` as base64url JSON without padding and
rejects any returned state that does not decode with a no-padding decoder
and match its stored copy. initiateGoogleAuth decoded that state, added a
sessionId for the deep-link stash, and re-encoded it with @stablelib/base64,
which pads with `=`. That only worked while the rewritten JSON happened to
be a multiple of 3 bytes; since the enclave added `redirect_url` to the
state on 2026-09-21 every Google login fails with 400 Bad Request.

Return the auth URL untouched and key the sessionStorage stash by the
SHA-256 of the verbatim state instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agicash Ready Ready Preview Sep 25, 2026 8:55am UTC

Request Review

@supabase

supabase Bot commented Sep 25, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project hrebgkfhjpkbxpztqqke because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@jbojcic1
jbojcic1 merged commit 5f50408 into live Sep 25, 2026
5 checks passed
@jbojcic1
jbojcic1 deleted the fix/google-login-oauth-state-live branch September 25, 2026 09:05

This branch was successfully deployed

1 active deployment
Preview — 6a03ee64 Deployed Sep 25, 2026 by vercel[bot]
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