Skip to content

Email OAuth setup (operator)

Register one OAuth app per provider, once. The credentials become platform secrets. Clients never do this — they only click "Connect Gmail/Outlook" and approve their own mailbox.

Callback (redirect) URIs

Environment-derived in apps/api/src/connectors/{gmail,outlook}.ts — must be whitelisted exactly:

ProviderStagingProduction
Gmailhttps://api-sta.kordox.com/api/oauth/gmail/callbackhttps://api.kordox.com/api/oauth/gmail/callback
Outlookhttps://api-sta.kordox.com/api/oauth/outlook/callbackhttps://api.kordox.com/api/oauth/outlook/callback

These are the API domain, not the app.

Gmail — Google Cloud (project kordox)

  1. Enable the Gmail API (APIs & Services → Library).
  2. Google Auth Platform → Clients → create a Web application client (or reuse the Google-login client).
  3. Add the two Gmail redirect URIs above.
  4. Google Auth Platform → Data Access → add scopes: gmail.readonly, gmail.send, gmail.modify, userinfo.email.
  5. Set secrets:
    bash
    cd apps/api
    npx wrangler secret put GMAIL_CLIENT_ID
    npx wrangler secret put GMAIL_CLIENT_SECRET
    # prod: append  --env production

Restricted scopes & verification

gmail.* are restricted scopes.

  • Testing mode (beta): Google Auth Platform → Audience → add Test users. Works immediately, no verification, no live site needed. Up to 100.
  • Production: publish + complete Google verification — needs a live homepage, privacy policy + terms URLs, domain verification, and a demo. A "coming soon" page won't pass. A waitlist form on a real homepage is fine.

Outlook — Microsoft Entra (Azure)

  1. App registrations → New registration. Multi-tenant + personal accounts (code uses the /common endpoint).
  2. Add the two Outlook redirect URIs above (platform: Web).
  3. API permissions → Microsoft Graph → Delegated: Mail.ReadWrite, Mail.Send, User.Read, offline_access → grant admin consent.
  4. Certificates & secrets → New client secret → copy the Value.
  5. Set secrets:
    bash
    cd apps/api
    npx wrangler secret put OUTLOOK_CLIENT_ID
    npx wrangler secret put OUTLOOK_CLIENT_SECRET
    # prod: append  --env production

Notes

  • Until the secrets are set, Connect returns 503 EMAIL_OAUTH_NOT_CONFIGURED.
  • Keep the APP_URL worker var unset — it's the frontend URL and unused for these callbacks (redirect is derived from ENVIRONMENT).
  • Routes: apps/api/src/routes/oauth.ts; connectors: apps/api/src/connectors/{gmail,outlook}.ts; account/send/sync API: apps/api/src/routes/email.ts.

Every project, one cockpit.