import supertest from "supertest"; import CsrfProtectionComponent from "../src/components/CsrfProtectionComponent.js"; import Controller from "../src/Controller.js"; import TestApp from "../src/TestApp.js"; import useApp from "./_app.js"; let app: TestApp; useApp(async (addr, port) => { return app = new class extends TestApp { protected async init(): Promise { this.use(new class extends Controller { public routes(): void { this.get('/', (req, res) => { res.send(this.getApp().as(CsrfProtectionComponent).getSessionCsrfToken(req.getSession())); }, 'csrf_test'); this.post('/', (req, res) => { res.json({ status: 'ok', }); }, 'csrf_test'); } }()); await super.init(); } }('test', addr, port, true, false); }); describe('Test CSRF protection', () => { let cookies: string[]; let csrf: string; test('no csrf token should be in session at first', (done) => { const agent = supertest(app.getExpressApp()); agent.post('/') .accept('json') .expect(401) .then(res => { expect(res.text).toContain(`You weren't assigned any CSRF token.`); cookies = res.get('Set-Cookie') || []; agent.get('/') .set('Cookie', cookies) .expect(200) .then(res => { csrf = res.text; done(); }).catch(done.fail); }).catch(done.fail); }); test('sending no csrf token should fail', (done) => { expect(cookies).toBeDefined(); const agent = supertest(app.getExpressApp()); agent.post('/') .accept('json') .set('Cookie', cookies) .expect(401) .then((res) => { expect(res.text).toContain(`You didn't provide any CSRF token.`); done(); }).catch(done.fail); }); test('sending an invalid csrf token should fail', (done) => { expect(cookies).toBeDefined(); const agent = supertest(app.getExpressApp()); agent.post('/') .accept('json') .set('Cookie', cookies) .set('Content-Type', 'application/json') .send({csrf: 'not_a_valid_csrf'}) .expect(401) .then(res => { expect(res.text).toContain(`Tokens don't match.`); done(); }).catch(done.fail); }); test('sending a valid csrf token should success', (done) => { expect(cookies).toBeDefined(); const agent = supertest(app.getExpressApp()); agent.post('/') .set('Cookie', cookies) .set('Content-Type', 'application/json') .send({csrf: csrf}) .expect(200) .then(() => done()) .catch(done.fail); }); });