125 lines · 5.6 KB · TypeScript
RawDownload
// The DCR root-domain collision at the picker-classification level (issue #1120).//// Two DIFFERENT integrations share one registrable root domain (cloudflare.com)// but differ by host: a "Cloudflare" MCP integration whose OAuth is on// mcp.cloudflare.com, and the plain "Cloudflare" REST integration on// api.cloudflare.com. Connecting the MCP integration Dynamic-Client-Registers an// oauth_client (origin: dynamic_client_registration) against mcp.cloudflare.com.//// The regression PR #1139 missed: that auto-registered client leaking into the// REST integration's Add-connection app picker. The existing unit tests in// use-effective-oauth-client.test.ts check DCR exclusion and root-domain tiering// one picker at a time; this file asserts the CROSS-INTEGRATION property those// don't: the MCP integration's DCR client is offered in NONE of the REST// integration's picker tiers, yet stays visible in the MCP integration's own// auto-registered management list. It runs the exact pure classifier the app// (add-account-modal.tsx via useOAuthClientsForIntegration) uses to build the// picker, so it guards the shipped behaviour, not a reimplementation.//// The server-side half (that DCR actually mints this row over the wire and// reuses it on reconnect) is covered by e2e/cloud/dcr-root-domain-isolation.test.ts.import { describe, expect, it } from "@effect/vitest";import { IntegrationSlug, OAuthClientSlug, type Owner } from "@executor-js/sdk/shared";import type { OAuthClientOrigin } from "@executor-js/sdk/shared"; import {  selectClientsForEndpoints,  selectDcrClientsForIntegration,  type OAuthClientOption,} from "./use-effective-oauth-client"; const client = (  slug: string,  opts: {    readonly owner?: Owner;    readonly authorizationUrl: string;    readonly tokenUrl: string;    readonly origin: OAuthClientOrigin;  },): OAuthClientOption => ({  owner: opts.owner ?? "org",  slug: OAuthClientSlug.make(slug),  grant: "authorization_code",  authorizationUrl: opts.authorizationUrl,  tokenUrl: opts.tokenUrl,  clientId: "client-id",  origin: opts.origin,}); const MCP_INTEGRATION = IntegrationSlug.make("cloudflare_mcp");const REST_INTEGRATION = IntegrationSlug.make("cloudflare_api"); // The auto-registered client the MCP connect flow mints, exactly as the API// projects it (origin.kind = dynamic_client_registration, endpoints on the MCP// host, stamped with the MCP integration as its origin).const mcpDcrClient = client("dcr-mcp-cloudflare-com", {  authorizationUrl: "https://mcp.cloudflare.com/authorize",  tokenUrl: "https://mcp.cloudflare.com/token",  origin: { kind: "dynamic_client_registration", integration: MCP_INTEGRATION },}); // What the REST integration (api.cloudflare.com) declares to its picker.const restEndpoints = {  tokenUrl: "https://api.cloudflare.com/client/v4/oauth/token",  authorizationUrl: "https://api.cloudflare.com/client/v4/oauth/authorize",  integration: REST_INTEGRATION,  requireEndpointMatch: true,} as const; describe("DCR root-domain isolation across two same-provider integrations", () => {  it("the MCP integration's DCR client is offered in NO tier of the REST integration's picker", () => {    const rest = selectClientsForEndpoints([mcpDcrClient], restEndpoints);     const offeredInAnyTier = [...rest.matched, ...rest.nearMatches, ...rest.unmatched].map((c) =>      String(c.slug),    );    expect(      offeredInAnyTier,      "the auto-registered client never surfaces as a selectable app for a same-root integration",    ).not.toContain("dcr-mcp-cloudflare-com");    // The three tiers ARE the whole picker; nothing selectable remains.    expect(offeredInAnyTier, "the picker offers nothing to select").toEqual([]);    expect(      rest.matched.length,      "no exact/intent match, so the REST picker shows the register-an-app CTA",    ).toBe(0);    expect(rest.endpointMatched, "an endpoint was declared but nothing matched exactly").toBe(      false,    );  });   it("a same-root MANUAL app (not DCR) still lands in the near-matches tier, proving the exclusion is DCR-specific", () => {    // Same mcp.cloudflare.com endpoints, but a manual app: the classifier must    // still surface it (as a subdued near-match), so the empty picker above is    // due to the DCR origin, not the host mismatch.    const manualNearMiss = client("cloudflare-mcp-manual", {      authorizationUrl: "https://mcp.cloudflare.com/authorize",      tokenUrl: "https://mcp.cloudflare.com/token",      origin: { kind: "manual", integration: null },    });    const rest = selectClientsForEndpoints([manualNearMiss, mcpDcrClient], restEndpoints);     expect(      rest.nearMatches.map((c) => String(c.slug)),      "the manual same-root app is a tier-2 near-match",    ).toEqual(["cloudflare-mcp-manual"]);    expect(      [...rest.matched, ...rest.nearMatches, ...rest.unmatched].map((c) => String(c.slug)),      "the DCR client is still excluded even alongside a pickable manual app",    ).not.toContain("dcr-mcp-cloudflare-com");  });   it("the DCR client stays visible in the MCP integration's own auto-registered management list", () => {    // Hidden from the picker is not hidden from management: the MCP integration    // that minted it must still be able to review and remove it.    const managed = selectDcrClientsForIntegration([mcpDcrClient], {      integration: MCP_INTEGRATION,      tokenUrl: "https://mcp.cloudflare.com/token",      authorizationUrl: "https://mcp.cloudflare.com/authorize",    });    expect(      managed.map((c) => String(c.slug)),      "the auto-registered client is manageable from the integration that created it",    ).toEqual(["dcr-mcp-cloudflare-com"]);  });});