686 lines · 24.2 KB · TypeScript
RawDownload
import { describe, expect, it } from "@effect/vitest";import {  AuthTemplateSlug,  IntegrationSlug,  OAuthClientSlug,  ProviderItemId,  ProviderKey,  type Owner,} from "@executor-js/sdk/shared"; import type { AuthMethod } from "../lib/auth-placements";import {  connectionNameFrom,  connectionLabel,  connectionLabelForHost,  createCredentialPayloadOrigin,  DEFAULT_CONNECTION_OWNER,  mergeCustomMethods,  oauthIdentityLabelFromHealth,  runCimdConnect,  runDcrConnect,  typedIdentityLabel,  uniqueConnectionName,} from "./add-account-modal"; const apiKeyMethod = (id: string, source: "spec" | "custom", template = id): AuthMethod => ({  id,  label: `API key (${id})`,  kind: "apikey",  source,  template: AuthTemplateSlug.make(template),  placements: [{ carrier: "header", name: "Authorization", prefix: "" }],}); type ProbeResult = {  readonly issuer?: string | null;  readonly authorizationUrl: string;  readonly tokenUrl: string;  readonly resource?: string | null;  readonly scopesSupported?: readonly string[];  readonly registrationEndpoint?: string | null;  readonly tokenEndpointAuthMethodsSupported?: readonly string[];}; type RegisterArgs = {  readonly owner: Owner;  readonly slug: OAuthClientSlug;  readonly issuer?: string | null;  readonly registrationEndpoint: string;  readonly authorizationUrl: string;  readonly tokenUrl: string;  readonly resource?: string | null;  readonly scopes: readonly string[];  readonly tokenEndpointAuthMethodsSupported?: readonly string[];  readonly clientName: string;  readonly redirectUri?: string;  readonly originIntegration?: IntegrationSlug;}; type StartArgs = { readonly client: OAuthClientSlug; readonly owner: Owner }; type CimdCreateArgs = {  readonly owner: Owner;  readonly slug: OAuthClientSlug;  readonly authorizationUrl: string;  readonly tokenUrl: string;  readonly resource?: string | null;  readonly grant: "authorization_code";  readonly clientId: string;  readonly clientSecret: "";}; type CimdStartArgs = { readonly client: OAuthClientSlug; readonly owner: Owner }; const TEST_INTEGRATION = IntegrationSlug.make("linear_mcp"); describe("connectionLabel (name placeholder derivation)", () => {  // The name field is optional but prefilled-via-derivation. With an empty  // label this is the derived name shown as the input's placeholder, so the  // intent ("leave blank ⇒ use this name") is visible.  it("derives '<owner> <integration>' for an empty label (the placeholder)", () => {    expect(connectionLabel("", "user", "GitHub")).toBe("Personal GitHub");    expect(connectionLabel("", "org", "GitHub")).toBe("Workspace GitHub");  });   it("treats whitespace-only labels as empty (still derives the placeholder)", () => {    expect(connectionLabel("   ", "user", "GitHub")).toBe("Personal GitHub");  });   it("uses the typed label (trimmed) when one is provided", () => {    expect(connectionLabel("  My Bot  ", "user", "GitHub")).toBe("My Bot");  });   it("uses Local in derived labels for non-org-scoped hosts", () => {    expect(connectionLabelForHost("", "org", "GitHub", null)).toBe("Local GitHub");    expect(connectionLabelForHost("", "org", "GitHub", "org_123")).toBe("Workspace GitHub");  });}); describe("connectionNameFrom", () => {  it("derives the JS-callable name from the display name", () => {    expect(String(connectionNameFrom("Autumn Production", "user", "Autumn", "org_123"))).toBe(      "autumnProduction",    );    expect(String(connectionNameFrom("linear-mcp-oauth", "user", "Linear MCP", "org_123"))).toBe(      "linearMcpOauth",    );  });   it("derives a callable default from owner and integration when the display name is empty", () => {    expect(String(connectionNameFrom("", "org", "GitHub", "org_123"))).toBe("workspaceGithub");    expect(String(connectionNameFrom("", "org", "GitHub", null))).toBe("localGithub");  });}); describe("uniqueConnectionName", () => {  const base = connectionNameFrom("", "user", "Gmail", "org_123");   it("keeps the derived name when it is not taken", () => {    expect(String(uniqueConnectionName(base, new Set()))).toBe("personalGmail");  });   it("suffixes past taken names so a second untyped connect mints a NEW connection", () => {    expect(String(uniqueConnectionName(base, new Set(["personalGmail"])))).toBe("personalGmail2");    expect(String(uniqueConnectionName(base, new Set(["personalGmail", "personalGmail2"])))).toBe(      "personalGmail3",    );  });}); describe("typedIdentityLabel", () => {  it("returns undefined for empty/whitespace labels so oauth.start omits the label", () => {    expect(typedIdentityLabel("")).toBeUndefined();    expect(typedIdentityLabel("   ")).toBeUndefined();  });   it("returns the trimmed label the user typed", () => {    expect(typedIdentityLabel("  Work Gmail ")).toBe("Work Gmail");  });}); describe("oauthIdentityLabelFromHealth", () => {  const healthyResult = {    status: "healthy" as const,    identity: " user@example.com ",    checkedAt: 1,  };   it("fills an unset label (untyped connect with no OIDC claims)", () => {    expect(      oauthIdentityLabelFromHealth({        result: healthyResult,        typedLabel: "",        storedIdentityLabel: null,      }),    ).toBe("user@example.com");  });   it("does not overwrite a hand-typed label", () => {    expect(      oauthIdentityLabelFromHealth({        result: healthyResult,        typedLabel: "My Google Account",        storedIdentityLabel: "My Google Account",      }),    ).toBeNull();  });   it("does not overwrite a stored custom label", () => {    expect(      oauthIdentityLabelFromHealth({        result: healthyResult,        typedLabel: "",        storedIdentityLabel: "Finance Google",      }),    ).toBeNull();  });   it("does not overwrite a label already filled from OIDC claims", () => {    expect(      oauthIdentityLabelFromHealth({        result: healthyResult,        typedLabel: "",        storedIdentityLabel: "alice@example.com",      }),    ).toBeNull();  });   it("requires a healthy result with an identity", () => {    expect(      oauthIdentityLabelFromHealth({        result: { status: "degraded", checkedAt: 1 },        typedLabel: "",        storedIdentityLabel: null,      }),    ).toBeNull();    expect(      oauthIdentityLabelFromHealth({        result: { status: "healthy", checkedAt: 1 },        typedLabel: "",        storedIdentityLabel: null,      }),    ).toBeNull();  });}); describe("DEFAULT_CONNECTION_OWNER", () => {  // The 'saved to' owner defaults to Personal: a connection is most often a  // personal credential.  it("defaults a new connection's owner to Personal (user)", () => {    expect(DEFAULT_CONNECTION_OWNER).toBe("user");  });}); describe("mergeCustomMethods (in-session custom method append)", () => {  // A just-created custom method joins the selectable list (custom last) so it  // can be selected before the catalog refresh lands.  it("appends a session-created method after the declared methods", () => {    const declared = [apiKeyMethod("spec-1", "spec")];    const created = [apiKeyMethod("custom_a", "custom")];    const merged = mergeCustomMethods(declared, created);    expect(merged.map((m: AuthMethod) => m.id)).toEqual(["spec-1", "custom_a"]);  });   it("dedupes by stable identity (a refreshed catalog method wins over its session copy)", () => {    const declared = [apiKeyMethod("spec-1", "spec"), apiKeyMethod("custom_a", "custom")];    const created = [apiKeyMethod("custom_a", "custom")];    const merged = mergeCustomMethods(declared, created);    expect(merged.map((m: AuthMethod) => m.id)).toEqual(["spec-1", "custom_a"]);  });   it("dedupes custom methods by template even when their rendered ids differ", () => {    const declared = [      apiKeyMethod("spec-1", "spec"),      apiKeyMethod("custom_a_refreshed", "custom", "custom_a"),    ];    const created = [apiKeyMethod("custom_a", "custom", "custom_a")];    const merged = mergeCustomMethods(declared, created);    expect(merged.map((m: AuthMethod) => m.id)).toEqual(["spec-1", "custom_a_refreshed"]);  });   it("returns the declared list unchanged when nothing was created", () => {    const declared = [apiKeyMethod("spec-1", "spec")];    expect(mergeCustomMethods(declared, [])).toEqual(declared);  });}); describe("createCredentialPayloadOrigin", () => {  it("creates an empty-string sentinel value for no-auth connection methods", () => {    expect(      createCredentialPayloadOrigin({        origin: "paste",        inputs: [],        values: {},        onePasswordItemId: "",        singleInput: true,      }),    ).toEqual({ values: { token: "" } });  });   it("keeps pasted credential values trimmed and keyed by input variable", () => {    expect(      createCredentialPayloadOrigin({        origin: "paste",        inputs: [{ variable: "token", label: "Authorization" }],        values: { token: "  secret-token  " },        onePasswordItemId: "",        singleInput: true,      }),    ).toEqual({ values: { token: "secret-token" } });  });   it("creates a 1Password external origin for single-input methods", () => {    expect(      createCredentialPayloadOrigin({        origin: "onepassword",        inputs: [{ variable: "token", label: "Authorization" }],        values: {},        onePasswordItemId: " op://Private/Vercel/token ",        singleInput: true,      }),    ).toEqual({      from: {        provider: ProviderKey.make("onepassword"),        id: ProviderItemId.make("op://Private/Vercel/token"),      },    });  });   it("does not allow 1Password selection for multi-input methods yet", () => {    expect(      createCredentialPayloadOrigin({        origin: "onepassword",        inputs: [          { variable: "apiKey", label: "API key" },          { variable: "appKey", label: "Application key" },        ],        values: {},        onePasswordItemId: "op://Private/Datadog/api-key",        singleInput: false,      }),    ).toBeNull();  });}); describe("runCimdConnect", () => {  it("creates a public metadata-document OAuth client and starts OAuth", async () => {    let createArgs: CimdCreateArgs | null = null;    let startArgs: CimdStartArgs | null = null;     const outcome = await runCimdConnect(      {        createClient: (args: CimdCreateArgs): Promise<OAuthClientSlug | null> => {          createArgs = args;          return Promise.resolve(args.slug);        },        start: (args: CimdStartArgs): void => {          startArgs = args;        },      },      {        owner: "user",        integrationName: "PostHog API",        authorizationUrl: "https://us.posthog.com/oauth/authorize/",        tokenUrl: "https://us.posthog.com/oauth/token/",        resource: "https://us.posthog.com",        clientIdMetadataDocumentUrl:          "https://executor.example/api/oauth/client-id-metadata/acme.json",        existingClients: [],      },    );     expect(outcome.kind).toBe("started");    expect(createArgs).toMatchObject({      owner: "user",      authorizationUrl: "https://us.posthog.com/oauth/authorize/",      tokenUrl: "https://us.posthog.com/oauth/token/",      resource: "https://us.posthog.com",      grant: "authorization_code",      clientId: "https://executor.example/api/oauth/client-id-metadata/acme.json",      clientSecret: "",    });    expect(String(createArgs!.slug)).toBe("posthog-api-cimd");    expect(String(startArgs!.client)).toBe("posthog-api-cimd");    expect(startArgs!.owner).toBe("user");  });   it("reuses an existing matching metadata-document client", async () => {    const existingSlug = OAuthClientSlug.make("posthog-api-cimd");    let created = false;    let startArgs: CimdStartArgs | null = null;     const outcome = await runCimdConnect(      {        createClient: (): Promise<OAuthClientSlug | null> => {          created = true;          return Promise.resolve(OAuthClientSlug.make("new-client"));        },        start: (args: CimdStartArgs): void => {          startArgs = args;        },      },      {        owner: "user",        integrationName: "PostHog API",        authorizationUrl: "https://us.posthog.com/oauth/authorize/",        tokenUrl: "https://us.posthog.com/oauth/token/",        resource: "https://us.posthog.com",        clientIdMetadataDocumentUrl: "https://executor.example/api/oauth/client-id-metadata.json",        existingClients: [          {            owner: "user",            slug: existingSlug,            grant: "authorization_code",            authorizationUrl: "https://us.posthog.com/oauth/authorize/",            tokenUrl: "https://us.posthog.com/oauth/token/",            resource: "https://us.posthog.com",            clientId: "https://executor.example/api/oauth/client-id-metadata.json",          },        ],      },    );     expect(outcome).toEqual({ kind: "started", client: existingSlug, reused: true });    expect(created).toBe(false);    expect(startArgs).toEqual({ client: existingSlug, owner: "user" });  });}); describe("runDcrConnect", () => {  it("auto-registers (no picker) then starts: probe → register → start in order", async () => {    const calls: string[] = [];    let registerArgs: RegisterArgs | null = null;    let startArgs: StartArgs | null = null;     const probe = (_url: string): Promise<ProbeResult | null> => {      calls.push("probe");      return Promise.resolve({        issuer: "https://auth.example.com",        authorizationUrl: "https://auth.example.com/authorize",        tokenUrl: "https://auth.example.com/token",        resource: "https://mcp.example.com/mcp",        scopesSupported: ["mcp.read"],        registrationEndpoint: "https://auth.example.com/register",        tokenEndpointAuthMethodsSupported: ["none"],      });    };    const register = (args: RegisterArgs): Promise<OAuthClientSlug | null> => {      calls.push("register");      registerArgs = args;      return Promise.resolve(OAuthClientSlug.make("linear-mcp"));    };    const start = (args: StartArgs): void => {      calls.push("start");      startArgs = args;    };     const outcome = await runDcrConnect(      { probe, register, start },      {        discoveryUrl: "https://mcp.example.com/mcp",        owner: "user",        redirectUri: "https://localhost:5394/api/oauth/callback",        integration: TEST_INTEGRATION,      },    );     expect(outcome.kind).toBe("started");    expect(calls).toEqual(["probe", "register", "start"]);    // Registered with the probed registration endpoint + probed auth methods.    // DCR always mints an authorization-code/PKCE client; callers do not choose    // a grant here.    expect(registerArgs).not.toBeNull();    expect(String(registerArgs!.slug)).toBe("dcr-auth-example-com");    expect(registerArgs!.issuer).toBe("https://auth.example.com");    expect(registerArgs!.registrationEndpoint).toBe("https://auth.example.com/register");    expect(registerArgs!.authorizationUrl).toBe("https://auth.example.com/authorize");    expect(registerArgs!.tokenUrl).toBe("https://auth.example.com/token");    expect(registerArgs!.resource).toBe("https://mcp.example.com/mcp");    expect(registerArgs!.tokenEndpointAuthMethodsSupported).toEqual(["none"]);    // Always the bare product name: brand-vetting servers (e.g. Mercury)    // reject client_names containing their own brand.    expect(registerArgs!.clientName).toBe("Executor");    expect(registerArgs!.scopes).toEqual(["mcp.read"]);    expect(registerArgs!.redirectUri).toBe("https://localhost:5394/api/oauth/callback");    expect(registerArgs!.originIntegration).toBe(TEST_INTEGRATION);    // Started with the minted client slug under the chosen owner.    expect(startArgs).not.toBeNull();    expect(String(startArgs!.client)).toBe("linear-mcp");    expect(startArgs!.owner).toBe("user");  });   it("prefers declared scopes over probed scopes when present", async () => {    let registerArgs: RegisterArgs | null = null;    const outcome = await runDcrConnect(      {        probe: (): Promise<ProbeResult | null> =>          Promise.resolve({            authorizationUrl: "https://auth.example.com/authorize",            tokenUrl: "https://auth.example.com/token",            scopesSupported: ["probed.scope"],            registrationEndpoint: "https://auth.example.com/register",          }),        register: (args: RegisterArgs): Promise<OAuthClientSlug | null> => {          registerArgs = args;          return Promise.resolve(OAuthClientSlug.make("app"));        },        start: (): void => {},      },      {        discoveryUrl: "https://mcp.example.com/mcp",        resourceFallback: "https://mcp.example.com/mcp",        owner: "user",        declaredScopes: ["declared.scope"],        integration: TEST_INTEGRATION,      },    );    expect(outcome.kind).toBe("started");    expect(registerArgs!.scopes).toEqual(["declared.scope"]);    // PRM named no `resource`, so the genuine discovery URL (MCP) seeds the    // RFC 8707 resource indicator.    expect(registerArgs!.resource).toBe("https://mcp.example.com/mcp");  });   it("never seeds the resource indicator from the token endpoint (non-MCP DCR)", async () => {    // A DCR integration with no discovery URL: `discoveryUrl` falls back to the    // token endpoint for probing, but the token endpoint is not an RFC 8707    // resource identifier, so it must NOT become the resource. With no genuine    // discovery URL and no PRM-named resource, the indicator stays null.    let registerArgs: RegisterArgs | null = null;    const outcome = await runDcrConnect(      {        probe: (): Promise<ProbeResult | null> =>          Promise.resolve({            authorizationUrl: "https://auth.example.com/authorize",            tokenUrl: "https://auth.example.com/token",            registrationEndpoint: "https://auth.example.com/register",          }),        register: (args: RegisterArgs): Promise<OAuthClientSlug | null> => {          registerArgs = args;

Lines 1–500 of 686.