import { describe, expect, it } from "vitest"; import { apiKeyValueSchema, awsCredentialSchema, azureCredentialSchema, credentialPayloadSchema, gcpAdcCredentialSchema, isAwsBedrockEndpointUrl, isLocalConnectorBaseUrl, localCredentialSchema, removeCredentialInputSchema, saveCredentialInputSchema, testCredentialInputSchema, } from "../../src/shared/contracts/schemas-credentials"; import { oauthCancelInputSchema, oauthManualCodeResponseSchema, oauthPromptResponseSchema, oauthStartInputSchema, } from "../../src/shared/contracts/schemas-oauth"; /** Verifies the IPC payload schemas reject malformed input and accept valid * shapes. These are the only contract between renderer ↔ main for the new * credential / OAuth channels — incorrect validation would let bad data * reach pi-mono primitives. */ describe("credentials Zod schemas", () => { it("apiKeyValueSchema rejects empty value", () => { const result = apiKeyValueSchema.safeParse({ source: "literal", value: "" }); expect(result.success).toBe(false); }); it("apiKeyValueSchema accepts both source kinds", () => { expect(apiKeyValueSchema.safeParse({ source: "literal", value: "sk-x" }).success).toBe(true); expect(apiKeyValueSchema.safeParse({ source: "env", value: "MY_KEY" }).success).toBe(true); }); it("apiKeyValueSchema rejects unknown source", () => { const result = apiKeyValueSchema.safeParse({ source: "shell", value: "$(echo x)" }); expect(result.success).toBe(false); }); it("awsCredentialSchema requires authMode", () => { expect(awsCredentialSchema.safeParse({ region: "us-east-1" }).success).toBe(false); expect(awsCredentialSchema.safeParse({ authMode: "profile", region: "us-east-1", awsProfile: "default" }).success).toBe(true); }); it("awsCredentialSchema accepts all three auth modes", () => { for (const authMode of ["profile", "iam", "bearer"] as const) { const result = awsCredentialSchema.safeParse({ authMode, region: "us-east-1" }); expect(result.success).toBe(true); } }); it("awsCredentialSchema accepts AWS Bedrock and private HTTPS endpointUrl values", () => { for (const endpointUrl of [ "https://bedrock-runtime.us-east-1.amazonaws.com", "https://bedrock-runtime.us-east-1.amazonaws.com/", "https://bedrock-runtime-fips.us-gov-west-1.amazonaws.com", "https://bedrock-runtime.cn-north-1.amazonaws.com.cn", "https://vpce-123abc.bedrock-runtime.us-east-1.vpce.amazonaws.com", "https://vpce-123abc-us-east-1a.bedrock-runtime.us-east-1.vpce.amazonaws.com", "https://10.0.0.20", "https://192.168.1.20", "https://[fd12::1]", ]) { const result = awsCredentialSchema.safeParse({ authMode: "profile", region: "us-east-1", awsProfile: "default", endpointUrl }); expect(result.success).toBe(true); expect(isAwsBedrockEndpointUrl(endpointUrl)).toBe(true); } }); it("awsCredentialSchema rejects unsafe endpointUrl values", () => { for (const endpointUrl of [ "http://bedrock-runtime.us-east-1.amazonaws.com", "https://api.openai.com/v1", "https://bedrock-runtime.example.com", "https://user:pass@bedrock-runtime.us-east-1.amazonaws.com", "https://bedrock-runtime.us-east-1.amazonaws.com/model/test", "https://bedrock-runtime.us-east-1.amazonaws.com?proxy=1", "ftp://bedrock-runtime.us-east-1.amazonaws.com", "https://bedrock-runtime.us-east-1.amazonaws.com?", "https://bedrock-runtime.us-east-1.amazonaws.com#", "https://bedrock-runtime.us-east-1.amazonaws.com/%2e%2e", "https://bedrock-runtime.us-east-1.amazonaws.com/a/..", "https://bedrock-runtime.us-east-1.vpce.amazonaws.com", "https://foo.bar.bedrock-runtime.us-east-1.vpce.amazonaws.com", ]) { const result = awsCredentialSchema.safeParse({ authMode: "profile", region: "us-east-1", awsProfile: "default", endpointUrl }); expect(result.success).toBe(false); expect(isAwsBedrockEndpointUrl(endpointUrl)).toBe(false); } }); it("azureCredentialSchema requires apiKey", () => { expect(azureCredentialSchema.safeParse({}).success).toBe(false); expect(azureCredentialSchema.safeParse({ apiKey: "azure-secret" }).success).toBe(true); }); it("gcpAdcCredentialSchema requires project + location", () => { expect(gcpAdcCredentialSchema.safeParse({ project: "" }).success).toBe(false); expect(gcpAdcCredentialSchema.safeParse({ project: "p", location: "us-central1" }).success).toBe(true); }); it("localCredentialSchema accepts loopback and private-network baseUrl values", () => { for (const baseUrl of [ "http://localhost:11434/v1", "http://127.0.0.1:11434/v1", "http://10.0.0.20:11434/v1", "https://172.16.0.10:11434/v1", "http://172.31.255.255:11434/v1", "http://192.168.1.20:11434/v1", "http://169.254.1.20:11434/v1", "http://[::1]:11434/v1", "http://[fc00::1]:11434/v1", "http://[fd12::1]:11434/v1", "http://[fe80::1]:11434/v1", ]) { expect(localCredentialSchema.safeParse({ baseUrl }).success).toBe(true); expect(isLocalConnectorBaseUrl(baseUrl)).toBe(true); } }); it("localCredentialSchema rejects remote OpenAI-compatible endpoints", () => { for (const baseUrl of [ "https://api.openai.com/v1", "https://example.com/v1", "http://172.32.0.1:11434/v1", "http://100.64.0.1:11434/v1", "ftp://localhost:11434/v1", "http://user:pass@127.0.0.1:11434/v1", ]) { expect(localCredentialSchema.safeParse({ baseUrl }).success).toBe(false); expect(isLocalConnectorBaseUrl(baseUrl)).toBe(false); } }); it("credentialPayloadSchema discriminates on kind", () => { expect( credentialPayloadSchema.safeParse({ kind: "api_key", value: { source: "literal", value: "sk-x" }, }).success, ).toBe(true); expect( credentialPayloadSchema.safeParse({ kind: "azure", value: { source: "literal", value: "wrong-shape" }, }).success, ).toBe(false); }); it("saveCredentialInputSchema requires connectorId + payload", () => { expect( saveCredentialInputSchema.safeParse({ connectorId: "anthropic", payload: { kind: "api_key", value: { source: "literal", value: "sk-x" } }, }).success, ).toBe(true); expect(saveCredentialInputSchema.safeParse({ connectorId: "" }).success).toBe(false); expect(saveCredentialInputSchema.safeParse({ payload: {} }).success).toBe(false); }); it("removeCredentialInputSchema rejects empty connectorId", () => { expect(removeCredentialInputSchema.safeParse({ connectorId: "openai" }).success).toBe(true); expect(removeCredentialInputSchema.safeParse({ connectorId: "" }).success).toBe(false); expect(removeCredentialInputSchema.safeParse({}).success).toBe(false); }); it("testCredentialInputSchema rejects empty connectorId", () => { expect(testCredentialInputSchema.safeParse({ connectorId: "openai" }).success).toBe(true); expect(testCredentialInputSchema.safeParse({ connectorId: "" }).success).toBe(false); }); }); describe("oauth Zod schemas", () => { it("oauthStartInputSchema rejects empty connectorId", () => { expect(oauthStartInputSchema.safeParse({ connectorId: "claude-pro" }).success).toBe(true); expect(oauthStartInputSchema.safeParse({ connectorId: "" }).success).toBe(false); }); it("oauthCancelInputSchema rejects missing connectorId", () => { expect(oauthCancelInputSchema.safeParse({ connectorId: "claude-pro" }).success).toBe(true); expect(oauthCancelInputSchema.safeParse({}).success).toBe(false); }); it("oauthPromptResponseSchema requires connectorId, requestId and a (possibly empty) value", () => { expect( oauthPromptResponseSchema.safeParse({ connectorId: "github-copilot", requestId: "req-1", value: "github.com", }).success, ).toBe(true); expect( oauthPromptResponseSchema.safeParse({ connectorId: "github-copilot", requestId: "" }).success, ).toBe(false); expect( oauthPromptResponseSchema.safeParse({ connectorId: "github-copilot", value: "x" }).success, ).toBe(false); }); it("oauthManualCodeResponseSchema requires non-empty code", () => { expect( oauthManualCodeResponseSchema.safeParse({ connectorId: "anthropic", requestId: "req-1", code: "abcd", }).success, ).toBe(true); expect( oauthManualCodeResponseSchema.safeParse({ connectorId: "anthropic", requestId: "req-1", code: "", }).success, ).toBe(false); }); });