import { describe, expect, it } from 'vitest' import { db } from '~/data/db' import { apiClients } from '~/data/schema' import { hashToken, resolveClient } from '~/lib/api-auth' async function seedClient(token: string, revoked = false) { const [client] = await db.insert(apiClients).values({ name: 'Trakk Leseclient', tokenHash: hashToken(token), mode: 'read', scope: 'internal', revokedAt: revoked ? new Date() : null, }).returning() return client! } describe('resolveClient', () => { it('findet den Client zu einem gültigen Bearer-Token', async () => { const client = await seedClient('lb_live_abc') const request = new Request('http://localhost/api/v1/posts', { headers: { authorization: 'Bearer lb_live_abc' }, }) await expect(resolveClient(request)).resolves.toMatchObject({ id: client.id }) }) it('liefert nichts ohne Kopfzeile', async () => { await seedClient('lb_live_abc') const request = new Request('http://localhost/api/v1/posts') await expect(resolveClient(request)).resolves.toBeUndefined() }) it('liefert nichts für ein widerrufenes Token', async () => { await seedClient('lb_live_abc', true) const request = new Request('http://localhost/api/v1/posts', { headers: { authorization: 'Bearer lb_live_abc' }, }) await expect(resolveClient(request)).resolves.toBeUndefined() }) it('speichert das Token niemals im Klartext', async () => { await seedClient('lb_live_abc') const rows = await db.select().from(apiClients) expect(rows[0]!.tokenHash).not.toContain('lb_live_abc') }) })