-
-
Notifications
You must be signed in to change notification settings - Fork 137
/
spa-and-api.stateful.spec.ts
103 lines (88 loc) 路 2.41 KB
/
spa-and-api.stateful.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// 3p
import { createConnection, getConnection } from '@foal/typeorm/node_modules/typeorm';
import * as request from 'supertest';
// FoalTS
import {
controller,
createApp,
dependency,
HttpResponseCreated,
HttpResponseOK,
Post,
setSessionCookie,
TokenRequired
} from '@foal/core';
import { CsrfTokenRequired, getCsrfToken, setCsrfCookie } from '@foal/csrf';
import { TypeORMStore } from '@foal/typeorm';
describe('[CSRF|spa and api|stateful] Users', () => {
let app;
let sessionToken: string;
let csrfToken: string;
class AuthController {
@dependency
store: TypeORMStore;
@Post('/login')
async login() {
const session = await this.store.createAndSaveSessionFromUser({ id: 1 }, { csrfToken: true });
const response = new HttpResponseOK();
setSessionCookie(response, session.getToken());
setCsrfCookie(response, await getCsrfToken(session));
return response;
}
}
@TokenRequired({
cookie: true,
store: TypeORMStore,
})
@CsrfTokenRequired()
class ApiController {
@Post('/products')
createProduct() {
return new HttpResponseCreated();
}
}
class AppController {
subControllers = [
AuthController,
controller('/api', ApiController),
];
}
before(async () => {
process.env.SETTINGS_SESSION_SECRET = 'session-secret';
await createConnection({
database: 'e2e_db.sqlite',
dropSchema: true,
synchronize: true,
type: 'sqlite',
});
app = createApp(AppController);
});
after(async () => {
await getConnection().close();
delete process.env.SETTINGS_SESSION_SECRET;
});
it('can log in and get a CSRF token.', () => {
return request(app)
.post('/login')
.expect(200)
.then(response => {
const cookies = response.header['set-cookie'];
sessionToken = cookies[0].split('sessionID=')[1].split(';')[0];
csrfToken = cookies[1].split('csrfToken=')[1].split(';')[0];
});
});
it('cannot access POST routes with no CSRF token.', () => {
return request(app)
.post('/api/products')
.set('Cookie', [`sessionID=${sessionToken}`])
.expect(403)
.expect('Bad csrf token.');
});
it('can access POST routes with the CSRF token.', () => {
return request(app)
.post('/api/products')
.set('Cookie', [`sessionID=${sessionToken}`])
.set('X-CSRF-TOKEN', csrfToken)
.expect(201);
});
});