Spaces:
Paused
Paused
File size: 3,026 Bytes
2276d59 1f34571 2276d59 1f34571 2276d59 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | import { describe, it, expect, afterEach, vi } from 'vitest';
import request from 'supertest';
import app from '../../src/app.js';
import { assertProdConfig } from '../../src/utils/network/auth.util.js';
// non-local test client
const REMOTE = '203.0.113.5';
describe('inbound API key auth', () => {
afterEach(() => {
vi.unstubAllEnvs();
});
it('is disabled when API_KEY is unset', async () => {
vi.stubEnv('API_KEY', '');
const res = await request(app).get('/proxy').set('X-Forwarded-For', REMOTE);
expect(res.status).toBe(403);
});
it('returns 401 for a remote request with no key', async () => {
vi.stubEnv('API_KEY', 'secret');
const res = await request(app).get('/proxy').set('X-Forwarded-For', REMOTE);
expect(res.status).toBe(401);
});
it('returns 401 for a wrong key', async () => {
vi.stubEnv('API_KEY', 'secret');
const res = await request(app)
.get('/proxy')
.set('X-Forwarded-For', REMOTE)
.set('x-api-key', 'nope');
expect(res.status).toBe(401);
});
it('accepts a correct key header (then hits the 403 sig gate)', async () => {
vi.stubEnv('API_KEY', 'secret');
const res = await request(app)
.get('/proxy')
.set('X-Forwarded-For', REMOTE)
.set('x-api-key', 'secret');
expect(res.status).toBe(403);
});
it('accepts a correct ?key= query', async () => {
vi.stubEnv('API_KEY', 'secret');
const res = await request(app)
.get('/proxy?key=secret')
.set('X-Forwarded-For', REMOTE);
expect(res.status).toBe(403);
});
it('exempts localhost even with no key', async () => {
vi.stubEnv('API_KEY', 'secret');
const res = await request(app).get('/proxy');
expect(res.status).toBe(403);
});
});
describe('localhost bypass cannot be spoofed via header', () => {
afterEach(() => vi.unstubAllEnvs());
it('rejects a spoofed X-Forwarded-For: 127.0.0.1', async () => {
vi.stubEnv('API_KEY', 'secret');
const res = await request(app)
.get('/proxy')
.set('X-Forwarded-For', '127.0.0.1');
expect(res.status).toBe(401);
});
});
describe('assertProdConfig', () => {
it('passes in production without API_KEY (auth disabled)', () => {
expect(() =>
assertProdConfig({
NODE_ENV: 'production',
PROXY_SIGNING_SECRET: 's',
} as NodeJS.ProcessEnv)
).not.toThrow();
});
it('throws in production without PROXY_SIGNING_SECRET', () => {
expect(() =>
assertProdConfig({
NODE_ENV: 'production',
API_KEY: 'x',
} as NodeJS.ProcessEnv)
).toThrow();
});
it('passes in production with API_KEY and PROXY_SIGNING_SECRET', () => {
expect(() =>
assertProdConfig({
NODE_ENV: 'production',
API_KEY: 'x',
PROXY_SIGNING_SECRET: 's',
} as NodeJS.ProcessEnv)
).not.toThrow();
});
it('passes outside production', () => {
expect(() =>
assertProdConfig({ NODE_ENV: 'development' } as NodeJS.ProcessEnv)
).not.toThrow();
});
});
|