Extract OAuth2 flows from OpenAPI security schemes#250
Merged
RhysSullivan merged 6 commits intomainfrom Apr 15, 2026
Merged
Conversation
Generic provider-agnostic helpers for PKCE, authorization URL building, code exchange, refresh, and the refresh-skew predicate. Locks every real-world quirk the prior google-discovery oauth.ts handled (string expires_in, error_description fallback chain, non-JSON 5xx bodies, empty access_token, 20s timeout, body vs Basic client auth) into a 33-test fidelity suite so future cleanups fail loudly instead of silently breaking refresh. Ports google-discovery to use the shared helpers via a thin wrapper that preserves Google-only authorization params (access_type=offline, prompt=consent, include_granted_scopes=true) through the extraParams escape hatch. All existing google-discovery tests still pass.
4 tasks
Owner
Author
This was referenced Apr 15, 2026
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | 99784f0 | Commit Preview URL | Apr 15 2026, 06:52 AM |
@executor/sdk
@executor/plugin-file-secrets
@executor/plugin-google-discovery
@executor/plugin-graphql
@executor/plugin-keychain
@executor/plugin-mcp
@executor/plugin-oauth2
@executor/plugin-onepassword
@executor/plugin-openapi
@executor/plugin-workos-vault
commit: |
967f538 to
f9f845a
Compare
b100de4 to
61810ab
Compare
f9f845a to
ddab854
Compare
61810ab to
0ad06ea
Compare
Split the package into three entrypoints (`.`, `/http`, `/react`) so browser consumers do not pull Node crypto. New surface: - `OAuthPopupResult<TAuth>` + `isOAuthPopupResult` in a shared types module so both the server-side HTML generator and the client-side popup opener agree on the message shape. - `/http` entry: `popupDocument(payload, channelName)` HTML generator (with XSS-safe serialization, dark-mode CSS, postMessage + BroadcastChannel fallback), and `runOAuthCallback` wrapper that turns a `completeOAuth` Effect into the HTML body for the redirect route. - `/react` entry: `openOAuthPopup` browser util with centered-popup math, same-origin message filtering, settle-once semantics, and popup-blocked detection. Ports `google-discovery` to use them: `api/handlers.ts` drops its inline `popupDocument` / OAuth glue and becomes a ~20-line handler, and `AddGoogleDiscoverySource.tsx` drops its inline `openOAuthPopup`. 20 new fidelity tests lock every behavior (XSS escaping, channel name escape, origin filtering, settle-once across both channels, popup block handling).
Generic helpers that take a secrets-I/O adapter and a `persistAuth` callback so plugins can transparently refresh access tokens before a request without re-implementing the ~150-line token-rotation dance. - `storeOAuthTokens`: persist a fresh OAuth2TokenResponse as new access and (optionally) refresh-token secrets via a `createSecret` callback and return a `StoredOAuthTokens` descriptor ready to write to a source config. - `withRefreshedAccessToken`: check `shouldRefreshToken`, resolve client/refresh credentials from secrets, call `refreshAccessToken`, overwrite the access-token secret in place, optionally rotate the refresh-token secret, invoke `persistAuth` with the updated snapshot, and return the current access token to be injected into the request. Ports `google-discovery`: - `completeOAuth` drops its manual `storeSecret` dance (now a ~15 line call to `storeOAuthTokens`). - `invoke.ts`'s `resolveOAuthAccessToken` shrinks from ~150 lines of secret-resolution + refresh + persist glue to ~75 lines of adapter. - The google-discovery-local `refreshAccessToken` wrapper is removed (unused after the port); the google token URL is exported so the invoker can pass it to the shared helper. 12 new fidelity tests lock in every branch (no refresh, refresh within skew, rotated refresh token, preserved refresh token, null refresh ID, public client without client_secret, secret-resolve failure wrapping).
Exposes the `flows` object on `components.securitySchemes` through the preview pipeline so the onboarding UI can offer an OAuth2 path for any spec that declares one. Previously we detected `type: oauth2` but silently dropped the flow metadata, leaving users to paste a bearer token manually. Schema additions: - `OAuth2AuthorizationCodeFlow`, `OAuth2ClientCredentialsFlow`, and `OAuth2Flows` classes capturing `authorizationUrl`, `tokenUrl`, `refreshUrl`, and `scopes` per flow. `implicit` and `password` are intentionally excluded — both are deprecated by OAuth 2.1 and adding them would only encourage users to onboard onto them. - `SecurityScheme` now carries `flows`, `bearerFormat`, and `openIdConnectUrl` (previously dropped). - `OAuth2Preset` class — one entry per (scheme × flow) pair with the label, URLs, and scope map the onboarding UI needs to render a "Connect via OAuth2" flow with a scope checklist. - `SpecPreview.oauth2Presets` carries the derived presets. Extraction: - `extractSecuritySchemes` now takes a `DocResolver` and resolves `$ref` entries instead of silently dropping them. Specs that alias their security schemes through `components.securitySchemes` refs (rare but real) now surface correctly. - `extractFlows` tolerates malformed flows (missing `tokenUrl` / `authorizationUrl`) by dropping them, so a broken flow does not prevent the rest of the spec from previewing. 5 new tests cover authorizationCode + clientCredentials extraction, the `$ref` resolution path, `bearerFormat` / `openIdConnectUrl` capture, and the malformed-flow ignore case.
0ad06ea to
ef43334
Compare
ddab854 to
12433ef
Compare
Owner
Author
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.

Exposes the
flowsobject oncomponents.securitySchemesthrough thepreview pipeline so the onboarding UI can offer an OAuth2 path for any
spec that declares one. Previously we detected
type: oauth2butsilently dropped the flow metadata, leaving users to paste a bearer
token manually.
Schema additions:
OAuth2AuthorizationCodeFlow,OAuth2ClientCredentialsFlow, andOAuth2Flowsclasses capturingauthorizationUrl,tokenUrl,refreshUrl, andscopesper flow.implicitandpasswordareintentionally excluded — both are deprecated by OAuth 2.1 and adding
them would only encourage users to onboard onto them.
SecuritySchemenow carriesflows,bearerFormat, andopenIdConnectUrl(previously dropped).OAuth2Presetclass — one entry per (scheme × flow) pair with thelabel, URLs, and scope map the onboarding UI needs to render a
"Connect via OAuth2" flow with a scope checklist.
SpecPreview.oauth2Presetscarries the derived presets.Extraction:
extractSecuritySchemesnow takes aDocResolverand resolves$refentries instead of silently dropping them. Specs that aliastheir security schemes through
components.securitySchemesrefs(rare but real) now surface correctly.
extractFlowstolerates malformed flows (missingtokenUrl/authorizationUrl) by dropping them, so a broken flow does notprevent the rest of the spec from previewing.
5 new tests cover authorizationCode + clientCredentials extraction,
the
$refresolution path,bearerFormat/openIdConnectUrlcapture, and the malformed-flow ignore case.