mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-22 18:11:32 +03:00
143 lines
3.4 KiB
TypeScript
143 lines
3.4 KiB
TypeScript
import { Controller, Get, HttpStatus, INestApplication } from '@nestjs/common';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import ava, { TestFn } from 'ava';
|
|
import Sinon from 'sinon';
|
|
import request from 'supertest';
|
|
|
|
import { AuthModule, CurrentUser, Public, Session } from '../../src/core/auth';
|
|
import { AuthService } from '../../src/core/auth/service';
|
|
import { createTestingApp } from '../utils';
|
|
|
|
@Controller('/')
|
|
class TestController {
|
|
@Public()
|
|
@Get('/public')
|
|
home(@CurrentUser() user?: CurrentUser) {
|
|
return { user };
|
|
}
|
|
|
|
@Get('/private')
|
|
private(@CurrentUser() user: CurrentUser) {
|
|
return { user };
|
|
}
|
|
|
|
@Get('/session')
|
|
session(@Session() session: Session) {
|
|
return session;
|
|
}
|
|
}
|
|
|
|
const test = ava as TestFn<{
|
|
app: INestApplication;
|
|
}>;
|
|
|
|
let server!: any;
|
|
let auth!: AuthService;
|
|
let u1!: CurrentUser;
|
|
|
|
test.before(async t => {
|
|
const { app } = await createTestingApp({
|
|
imports: [AuthModule],
|
|
controllers: [TestController],
|
|
});
|
|
|
|
auth = app.get(AuthService);
|
|
u1 = await auth.signUp('u1@affine.pro', '1');
|
|
|
|
const db = app.get(PrismaClient);
|
|
await db.session.create({
|
|
data: {
|
|
id: '1',
|
|
},
|
|
});
|
|
await auth.createUserSession(u1.id, '1');
|
|
|
|
server = app.getHttpServer();
|
|
t.context.app = app;
|
|
});
|
|
|
|
test.after.always(async t => {
|
|
await t.context.app.close();
|
|
});
|
|
|
|
test('should be able to visit public api if not signed in', async t => {
|
|
const res = await request(server).get('/public').expect(200);
|
|
|
|
t.is(res.body.user, undefined);
|
|
});
|
|
|
|
test('should be able to visit public api if signed in', async t => {
|
|
const res = await request(server)
|
|
.get('/public')
|
|
.set('Cookie', `${AuthService.sessionCookieName}=1`)
|
|
.expect(HttpStatus.OK);
|
|
|
|
t.is(res.body.user.id, u1.id);
|
|
});
|
|
|
|
test('should not be able to visit private api if not signed in', async t => {
|
|
await request(server).get('/private').expect(HttpStatus.UNAUTHORIZED).expect({
|
|
status: 401,
|
|
code: 'Unauthorized',
|
|
type: 'AUTHENTICATION_REQUIRED',
|
|
name: 'AUTHENTICATION_REQUIRED',
|
|
message: 'You must sign in first to access this resource.',
|
|
});
|
|
|
|
t.assert(true);
|
|
});
|
|
|
|
test('should be able to visit private api if signed in', async t => {
|
|
const res = await request(server)
|
|
.get('/private')
|
|
.set('Cookie', `${AuthService.sessionCookieName}=1`)
|
|
.expect(HttpStatus.OK);
|
|
|
|
t.is(res.body.user.id, u1.id);
|
|
});
|
|
|
|
test('should be able to parse session cookie', async t => {
|
|
const spy = Sinon.spy(auth, 'getUserSession');
|
|
await request(server)
|
|
.get('/public')
|
|
.set('cookie', `${AuthService.sessionCookieName}=1`)
|
|
.expect(200);
|
|
|
|
t.deepEqual(spy.firstCall.args, ['1', undefined]);
|
|
spy.restore();
|
|
});
|
|
|
|
test('should be able to parse bearer token', async t => {
|
|
const spy = Sinon.spy(auth, 'getUserSession');
|
|
|
|
await request(server)
|
|
.get('/public')
|
|
.auth('1', { type: 'bearer' })
|
|
.expect(200);
|
|
|
|
t.deepEqual(spy.firstCall.args, ['1', undefined]);
|
|
spy.restore();
|
|
});
|
|
|
|
test('should be able to refresh session if needed', async t => {
|
|
await t.context.app.get(PrismaClient).userSession.updateMany({
|
|
where: {
|
|
sessionId: '1',
|
|
},
|
|
data: {
|
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60 /* expires in 1 hour */),
|
|
},
|
|
});
|
|
|
|
const res = await request(server)
|
|
.get('/session')
|
|
.set('cookie', `${AuthService.sessionCookieName}=1`)
|
|
.expect(200);
|
|
|
|
const cookie = res
|
|
.get('Set-Cookie')
|
|
?.find(c => c.startsWith(AuthService.sessionCookieName));
|
|
|
|
t.truthy(cookie);
|
|
});
|