mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 00:01:40 +03:00
df73b6ddc7
fix #6914
219 lines
5.6 KiB
TypeScript
219 lines
5.6 KiB
TypeScript
import { randomBytes } from 'node:crypto';
|
|
|
|
import {
|
|
getCurrentMailMessageCount,
|
|
getTokenFromLatestMailMessage,
|
|
} from '@affine-test/kit/utils/cloud';
|
|
import type { INestApplication } from '@nestjs/common';
|
|
import type { TestFn } from 'ava';
|
|
import ava from 'ava';
|
|
|
|
import { AuthService } from '../src/core/auth/service';
|
|
import { MailService } from '../src/fundamentals/mailer';
|
|
import {
|
|
changeEmail,
|
|
changePassword,
|
|
createTestingApp,
|
|
currentUser,
|
|
sendChangeEmail,
|
|
sendSetPasswordEmail,
|
|
sendVerifyChangeEmail,
|
|
signUp,
|
|
} from './utils';
|
|
|
|
const test = ava as TestFn<{
|
|
app: INestApplication;
|
|
auth: AuthService;
|
|
mail: MailService;
|
|
}>;
|
|
|
|
test.beforeEach(async t => {
|
|
const { app } = await createTestingApp();
|
|
const auth = app.get(AuthService);
|
|
const mail = app.get(MailService);
|
|
t.context.app = app;
|
|
t.context.auth = auth;
|
|
t.context.mail = mail;
|
|
});
|
|
|
|
test.afterEach.always(async t => {
|
|
await t.context.app.close();
|
|
});
|
|
|
|
test('change email', async t => {
|
|
const { mail, app } = t.context;
|
|
if (mail.hasConfigured()) {
|
|
const u1Email = 'u1@affine.pro';
|
|
const u2Email = 'u2@affine.pro';
|
|
|
|
const u1 = await signUp(app, 'u1', u1Email, '1');
|
|
|
|
const primitiveMailCount = await getCurrentMailMessageCount();
|
|
|
|
await sendChangeEmail(app, u1.token.token, u1Email, 'affine.pro');
|
|
|
|
const afterSendChangeMailCount = await getCurrentMailMessageCount();
|
|
t.is(
|
|
primitiveMailCount + 1,
|
|
afterSendChangeMailCount,
|
|
'failed to send change email'
|
|
);
|
|
|
|
const changeEmailToken = await getTokenFromLatestMailMessage();
|
|
|
|
t.not(
|
|
changeEmailToken,
|
|
null,
|
|
'fail to get change email token from email content'
|
|
);
|
|
|
|
await sendVerifyChangeEmail(
|
|
app,
|
|
u1.token.token,
|
|
changeEmailToken as string,
|
|
u2Email,
|
|
'affine.pro'
|
|
);
|
|
|
|
const afterSendVerifyMailCount = await getCurrentMailMessageCount();
|
|
|
|
t.is(
|
|
afterSendChangeMailCount + 1,
|
|
afterSendVerifyMailCount,
|
|
'failed to send verify email'
|
|
);
|
|
|
|
const verifyEmailToken = await getTokenFromLatestMailMessage();
|
|
|
|
t.not(
|
|
verifyEmailToken,
|
|
null,
|
|
'fail to get verify change email token from email content'
|
|
);
|
|
|
|
await changeEmail(app, u1.token.token, verifyEmailToken as string, u2Email);
|
|
|
|
const afterNotificationMailCount = await getCurrentMailMessageCount();
|
|
|
|
t.is(
|
|
afterSendVerifyMailCount + 1,
|
|
afterNotificationMailCount,
|
|
'failed to send notification email'
|
|
);
|
|
}
|
|
t.pass();
|
|
});
|
|
|
|
test('set and change password', async t => {
|
|
const { mail, app, auth } = t.context;
|
|
if (mail.hasConfigured()) {
|
|
const u1Email = 'u1@affine.pro';
|
|
|
|
const u1 = await signUp(app, 'u1', u1Email, '1');
|
|
|
|
const primitiveMailCount = await getCurrentMailMessageCount();
|
|
|
|
await sendSetPasswordEmail(app, u1.token.token, u1Email, 'affine.pro');
|
|
|
|
const afterSendSetMailCount = await getCurrentMailMessageCount();
|
|
|
|
t.is(
|
|
primitiveMailCount + 1,
|
|
afterSendSetMailCount,
|
|
'failed to send set email'
|
|
);
|
|
|
|
const setPasswordToken = await getTokenFromLatestMailMessage();
|
|
|
|
t.not(
|
|
setPasswordToken,
|
|
null,
|
|
'fail to get set password token from email content'
|
|
);
|
|
|
|
const newPassword = randomBytes(16).toString('hex');
|
|
const userId = await changePassword(
|
|
app,
|
|
u1.token.token,
|
|
setPasswordToken as string,
|
|
newPassword
|
|
);
|
|
t.is(u1.id, userId, 'failed to set password');
|
|
|
|
const ret = auth.signIn(u1Email, newPassword);
|
|
t.notThrowsAsync(ret, 'failed to check password');
|
|
t.is((await ret).id, u1.id, 'failed to check password');
|
|
}
|
|
t.pass();
|
|
});
|
|
test('should revoke token after change user identify', async t => {
|
|
const { mail, app, auth } = t.context;
|
|
if (mail.hasConfigured()) {
|
|
// change email
|
|
{
|
|
const u1Email = 'u1@affine.pro';
|
|
const u2Email = 'u2@affine.pro';
|
|
|
|
const u1 = await signUp(app, 'u1', u1Email, '1');
|
|
|
|
{
|
|
const user = await currentUser(app, u1.token.token);
|
|
t.is(user?.email, u1Email, 'failed to get current user');
|
|
}
|
|
|
|
await sendChangeEmail(app, u1.token.token, u1Email, 'affine.pro');
|
|
|
|
const changeEmailToken = await getTokenFromLatestMailMessage();
|
|
await sendVerifyChangeEmail(
|
|
app,
|
|
u1.token.token,
|
|
changeEmailToken as string,
|
|
u2Email,
|
|
'affine.pro'
|
|
);
|
|
|
|
const verifyEmailToken = await getTokenFromLatestMailMessage();
|
|
await changeEmail(
|
|
app,
|
|
u1.token.token,
|
|
verifyEmailToken as string,
|
|
u2Email
|
|
);
|
|
|
|
const user = await currentUser(app, u1.token.token);
|
|
t.is(user, null, 'token should be revoked');
|
|
|
|
const newUserSession = await auth.signIn(u2Email, '1');
|
|
t.is(newUserSession?.email, u2Email, 'failed to sign in with new email');
|
|
}
|
|
|
|
// change password
|
|
{
|
|
const u3Email = 'u3@affine.pro';
|
|
|
|
const u3 = await signUp(app, 'u1', u3Email, '1');
|
|
|
|
{
|
|
const user = await currentUser(app, u3.token.token);
|
|
t.is(user?.email, u3Email, 'failed to get current user');
|
|
}
|
|
|
|
await sendSetPasswordEmail(app, u3.token.token, u3Email, 'affine.pro');
|
|
const token = await getTokenFromLatestMailMessage();
|
|
const newPassword = randomBytes(16).toString('hex');
|
|
await changePassword(app, u3.token.token, token as string, newPassword);
|
|
|
|
const user = await currentUser(app, u3.token.token);
|
|
t.is(user, null, 'token should be revoked');
|
|
|
|
const newUserSession = await auth.signIn(u3Email, newPassword);
|
|
t.is(
|
|
newUserSession?.email,
|
|
u3Email,
|
|
'failed to sign in with new password'
|
|
);
|
|
}
|
|
}
|
|
t.pass();
|
|
});
|