History

Registry auth for OpenAPI and preset add flows; product-key matching

GitHub's official OpenAPI description declares no securitySchemes, so the add flow offered OAuth (from the preset template) and nothing else, while a PAT bearer header is how most calls actually authenticate. The registry's declared placement now seeds an API key method alongside detected OAuth; a spec-declared key method still wins over the registry's version of the same fact. Preset-to-catalog matching moves from rendered titles to a product key (normalized name plus kind), so 'GitHub REST' and the registry's 'GitHub API' count as one product — titles and domains both proved unreliable joins. MCP surfaces carry their auth facts too.

Rhys Sullivan committed 2 months ago

Commit 97c4ef41 parent d3acfe32 files · +50 −16Browse files

Showing the changes to packages/plugins/openapi/src (1 of 2 files). Show all

Unified · Split

packages/plugins/openapi/src/react/AddOpenApiIntegration.tsx+21−2
@@ -25,6 +25,7 @@ import { · 24 unmodified lines
25 type AuthMethodRow,25 type AuthMethodRow,
26 type AuthMethodSeed,26 type AuthMethodSeed,
27} from "@executor-js/react/components/auth-method-list-editor";27} from "@executor-js/react/components/auth-method-list-editor";
28import { placementFromHeaderPattern } from "@executor-js/react/lib/auth-placements";
28import { CardStack, CardStackContent } from "@executor-js/react/components/card-stack";29import { CardStack, CardStackContent } from "@executor-js/react/components/card-stack";
29import { FieldLabel } from "@executor-js/react/components/field";30import { FieldLabel } from "@executor-js/react/components/field";
30import { FloatActions } from "@executor-js/react/components/float-actions";31import { FloatActions } from "@executor-js/react/components/float-actions";
@@ -170,6 +171,8 @@ export default function AddOpenApiIntegration(props: { · 139 unmodified lines
170 initialUrl?: string;171 initialUrl?: string;
171 initialPreset?: string;172 initialPreset?: string;
172 initialNamespace?: string;173 initialNamespace?: string;
174 initialAuthHeader?: string;
175 initialAuthNote?: string;
173}) {176}) {
174 const integrationPlugins = useIntegrationPlugins();177 const integrationPlugins = useIntegrationPlugins();
175 const openApiPlugin = integrationPlugins.find((plugin) => plugin.key === "openapi");178 const openApiPlugin = integrationPlugins.find((plugin) => plugin.key === "openapi");
@@ -297,14 +300,26 @@ export default function AddOpenApiIntegration(props: { · 121 unmodified lines
297 ...(preview?.headerPresets ?? []).map((preset) => preset.label),300 ...(preview?.headerPresets ?? []).map((preset) => preset.label),
298 ...(preview?.oauth2Presets ?? []).map((preset) => preset.label),301 ...(preview?.oauth2Presets ?? []).map((preset) => preset.label),
299 ];302 ];
300 return authenticationTemplate.map(303 const detected = authenticationTemplate.map(
301 (template: Authentication, index: number): AuthMethodSeed => ({304 (template: Authentication, index: number): AuthMethodSeed => ({
302 value: editorValueFromAuthentication(template),305 value: editorValueFromAuthentication(template),
303 slug: String(template.slug),306 slug: String(template.slug),
304 ...(labels[index] !== undefined ? { label: labels[index] } : {}),307 ...(labels[index] !== undefined ? { label: labels[index] } : {}),
305 }),308 }),
306 );309 );
307 }, [preview, authenticationTemplate]);310 if (preview === null) return detected;
311 // The registry's declared credential placement fills what the document
312 // leaves out. GitHub's official description famously declares no
313 // securitySchemes at all, and even with the OAuth preset template a PAT
314 // bearer header is how most calls actually authenticate — so the key
315 // method is offered alongside OAuth. A spec-declared key method wins over
316 // the registry's version of the same fact.
317 const placement = props.initialAuthHeader
318 ? placementFromHeaderPattern(props.initialAuthHeader)
319 : null;
320 if (!placement || detected.some((seed) => seed.value.kind === "apikey")) return detected;
321 return [...detected, { value: { kind: "apikey", placements: [placement] } }];
322 }, [preview, authenticationTemplate, props.initialAuthHeader]);
308 const authMethodList = useAuthMethodList(authMethodSeeds);323 const authMethodList = useAuthMethodList(authMethodSeeds);
309 324
310 // The methods to register, mapped back to stored `Authentication[]`. Drops325 // The methods to register, mapped back to stored `Authentication[]`. Drops
@@ -601,6 +616,10 @@ export default function AddOpenApiIntegration(props: { · 290 unmodified lines
601 />616 />
602 )}617 )}
603 618
619 {preview && props.initialAuthNote ? (
620 <p className="text-xs leading-relaxed text-muted-foreground">{props.initialAuthNote}</p>
621 ) : null}
622
604 {preview ? (623 {preview ? (
605 <AddOpenApiHealthCheckSection624 <AddOpenApiHealthCheckSection
606 presetHealthCheck={activePreset?.healthCheck}625 presetHealthCheck={activePreset?.healthCheck}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t