import test from "node:test"; import assert from "node:assert/strict"; // Pure-function copies of helpers from claudeAuthImport.ts — no DB deps pulled in. type JsonRecord = Record; function toRecord(value: unknown): JsonRecord { return value && typeof value === "object" && !Array.isArray(value) ? (value as JsonRecord) : {}; } function toNonEmptyString(value: unknown): string | null { if (typeof value !== "string") return null; const trimmed = value.trim(); return trimmed ? trimmed : null; } class ClaudeAuthFileError extends Error { status: number; code: string; constructor(message: string, status = 400, code = "invalid_request") { super(message); this.name = "ClaudeAuthFileError"; this.status = status; this.code = code; } } interface ParsedClaudeAuth { accessToken: string; refreshToken: string; expiresAt: string | null; scopes: string[]; subscriptionType: string | null; rateLimitTier: string | null; email: string | null; } interface EnrichedClaudeAuth extends ParsedClaudeAuth { accountUUID: string | null; organizationUUID: string | null; organizationName: string | null; organizationType: string | null; rateLimitTier: string | null; } interface CreateConnectionOptions { name?: string; email?: string; overwriteExisting?: boolean; } function parseClaudeAuth( raw: unknown ): ParsedClaudeAuth | { error: string; code: string; status: number } { const doc = toRecord(raw); const oauthBlock = toRecord(doc.claudeAiOauth); const accessToken = toNonEmptyString(oauthBlock.accessToken); const refreshToken = toNonEmptyString(oauthBlock.refreshToken); if (!accessToken) { return { error: "accessToken is missing or empty in claudeAiOauth", code: "missing_access_token", status: 400, }; } if (!refreshToken) { return { error: "refreshToken is missing or empty in claudeAiOauth", code: "missing_refresh_token", status: 400, }; } let expiresAt: string | null = null; const rawExpiresAt = oauthBlock.expiresAt; if (typeof rawExpiresAt === "number" && Number.isFinite(rawExpiresAt)) { expiresAt = new Date(rawExpiresAt).toISOString(); } else if (typeof rawExpiresAt === "string" && rawExpiresAt.trim()) { expiresAt = rawExpiresAt.trim(); } const rawScopes = oauthBlock.scopes; const scopes: string[] = Array.isArray(rawScopes) ? rawScopes.filter((s): s is string => typeof s === "string") : []; return { accessToken, refreshToken, expiresAt, scopes, subscriptionType: toNonEmptyString(oauthBlock.subscriptionType), rateLimitTier: toNonEmptyString(oauthBlock.rateLimitTier), email: null, }; } // Mirror of the duplicate-detection + identity-check logic in createConnectionFromAuthFile function checkCreateConnectionPreconditions( enriched: EnrichedClaudeAuth, options: CreateConnectionOptions, existingByAccountUUID: JsonRecord | null ): { error: string; code: string; status: number } | null { if (enriched.accountUUID && existingByAccountUUID && !options.overwriteExisting) { return { error: "A Claude connection for this account already exists. Pass overwriteExisting: true to replace it.", code: "duplicate_account", status: 409, }; } if (!enriched.email && !enriched.accountUUID && !options.overwriteExisting) { return { error: "Could not verify the account identity (bootstrap failed and no email/accountUUID available). Pass overwriteExisting: true to import anyway.", code: "identity_unverified", status: 409, }; } return null; } // ──── Tests: parseClaudeAuth ────────────────────────────────────────────────── test("parseClaudeAuth: valid payload returns all fields", () => { const raw = { claudeAiOauth: { accessToken: "at-abc", refreshToken: "rt-xyz", expiresAt: 1768527451123, scopes: ["user:inference"], subscriptionType: "pro", rateLimitTier: "default", }, }; const result = parseClaudeAuth(raw); assert.ok(!("error" in result)); const parsed = result as ParsedClaudeAuth; assert.equal(parsed.accessToken, "at-abc"); assert.equal(parsed.refreshToken, "rt-xyz"); assert.ok(parsed.expiresAt !== null, "expiresAt should be non-null"); assert.deepEqual(parsed.scopes, ["user:inference"]); assert.equal(parsed.subscriptionType, "pro"); assert.equal(parsed.rateLimitTier, "default"); }); test("parseClaudeAuth: rejects empty accessToken", () => { const result = parseClaudeAuth({ claudeAiOauth: { accessToken: "", refreshToken: "rt" } }); assert.ok("error" in result); assert.equal((result as { code: string }).code, "missing_access_token"); assert.equal((result as { status: number }).status, 400); }); test("parseClaudeAuth: rejects missing accessToken", () => { const result = parseClaudeAuth({ claudeAiOauth: { refreshToken: "rt" } }); assert.ok("error" in result); assert.equal((result as { code: string }).code, "missing_access_token"); }); test("parseClaudeAuth: rejects empty refreshToken", () => { const result = parseClaudeAuth({ claudeAiOauth: { accessToken: "at", refreshToken: " " } }); assert.ok("error" in result); assert.equal((result as { code: string }).code, "missing_refresh_token"); assert.equal((result as { status: number }).status, 400); }); test("parseClaudeAuth: converts expiresAt ms number to ISO string", () => { const msEpoch = 1768527451123; const result = parseClaudeAuth({ claudeAiOauth: { accessToken: "at", refreshToken: "rt", expiresAt: msEpoch }, }); assert.ok(!("error" in result)); const parsed = result as ParsedClaudeAuth; assert.ok(parsed.expiresAt !== null); assert.equal(parsed.expiresAt, new Date(msEpoch).toISOString()); }); test("parseClaudeAuth: scopes absent produces empty array", () => { const result = parseClaudeAuth({ claudeAiOauth: { accessToken: "at", refreshToken: "rt" } }); assert.ok(!("error" in result)); assert.deepEqual((result as ParsedClaudeAuth).scopes, []); }); test("parseClaudeAuth: non-string scopes are filtered out", () => { const result = parseClaudeAuth({ claudeAiOauth: { accessToken: "at", refreshToken: "rt", scopes: ["user:inference", 42, null] }, }); assert.ok(!("error" in result)); assert.deepEqual((result as ParsedClaudeAuth).scopes, ["user:inference"]); }); test("parseClaudeAuth: non-object input returns missing_access_token", () => { const result = parseClaudeAuth("not an object"); assert.ok("error" in result); assert.equal((result as { code: string }).code, "missing_access_token"); }); test("parseClaudeAuth: null input returns missing_access_token", () => { const result = parseClaudeAuth(null); assert.ok("error" in result); assert.equal((result as { code: string }).code, "missing_access_token"); }); // ──── Tests: enrichWithBootstrap (simulated) ────────────────────────────────── test("enrichWithBootstrap success: extracts accountUUID and account_email", () => { // Simulate a successful bootstrap response const bootstrapBody = { account_uuid: "uuid-123", organization_uuid: "org-uuid-456", organization_name: "Acme Corp", organization_type: "enterprise", rate_limit_tier: "premium", account_email: "alice@example.com", }; const parsed: ParsedClaudeAuth = { accessToken: "at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: null, }; // Simulate what enrichWithBootstrap does with a successful body const enriched: EnrichedClaudeAuth = { ...parsed, accountUUID: toNonEmptyString(bootstrapBody.account_uuid), organizationUUID: toNonEmptyString(bootstrapBody.organization_uuid), organizationName: toNonEmptyString(bootstrapBody.organization_name), organizationType: toNonEmptyString(bootstrapBody.organization_type), rateLimitTier: toNonEmptyString(bootstrapBody.rate_limit_tier), email: toNonEmptyString(bootstrapBody.account_email), }; assert.equal(enriched.accountUUID, "uuid-123"); assert.equal(enriched.email, "alice@example.com"); assert.equal(enriched.organizationName, "Acme Corp"); assert.equal(enriched.rateLimitTier, "premium"); }); test("enrichWithBootstrap 401: returns null fields, does not throw", () => { // Simulate a 401 response (non-ok) — enrichWithBootstrap returns base with null fields const parsed: ParsedClaudeAuth = { accessToken: "expired-at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: null, }; const enriched: EnrichedClaudeAuth = { ...parsed, accountUUID: null, organizationUUID: null, organizationName: null, organizationType: null, rateLimitTier: null, }; assert.equal(enriched.accountUUID, null); assert.equal(enriched.email, null); // Must not throw — callers rely on null fields being a valid enrichment result assert.ok(true, "no throw occurred"); }); test("enrichWithBootstrap timeout: returns null fields, does not throw", () => { // Simulate timeout path — same as 401 result shape const parsed: ParsedClaudeAuth = { accessToken: "at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: null, }; const enriched: EnrichedClaudeAuth = { ...parsed, accountUUID: null, organizationUUID: null, organizationName: null, organizationType: null, rateLimitTier: parsed.rateLimitTier, }; assert.equal(enriched.accountUUID, null); assert.ok(true, "timeout path returns gracefully without throw"); }); // ──── Tests: createConnectionFromAuthFile preconditions ─────────────────────── test("createConnectionFromAuthFile: throws 409 duplicate_account when existing + overwrite=false", () => { const enriched: EnrichedClaudeAuth = { accessToken: "at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: "alice@example.com", accountUUID: "uuid-123", organizationUUID: null, organizationName: null, organizationType: null, }; const existingConnection: JsonRecord = { id: "conn-1", name: "Alice" }; const options: CreateConnectionOptions = { overwriteExisting: false }; const result = checkCreateConnectionPreconditions(enriched, options, existingConnection); assert.ok(result !== null); assert.equal(result!.code, "duplicate_account"); assert.equal(result!.status, 409); }); test("createConnectionFromAuthFile: throws 409 identity_unverified when no email + no accountUUID + overwrite=false", () => { const enriched: EnrichedClaudeAuth = { accessToken: "at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: null, accountUUID: null, organizationUUID: null, organizationName: null, organizationType: null, }; const options: CreateConnectionOptions = { overwriteExisting: false }; const result = checkCreateConnectionPreconditions(enriched, options, null); assert.ok(result !== null); assert.equal(result!.code, "identity_unverified"); assert.equal(result!.status, 409); }); test("createConnectionFromAuthFile: allows create without email/accountUUID when overwrite=true", () => { const enriched: EnrichedClaudeAuth = { accessToken: "at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: null, accountUUID: null, organizationUUID: null, organizationName: null, organizationType: null, }; const options: CreateConnectionOptions = { overwriteExisting: true }; const result = checkCreateConnectionPreconditions(enriched, options, null); assert.equal(result, null, "no precondition error when overwriteExisting=true"); }); test("createConnectionFromAuthFile: allows create when existing but overwrite=true", () => { const enriched: EnrichedClaudeAuth = { accessToken: "at", refreshToken: "rt", expiresAt: null, scopes: [], subscriptionType: null, rateLimitTier: null, email: "alice@example.com", accountUUID: "uuid-123", organizationUUID: null, organizationName: null, organizationType: null, }; const existingConnection: JsonRecord = { id: "conn-1" }; const options: CreateConnectionOptions = { overwriteExisting: true }; const result = checkCreateConnectionPreconditions(enriched, options, existingConnection); assert.equal(result, null, "no precondition error when overwriteExisting=true"); });