CI / Generate TypeScript types (push) Successful in 11s
CI / Server unit tests (push) Successful in 31s
CI / Build server (push) Successful in 27s
CI / Build client (push) Successful in 47s
CI / Playwright E2E tests (push) Successful in 1m39s
CI / Build and push Docker image (push) Successful in 45s
CI / Notify (push) Successful in 2s
65 lines
2.9 KiB
TypeScript
65 lines
2.9 KiB
TypeScript
import express from 'express';
|
|
import request from 'supertest';
|
|
import { getTrustedRemoteUser, isTrustedPeer, parseTrustedIps } from '../trustedHeaders';
|
|
|
|
describe('parseTrustedIps / isTrustedPeer', () => {
|
|
const trusted = parseTrustedIps('10.42.0.0/16, 127.0.0.1, ::1, fd00::/8');
|
|
|
|
test('rozsah CIDR i jednotlivé adresy (IPv4 i IPv6)', () => {
|
|
expect(isTrustedPeer('10.42.0.84', trusted)).toBe(true);
|
|
expect(isTrustedPeer('10.43.0.1', trusted)).toBe(false);
|
|
expect(isTrustedPeer('127.0.0.1', trusted)).toBe(true);
|
|
expect(isTrustedPeer('::1', trusted)).toBe(true);
|
|
expect(isTrustedPeer('fd12:3456::1', trusted)).toBe(true);
|
|
expect(isTrustedPeer('192.168.1.10', trusted)).toBe(false);
|
|
});
|
|
|
|
test('IPv4 mapovaná do IPv6 (jak ji hlásí Node) se porovnává jako IPv4', () => {
|
|
expect(isTrustedPeer('::ffff:10.42.0.84', trusted)).toBe(true);
|
|
expect(isTrustedPeer('::FFFF:8.8.8.8', trusted)).toBe(false);
|
|
});
|
|
|
|
test('chybějící nebo nesmyslná adresa není důvěryhodná', () => {
|
|
expect(isTrustedPeer(undefined, trusted)).toBe(false);
|
|
expect(isTrustedPeer('nesmysl', trusted)).toBe(false);
|
|
});
|
|
|
|
test('neplatná konfigurace vyhodí chybu (server nenaběhne)', () => {
|
|
expect(() => parseTrustedIps('10.0.0.0/33')).toThrow('neplatný rozsah');
|
|
expect(() => parseTrustedIps('proxy.local')).toThrow('neplatná adresa');
|
|
expect(() => parseTrustedIps('10.0.0.0/x')).toThrow('neplatný rozsah');
|
|
});
|
|
|
|
test('prázdný seznam nedůvěřuje nikomu', () => {
|
|
expect(isTrustedPeer('127.0.0.1', parseTrustedIps(''))).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('getTrustedRemoteUser', () => {
|
|
/** Mini aplikace, která vrátí identitu z hlavičky (jako /api/whoami). */
|
|
function buildApp(trustedList: string) {
|
|
const trusted = parseTrustedIps(trustedList);
|
|
const app = express();
|
|
app.get('/whoami', (req, res) => res.send(getTrustedRemoteUser(req, 'remote-user', trusted) ?? ''));
|
|
return app;
|
|
}
|
|
|
|
test('hlavička od důvěryhodné adresy se přijme (i s diakritikou v latin1)', async () => {
|
|
const res = await request(buildApp('127.0.0.1,::1,::ffff:127.0.0.1'))
|
|
.get('/whoami')
|
|
.set('remote-user', Buffer.from('Novák', 'utf8').toString('latin1'));
|
|
expect(res.text).toBe('Novák');
|
|
});
|
|
|
|
test('hlavička od nedůvěryhodné adresy se ignoruje — ani X-Forwarded-For nepomůže', async () => {
|
|
const warn = jest.spyOn(console, 'warn').mockImplementation(() => { });
|
|
const res = await request(buildApp('10.42.0.0/16'))
|
|
.get('/whoami')
|
|
.set('remote-user', 'utocnik')
|
|
.set('X-Forwarded-For', '10.42.0.84');
|
|
expect(res.text).toBe('');
|
|
expect(warn).toHaveBeenCalledWith(expect.stringContaining('nedůvěryhodné adresy'));
|
|
warn.mockRestore();
|
|
});
|
|
});
|