teach/test/api-security.test.js
Ramon f9b2be8187
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 4s
v0.3.03-beta: versterk publieke beveiliging
2026-07-14 12:42:16 +02:00

61 lines
2.3 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import Fastify from 'fastify';
import cookie from '@fastify/cookie';
import rateLimit from '@fastify/rate-limit';
import api from '../src/api.js';
import { hashPassword } from '../src/auth.js';
async function makeApp() {
const passwordHash = await hashPassword('Veilig123');
const calls = [];
const pool = {
async query(sql, params=[]) {
calls.push({sql, params});
if (sql.includes('FROM users WHERE school_id = $1')) return {rows:[{
id: 7, username: 'docent', display_name: 'Docent', role: 'teacher',
school_id: 2, class_id: null, password_hash: passwordHash, data: {},
}]};
return {rows:[]};
},
};
const app = Fastify({trustProxy: 2});
await app.register(cookie);
await app.register(rateLimit, {global:false});
app.decorate('pg', pool);
await app.register(api, {prefix:'/api'});
await app.ready();
return {app, calls};
}
test('login zet HttpOnly-cookie en bewaart alleen een tokenhash', async () => {
const oldNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = 'production';
const {app, calls} = await makeApp();
const res = await app.inject({method:'POST', url:'/api/auth/login', payload:{
schoolId:2, username:'docent', password:'Veilig123',
}});
assert.equal(res.statusCode, 200, res.body);
assert.equal('token' in res.json(), false);
const setCookie = res.headers['set-cookie'];
assert.match(setCookie, /teach_session=/);
assert.match(setCookie, /HttpOnly/);
assert.match(setCookie, /Secure/);
assert.match(setCookie, /SameSite=Strict/);
const rawToken = /teach_session=([^;]+)/.exec(setCookie)[1];
const insert = calls.find(c=>c.sql.includes('INSERT INTO sessions'));
assert.ok(insert);
assert.notEqual(insert.params[0], rawToken);
assert.match(insert.params[0], /^[a-f0-9]{64}$/);
await app.close();
if (oldNodeEnv === undefined) delete process.env.NODE_ENV; else process.env.NODE_ENV = oldNodeEnv;
});
test('state-changing request met vreemde Origin wordt geweigerd', async () => {
const {app} = await makeApp();
const res = await app.inject({method:'POST', url:'/api/auth/logout', headers:{
origin:'https://aanvaller.example', host:'teach.example',
}, payload:{}});
assert.equal(res.statusCode, 403);
await app.close();
});