feat(data-warehouse): generic OAuth flow starter for inbox sources#3613
Merged
Conversation
Generalize the inbox OAuth connect flow so any PostHog-supported OAuth integration kind works without provider-specific code. `DynamicSourceSetup` already renders `oauth` and `oauth-account-select` fields generically (account listing + server-side resource search); the only provider-specific gate was the flow starter, which hardcoded `kind === "linear"`. PostHog's `…/integrations/authorize/?kind=<kind>` endpoint is already generic, so this adds a kind-parameterized `IntegrationService` + `integration` tRPC router and points the OAuth field's connect button at it via `field.kind`. Result: adding an OAuth warehouse source (Intercom, HubSpot, Salesforce, Stripe, ad platforms, …) needs no bespoke setup form or per-kind router — just the source's registry entry, whose connect-form schema already carries the oauth field and kind.
|
😎 Merged successfully - details. |
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
This was referenced Jul 21, 2026
Merged
The HostRouter type declares an `integration` route, but the desktop app's trpcRouter assembly did not serve it, tripping the servesEveryHostRoute compile-time guard and failing typecheck. Generated-By: PostHog Code Task-Id: 9fd73e57-6627-4884-bb0e-953cc4fa6b33
Generated-By: PostHog Code Task-Id: 9fd73e57-6627-4884-bb0e-953cc4fa6b33
There was a problem hiding this comment.
The gates denied this PR because it touches OAuth/auth flows, which are in the deny-list. Additionally, the new router uses ctx.container.get<IntegrationService>(INTEGRATION_SERVICE) — a service-locator call inside a router that is explicitly forbidden by the project's architecture rules. This PR needs a human review before it can be merged.
MarconLP
approved these changes
Jul 21, 2026
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.
Problem
Adding an OAuth-based warehouse source to the Self-driving inbox appeared to require a bespoke
setup form + a per-provider integration service and router. It doesn't —
DynamicSourceSetupalready renders
oauthandoauth-account-selectfields generically (integration/accountlisting via
getIntegrationsForProject, server-side resource search). The only thing gatingarbitrary providers was the flow starter:
OAuthSourceField.startFlowhardcodedfield.kind === "linear"and threw for anything else.Changes
Make the connect flow generic over the integration
kind:core/integrations/integration.ts— a kind-parameterizedIntegrationService.startFlow(kind, region, projectId)that launches PostHog's already-generic…/integrations/authorize/?kind=<kind>endpoint (the Linear service is the template; onlykindwas ever provider-specific).core/integrations/schemas.ts—startGenericIntegrationFlowInput(addskind); the per-kind linear/slack/github inputs are untouched.core/integrations/identifiers.ts+integrations.module.ts— bindINTEGRATION_SERVICE.host-router/src/routers/integration.router.ts— a genericintegration.startFlowtRPC route, registered inappRouter.ui/.../DynamicSourceSetup.tsx—OAuthSourceFielddrops the linear-only branch and calls the generic starter withfield.kind(Linear keeps working: same authorize URL).After this, any OAuth warehouse source PostHog supports (Intercom, HubSpot, Salesforce, Stripe,
the ad platforms, …) connects through the generic form with no provider-specific UI code —
just the source's registry entry, whose connect-form schema already carries the oauth field/kind.
How did you test this?
integration.test.ts(authorize URL per kind, url-encoding, failure path).turbo typecheckfor@posthog/core,@posthog/host-router,@posthog/ui— pass.biome checkon all changed files — clean.Follow-ups that build on this: Intercom + HubSpot backend emitters (PostHog/posthog) and their
inbox registry entries (a separate
codePR).