import { strict as assert } from 'node:assert'; import { describe, it } from 'node:test'; import type { Principal } from '../src/lib/auth'; import { assertApiKeyActive, AuthError, hashApiKey, requireCapability, } from '../src/lib/auth'; import { apiKeyCreationResponse, apiKeyCreateSchema, apiKeyMetadata, generateApiKey, resolveApiKeyTarget, } from '../src/routes/api-keys'; const userId = '00000000-0000-0000-0000-000000000001'; const otherUserId = '00000000-0000-0000-0000-000000000002'; function principal(overrides: Partial = {}): Principal { return { userId, email: 'seller@example.com', name: 'Seller', isPlatformAdmin: false, teams: [{ team: 'demand', role: 'member' }], via: 'jwt', scopes: ['read', 'write'], ...overrides, }; } function storedKey(overrides: Record = {}) { return { id: '00000000-0000-0000-0000-000000000010', userId, name: 'Codex', keyHash: 'stored-hash', keyPrefix: 'pig_abc123', scopes: ['read'], lastUsedAt: null, expiresAt: null, revokedAt: null, createdAt: new Date('2026-08-12T12:00:00.000Z'), ...overrides, } as Parameters[0]; } describe('API key lifecycle decisions', () => { it('stores only a SHA-256 hash and returns plaintext only from creation', () => { const generated = generateApiKey(); assert.match(generated.key, /^pig_[A-Za-z0-9_-]{43}$/); assert.equal(generated.keyHash, hashApiKey(generated.key)); assert.equal(generated.keyHash.length, 64); assert.equal(generated.keyPrefix, generated.key.slice(0, 10)); const row = storedKey({ keyHash: generated.keyHash, keyPrefix: generated.keyPrefix }); const created = apiKeyCreationResponse(row, generated.key); const listed = apiKeyMetadata(row); assert.equal(created.key, generated.key); assert.equal('key' in listed, false); assert.equal('keyHash' in listed, false); }); it('allows read-only or read/write keys, never write-only keys', () => { assert.deepEqual(apiKeyCreateSchema.parse({ name: 'Reader' }).scopes, ['read']); assert.deepEqual( apiKeyCreateSchema.parse({ name: 'Writer', scopes: ['read', 'write'] }).scopes, ['read', 'write'], ); assert.equal(apiKeyCreateSchema.safeParse({ name: 'Writer', scopes: ['write'] }).success, false); assert.equal( apiKeyCreateSchema.safeParse({ name: 'Duplicate', scopes: ['read', 'read'] }).success, false, ); assert.throws( () => requireCapability(principal({ via: 'api_key', scopes: ['read'] }), 'deal:write', 'demand'), (error: unknown) => error instanceof AuthError && error.code === 'insufficient_scope', ); assert.doesNotThrow(() => requireCapability( principal({ via: 'api_key', scopes: ['read', 'write'] }), 'deal:write', 'demand', ), ); }); it('rejects a revoked key immediately while leaving an active key usable', () => { const now = new Date('2026-08-12T12:00:00.000Z'); assert.doesNotThrow(() => assertApiKeyActive({ revokedAt: null, expiresAt: null }, now)); assert.throws( () => assertApiKeyActive({ revokedAt: new Date('2026-08-12T11:59:00.000Z'), expiresAt: null }, now), (error: unknown) => error instanceof AuthError && error.code === 'revoked_key', ); }); it('keeps self-service personal, with explicit platform-admin cross-user access', () => { assert.equal(resolveApiKeyTarget(principal()), userId); assert.throws( () => resolveApiKeyTarget(principal(), otherUserId), (error: unknown) => error instanceof AuthError && error.code === 'insufficient_permission', ); assert.equal( resolveApiKeyTarget(principal({ isPlatformAdmin: true }), otherUserId), otherUserId, ); assert.throws( () => resolveApiKeyTarget(principal({ via: 'api_key' })), (error: unknown) => error instanceof AuthError && error.code === 'credential_management_forbidden', ); }); });