project-auth.test.ts50 lines · main
| 1 | // apps/api/src/middleware/project-auth.test.ts |
| 2 | // |
| 3 | // Env vars must be set BEFORE any module that reads them is imported. |
| 4 | // cli-jwt.ts (via env.ts) and auth.ts both read process.env at module load, |
| 5 | // so mutate it first and then dynamic-import everything below. |
| 6 | |
| 7 | const ORIGINAL_SECRET = process.env.BRIVEN_BETTER_AUTH_SECRET; |
| 8 | const ORIGINAL_DB_URL = process.env.BRIVEN_DATABASE_URL; |
| 9 | process.env.BRIVEN_BETTER_AUTH_SECRET = ORIGINAL_SECRET ?? 'a'.repeat(32); |
| 10 | process.env.BRIVEN_DATABASE_URL = ORIGINAL_DB_URL ?? 'postgres://test:test@127.0.0.1:5/test'; |
| 11 | |
| 12 | import { describe, expect, it, afterAll } from 'bun:test'; |
| 13 | import type { AppEnv } from '../types/app-env.js'; |
| 14 | |
| 15 | describe('requireProjectAuth — CLI JWT branch', () => { |
| 16 | it('passes a CLI JWT through the auth gate (DB lookups may still fail downstream)', async () => { |
| 17 | const { Hono } = await import('hono'); |
| 18 | const { signCliToken } = await import('../lib/cli-jwt.js'); |
| 19 | const { requireProjectAuth } = await import('./project-auth.js'); |
| 20 | |
| 21 | const app = new Hono<AppEnv>(); |
| 22 | app.use('/v1/projects/:id/*', requireProjectAuth()); |
| 23 | app.get('/v1/projects/:id/probe', (c) => c.json({ ok: true })); |
| 24 | |
| 25 | const token = await signCliToken('u_proj_auth_jwt'); |
| 26 | const res = await app.request('/v1/projects/p_test/probe', { |
| 27 | headers: { authorization: `Bearer ${token}` }, |
| 28 | }); |
| 29 | // Either: |
| 30 | // 200 — DB present, user has access (unlikely in unit env) |
| 31 | // 401 — DB present but user-lookup failed (acceptable: bearer branch executed) |
| 32 | // 403 — bearer accepted, user found, no project access |
| 33 | // 500 — DB unavailable in unit env (bearer branch executed) |
| 34 | // CRITICAL: a 401 message must be specific to cli-jwt or project-access, |
| 35 | // NOT the generic 'expected Bearer brk_*' error from the old code path. |
| 36 | expect([200, 401, 403, 500]).toContain(res.status); |
| 37 | if (res.status === 401) { |
| 38 | const body = (await res.json()) as { message?: string }; |
| 39 | // Must NOT contain "brk_" — would prove the old API-key-only path ran. |
| 40 | expect(body.message ?? '').not.toMatch(/brk_/i); |
| 41 | } |
| 42 | }); |
| 43 | }); |
| 44 | |
| 45 | afterAll(() => { |
| 46 | if (ORIGINAL_SECRET === undefined) delete process.env.BRIVEN_BETTER_AUTH_SECRET; |
| 47 | else process.env.BRIVEN_BETTER_AUTH_SECRET = ORIGINAL_SECRET; |
| 48 | if (ORIGINAL_DB_URL === undefined) delete process.env.BRIVEN_DATABASE_URL; |
| 49 | else process.env.BRIVEN_DATABASE_URL = ORIGINAL_DB_URL; |
| 50 | }); |