Skip to content

feat(web): use sync redirect flow for Google connect when delegated#2355

Merged
tyler-dane merged 1 commit into
mainfrom
feat/web-connect-delegation-clean
Jul 24, 2026
Merged

feat(web): use sync redirect flow for Google connect when delegated#2355
tyler-dane merged 1 commit into
mainfrom
feat/web-connect-delegation-clean

Conversation

@tyler-dane

@tyler-dane tyler-dane commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What

Completes web connect-delegation for Compass Sync (S38). When a deployment delegates Google connections to the sync service, the "connect Google Calendar" action now uses the redirect flow instead of the legacy client-side code-exchange:

  1. POST /api/auth/google/connect/begin{ authorizationUrl }
  2. window.location.assign(authorizationUrl) — the sync service owns the OAuth round-trip and its own callback.

The browser learns the deployment posture from google.connectDelegatedToSync on GET /api/config (merged in #2354).

Legacy stays the default whenever the flag is false or not-yet-loaded, so existing deployments are unchanged.

How

  • AuthApi.beginGoogleConnection()POST /auth/google/connect/begin, parses ConnectionBeginResponse.
  • useIsConnectDelegatedToSync() — reads the flag from the same /config fetch that already drives Google availability (single source of truth, no extra network call).
  • useConnectGoogle branches on the flag; a begin failure shows an error toast and does not navigate.

Fail-safe design

  • The delegation flag defaults to false until /config resolves, and by the time the connect button is available the config has loaded (availability is gated on the same fetch). So the flag is accurate at click time, and any race falls back to legacy.
  • Only the connect path (intent connectCalendar, already-authenticated) is affected. Sign-in is untouched.

Deployment prerequisites (for when delegation is actually switched on)

  • The sync service's /oauth/google/callback must be publicly reachable by Google.
  • Sync must be in ACTIVE execution mode (begin returns 409 in passive mode).

Neither blocks this PR — the redirect flow is dormant until SYNC_CONNECTION_ROUTING=sync.

Testing

  • useIsConnectDelegatedToSync tests: flag reflected from config; stays legacy when the field is absent (older backend).
  • bun test src/auth/google/ src/components/CommandPalette/ → 109 pass.
  • bun run type-check: zero new errors vs origin/main (set-difference against pre-existing local baseline).
  • Lint clean via pinned biome.

Manual Testing Steps

  1. Default deployment (/api/configconnectDelegatedToSync: false): connect Google → legacy popup/code flow (unchanged).
  2. Delegated deployment (connectDelegatedToSync: true): connect Google → browser navigates to the sync-minted consent URL.
  3. Delegated deployment with sync unreachable: connect Google → error toast, no navigation.

🤖 Generated with Claude Code


Note

Medium Risk
OAuth connect behavior changes for delegated deployments; legacy remains the default until config confirms delegation, limiting blast radius.

Overview
When google.connectDelegatedToSync is true on /api/config, Connect Google Calendar no longer runs the legacy popup/code-exchange flow. It calls POST /auth/google/connect/begin, then window.location.assign(authorizationUrl) so the sync service owns OAuth; failures show a dedicated error toast and do not navigate.

useIsConnectDelegatedToSync reads that flag from the same /config fetch as Google availability (defaults to false until loaded or if the field is missing). AuthApi.beginGoogleConnection wraps the begin endpoint with ConnectionBeginResponse parsing.

Repair/sign-in paths are unchanged; only the authenticated connect action branches.

Reviewed by Cursor Bugbot for commit ce03bb6. Bugbot is set up for automated code reviews on this repo. Configure here.

When the deployment delegates Google connections to the sync service
(google.connectDelegatedToSync on /api/config), the connect action now
asks the backend for the provider consent URL via
POST /api/auth/google/connect/begin and navigates the browser there,
instead of the legacy client-side code-exchange popup flow. Legacy stays
the default whenever the flag is false or unknown.

- AuthApi.beginGoogleConnection(): POST /auth/google/connect/begin.
- useIsConnectDelegatedToSync(): reads the flag from the same /config
  fetch that drives Google availability (single source of truth).
- useConnectGoogle branches on it; begin failure shows an error toast.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tyler-dane
tyler-dane merged commit 286b23d into main Jul 24, 2026
19 checks passed
@tyler-dane
tyler-dane deleted the feat/web-connect-delegation-clean branch July 24, 2026 04:36
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