// Generated, do not edit. sha256:47f02343d278744260374448334893708a776affbe44624b7fc8f089e85783c7 import { describe, it, before, after } from 'node:test'; import assert from 'node:assert/strict'; import { createServer } from 'node:http'; import { createRequestListener } from '../../server/app.mjs'; import { originOf, connectSrcOrigins, originAllowedByCsp } from '../../shared/csp.js'; import { CONFIG } from '../../shared/config.js'; describe('originOf', () => { it('geeft het origin van een gewone URL', () => { assert.equal(originOf('https://mempool.space/api/blocks/tip/height'), 'https://mempool.space'); assert.equal(originOf('https://pool.example.nl:3006/api'), 'https://pool.example.nl:3006'); }); it('geeft null bij iets dat geen URL is, in plaats van te gooien', () => { for (const rommel of ['', ' ', 'pool.example.nl', 'niet eens een adres', null, undefined, 42]) { assert.equal(originOf(rommel), null, `${rommel} hoort null te geven`); } }); }); describe('connectSrcOrigins', () => { it('bevat altijd de publieke mempool.space, ook zonder verbindingen', () => { assert.deepEqual(connectSrcOrigins(), [originOf(CONFIG.PRICE_SOURCES.MEMPOOL_PUBLIC_BASE)]); }); it('neemt een eigen explorer-verbinding op, zonder codewijziging', () => { const origins = connectSrcOrigins(['https://pool.example.nl:3006/', 'https://mempool.space']); assert.deepEqual(origins, ['https://mempool.space', 'https://pool.example.nl:3006']); }); it('laat met een verbindingsadres niets anders in de header komen dan een origin', () => { const origins = connectSrcOrigins([ 'javascript:alert(1)', 'data:text/plain,x', 'https://a.example; script-src *', 'https://b.example *', 'file:///etc/passwd', 'niet eens een adres', ]); assert.deepEqual(origins, ['https://mempool.space']); }); it('ontdubbelt en bevat geen null', () => { const origins = connectSrcOrigins(['https://mempool.space/api', 'https://mempool.space']); assert.equal(new Set(origins).size, origins.length); assert.equal(origins.some(o => !o), false); }); }); describe('originAllowedByCsp', () => { it('staat een origin uit de allowlist toe', () => { assert.equal(originAllowedByCsp(`${CONFIG.PRICE_SOURCES.MEMPOOL_PUBLIC_BASE}/api/blocks/tip/height`), true); }); it('WEIGERT een profiel dat niet in de lijst van het document stond', () => { assert.equal(originAllowedByCsp('https://mijn-eigen-explorer.example/api'), false); }); it('staat een profiel toe dat bij het laden al een verbinding was', () => { assert.equal(originAllowedByCsp('https://mijn-eigen-explorer.example/api/blocks/tip/height', null, ['https://mijn-eigen-explorer.example']), true); }); it('weigert rommel in plaats van hem door te laten', () => { for (const rommel of ['', 'pool.example.nl', null, undefined]) { assert.equal(originAllowedByCsp(rommel), false); } }); it('staat de eigen origin toe, maar alleen als die is meegegeven', () => { assert.equal(originAllowedByCsp('https://localhost:8080/api/data', 'https://localhost:8080'), true); assert.equal(originAllowedByCsp('https://localhost:8080/api/data'), false); }); }); describe('de CSP-header van een echt verzoek', () => { let server, basis, csp; before(async () => { server = createServer(createRequestListener({ credentials: null })); await new Promise(klaar => server.listen(0, '127.0.0.1', klaar)); basis = `http://127.0.0.1:${server.address().port}`; const res = await fetch(`${basis}/index.html`); assert.equal(res.status, 200, 'het inlaadpunt hoort gewoon geserveerd te worden'); csp = res.headers.get('content-security-policy'); }); after(() => server.close()); it('stuurt een header mee', () => { assert.ok(csp, 'zonder header is er geen grens en zegt de rest van deze suite niets'); }); it('staat in connect-src precies de origins toe die de helper noemt', () => { const directive = csp.split(';').map(d => d.trim()).find(d => d.startsWith('connect-src')); const bronnen = directive.split(/\s+/).slice(1); assert.deepEqual(bronnen, [`'self'`, ...connectSrcOrigins()]); }); it('houdt script-src kaal op self, zonder enige uitzondering', () => { const directive = csp.split(';').map(d => d.trim()).find(d => d.startsWith('script-src')); assert.equal(directive, `script-src 'self'`); }); it('sluit object-src en frame-ancestors helemaal af', () => { assert.match(csp, /object-src 'none'/); assert.match(csp, /frame-ancestors 'none'/); }); });