Skip to content

feat: add EU region support to companion apps#80

Draft
PeerRich wants to merge 1 commit intomainfrom
devin/1776355396-eu-region-support
Draft

feat: add EU region support to companion apps#80
PeerRich wants to merge 1 commit intomainfrom
devin/1776355396-eu-region-support

Conversation

@PeerRich
Copy link
Copy Markdown
Member

Summary

Enables cal.eu alongside cal.com across the companion mobile app and browser extension. Users pick a data region on the login screen; from that point onward the app uses region-scoped OAuth, API, and deep-link hosts.

Mobile app

  • New apps/mobile/utils/region.ts — persists us/eu in generalStorage, exposes synchronous getRegion(), async setRegion()/preloadRegion(), a subscribeRegion() listener, and helpers getCalAppUrl() / getCalApiUrl() / getCalWebUrl() plus a CAL_APP_HOSTNAMES set for host checks.
  • LoginScreen.tsx — adds a "Data region" dropdown (United States / European Union), preloads the region on mount, subscribes to changes, and makes the "Sign up" link region-aware.
  • AuthContext.tsx — preloads the region on app startup and recreates the OAuth service whenever the region changes so subsequent authorization flows target the correct cal.{com|eu}.
  • oauthService.tscalcomBaseUrl now comes from getCalAppUrl(region). Each browser's OAuth config (iOS WebAuth, Firefox, Safari, Edge) reads region-scoped env vars (..._EU variants) with fallback to the US values.
  • services/calcom/request.ts — replaces the hardcoded API_BASE_URL with getApiBaseUrl() so every authenticated API call routes to api.cal.com or api.cal.eu.
  • Deep links, in-app browser, WebAuth callbacks, profile sheet, and the More tab — now recognize both app.cal.com and app.cal.eu hosts and build URLs from getCalAppUrl().

Extension

  • wxt.config.ts — adds https://app.cal.eu/* and https://api.cal.eu/* to host_permissions and plumbs EU OAuth env vars (base + Firefox/Safari/Edge variants) into the Vite define so the mobile code running in the iframe can read them.
  • entrypoints/content.ts + entrypoints/background/index.ts — the iframe forwards the selected region alongside OAuth tokens on sync; the background persists it in extension storage and derives its API_BASE_URL per-request so validateTokens, fetchEventTypes, getBookingStatus, and markAttendeeNoShow all hit the correct regional API. Clearing tokens also clears the stored region.

New env vars (unset = fall back to the US values):

  • EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID_EU
  • EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI_EU
  • ..._FIREFOX_EU, ..._SAFARI_EU, ..._EDGE_EU variants

Review & Testing Checklist for Human

  • Provision the EXPO_PUBLIC_CALCOM_OAUTH_*_EU env vars in the deployment / extension build pipeline before shipping; without them EU users silently fall back to the US client IDs and the redirect to app.cal.eu will fail.
  • End-to-end login as a US user: verify OAuth still redirects through app.cal.com, tokens are minted against api.cal.com, and post-login API calls go to api.cal.com.
  • End-to-end login as an EU user: pick "European Union" on the login screen, verify OAuth redirects through app.cal.eu, tokens are minted against api.cal.eu, and post-login API calls go to api.cal.eu (check Network tab / extension service worker logs).
  • Region switching: log out, switch region, log back in — confirm the OAuth service is recreated and the new region sticks across app restarts.
  • Extension: with an EU session active, confirm validateTokens succeeds on app resume (would fail silently if it still hit api.cal.com) and that fetch-event-types / getBookingStatus return EU data.
  • Extension "Delete Account" and other openInAppBrowser deep links point at the correct host for the selected region.

Notes

  • cal.com/help/... and cal.com/roadmap marketing URLs are intentionally left on .com (not region-scoped content).
  • Icon/image URLs served off app.cal.com in locationHelpers.ts, defaultLocations.ts, and getAppIconUrl.ts are also left alone — they're public static assets and not part of the auth/API surface. Happy to make them region-aware in a follow-up if the EU CDN serves the same paths.
  • PR is slightly over the 10-file soft limit (18 files) because region plumbing is a cross-cutting change; splitting it would leave the app in half-migrated states. Most files are small host-substitution edits.

Link to Devin session: https://app.devin.ai/sessions/ed4320aeeb174166b9bd2c995f9ec364
Requested by: @PeerRich

Adds a Region Select (US / EU) to the mobile login screen and routes OAuth
redirects, API calls, and deep links to the correct regional host
(app.cal.com + api.cal.com vs app.cal.eu + api.cal.eu) based on the user's
selection. The extension's host_permissions and background API_BASE_URL are
also region-aware; the selected region is synced from the iframe alongside
OAuth tokens so validateTokens + all background API calls hit the correct
regional endpoint.

Co-Authored-By: peer@cal.com <peer@cal.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

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