fix: persist region in secureStorage alongside OAuth tokens to prevent cross-instance auth#90
Closed
anikdhabal wants to merge 1 commit into
Closed
fix: persist region in secureStorage alongside OAuth tokens to prevent cross-instance auth#90anikdhabal wants to merge 1 commit into
anikdhabal wants to merge 1 commit into
Conversation
…t cross-instance auth On iOS, SecureStore (Keychain) persists across app reinstalls but AsyncStorage does not. When the region was only stored in AsyncStorage, a reinstall (or AsyncStorage corruption) would lose the region while the OAuth tokens survived in SecureStore, defaulting API calls to cal.com instead of cal.eu. If two users on different instances share the same numeric user ID (e.g. 82126), the app would authenticate to the wrong instance and return the wrong user's data. Changes: - Store current region in secureStorage (AUTH_REGION_KEY) whenever OAuth tokens or web-session auth state are saved - On boot, restore the region from secureStorage before preloadRegion() so the authoritative region is never lost - Clear AUTH_REGION_KEY on logout alongside other auth state - Scope the persisted query cache key by region as defense-in-depth - Clear in-memory query cache on region change to prevent stale cross-region data Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a critical security vulnerability where a cal.eu user could accidentally see another user's data from cal.com when both users share the same numeric user ID (82126).
Root cause: On iOS, OAuth tokens are stored in
SecureStore(Keychain), which persists across app reinstalls, but the region (US/EU) is stored inAsyncStorage, which does not persist across reinstalls. After a reinstall or AsyncStorage corruption, the tokens survive while the region defaults to "us", routing all API calls toapi.cal.cominstead ofapi.cal.eu— returning a completely different user's data.Primary fix: Store the region in
secureStoragealongside the OAuth tokens (cal_auth_regionkey). On boot, restore the region from secureStorage beforepreloadRegion()so the authoritative region is never lost, regardless of AsyncStorage state.Defense-in-depth: Scope the persisted query cache key by region (
cal-companion-query-cache-us/cal-companion-query-cache-eu) and clear the in-memory query cache on region change.Changes
AuthContext.tsx:AUTH_REGION_KEYstored in secureStorage alongside tokens on login (both OAuth and web session)preloadRegion()AUTH_REGION_KEYon logout alongside other auth statequeryPersister.ts: Scope persisted cache storage key by region; clear legacy unscoped key on cache clearQueryContext.tsx: Subscribe to region changes and clear in-memory query cache when region changesReview & Testing Checklist for Human
api.cal.eu(notapi.cal.com)cal_auth_regionis written to SecureStore with the correct value ("us" or "eu")cal_auth_regionis removed from SecureStore and the login screen region picker appearschrome.storage.local(same persistence), so no change in behavior expected — but verify the sidebar still loads correctlyNotes
cal_auth_regionin secureStorage will fall through to the existingpreloadRegion()path (backward compatible)Link to Devin session: https://app.devin.ai/sessions/0e094b9d77cc4b6ebf523ce7ef4ef1f4
Requested by: @anikdhabal
Summary by cubic
Fixes cross-instance auth on iOS by persisting the region (US/EU) in secure storage with OAuth tokens and scoping query caches by region. Prevents users from being routed to the wrong API after app reinstalls or storage corruption.
secureStorage(cal_auth_region) when storing OAuth or web-session auth; restore it on boot beforepreloadRegion().cal_auth_regionon logout with other auth keys.Written for commit 1be585b. Summary will update on new commits. Review in cubic