import fetch, {Response} from "node-fetch"; import useApp, {DEFAULT_ADDR, TestApp} from "./_app"; import Controller from "../src/Controller"; import CsrfProtectionComponent from "../src/components/CsrfProtectionComponent"; useApp(port => { return new class extends TestApp { protected async init(): Promise { this.use(new class extends Controller { routes(): void { this.get('/', (req, res, next) => { res.render('test/csrf.njk'); }, 'csrf_test'); this.post('/', (req, res, next) => { res.json({ status: 'ok', }); }, 'csrf_test'); } }()); await super.init(); } protected registerComponents() { super.registerComponents(); this.use(new CsrfProtectionComponent()); } }(port); }); describe('Test CSRF protection', () => { let res: Response; test('no csrf token should be in session at first', async () => { res = await fetch(DEFAULT_ADDR, { method: 'POST', }); expect(res.status).toBe(401); expect(await res.text()).toContain(`You weren't assigned any CSRF token.`); }); let cookies: string | null; test('sending no csrf token should fail', async () => { cookies = res.headers.get('set-cookie'); expect(cookies).toBeDefined(); res = await fetch(`${DEFAULT_ADDR}${Controller.route('csrf_test')}`, { headers: { 'Cookie': cookies!, } }); expect(res.ok).toBe(true); res = await fetch(DEFAULT_ADDR, { method: 'POST', headers: { 'Cookie': cookies!, } }); expect(res.status).toBe(401); expect(await res.text()).toContain(`You didn't provide any CSRF token.`); }); test('sending an invalid csrf token should fail', async () => { cookies = res.headers.get('set-cookie'); expect(cookies).toBeDefined(); res = await fetch(`${DEFAULT_ADDR}${Controller.route('csrf_test')}`, { headers: { 'Cookie': cookies!, } }); expect(res.ok).toBe(true); res = await fetch(DEFAULT_ADDR, { method: 'POST', body: JSON.stringify({ csrf: 'not_a_valid_csrf', }), headers: { 'Content-Type': 'application/json', 'Cookie': cookies!, } }); expect(res.status).toBe(401); expect(await res.text()).toContain(`Tokens don't match.`); }); test('sending a valid csrf token should success', async () => { cookies = res.headers.get('set-cookie'); expect(cookies).toBeDefined(); res = await fetch(`${DEFAULT_ADDR}${Controller.route('csrf_test')}`, { headers: { 'Cookie': cookies!, } }); expect(res.ok).toBe(true); let csrf = await res.text(); res = await fetch(DEFAULT_ADDR, { method: 'POST', body: JSON.stringify({ csrf: csrf, }), headers: { 'Content-Type': 'application/json', 'Cookie': cookies!, } }); expect(res.ok).toBe(true); }); });