0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-17 22:31:28 -05:00

refactor: rename MessageTypes -> VerificationCodeType (#2745)

This commit is contained in:
Gao Sun 2022-12-28 14:28:46 +08:00 committed by GitHub
parent fd4bd8a2df
commit 06ec86d831
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 166 additions and 146 deletions

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import type { Application, Passcode, Resource, Role, Setting } from '@logto/schemas';
import { ApplicationType } from '@logto/schemas';
@ -55,7 +55,7 @@ export const mockPasscode: Passcode = {
interactionJti: 'jti',
phone: '888 888 8888',
email: 'foo@logto.io',
type: MessageTypes.SignIn,
type: VerificationCodeType.SignIn,
code: 'asdfghjkl',
consumed: false,
tryCount: 2,

View file

@ -1,10 +1,10 @@
import type { AllConnector, CreateConnector, MessageTypes } from '@logto/connector-kit';
import type { AllConnector, CreateConnector, VerificationCodeType } from '@logto/connector-kit';
import type { Connector } from '@logto/schemas';
import { z } from 'zod';
export { ConnectorType } from '@logto/schemas';
export type TemplateType = MessageTypes;
export type TemplateType = VerificationCodeType;
export const socialUserInfoGuard = z.object({
id: z.string(),

View file

@ -1,4 +1,4 @@
import { ConnectorType, MessageTypes } from '@logto/connector-kit';
import { ConnectorType, VerificationCodeType } from '@logto/connector-kit';
import { Passcode } from '@logto/schemas';
import { createMockUtils } from '@logto/shared/esm';
import { any } from 'zod';
@ -60,7 +60,7 @@ afterEach(() => {
describe('createPasscode', () => {
it('should generate `passcodeLength` digits code for phone and insert to database', async () => {
const phone = '13000000000';
const passcode = await createPasscode('jti', MessageTypes.SignIn, {
const passcode = await createPasscode('jti', VerificationCodeType.SignIn, {
phone,
});
expect(new RegExp(`^\\d{${passcodeLength}}$`).test(passcode.code)).toBeTruthy();
@ -69,7 +69,7 @@ describe('createPasscode', () => {
it('should generate `passcodeLength` digits code for email and insert to database', async () => {
const email = 'jony@example.com';
const passcode = await createPasscode('jti', MessageTypes.SignIn, {
const passcode = await createPasscode('jti', VerificationCodeType.SignIn, {
email,
});
expect(new RegExp(`^\\d{${passcodeLength}}$`).test(passcode.code)).toBeTruthy();
@ -84,7 +84,7 @@ describe('createPasscode', () => {
id: 'id',
interactionJti: jti,
code: '1234',
type: MessageTypes.SignIn,
type: VerificationCodeType.SignIn,
createdAt: Date.now(),
phone: '',
email,
@ -92,7 +92,7 @@ describe('createPasscode', () => {
tryCount: 0,
},
]);
await createPasscode(jti, MessageTypes.SignIn, {
await createPasscode(jti, VerificationCodeType.SignIn, {
email,
});
expect(deletePasscodesByIds).toHaveBeenCalledWith(['id']);
@ -106,7 +106,7 @@ describe('sendPasscode', () => {
interactionJti: 'jti',
phone: null,
email: null,
type: MessageTypes.SignIn,
type: VerificationCodeType.SignIn,
code: '1234',
consumed: false,
tryCount: 0,
@ -139,7 +139,7 @@ describe('sendPasscode', () => {
interactionJti: 'jti',
phone: 'phone',
email: null,
type: MessageTypes.SignIn,
type: VerificationCodeType.SignIn,
code: '1234',
consumed: false,
tryCount: 0,
@ -190,7 +190,7 @@ describe('sendPasscode', () => {
interactionJti: 'jti',
phone: 'phone',
email: null,
type: MessageTypes.SignIn,
type: VerificationCodeType.SignIn,
code: '1234',
consumed: false,
tryCount: 0,
@ -213,7 +213,7 @@ describe('verifyPasscode', () => {
interactionJti: 'jti',
phone: 'phone',
email: null,
type: MessageTypes.SignIn,
type: VerificationCodeType.SignIn,
code: '1234',
consumed: false,
tryCount: 0,

View file

@ -1,5 +1,9 @@
import type { EmailConnector, MessageTypes, SmsConnector } from '@logto/connector-kit';
import { messageTypesGuard, ConnectorError, ConnectorErrorCodes } from '@logto/connector-kit';
import type { EmailConnector, VerificationCodeType, SmsConnector } from '@logto/connector-kit';
import {
verificationCodeTypeGuard,
ConnectorError,
ConnectorErrorCodes,
} from '@logto/connector-kit';
import type { Passcode } from '@logto/schemas';
import { customAlphabet, nanoid } from 'nanoid';
@ -22,7 +26,7 @@ const randomCode = customAlphabet('1234567890', passcodeLength);
export const createPasscode = async (
jti: string,
type: MessageTypes,
type: VerificationCodeType,
payload: { phone: string } | { email: string }
) => {
// Disable existing passcodes.
@ -66,7 +70,7 @@ export const sendPasscode = async (passcode: Passcode) => {
const { dbEntry, metadata, sendMessage } = connector;
const messageTypeResult = messageTypesGuard.safeParse(passcode.type);
const messageTypeResult = verificationCodeTypeGuard.safeParse(passcode.type);
if (!messageTypeResult.success) {
throw new ConnectorError(ConnectorErrorCodes.InvalidConfig);
@ -88,7 +92,7 @@ export const passcodeMaxTryCount = 10;
export const verifyPasscode = async (
sessionId: string,
type: MessageTypes,
type: VerificationCodeType,
code: string,
payload: { phone: string } | { email: string }
): Promise<void> => {

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { Passcodes } from '@logto/schemas';
import { convertToIdentifiers, convertToPrimitiveOrSql, excludeAutoSetFields } from '@logto/shared';
import { createMockPool, createMockQueryResult, sql } from 'slonik';
@ -35,7 +35,7 @@ describe('passcode query', () => {
it('findUnconsumedPasscodeByJtiAndType', async () => {
const jti = 'foo';
const type = MessageTypes.SignIn;
const type = VerificationCodeType.SignIn;
const expectSql = sql`
select ${sql.join(Object.values(fields), sql`, `)}
@ -55,7 +55,7 @@ describe('passcode query', () => {
it('findUnconsumedPasscodesByJtiAndType', async () => {
const jti = 'foo';
const type = MessageTypes.SignIn;
const type = VerificationCodeType.SignIn;
const expectSql = sql`
select ${sql.join(Object.values(fields), sql`, `)}

View file

@ -1,4 +1,4 @@
import type { MessageTypes } from '@logto/connector-kit';
import type { VerificationCodeType } from '@logto/connector-kit';
import type { Passcode, CreatePasscode } from '@logto/schemas';
import { Passcodes } from '@logto/schemas';
import { convertToIdentifiers } from '@logto/shared';
@ -10,14 +10,17 @@ import { DeletionError } from '#src/errors/SlonikError/index.js';
const { table, fields } = convertToIdentifiers(Passcodes);
export const findUnconsumedPasscodeByJtiAndType = async (jti: string, type: MessageTypes) =>
export const findUnconsumedPasscodeByJtiAndType = async (jti: string, type: VerificationCodeType) =>
envSet.pool.maybeOne<Passcode>(sql`
select ${sql.join(Object.values(fields), sql`, `)}
from ${table}
where ${fields.interactionJti}=${jti} and ${fields.type}=${type} and ${fields.consumed} = false
`);
export const findUnconsumedPasscodesByJtiAndType = async (jti: string, type: MessageTypes) =>
export const findUnconsumedPasscodesByJtiAndType = async (
jti: string,
type: VerificationCodeType
) =>
envSet.pool.any<Passcode>(sql`
select ${sql.join(Object.values(fields), sql`, `)}
from ${table}

View file

@ -1,6 +1,6 @@
/* eslint-disable max-lines */
import type { EmailConnector, SmsConnector } from '@logto/connector-kit';
import { ConnectorPlatform, MessageTypes } from '@logto/connector-kit';
import { ConnectorPlatform, VerificationCodeType } from '@logto/connector-kit';
import { ConnectorType } from '@logto/schemas';
import { pickDefault, createMockUtils } from '@logto/shared/esm';
import { any } from 'zod';
@ -390,7 +390,7 @@ describe('connector route', () => {
expect(sendMessage).toHaveBeenCalledWith(
{
to: '12345678901',
type: MessageTypes.Test,
type: VerificationCodeType.Test,
payload: {
code: '123456',
},
@ -418,7 +418,7 @@ describe('connector route', () => {
expect(sendMessage).toHaveBeenCalledWith(
{
to: 'test@email.com',
type: MessageTypes.Test,
type: VerificationCodeType.Test,
payload: {
code: 'email-test',
},

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { emailRegEx, phoneRegEx, buildIdGenerator } from '@logto/core-kit';
import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas';
import { arbitraryObjectGuard, Connectors, ConnectorType } from '@logto/schemas';
@ -282,7 +282,7 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
await sendMessage(
{
to: subject,
type: MessageTypes.Test,
type: VerificationCodeType.Test,
payload: {
code: phone ? '123456' : 'email-test',
},

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { InteractionEvent } from '@logto/schemas';
import { createMockUtils } from '@logto/shared/esm';
@ -19,27 +19,27 @@ const { sendPasscodeToIdentifier } = await import('./passcode-validation.js');
const sendPasscodeTestCase = [
{
payload: { email: 'email', event: InteractionEvent.SignIn },
createPasscodeParams: [MessageTypes.SignIn, { email: 'email' }],
createPasscodeParams: [VerificationCodeType.SignIn, { email: 'email' }],
},
{
payload: { email: 'email', event: InteractionEvent.Register },
createPasscodeParams: [MessageTypes.Register, { email: 'email' }],
createPasscodeParams: [VerificationCodeType.Register, { email: 'email' }],
},
{
payload: { email: 'email', event: InteractionEvent.ForgotPassword },
createPasscodeParams: [MessageTypes.ForgotPassword, { email: 'email' }],
createPasscodeParams: [VerificationCodeType.ForgotPassword, { email: 'email' }],
},
{
payload: { phone: 'phone', event: InteractionEvent.SignIn },
createPasscodeParams: [MessageTypes.SignIn, { phone: 'phone' }],
createPasscodeParams: [VerificationCodeType.SignIn, { phone: 'phone' }],
},
{
payload: { phone: 'phone', event: InteractionEvent.Register },
createPasscodeParams: [MessageTypes.Register, { phone: 'phone' }],
createPasscodeParams: [VerificationCodeType.Register, { phone: 'phone' }],
},
{
payload: { phone: 'phone', event: InteractionEvent.ForgotPassword },
createPasscodeParams: [MessageTypes.ForgotPassword, { phone: 'phone' }],
createPasscodeParams: [VerificationCodeType.ForgotPassword, { phone: 'phone' }],
},
];

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import type { InteractionEvent } from '@logto/schemas';
import { createPasscode, sendPasscode, verifyPasscode } from '#src/libraries/passcode.js';
@ -8,16 +8,16 @@ import type { SendPasscodePayload, PasscodeIdentifierPayload } from '../types/in
/**
* Refactor Needed:
* This is a work around to map the latest interaction event type to old MessageTypes
* This is a work around to map the latest interaction event type to old VerificationCodeType
* */
const eventToMessageTypesMap: Record<InteractionEvent, MessageTypes> = {
SignIn: MessageTypes.SignIn,
Register: MessageTypes.Register,
ForgotPassword: MessageTypes.ForgotPassword,
const eventToVerificationCodeTypeMap: Record<InteractionEvent, VerificationCodeType> = {
SignIn: VerificationCodeType.SignIn,
Register: VerificationCodeType.Register,
ForgotPassword: VerificationCodeType.ForgotPassword,
};
const getMessageTypesByEvent = (event: InteractionEvent): MessageTypes =>
eventToMessageTypesMap[event];
const getVerificationCodeTypeByEvent = (event: InteractionEvent): VerificationCodeType =>
eventToVerificationCodeTypeMap[event];
export const sendPasscodeToIdentifier = async (
payload: SendPasscodePayload & { event: InteractionEvent },
@ -25,7 +25,7 @@ export const sendPasscodeToIdentifier = async (
createLog: LogContext['createLog']
) => {
const { event, ...identifier } = payload;
const messageType = getMessageTypesByEvent(event);
const messageType = getVerificationCodeTypeByEvent(event);
const log = createLog(`Interaction.${event}.Identifier.VerificationCode.Create`);
log.append(identifier);
@ -42,7 +42,7 @@ export const verifyIdentifierByPasscode = async (
createLog: LogContext['createLog']
) => {
const { event, passcode, ...identifier } = payload;
const messageType = getMessageTypesByEvent(event);
const messageType = getVerificationCodeTypeByEvent(event);
// TODO: @Simeng maybe we should just log all interaction payload in every request?
const log = createLog(`Interaction.${event}.Identifier.VerificationCode.Submit`);

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { addDays, subSeconds } from 'date-fns';
import { Provider } from 'oidc-provider';
@ -140,7 +140,7 @@ describe('session -> continueRoutes', () => {
continueSignIn: {
userId: mockUser.id,
expiresAt: getTomorrowIsoString(),
type: MessageTypes.Continue,
type: VerificationCodeType.Continue,
},
},
});
@ -172,7 +172,7 @@ describe('session -> continueRoutes', () => {
continueSignIn: {
userId: mockUser.id,
expiresAt: getTomorrowIsoString(),
type: MessageTypes.Continue,
type: VerificationCodeType.Continue,
},
},
});

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import type { User } from '@logto/schemas';
import { addDays, subDays } from 'date-fns';
import { Provider } from 'oidc-provider';
@ -97,7 +97,7 @@ describe('session -> forgotPasswordRoutes', () => {
verification: {
userId: 'id',
expiresAt: getTomorrowDate().toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
},
});
@ -118,7 +118,7 @@ describe('session -> forgotPasswordRoutes', () => {
result: {
verification: {
expiresAt: getTomorrowDate().toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
},
});
@ -134,7 +134,7 @@ describe('session -> forgotPasswordRoutes', () => {
verification: {
userId: 'id',
expiresAt: getTomorrowDate().toISOString(),
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
},
},
});
@ -147,7 +147,7 @@ describe('session -> forgotPasswordRoutes', () => {
it('should throw when `verification.expiresAt` is not string', async () => {
interactionDetails.mockResolvedValueOnce({
result: {
verification: { userId: 'id', expiresAt: 0, flow: MessageTypes.ForgotPassword },
verification: { userId: 'id', expiresAt: 0, flow: VerificationCodeType.ForgotPassword },
},
});
const response = await sessionRequest
@ -162,7 +162,7 @@ describe('session -> forgotPasswordRoutes', () => {
verification: {
userId: 'id',
expiresAt: 'invalid date string',
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
},
});
@ -178,7 +178,7 @@ describe('session -> forgotPasswordRoutes', () => {
verification: {
userId: 'id',
expiresAt: getYesterdayDate().toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
},
});
@ -194,7 +194,7 @@ describe('session -> forgotPasswordRoutes', () => {
verification: {
userId: 'id',
expiresAt: getTomorrowDate().toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
},
});
@ -211,7 +211,7 @@ describe('session -> forgotPasswordRoutes', () => {
verification: {
userId: 'id',
expiresAt: getTomorrowDate().toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
},
});

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { SignInIdentifier } from '@logto/schemas';
import type { MiddlewareType } from 'koa';
import type { Provider } from 'oidc-provider';
@ -52,7 +52,7 @@ export const smsSignInAction = <StateT, ContextT extends WithLogContextLegacy, R
smsSessionResultGuard
);
const type = getPasswordlessRelatedLogType(MessageTypes.SignIn, 'sms');
const type = getPasswordlessRelatedLogType(VerificationCodeType.SignIn, 'sms');
ctx.log(type, verificationStorage);
const { phone, expiresAt } = verificationStorage;
@ -97,7 +97,7 @@ export const emailSignInAction = <StateT, ContextT extends WithLogContextLegacy,
emailSessionResultGuard
);
const type = getPasswordlessRelatedLogType(MessageTypes.SignIn, 'email');
const type = getPasswordlessRelatedLogType(VerificationCodeType.SignIn, 'email');
ctx.log(type, verificationStorage);
const { email, expiresAt } = verificationStorage;
@ -140,7 +140,7 @@ export const smsRegisterAction = <StateT, ContextT extends WithLogContextLegacy,
smsSessionResultGuard
);
const type = getPasswordlessRelatedLogType(MessageTypes.Register, 'sms');
const type = getPasswordlessRelatedLogType(VerificationCodeType.Register, 'sms');
ctx.log(type, verificationStorage);
const { phone, expiresAt } = verificationStorage;
@ -184,7 +184,7 @@ export const emailRegisterAction = <StateT, ContextT extends WithLogContextLegac
emailSessionResultGuard
);
const type = getPasswordlessRelatedLogType(MessageTypes.Register, 'email');
const type = getPasswordlessRelatedLogType(VerificationCodeType.Register, 'email');
ctx.log(type, verificationStorage);
const { email, expiresAt } = verificationStorage;

View file

@ -1,5 +1,5 @@
/* eslint-disable max-lines */
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import type { User } from '@logto/schemas';
import { SignInIdentifier } from '@logto/schemas';
import type { Nullable } from '@silverhand/essentials';
@ -108,9 +108,9 @@ describe('session -> passwordlessRoutes', () => {
it('should call sendPasscode (with flow `sign-in`)', async () => {
const response = await sessionRequest
.post('/session/passwordless/sms/send')
.send({ phone: '13000000000', flow: MessageTypes.SignIn });
.send({ phone: '13000000000', flow: VerificationCodeType.SignIn });
expect(response.statusCode).toEqual(204);
expect(createPasscode).toHaveBeenCalledWith('jti', MessageTypes.SignIn, {
expect(createPasscode).toHaveBeenCalledWith('jti', VerificationCodeType.SignIn, {
phone: '13000000000',
});
expect(sendPasscode).toHaveBeenCalled();
@ -118,9 +118,9 @@ describe('session -> passwordlessRoutes', () => {
it('should call sendPasscode (with flow `register`)', async () => {
const response = await sessionRequest
.post('/session/passwordless/sms/send')
.send({ phone: '13000000000', flow: MessageTypes.Register });
.send({ phone: '13000000000', flow: VerificationCodeType.Register });
expect(response.statusCode).toEqual(204);
expect(createPasscode).toHaveBeenCalledWith('jti', MessageTypes.Register, {
expect(createPasscode).toHaveBeenCalledWith('jti', VerificationCodeType.Register, {
phone: '13000000000',
});
expect(sendPasscode).toHaveBeenCalled();
@ -128,9 +128,9 @@ describe('session -> passwordlessRoutes', () => {
it('should call sendPasscode (with flow `forgot-password`)', async () => {
const response = await sessionRequest
.post('/session/passwordless/sms/send')
.send({ phone: '13000000000', flow: MessageTypes.ForgotPassword });
.send({ phone: '13000000000', flow: VerificationCodeType.ForgotPassword });
expect(response.statusCode).toEqual(204);
expect(createPasscode).toHaveBeenCalledWith('jti', MessageTypes.ForgotPassword, {
expect(createPasscode).toHaveBeenCalledWith('jti', VerificationCodeType.ForgotPassword, {
phone: '13000000000',
});
expect(sendPasscode).toHaveBeenCalled();
@ -138,7 +138,7 @@ describe('session -> passwordlessRoutes', () => {
it('throw when phone not given in input params', async () => {
const response = await sessionRequest
.post('/session/passwordless/sms/send')
.send({ flow: MessageTypes.Register });
.send({ flow: VerificationCodeType.Register });
expect(response.statusCode).toEqual(400);
});
});
@ -152,9 +152,9 @@ describe('session -> passwordlessRoutes', () => {
it('should call sendPasscode (with flow `sign-in`)', async () => {
const response = await sessionRequest
.post('/session/passwordless/email/send')
.send({ email: 'a@a.com', flow: MessageTypes.SignIn });
.send({ email: 'a@a.com', flow: VerificationCodeType.SignIn });
expect(response.statusCode).toEqual(204);
expect(createPasscode).toHaveBeenCalledWith('jti', MessageTypes.SignIn, {
expect(createPasscode).toHaveBeenCalledWith('jti', VerificationCodeType.SignIn, {
email: 'a@a.com',
});
expect(sendPasscode).toHaveBeenCalled();
@ -162,9 +162,9 @@ describe('session -> passwordlessRoutes', () => {
it('should call sendPasscode (with flow `register`)', async () => {
const response = await sessionRequest
.post('/session/passwordless/email/send')
.send({ email: 'a@a.com', flow: MessageTypes.Register });
.send({ email: 'a@a.com', flow: VerificationCodeType.Register });
expect(response.statusCode).toEqual(204);
expect(createPasscode).toHaveBeenCalledWith('jti', MessageTypes.Register, {
expect(createPasscode).toHaveBeenCalledWith('jti', VerificationCodeType.Register, {
email: 'a@a.com',
});
expect(sendPasscode).toHaveBeenCalled();
@ -172,9 +172,9 @@ describe('session -> passwordlessRoutes', () => {
it('should call sendPasscode (with flow `forgot-password`)', async () => {
const response = await sessionRequest
.post('/session/passwordless/email/send')
.send({ email: 'a@a.com', flow: MessageTypes.ForgotPassword });
.send({ email: 'a@a.com', flow: VerificationCodeType.ForgotPassword });
expect(response.statusCode).toEqual(204);
expect(createPasscode).toHaveBeenCalledWith('jti', MessageTypes.ForgotPassword, {
expect(createPasscode).toHaveBeenCalledWith('jti', VerificationCodeType.ForgotPassword, {
email: 'a@a.com',
});
expect(sendPasscode).toHaveBeenCalled();
@ -182,7 +182,7 @@ describe('session -> passwordlessRoutes', () => {
it('throw when email not given in input params', async () => {
const response = await sessionRequest
.post('/session/passwordless/email/send')
.send({ flow: MessageTypes.Register });
.send({ flow: VerificationCodeType.Register });
expect(response.statusCode).toEqual(400);
});
});
@ -204,14 +204,14 @@ describe('session -> passwordlessRoutes', () => {
await sessionRequest
.post('/session/passwordless/sms/verify')
.send({ phone: '13000000000', code: '1234', flow: MessageTypes.SignIn });
.send({ phone: '13000000000', code: '1234', flow: VerificationCodeType.SignIn });
expect(interactionResult).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
expect.objectContaining({
verification: {
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
phone: '13000000000',
expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(),
},
@ -228,14 +228,14 @@ describe('session -> passwordlessRoutes', () => {
await sessionRequest
.post('/session/passwordless/sms/verify')
.send({ phone: '13000000000', code: '1234', flow: MessageTypes.Register });
.send({ phone: '13000000000', code: '1234', flow: VerificationCodeType.Register });
expect(interactionResult).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
expect.objectContaining({
verification: {
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
phone: '13000000000',
expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(),
},
@ -251,7 +251,7 @@ describe('session -> passwordlessRoutes', () => {
const response = await sessionRequest
.post('/session/passwordless/sms/verify')
.send({ phone: '13000000000', code: '1234', flow: MessageTypes.ForgotPassword });
.send({ phone: '13000000000', code: '1234', flow: VerificationCodeType.ForgotPassword });
expect(response.statusCode).toEqual(204);
@ -262,7 +262,7 @@ describe('session -> passwordlessRoutes', () => {
verification: {
userId: mockUser.id,
expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
})
);
@ -272,7 +272,7 @@ describe('session -> passwordlessRoutes', () => {
findUserByPhone.mockResolvedValueOnce(null);
const response = await sessionRequest
.post('/session/passwordless/sms/verify')
.send({ phone: '13000000001', code: '1234', flow: MessageTypes.ForgotPassword });
.send({ phone: '13000000001', code: '1234', flow: VerificationCodeType.ForgotPassword });
expect(response.statusCode).toEqual(404);
expect(interactionResult).toHaveBeenCalledTimes(0);
});
@ -280,7 +280,7 @@ describe('session -> passwordlessRoutes', () => {
it('throw when code is wrong', async () => {
const response = await sessionRequest
.post('/session/passwordless/sms/verify')
.send({ phone: '13000000000', code: '1231', flow: MessageTypes.SignIn });
.send({ phone: '13000000000', code: '1231', flow: VerificationCodeType.SignIn });
expect(response.statusCode).toEqual(400);
});
});
@ -302,14 +302,14 @@ describe('session -> passwordlessRoutes', () => {
await sessionRequest
.post('/session/passwordless/email/verify')
.send({ email: 'a@a.com', code: '1234', flow: MessageTypes.SignIn });
.send({ email: 'a@a.com', code: '1234', flow: VerificationCodeType.SignIn });
expect(interactionResult).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
expect.objectContaining({
verification: {
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
email: 'a@a.com',
expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(),
},
@ -325,14 +325,14 @@ describe('session -> passwordlessRoutes', () => {
await sessionRequest
.post('/session/passwordless/email/verify')
.send({ email: 'a@a.com', code: '1234', flow: MessageTypes.Register });
.send({ email: 'a@a.com', code: '1234', flow: VerificationCodeType.Register });
expect(interactionResult).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
expect.objectContaining({
verification: {
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
email: 'a@a.com',
expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(),
},
@ -348,7 +348,7 @@ describe('session -> passwordlessRoutes', () => {
const response = await sessionRequest
.post('/session/passwordless/email/verify')
.send({ email: 'a@a.com', code: '1234', flow: MessageTypes.ForgotPassword });
.send({ email: 'a@a.com', code: '1234', flow: VerificationCodeType.ForgotPassword });
expect(response.statusCode).toEqual(204);
@ -359,7 +359,7 @@ describe('session -> passwordlessRoutes', () => {
verification: {
userId: mockUser.id,
expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(),
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
},
})
);
@ -371,7 +371,7 @@ describe('session -> passwordlessRoutes', () => {
findUserByEmail.mockResolvedValueOnce(null);
const response = await sessionRequest
.post('/session/passwordless/email/verify')
.send({ email: 'b@a.com', code: '1234', flow: MessageTypes.ForgotPassword });
.send({ email: 'b@a.com', code: '1234', flow: VerificationCodeType.ForgotPassword });
expect(response.statusCode).toEqual(404);
expect(interactionResult).toHaveBeenCalledTimes(0);
});
@ -379,7 +379,7 @@ describe('session -> passwordlessRoutes', () => {
it('throw when code is wrong', async () => {
const response = await sessionRequest
.post('/session/passwordless/email/verify')
.send({ email: 'a@a.com', code: '1231', flow: MessageTypes.SignIn });
.send({ email: 'a@a.com', code: '1231', flow: VerificationCodeType.SignIn });
expect(response.statusCode).toEqual(400);
});
});
@ -390,7 +390,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -414,7 +414,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -449,7 +449,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
expiresAt: getTomorrowIsoString(),
},
},
@ -463,7 +463,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: 'invalid date string',
},
},
@ -477,7 +477,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: subDays(Date.now(), 1).toISOString(),
},
},
@ -491,7 +491,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'XX@foo',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -505,7 +505,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000001',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -524,7 +524,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -572,7 +572,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'a@a.com',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -596,7 +596,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'a@a.com',
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -633,7 +633,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'a@a.com',
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
expiresAt: getTomorrowIsoString(),
},
},
@ -646,7 +646,7 @@ describe('session -> passwordlessRoutes', () => {
interactionDetails.mockResolvedValueOnce({
result: {
verification: {
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -660,7 +660,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'b@a.com',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -679,7 +679,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'a@a.com',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -726,7 +726,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000001',
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -748,7 +748,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000001',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -783,7 +783,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000001',
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
expiresAt: getTomorrowIsoString(),
},
},
@ -796,7 +796,7 @@ describe('session -> passwordlessRoutes', () => {
interactionDetails.mockResolvedValueOnce({
result: {
verification: {
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -810,7 +810,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
phone: '13000000000',
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -854,7 +854,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'b@a.com',
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -876,7 +876,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'b@a.com',
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
expiresAt: getTomorrowIsoString(),
},
},
@ -911,7 +911,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'b@a.com',
flow: MessageTypes.ForgotPassword,
flow: VerificationCodeType.ForgotPassword,
expiresAt: getTomorrowIsoString(),
},
},
@ -924,7 +924,7 @@ describe('session -> passwordlessRoutes', () => {
interactionDetails.mockResolvedValueOnce({
result: {
verification: {
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},
@ -938,7 +938,7 @@ describe('session -> passwordlessRoutes', () => {
result: {
verification: {
email: 'a@a.com',
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
expiresAt: getTomorrowIsoString(),
},
},

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { emailRegEx, phoneRegEx } from '@logto/core-kit';
import type { Provider } from 'oidc-provider';
import { object, string } from 'zod';
@ -103,7 +103,7 @@ export default function passwordlessRoutes<T extends AnonymousRouterLegacy>(
await verifyPasscode(jti, flow, code, { phone });
if (flow === MessageTypes.ForgotPassword) {
if (flow === VerificationCodeType.ForgotPassword) {
const user = await findUserByPhone(phone);
assertThat(user, new RequestError({ code: 'user.phone_not_exist', status: 404 }));
@ -113,13 +113,13 @@ export default function passwordlessRoutes<T extends AnonymousRouterLegacy>(
return next();
}
if (flow === MessageTypes.SignIn) {
if (flow === VerificationCodeType.SignIn) {
await assignVerificationResult(ctx, provider, { flow, phone });
return smsSignInAction(provider)(ctx, next);
}
if (flow === MessageTypes.Register) {
if (flow === VerificationCodeType.Register) {
await assignVerificationResult(ctx, provider, { flow, phone });
return smsRegisterAction(provider)(ctx, next);
@ -152,7 +152,7 @@ export default function passwordlessRoutes<T extends AnonymousRouterLegacy>(
await verifyPasscode(jti, flow, code, { email });
if (flow === MessageTypes.ForgotPassword) {
if (flow === VerificationCodeType.ForgotPassword) {
const user = await findUserByEmail(email);
assertThat(user, new RequestError({ code: 'user.email_not_exist', status: 404 }));
@ -163,13 +163,13 @@ export default function passwordlessRoutes<T extends AnonymousRouterLegacy>(
return next();
}
if (flow === MessageTypes.SignIn) {
if (flow === VerificationCodeType.SignIn) {
await assignVerificationResult(ctx, provider, { flow, email });
return emailSignInAction(provider)(ctx, next);
}
if (flow === MessageTypes.Register) {
if (flow === VerificationCodeType.Register) {
await assignVerificationResult(ctx, provider, { flow, email });
return emailRegisterAction(provider)(ctx, next);

View file

@ -1,9 +1,9 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import { pick } from '@silverhand/essentials';
import { z } from 'zod';
export const flowTypeGuard = z.nativeEnum(
pick(MessageTypes, 'Continue', 'ForgotPassword', 'Register', 'SignIn')
pick(VerificationCodeType, 'Continue', 'ForgotPassword', 'Register', 'SignIn')
);
export const methodGuard = z.enum(['email', 'sms']);
@ -15,7 +15,7 @@ export const operationGuard = z.enum(['send', 'verify']);
export type Operation = z.infer<typeof operationGuard>;
const smsSessionStorageGuard = z.object({
flow: z.literal(MessageTypes.SignIn).or(z.literal(MessageTypes.Register)),
flow: z.literal(VerificationCodeType.SignIn).or(z.literal(VerificationCodeType.Register)),
expiresAt: z.string(),
phone: z.string(),
});
@ -25,7 +25,7 @@ export type SmsSessionStorage = z.infer<typeof smsSessionStorageGuard>;
export const smsSessionResultGuard = z.object({ verification: smsSessionStorageGuard });
const emailSessionStorageGuard = z.object({
flow: z.literal(MessageTypes.SignIn).or(z.literal(MessageTypes.Register)),
flow: z.literal(VerificationCodeType.SignIn).or(z.literal(VerificationCodeType.Register)),
expiresAt: z.string(),
email: z.string(),
});
@ -37,7 +37,7 @@ export const emailSessionResultGuard = z.object({
});
const forgotPasswordSessionStorageGuard = z.object({
flow: z.literal(MessageTypes.ForgotPassword),
flow: z.literal(VerificationCodeType.ForgotPassword),
expiresAt: z.string(),
userId: z.string(),
});
@ -49,7 +49,7 @@ export const forgotPasswordSessionResultGuard = z.object({
});
const continueEmailSessionStorageGuard = z.object({
flow: z.literal(MessageTypes.Continue),
flow: z.literal(VerificationCodeType.Continue),
expiresAt: z.string(),
email: z.string(),
});
@ -61,7 +61,7 @@ export const continueEmailSessionResultGuard = z.object({
});
const continueSmsSessionStorageGuard = z.object({
flow: z.literal(MessageTypes.Continue),
flow: z.literal(VerificationCodeType.Continue),
expiresAt: z.string(),
phone: z.string(),
});

View file

@ -1,4 +1,4 @@
import type { MessageTypes } from '@logto/connector-kit';
import type { VerificationCodeType } from '@logto/connector-kit';
import type { SignInExperience, User } from '@logto/schemas';
import { SignInIdentifier } from '@logto/schemas';
import type { LogPayload, LogType } from '@logto/schemas/lib/types/log-legacy.js';
@ -37,7 +37,7 @@ export const getRoutePrefix = (
};
export const getPasswordlessRelatedLogType = (
flow: MessageTypes,
flow: VerificationCodeType,
method: Method,
operation?: Operation
): LogType => {

View file

@ -1,4 +1,4 @@
import { MessageTypes } from '@logto/connector-kit';
import { VerificationCodeType } from '@logto/connector-kit';
import api from './api.js';
@ -69,7 +69,7 @@ export const sendRegisterUserWithEmailPasscode = (email: string, interactionCook
},
json: {
email,
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
},
});
@ -86,7 +86,7 @@ export const verifyRegisterUserWithEmailPasscode = (
json: {
email,
code,
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
},
})
.json<RedirectResponse>();
@ -107,7 +107,7 @@ export const sendSignInUserWithEmailPasscode = (email: string, interactionCookie
},
json: {
email,
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
},
});
@ -124,7 +124,7 @@ export const verifySignInUserWithEmailPasscode = (
json: {
email,
code,
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
},
})
.json<RedirectResponse>();
@ -145,7 +145,7 @@ export const sendRegisterUserWithSmsPasscode = (phone: string, interactionCookie
},
json: {
phone,
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
},
});
@ -162,7 +162,7 @@ export const verifyRegisterUserWithSmsPasscode = (
json: {
phone,
code,
flow: MessageTypes.Register,
flow: VerificationCodeType.Register,
},
})
.json<RedirectResponse>();
@ -183,7 +183,7 @@ export const sendSignInUserWithSmsPasscode = (phone: string, interactionCookie:
},
json: {
phone,
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
},
});
@ -200,7 +200,7 @@ export const verifySignInUserWithSmsPasscode = (
json: {
phone,
code,
flow: MessageTypes.SignIn,
flow: VerificationCodeType.SignIn,
},
})
.json<RedirectResponse>();

View file

@ -68,7 +68,7 @@ export class ConnectorError extends Error {
}
}
export enum MessageTypes {
export enum VerificationCodeType {
SignIn = 'SignIn',
Register = 'Register',
ForgotPassword = 'ForgotPassword',
@ -76,7 +76,20 @@ export enum MessageTypes {
Test = 'Test',
}
export const messageTypesGuard = z.nativeEnum(MessageTypes);
export const verificationCodeTypeGuard = z.nativeEnum(VerificationCodeType);
// Enum is string actually, keep this exported until GA for compatibility.
/** @deprecated Use `VerificationCodeType` instead. */
export enum MessageType {
SignIn = 'SignIn',
Register = 'Register',
ForgotPassword = 'ForgotPassword',
Continue = 'Continue',
Test = 'Test',
}
/** @deprecated Use `verificationCodeTypeGuard` instead. */
export const messageTypesGuard = verificationCodeTypeGuard;
const connectorMetadataGuard = z.object({
id: z.string(),
@ -139,7 +152,7 @@ export type EmailConnector = BaseConnector<ConnectorType.Email> & {
};
export type SendMessageFunction = (
data: { to: string; type: MessageTypes; payload: { code: string } },
data: { to: string; type: VerificationCodeType; payload: { code: string } },
config?: unknown
) => Promise<unknown>;