mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
fix: sign out (#14376)
#### PR Dependency Tree * **PR #14376** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Sign-out functionality now works in more scenarios, including when headers are absent or duplicated. * **Tests** * Added test coverage for sign-out behavior across different header configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -202,6 +202,68 @@ test('should be able to sign out', async t => {
|
|||||||
t.falsy(session);
|
t.falsy(session);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should be able to sign out when csrf header is missing (compat)', async t => {
|
||||||
|
const { app } = t.context;
|
||||||
|
|
||||||
|
const u1 = await app.createUser('u1@affine.pro');
|
||||||
|
|
||||||
|
const signInRes = await supertest(app.getHttpServer())
|
||||||
|
.post('/api/auth/sign-in')
|
||||||
|
.send({ email: u1.email, password: u1.password })
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
const cookies = parseCookies(signInRes);
|
||||||
|
const cookieHeader = Object.entries(cookies)
|
||||||
|
.map(([k, v]) => `${k}=${v}`)
|
||||||
|
.join('; ');
|
||||||
|
|
||||||
|
await supertest(app.getHttpServer())
|
||||||
|
.post('/api/auth/sign-out')
|
||||||
|
.set('Cookie', cookieHeader)
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
const sessionRes = await supertest(app.getHttpServer())
|
||||||
|
.get('/api/auth/session')
|
||||||
|
.set('Cookie', cookieHeader)
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
t.falsy(sessionRes.body.user);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should be able to sign out when duplicated csrf cookies exist', async t => {
|
||||||
|
const { app } = t.context;
|
||||||
|
|
||||||
|
const u1 = await app.createUser('u1@affine.pro');
|
||||||
|
|
||||||
|
const signInRes = await supertest(app.getHttpServer())
|
||||||
|
.post('/api/auth/sign-in')
|
||||||
|
.send({ email: u1.email, password: u1.password })
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
const cookies = parseCookies(signInRes);
|
||||||
|
const csrf = cookies[AuthService.csrfCookieName];
|
||||||
|
|
||||||
|
const cookieHeader = [
|
||||||
|
`${AuthService.sessionCookieName}=${cookies[AuthService.sessionCookieName]}`,
|
||||||
|
`${AuthService.userCookieName}=${cookies[AuthService.userCookieName]}`,
|
||||||
|
`${AuthService.csrfCookieName}=${csrf}`,
|
||||||
|
`${AuthService.csrfCookieName}=${randomUUID()}`,
|
||||||
|
].join('; ');
|
||||||
|
|
||||||
|
await supertest(app.getHttpServer())
|
||||||
|
.post('/api/auth/sign-out')
|
||||||
|
.set('Cookie', cookieHeader)
|
||||||
|
.set('x-affine-csrf-token', csrf)
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
const sessionRes = await supertest(app.getHttpServer())
|
||||||
|
.get('/api/auth/session')
|
||||||
|
.set('Cookie', cookieHeader)
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
t.falsy(sessionRes.body.user);
|
||||||
|
});
|
||||||
|
|
||||||
test('should reject sign out when csrf token mismatched', async t => {
|
test('should reject sign out when csrf token mismatched', async t => {
|
||||||
const { app } = t.context;
|
const { app } = t.context;
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,10 @@ export class AuthController {
|
|||||||
| string
|
| string
|
||||||
| undefined;
|
| undefined;
|
||||||
const csrfHeader = req.get('x-affine-csrf-token');
|
const csrfHeader = req.get('x-affine-csrf-token');
|
||||||
if (!csrfCookie || !csrfHeader || csrfCookie !== csrfHeader) {
|
if (
|
||||||
|
csrfHeader && // optional for backward compatibility, drop after 0.25.0 outdated
|
||||||
|
(!csrfCookie || csrfCookie !== csrfHeader)
|
||||||
|
) {
|
||||||
throw new ActionForbidden();
|
throw new ActionForbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user