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:
parent
81e8cc9201
commit
eea4d4cd3e
2 changed files with 21 additions and 33 deletions
|
@ -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({
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in a new issue