0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(core): should not use login to store session info (#2017)

This commit is contained in:
Darcy Ye 2022-09-28 21:01:10 +08:00 committed by GitHub
parent 81e8cc9201
commit eea4d4cd3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 33 deletions

View file

@ -97,20 +97,18 @@ describe('session -> forgotPasswordRoutes', () => {
const response = await sessionRequest const response = await sessionRequest
.post(`${forgotPasswordRoute}/sms/verify-passcode`) .post(`${forgotPasswordRoute}/sms/verify-passcode`)
.send({ phone: '13000000000', code: '1234' }); .send({ phone: '13000000000', code: '1234' });
expect(response.statusCode).toEqual(200); expect(response.statusCode).toEqual(204);
expect(response.body).toHaveProperty('redirectTo');
expect(interactionResult).toHaveBeenCalledWith( expect(interactionResult).toHaveBeenCalledWith(
expect.anything(), expect.anything(),
expect.anything(), expect.anything(),
expect.objectContaining({ expect.objectContaining({
login: { accountId: 'id' },
forgotPassword: { forgotPassword: {
userId: 'id',
expiresAt: dayjs(fakeTime) expiresAt: dayjs(fakeTime)
.add(forgotPasswordVerificationTimeout, 'second') .add(forgotPasswordVerificationTimeout, 'second')
.toISOString(), .toISOString(),
}, },
}), })
expect.anything()
); );
jest.useRealTimers(); jest.useRealTimers();
}); });
@ -150,20 +148,18 @@ describe('session -> forgotPasswordRoutes', () => {
const response = await sessionRequest const response = await sessionRequest
.post(`${forgotPasswordRoute}/email/verify-passcode`) .post(`${forgotPasswordRoute}/email/verify-passcode`)
.send({ email: 'a@a.com', code: '1234' }); .send({ email: 'a@a.com', code: '1234' });
expect(response.statusCode).toEqual(200); expect(response.statusCode).toEqual(204);
expect(response.body).toHaveProperty('redirectTo');
expect(interactionResult).toHaveBeenCalledWith( expect(interactionResult).toHaveBeenCalledWith(
expect.anything(), expect.anything(),
expect.anything(), expect.anything(),
expect.objectContaining({ expect.objectContaining({
login: { accountId: 'id' },
forgotPassword: { forgotPassword: {
userId: 'id',
expiresAt: dayjs(fakeTime) expiresAt: dayjs(fakeTime)
.add(forgotPasswordVerificationTimeout, 'second') .add(forgotPasswordVerificationTimeout, 'second')
.toISOString(), .toISOString(),
}, },
}), })
expect.anything()
); );
jest.useRealTimers(); jest.useRealTimers();
}); });
@ -188,8 +184,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('assign result and redirect', async () => { it('assign result and redirect', async () => {
interactionDetails.mockResolvedValueOnce({ interactionDetails.mockResolvedValueOnce({
result: { result: {
login: { accountId: 'id' }, forgotPassword: { userId: 'id', expiresAt: dayjs().add(1, 'day').toISOString() },
forgotPassword: { expiresAt: dayjs().add(1, 'day').toISOString() },
}, },
}); });
const response = await sessionRequest const response = await sessionRequest
@ -219,8 +214,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('should throw when `forgotPassword.expiresAt` is not string', async () => { it('should throw when `forgotPassword.expiresAt` is not string', async () => {
interactionDetails.mockResolvedValueOnce({ interactionDetails.mockResolvedValueOnce({
result: { result: {
login: { accountId: 'id' }, forgotPassword: { userId: 'id', expiresAt: 0 },
forgotPassword: { expiresAt: 0 },
}, },
}); });
const response = await sessionRequest const response = await sessionRequest
@ -232,8 +226,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('should throw when `expiresAt` is not a valid date string', async () => { it('should throw when `expiresAt` is not a valid date string', async () => {
interactionDetails.mockResolvedValueOnce({ interactionDetails.mockResolvedValueOnce({
result: { result: {
login: { accountId: 'id' }, forgotPassword: { userId: 'id', expiresAt: 'invalid date string' },
forgotPassword: { expiresAt: 'invalid date string' },
}, },
}); });
const response = await sessionRequest const response = await sessionRequest
@ -245,8 +238,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('should throw when verification expires', async () => { it('should throw when verification expires', async () => {
interactionDetails.mockResolvedValueOnce({ interactionDetails.mockResolvedValueOnce({
result: { result: {
login: { accountId: 'id' }, forgotPassword: { userId: 'id', expiresAt: dayjs().subtract(1, 'day').toISOString() },
forgotPassword: { expiresAt: dayjs().subtract(1, 'day').toISOString() },
}, },
}); });
const response = await sessionRequest const response = await sessionRequest
@ -258,8 +250,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('should throw when new password is the same as old one', async () => { it('should throw when new password is the same as old one', async () => {
interactionDetails.mockResolvedValueOnce({ interactionDetails.mockResolvedValueOnce({
result: { result: {
login: { accountId: 'id' }, forgotPassword: { userId: 'id', expiresAt: dayjs().add(1, 'day').toISOString() },
forgotPassword: { expiresAt: dayjs().add(1, 'day').toISOString() },
}, },
}); });
mockArgon2Verify.mockResolvedValueOnce(true); mockArgon2Verify.mockResolvedValueOnce(true);
@ -272,8 +263,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('should redirect when there was no old password', async () => { it('should redirect when there was no old password', async () => {
interactionDetails.mockResolvedValueOnce({ interactionDetails.mockResolvedValueOnce({
result: { result: {
login: { accountId: 'id' }, forgotPassword: { userId: 'id', expiresAt: dayjs().add(1, 'day').toISOString() },
forgotPassword: { expiresAt: dayjs().add(1, 'day').toISOString() },
}, },
}); });
findUserById.mockResolvedValueOnce({ findUserById.mockResolvedValueOnce({

View file

@ -7,7 +7,6 @@ import { z } from 'zod';
import RequestError from '@/errors/RequestError'; import RequestError from '@/errors/RequestError';
import { createPasscode, sendPasscode, verifyPasscode } from '@/lib/passcode'; import { createPasscode, sendPasscode, verifyPasscode } from '@/lib/passcode';
import { assignInteractionResults } from '@/lib/session';
import { encryptUserPassword } from '@/lib/user'; import { encryptUserPassword } from '@/lib/user';
import koaGuard from '@/middleware/koa-guard'; import koaGuard from '@/middleware/koa-guard';
import { import {
@ -27,7 +26,7 @@ import { getRoutePrefix } from './utils';
export const forgotPasswordRoute = getRoutePrefix('forgot-password'); export const forgotPasswordRoute = getRoutePrefix('forgot-password');
const forgotPasswordVerificationGuard = z.object({ const forgotPasswordVerificationGuard = z.object({
forgotPassword: z.object({ expiresAt: z.string() }), forgotPassword: z.object({ userId: z.string(), expiresAt: z.string() }),
}); });
export default function forgotPasswordRoutes<T extends AnonymousRouter>( export default function forgotPasswordRoutes<T extends AnonymousRouter>(
@ -70,12 +69,13 @@ export default function forgotPasswordRoutes<T extends AnonymousRouter>(
const { id } = await findUserByPhone(phone); const { id } = await findUserByPhone(phone);
ctx.log(type, { userId: id }); ctx.log(type, { userId: id });
await assignInteractionResults(ctx, provider, { await provider.interactionResult(ctx.req, ctx.res, {
login: { accountId: id },
forgotPassword: { forgotPassword: {
userId: id,
expiresAt: dayjs().add(forgotPasswordVerificationTimeout, 'second').toISOString(), expiresAt: dayjs().add(forgotPasswordVerificationTimeout, 'second').toISOString(),
}, },
}); });
ctx.status = 204;
return next(); return next();
} }
@ -115,12 +115,13 @@ export default function forgotPasswordRoutes<T extends AnonymousRouter>(
await verifyPasscode(jti, PasscodeType.ForgotPassword, code, { email }); await verifyPasscode(jti, PasscodeType.ForgotPassword, code, { email });
const { id } = await findUserByEmail(email); const { id } = await findUserByEmail(email);
await assignInteractionResults(ctx, provider, { await provider.interactionResult(ctx.req, ctx.res, {
login: { accountId: id },
forgotPassword: { forgotPassword: {
userId: id,
expiresAt: dayjs().add(forgotPasswordVerificationTimeout, 'second').toISOString(), expiresAt: dayjs().add(forgotPasswordVerificationTimeout, 'second').toISOString(),
}, },
}); });
ctx.status = 204;
return next(); return next();
} }
@ -135,15 +136,12 @@ export default function forgotPasswordRoutes<T extends AnonymousRouter>(
const forgotPasswordVerificationResult = forgotPasswordVerificationGuard.safeParse(result); const forgotPasswordVerificationResult = forgotPasswordVerificationGuard.safeParse(result);
assertThat( assertThat(
result?.login?.accountId && forgotPasswordVerificationResult.success, forgotPasswordVerificationResult.success,
new RequestError({ code: 'session.forgot_password_session_not_found', status: 404 }) new RequestError({ code: 'session.forgot_password_session_not_found', status: 404 })
); );
const { const {
login: { accountId: id }, forgotPassword: { userId: id, expiresAt },
} = result;
const {
forgotPassword: { expiresAt },
} = forgotPasswordVerificationResult.data; } = forgotPasswordVerificationResult.data;
assertThat( assertThat(