Accounts Phase 2: Google sign-in (OAuth 2.0 / OIDC)

- oauth_google.py (stdlib): PKCE, auth URL, code exchange, ID-token claim
  validation (iss/aud/exp/email_verified — token comes straight from Google's
  token endpoint over TLS, so no signature re-verify / JWKS needed).
- API: GET /api/auth/google/start (302 to Google, PKCE + signed state cookie
  binding the flow to the browser) and /callback (CSRF-checked state, exchange,
  find-or-create by verified email → links to an existing magic-link account,
  session cookie, redirect home). Errors land on /auth/verify?error=google.
- SignIn modal: "Continue with Google" + an "or email link" divider.
- 112 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-03 01:31:52 +00:00
parent 28dc79d0b7
commit b635d8f574
5 changed files with 280 additions and 5 deletions
+7 -1
View File
@@ -7,7 +7,13 @@
let error = $state('');
onMount(async () => {
const token = new URLSearchParams(window.location.search).get('token');
const params = new URLSearchParams(window.location.search);
if (params.get('error') === 'google') {
status = 'error';
error = "Google sign-in didn't complete. Please try again.";
return;
}
const token = params.get('token');
if (!token) {
status = 'error';
error = 'This sign-in link is missing its token.';