Skip to content

fix: improve region handling in OAuth login flow and persistent cache#91

Merged
volnei merged 7 commits into
mainfrom
fix/cache-isolation-by-region
May 19, 2026
Merged

fix: improve region handling in OAuth login flow and persistent cache#91
volnei merged 7 commits into
mainfrom
fix/cache-isolation-by-region

Conversation

@pedroccastro
Copy link
Copy Markdown
Contributor

What does this PR do?

Improves region handling across the OAuth login flow and the React Query persistent cache.

loginWithOAuth now constructs CalComOAuthService directly from the current region at call time instead of reading from React state, ensuring the correct OAuth endpoint is always used when the user logs in.

The React Query persister storage key now includes the active region (cal-companion-query-cache-us / cal-companion-query-cache-eu), scoping cached data per region.

Also fixes removeClient referencing an undefined variable and replaces console.warn with safeLogWarn.

Changes

File Change
utils/queryPersister.ts Append active region to storage key; fix removeClient referencing an undefined variable
contexts/AuthContext.tsx Build CalComOAuthService from current region at loginWithOAuth call time instead of reading React state

How should this be tested?

  1. Select EU region on login screen and complete OAuth — confirm the flow goes through app.cal.eu
  2. Select US region — confirm the flow goes through app.cal.com
  3. Log in as a US user, log out, log in as an EU user — confirm each session has its own independent cache

Mandatory Tasks

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A I have updated the developer docs in /docs if this PR makes changes that would require a documentation change.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

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

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
cal-companion-chat Ignored Ignored May 19, 2026 9:04pm
cal-companion-mcp Ignored Ignored May 19, 2026 9:04pm

Request Review

@pedroccastro pedroccastro marked this pull request as ready for review May 19, 2026 19:18
devin-ai-integration[bot]

This comment was marked as resolved.

@pedroccastro pedroccastro marked this pull request as draft May 19, 2026 19:21
cubic-dev-ai[bot]

This comment was marked as resolved.

@pedroccastro pedroccastro marked this pull request as ready for review May 19, 2026 19:27
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

devin-ai-integration[bot]

This comment was marked as resolved.

@pedroccastro pedroccastro marked this pull request as draft May 19, 2026 20:06
@pedroccastro pedroccastro marked this pull request as ready for review May 19, 2026 20:33
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Re-trigger cubic

@volnei volnei merged commit 80f7771 into main May 19, 2026
14 checks passed
devin-ai-integration Bot added a commit that referenced this pull request May 19, 2026
PR #91 migrated the persisted cache to a region-suffixed key
(`cal-companion-query-cache-{region}`). Users upgrading from before
that change still have the pre-migration unsuffixed key
(`cal-companion-query-cache`) on disk, which is now never read.
Without cleanup, it lingers forever and the per-user expiry sweep never
runs against it.

Add a one-line removeItem for the legacy key inside restoreClient. Runs
on every restore; removeItem on a missing key is a no-op so the cost
after the first cleanup is negligible.
dhairyashiil added a commit that referenced this pull request May 19, 2026
* fix(auth): isolate user data across logout and cold-start transitions

Eliminates cross-user data leaks in the mobile/web/extension app by
plugging gaps in the logout cleanup and persisted-cache rehydration flow.

- AuthContext.logout() now clears the in-memory QueryClient (A1) so the
  next login does not flash the previous user's userProfile, eventTypes,
  bookings, or schedules under staleTime: Infinity + refetchOnMount: false.
- AuthContext.logout() now calls clearWidgetBookings() (A3) so the iOS /
  Android home-screen widget does not keep showing the signed-out user's
  meetings.
- AuthContext.logout()'s clearAuth() step is wrapped in its own try/catch
  (A5) so a SecureStore failure no longer skips region/cache/widget
  cleanup and leaves a zombie session with isAuthenticated still true.
- useWidgetSync no longer fires syncBookingsToWidget on mount when
  isAuthenticated is false (A6), preventing an unauthenticated /bookings
  fallback during cold start before tokens are loaded.
- queryPersister.restoreClient checks for cal_oauth_tokens OR cal_auth_type
  before rehydrating (A2 pt 1); if neither is present the orphaned cache
  is wiped so a previously-logged-in user's data is never restored into a
  logged-out cold start. Checking both keys covers the web-session login
  path that writes cal_auth_type without OAuth tokens.
- setupAfterLogin compares the rehydrated userProfile.id to the just-
  fetched profile and wipes both in-memory and persisted caches on a
  mismatch (A2 pt 2).

* fix(persister): sweep pre-region-suffix cache key on every restore

PR #91 migrated the persisted cache to a region-suffixed key
(`cal-companion-query-cache-{region}`). Users upgrading from before
that change still have the pre-migration unsuffixed key
(`cal-companion-query-cache`) on disk, which is now never read.
Without cleanup, it lingers forever and the per-user expiry sweep never
runs against it.

Add a one-line removeItem for the legacy key inside restoreClient. Runs
on every restore; removeItem on a missing key is a no-op so the cost
after the first cleanup is negligible.

* fix(auth): drop stale user-profile singleton before post-login refetch

CalComAPIService.getUserProfile() is backed by a module-level singleton
(`_userProfile` in services/calcom/user.ts). If the JS context survives
between logout and the next login — long-lived extension iframe, rapid
re-login, or a future in-session account switch — the singleton can still
hold the previous user's profile and getUserProfile() will hand it back
without touching the API. The downstream identity-mismatch check would
then see two matching ids and silently pass.

Clearing the singleton between setAccessToken and getUserProfile forces a
fresh fetch tied to the just-installed access token, so identity
detection sees the true new-user profile.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.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