/** * Tests for API key authentication middleware and security features. */ import request from 'supertest'; import { createApp } from '../../src/server/index'; import { SessionStore } from '../../src/server/SessionStore'; function makeApp(apiKey?: string) { if (apiKey !== undefined) { process.env['ABE_API_KEY'] = apiKey; } else { delete process.env['ABE_API_KEY']; } const store = new SessionStore('./reports'); return createApp(store); } afterEach(() => { delete process.env['ABE_API_KEY']; }); describe('Auth middleware', () => { it('allows all requests in dev mode (no ABE_API_KEY set)', async () => { const app = makeApp(undefined); const res = await request(app).get('/api/sessions'); expect(res.status).not.toBe(401); }); it('returns 401 when API key is missing', async () => { const app = makeApp('my-secret-key'); const res = await request(app).get('/api/sessions'); expect(res.status).toBe(401); }); it('returns 401 when wrong API key provided', async () => { const app = makeApp('my-secret-key'); const res = await request(app).get('/api/sessions').set('x-abe-api-key', 'wrong-key'); expect(res.status).toBe(401); }); it('allows request with correct API key', async () => { const app = makeApp('my-secret-key'); const res = await request(app).get('/api/sessions').set('x-abe-api-key', 'my-secret-key'); expect(res.status).toBe(200); }); }); describe('Health endpoints (no auth)', () => { it('GET /health requires no auth', async () => { const app = makeApp('super-secret'); const res = await request(app).get('/health'); expect(res.status).toBe(200); expect(res.body.status).toBe('ok'); }); it('GET /ready requires no auth', async () => { const app = makeApp('super-secret'); const res = await request(app).get('/ready'); expect(res.status).toBe(200); }); }); describe('Concurrent session limit', () => { it('returns 429 when limit exceeded', async () => { delete process.env['ABE_API_KEY']; const store = new SessionStore('./reports', undefined, undefined, 0); const app = createApp(store); const res = await request(app) .post('/api/sessions') .send({ url: 'http://localhost:3000' }); expect(res.status).toBe(429); expect(res.body.error).toMatch(/Max concurrent/i); }); });