Skip to content

fix(web): redirect Google auth through callback#1723

Merged
Uarmagan merged 5 commits intomainfrom
feature/google-auth-redirect
May 6, 2026
Merged

fix(web): redirect Google auth through callback#1723
Uarmagan merged 5 commits intomainfrom
feature/google-auth-redirect

Conversation

@Uarmagan
Copy link
Copy Markdown
Contributor

@Uarmagan Uarmagan commented May 5, 2026

Summary

This PR changes Google authorization in Compass from a popup-based flow to a full-page redirect flow. Both Google sign-in/sign-up and “Connect Google Calendar” now leave Compass through Google and return through /auth/google/callback.

It also deepens the web-side Google authorization module so the redirect start, saved authorization intent, callback completion, scope validation, and return-path handling live behind one clearer module instead of being spread across the callback page and redirect helper files.

The PR also fixes a related local-data issue: seeded demo events are marked as demo-only in browser storage, so they do not get uploaded into a user’s real account when the user later signs in or connects Google.

Why This Changed

The previous Google flow relied on popup behavior and a looser redirect setup. That made the flow harder to reason about and left Compass depending on popup-specific cancellation/error handling.

This branch makes the Google authorization flow explicit:

  • Compass records the user's Google authorization intent before redirecting.
  • Google sends the user back to a dedicated Compass callback page.
  • The callback finishes the saved intent: either Google sign-in/sign-up or connecting Google Calendar.
  • The user is returned to the page they started from when that path is safe, with /day as the fallback.

What Changed

Google authorization now uses a redirect callback

Google authorization now returns through /auth/google/callback.

Before sending the user to Google, Compass stores a short-lived authorization intent in browser session storage. That saved intent says whether the user was trying to sign in with Google or connect Google Calendar from inside an existing session.

When Google redirects back to Compass, the callback flow:

  • checks that the callback belongs to a saved Google authorization attempt
  • rejects missing, expired, corrupt, or unsafe authorization state
  • validates that Google returned the required Calendar permissions
  • routes the result to the correct backend endpoint
  • returns the user to their original Compass page, or /day as a safe fallback
  • shows a recoverable error if the flow cannot be completed

Google authorization is now a deeper web module

The web-side Google authorization behavior now lives under packages/web/src/auth/google/authorization.

That module owns:

  • starting Google authorization through the redirect flow
  • writing and reading the saved Google authorization intent
  • building the callback URL and backend code-exchange payload
  • completing sign-in vs Calendar-connect intents
  • parsing callback failures and Google-connect errors
  • rejecting unsafe return paths such as protocol-relative URLs

The callback page is now a thin loading surface that delegates completion to the module, shows any error, and navigates to the returned path.

Removed stale popup/redirect wrapper code

The old popup-oriented wrapper, misspelled auth config type, and redirect helper folder were removed. Current docs and tests now point at the Google authorization module instead of the deleted redirect helper paths.

Backend now validates the Google redirect URI

The backend derives the expected Google callback URL from the configured frontend URL plus /auth/google/callback.

When exchanging a Google authorization code, the backend rejects requests that do not use that expected callback URL. This keeps the code exchange tied to the Compass instance that initiated the flow.

Calendar connect still syncs local user-created events first

For an existing password-authenticated user connecting Google Calendar, Compass still tries to sync pending local events before redirecting to Google.

After Google returns successfully, Compass connects the Google account, refreshes user metadata, and refetches calendar events so the UI moves into the normal import/sync state.

Demo events are no longer uploaded into real accounts

Seeded demo events are now marked locally in IndexedDB.

That marker is used only in browser storage. When local events are synced into a real account, Compass:

  • uploads user-created local events
  • skips seeded demo events
  • strips the local-only marker before anything is sent to the backend
  • preserves the marker if a user edits a seeded demo event before signing in

This prevents sample events from becoming real account data.

Docs were updated

The docs now describe the redirect-based Google flow, the new callback URL, and the current module locations.

Updated areas include:

  • auth acceptance notes
  • Google sync acceptance notes
  • password auth flow docs
  • frontend runtime docs
  • self-hosted Google Calendar setup docs
  • feature file map
  • domain language around Google authorization intent

Validation

  • bun test src/auth/google/authorization/google-authorization.test.ts src/auth/google/authorization/google-authorization.storage.test.ts src/auth/google/authorization/google-authorization.util.test.ts src/auth/google/util/google.auth.util.test.ts src/views/GoogleAuthCallback/GoogleAuthCallback.test.ts src/components/AuthModal/AuthModal.test.tsx from packages/web — 61 passed
  • bun run type-check
  • bunx biome check docs/development/feature-file-map.md packages/web/src/auth/google/authorization packages/web/src/auth/google/hooks/useConnectGoogle/useConnectGoogle.ts packages/web/src/auth/google/util/google.auth.util.ts packages/web/src/auth/google/util/google.auth.util.test.ts packages/web/src/views/GoogleAuthCallback/GoogleAuthCallback.tsx packages/web/src/views/GoogleAuthCallback/GoogleAuthCallback.test.ts packages/web/src/components/AuthModal/AuthModal.tsx packages/web/src/components/AuthModal/AuthModal.test.tsx packages/web/src/__tests__/__mocks__/mock.setup.ts
  • bunx playwright test e2e/oauth/google-auth-callback.spec.ts --project=chromium-desktop — 4 passed
  • git diff --check

@Uarmagan Uarmagan marked this pull request as ready for review May 6, 2026 16:30
@Uarmagan Uarmagan merged commit 88a0a90 into main May 6, 2026
9 checks passed
@Uarmagan Uarmagan deleted the feature/google-auth-redirect branch May 6, 2026 16:31
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.

1 participant