2020-08-05 12:05:52 +02:00
|
|
|
import supertest from "supertest";
|
2021-05-03 19:29:22 +02:00
|
|
|
|
|
|
|
import CsrfProtectionComponent from "../src/components/CsrfProtectionComponent.js";
|
|
|
|
import Controller from "../src/Controller.js";
|
|
|
|
import TestApp from "../src/TestApp.js";
|
|
|
|
import useApp from "./_app.js";
|
2020-07-08 10:49:29 +02:00
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
let app: TestApp;
|
2020-11-14 18:16:58 +01:00
|
|
|
useApp(async (addr, port) => {
|
2020-08-05 12:05:52 +02:00
|
|
|
return app = new class extends TestApp {
|
2020-07-08 10:49:29 +02:00
|
|
|
protected async init(): Promise<void> {
|
|
|
|
this.use(new class extends Controller {
|
2020-09-25 23:42:15 +02:00
|
|
|
public routes(): void {
|
|
|
|
this.get('/', (req, res) => {
|
2020-11-15 15:15:21 +01:00
|
|
|
res.send(CsrfProtectionComponent.getCsrfToken(req.getSession()));
|
2020-07-08 10:49:29 +02:00
|
|
|
}, 'csrf_test');
|
|
|
|
|
2020-09-25 23:42:15 +02:00
|
|
|
this.post('/', (req, res) => {
|
2020-07-08 10:49:29 +02:00
|
|
|
res.json({
|
|
|
|
status: 'ok',
|
|
|
|
});
|
|
|
|
}, 'csrf_test');
|
|
|
|
}
|
|
|
|
}());
|
|
|
|
|
|
|
|
await super.init();
|
|
|
|
}
|
2021-05-03 19:29:22 +02:00
|
|
|
}('test', addr, port, true);
|
2020-07-08 10:49:29 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('Test CSRF protection', () => {
|
2020-08-05 12:05:52 +02:00
|
|
|
let cookies: string[];
|
|
|
|
let csrf: string;
|
|
|
|
|
|
|
|
test('no csrf token should be in session at first', (done) => {
|
|
|
|
const agent = supertest(app.getExpressApp());
|
|
|
|
agent.post('/')
|
2020-10-01 14:01:35 +02:00
|
|
|
.expect(401)
|
|
|
|
.then(res => {
|
2020-08-05 12:05:52 +02:00
|
|
|
expect(res.text).toContain(`You weren't assigned any CSRF token.`);
|
|
|
|
cookies = res.get('Set-Cookie');
|
|
|
|
|
|
|
|
agent.get('/')
|
|
|
|
.set('Cookie', cookies)
|
2020-10-01 14:01:35 +02:00
|
|
|
.expect(200)
|
|
|
|
.then(res => {
|
2020-08-05 12:05:52 +02:00
|
|
|
csrf = res.text;
|
|
|
|
done();
|
2020-10-01 14:01:35 +02:00
|
|
|
}).catch(done.fail);
|
|
|
|
}).catch(done.fail);
|
2020-07-08 10:49:29 +02:00
|
|
|
});
|
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
test('sending no csrf token should fail', (done) => {
|
2020-07-08 10:49:29 +02:00
|
|
|
expect(cookies).toBeDefined();
|
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
const agent = supertest(app.getExpressApp());
|
|
|
|
agent.post('/')
|
|
|
|
.set('Cookie', cookies)
|
|
|
|
.expect(401)
|
2020-10-01 14:01:35 +02:00
|
|
|
.then((res) => {
|
2020-08-05 12:05:52 +02:00
|
|
|
expect(res.text).toContain(`You didn't provide any CSRF token.`);
|
|
|
|
done();
|
2020-10-01 14:01:35 +02:00
|
|
|
}).catch(done.fail);
|
2020-07-08 10:49:29 +02:00
|
|
|
});
|
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
test('sending an invalid csrf token should fail', (done) => {
|
2020-07-08 10:49:29 +02:00
|
|
|
expect(cookies).toBeDefined();
|
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
const agent = supertest(app.getExpressApp());
|
|
|
|
agent.post('/')
|
|
|
|
.set('Cookie', cookies)
|
|
|
|
.set('Content-Type', 'application/json')
|
|
|
|
.send({csrf: 'not_a_valid_csrf'})
|
2020-10-01 14:01:35 +02:00
|
|
|
.expect(401)
|
|
|
|
.then(res => {
|
2020-08-05 12:05:52 +02:00
|
|
|
expect(res.text).toContain(`Tokens don't match.`);
|
|
|
|
done();
|
2020-10-01 14:01:35 +02:00
|
|
|
}).catch(done.fail);
|
2020-07-08 10:49:29 +02:00
|
|
|
});
|
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
test('sending a valid csrf token should success', (done) => {
|
2020-07-08 10:49:29 +02:00
|
|
|
expect(cookies).toBeDefined();
|
|
|
|
|
2020-08-05 12:05:52 +02:00
|
|
|
const agent = supertest(app.getExpressApp());
|
|
|
|
agent.post('/')
|
|
|
|
.set('Cookie', cookies)
|
|
|
|
.set('Content-Type', 'application/json')
|
|
|
|
.send({csrf: csrf})
|
2020-10-01 14:01:35 +02:00
|
|
|
.expect(200)
|
|
|
|
.then(() => done())
|
|
|
|
.catch(done.fail);
|
2020-07-08 10:49:29 +02:00
|
|
|
});
|
2020-09-25 23:42:15 +02:00
|
|
|
});
|