mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
refactor!: update mock connector file paths
This commit is contained in:
parent
6d0f95739c
commit
6befe60149
23 changed files with 122 additions and 91 deletions
10
.changeset/clean-peaches-run.md
Normal file
10
.changeset/clean-peaches-run.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
"@logto/connector-mock-standard-email": major
|
||||
"@logto/connector-mock-email": major
|
||||
"@logto/connector-mock-sms": major
|
||||
---
|
||||
|
||||
update `writeFile` path according to the connector type
|
||||
|
||||
- SMS connector: `/tmp/logto_mock_sms_record.txt`
|
||||
- Email connector: `/tmp/logto_mock_email_record.txt`
|
5
.changeset/two-moles-hope.md
Normal file
5
.changeset/two-moles-hope.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@logto/connector-kit": minor
|
||||
---
|
||||
|
||||
add `mockConnectorFilePaths` and deprecate `mockSmsVerificationCodeFileName`
|
|
@ -1,6 +1,5 @@
|
|||
import { assert } from '@silverhand/essentials';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
GetConnectorConfig,
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
validateConfig,
|
||||
ConnectorType,
|
||||
mockConnectorFilePaths,
|
||||
} from '@logto/connector-kit';
|
||||
|
||||
import { defaultMetadata } from './constant.js';
|
||||
|
@ -36,8 +36,8 @@ const sendMessage =
|
|||
);
|
||||
|
||||
await fs.writeFile(
|
||||
path.join('/tmp', 'logto_mock_verification_code_record.txt'),
|
||||
JSON.stringify({ address: to, code: payload.code, type }) + '\n'
|
||||
mockConnectorFilePaths.Email,
|
||||
JSON.stringify({ address: to, code: payload.code, type, payload }) + '\n'
|
||||
);
|
||||
|
||||
return { address: to, data: payload };
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { assert } from '@silverhand/essentials';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
GetConnectorConfig,
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
validateConfig,
|
||||
ConnectorType,
|
||||
mockConnectorFilePaths,
|
||||
} from '@logto/connector-kit';
|
||||
|
||||
import { defaultMetadata } from './constant.js';
|
||||
|
@ -36,8 +36,8 @@ const sendMessage =
|
|||
);
|
||||
|
||||
await fs.writeFile(
|
||||
path.join('/tmp', 'logto_mock_verification_code_record.txt'),
|
||||
JSON.stringify({ address: to, code: payload.code, type }) + '\n'
|
||||
mockConnectorFilePaths.Email,
|
||||
JSON.stringify({ address: to, code: payload.code, type, payload }) + '\n'
|
||||
);
|
||||
|
||||
return { address: to, data: payload };
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { assert } from '@silverhand/essentials';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
GetConnectorConfig,
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
validateConfig,
|
||||
ConnectorType,
|
||||
mockConnectorFilePaths,
|
||||
} from '@logto/connector-kit';
|
||||
|
||||
import { defaultMetadata } from './constant.js';
|
||||
|
@ -36,8 +36,8 @@ const sendMessage =
|
|||
);
|
||||
|
||||
await fs.writeFile(
|
||||
path.join('/tmp', 'logto_mock_verification_code_record.txt'),
|
||||
JSON.stringify({ phone: to, code: payload.code, type }) + '\n'
|
||||
mockConnectorFilePaths.Sms,
|
||||
JSON.stringify({ phone: to, code: payload.code, type, payload }) + '\n'
|
||||
);
|
||||
|
||||
return { phone: to, data: payload };
|
||||
|
|
|
@ -14,8 +14,6 @@ import type Queries from '#src/tenants/Queries.js';
|
|||
|
||||
import { type ConnectorLibrary } from './connector.js';
|
||||
|
||||
const invitationLinkPath = '/invitation';
|
||||
|
||||
/**
|
||||
* The ending statuses of an organization invitation per RFC 0003. It means that the invitation
|
||||
* status cannot be changed anymore.
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import fs from 'node:fs/promises';
|
||||
import { createServer, type RequestListener } from 'node:http';
|
||||
import path from 'node:path';
|
||||
|
||||
import { mockSmsVerificationCodeFileName } from '@logto/connector-kit';
|
||||
import { mockConnectorFilePaths } from '@logto/connector-kit';
|
||||
import { RequestError } from 'got';
|
||||
|
||||
import { createUser } from '#src/api/index.js';
|
||||
import { generateUsername } from '#src/utils.js';
|
||||
|
||||
const temporaryVerificationCodeFilePath = path.join('/tmp', mockSmsVerificationCodeFileName);
|
||||
|
||||
export const createUserByAdmin = async (
|
||||
username?: string,
|
||||
password?: string,
|
||||
|
@ -33,8 +30,10 @@ type VerificationCodeRecord = {
|
|||
type: string;
|
||||
};
|
||||
|
||||
export const readVerificationCode = async (): Promise<VerificationCodeRecord> => {
|
||||
const buffer = await fs.readFile(temporaryVerificationCodeFilePath);
|
||||
export const readVerificationCode = async (
|
||||
forType: keyof typeof mockConnectorFilePaths
|
||||
): Promise<VerificationCodeRecord> => {
|
||||
const buffer = await fs.readFile(mockConnectorFilePaths[forType]);
|
||||
const content = buffer.toString();
|
||||
|
||||
// For test use only
|
||||
|
@ -42,9 +41,11 @@ export const readVerificationCode = async (): Promise<VerificationCodeRecord> =>
|
|||
return JSON.parse(content) as VerificationCodeRecord;
|
||||
};
|
||||
|
||||
export const removeVerificationCode = async (): Promise<void> => {
|
||||
export const removeVerificationCode = async (
|
||||
forType: keyof typeof mockConnectorFilePaths
|
||||
): Promise<void> => {
|
||||
try {
|
||||
await fs.unlink(temporaryVerificationCodeFilePath);
|
||||
await fs.unlink(mockConnectorFilePaths[forType]);
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
|
|
|
@ -101,7 +101,9 @@ export const resetPassword = async (
|
|||
...profile,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode(
|
||||
'email' in profile ? 'Email' : 'Sms'
|
||||
);
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
...profile,
|
||||
verificationCode,
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('reset password', () => {
|
|||
email: userProfile.primaryEmail,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
address: userProfile.primaryEmail,
|
||||
|
@ -108,7 +108,7 @@ describe('reset password', () => {
|
|||
phone: userProfile.primaryPhone,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Sms');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
phone: userProfile.primaryPhone,
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('reset password flow sad path', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: primaryEmail,
|
||||
verificationCode,
|
||||
|
@ -59,7 +59,7 @@ describe('reset password flow sad path', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Sms');
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
phone: primaryPhone,
|
||||
verificationCode,
|
||||
|
@ -95,7 +95,7 @@ describe('reset password flow sad path', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Sms');
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
phone: primaryPhone,
|
||||
verificationCode,
|
||||
|
|
|
@ -79,7 +79,7 @@ describe('register with passwordless identifier', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
address: primaryEmail,
|
||||
|
@ -125,7 +125,7 @@ describe('register with passwordless identifier', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
const { code } = verificationCodeRecord;
|
||||
|
||||
|
@ -186,7 +186,7 @@ describe('register with passwordless identifier', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Sms');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
phone: primaryPhone,
|
||||
|
@ -232,7 +232,7 @@ describe('register with passwordless identifier', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Sms');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
phone: primaryPhone,
|
||||
|
@ -296,7 +296,7 @@ describe('register with passwordless identifier', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
address: primaryEmail,
|
||||
|
@ -351,7 +351,7 @@ describe('register with passwordless identifier', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Sms');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
phone: primaryPhone,
|
||||
|
|
|
@ -30,7 +30,7 @@ describe('Register with identifiers sad path', () => {
|
|||
await clearSsoConnectors();
|
||||
});
|
||||
|
||||
it('Should fail to register if sign-in mode is sign-in only', async () => {
|
||||
it('should fail to register if sign-in mode is sign-in only', async () => {
|
||||
await updateSignInExperience({ signInMode: SignInMode.SignIn });
|
||||
const client = await initClient();
|
||||
|
||||
|
@ -48,13 +48,13 @@ describe('Register with identifiers sad path', () => {
|
|||
await updateSignInExperience({ signInMode: SignInMode.SignInAndRegister });
|
||||
});
|
||||
|
||||
describe('Should fail to register with identifiers if sign-up settings are not enabled', () => {
|
||||
describe('should fail to register with identifiers if sign-up settings are not enabled', () => {
|
||||
beforeAll(async () => {
|
||||
// This function call will disable all sign-up settings by default
|
||||
await enableAllPasswordSignInMethods();
|
||||
});
|
||||
|
||||
it('Should fail to register with username and password', async () => {
|
||||
it('should fail to register with username and password', async () => {
|
||||
const client = await initClient();
|
||||
|
||||
await expectRejects(
|
||||
|
@ -72,7 +72,7 @@ describe('Register with identifiers sad path', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('Should fail to register with email', async () => {
|
||||
it('should fail to register with email', async () => {
|
||||
await setEmailConnector();
|
||||
const { primaryEmail } = generateNewUserProfile({ primaryEmail: true });
|
||||
const client = await initClient();
|
||||
|
@ -85,7 +85,7 @@ describe('Register with identifiers sad path', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
@ -102,7 +102,7 @@ describe('Register with identifiers sad path', () => {
|
|||
await clearConnectorsByTypes([ConnectorType.Email]);
|
||||
});
|
||||
|
||||
it('Should fail to register with phone', async () => {
|
||||
it('should fail to register with phone', async () => {
|
||||
await setSmsConnector();
|
||||
|
||||
const { primaryPhone } = generateNewUserProfile({ primaryPhone: true });
|
||||
|
@ -116,7 +116,7 @@ describe('Register with identifiers sad path', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Sms');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
|
|
@ -32,7 +32,7 @@ const happyPath = async (email: string) => {
|
|||
email,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
address: email,
|
||||
|
@ -124,7 +124,7 @@ describe('test register with email with SSO feature', () => {
|
|||
email,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
|
|
@ -44,7 +44,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
email: userProfile.primaryEmail,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
address: userProfile.primaryEmail,
|
||||
|
@ -77,7 +77,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
phone: userProfile.primaryPhone,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Sms');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
phone: userProfile.primaryPhone,
|
||||
|
@ -116,7 +116,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
email: newEmail,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
const { code } = verificationCodeRecord;
|
||||
|
||||
|
@ -158,7 +158,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
phone: newPhone,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Sms');
|
||||
|
||||
const { code } = verificationCodeRecord;
|
||||
|
||||
|
@ -205,7 +205,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
await client.successSend(sendVerificationCode, {
|
||||
email: userProfile.primaryEmail,
|
||||
});
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Email');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: userProfile.primaryEmail,
|
||||
|
@ -267,7 +267,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
await client.successSend(sendVerificationCode, {
|
||||
email: userProfile.primaryEmail,
|
||||
});
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Email');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: userProfile.primaryEmail,
|
||||
|
@ -324,7 +324,7 @@ describe('Sign-in flow using verification-code identifiers', () => {
|
|||
await client.successSend(sendVerificationCode, {
|
||||
email: userProfile.primaryEmail,
|
||||
});
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Email');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: userProfile.primaryEmail,
|
||||
|
|
|
@ -33,7 +33,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
await clearSsoConnectors();
|
||||
});
|
||||
|
||||
it('Should fail to sign in with passcode if sign-in mode is register only', async () => {
|
||||
it('should fail to sign in with passcode if sign-in mode is register only', async () => {
|
||||
await updateSignInExperience({ signInMode: SignInMode.Register });
|
||||
const client = await initClient();
|
||||
|
||||
|
@ -51,7 +51,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
await enableAllVerificationCodeSignInMethods();
|
||||
});
|
||||
|
||||
it('Should fail to sign in if related identifiers are not enabled', async () => {
|
||||
it('should fail to sign in if related identifiers are not enabled', async () => {
|
||||
await updateSignInExperience({
|
||||
signIn: {
|
||||
methods: [],
|
||||
|
@ -72,7 +72,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const { code: emailVerificationCode } = await readVerificationCode();
|
||||
const { code: emailVerificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
@ -90,7 +90,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code: phoneVerificationCode } = await readVerificationCode();
|
||||
const { code: phoneVerificationCode } = await readVerificationCode('Sms');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
@ -107,7 +107,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
await enableAllVerificationCodeSignInMethods();
|
||||
});
|
||||
|
||||
it('Should fail to update sign in email identifier if verification code is incorrect or mismatch', async () => {
|
||||
it('should fail to update sign in email identifier if verification code is incorrect or mismatch', async () => {
|
||||
const {
|
||||
userProfile: { primaryEmail },
|
||||
} = await generateNewUser({ primaryEmail: true });
|
||||
|
@ -121,7 +121,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
@ -146,7 +146,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('Should fail to update sign in phone identifier if verification code is incorrect or mismatch', async () => {
|
||||
it('should fail to update sign in phone identifier if verification code is incorrect or mismatch', async () => {
|
||||
const {
|
||||
userProfile: { primaryPhone },
|
||||
} = await generateNewUser({ primaryPhone: true });
|
||||
|
@ -160,7 +160,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Sms');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
@ -185,7 +185,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('Should fail to sign in with email and passcode if related user is not exist', async () => {
|
||||
it('should fail to sign in with email and passcode if related user is not exist', async () => {
|
||||
const notExistUserEmail = generateEmail();
|
||||
|
||||
const client = await initClient();
|
||||
|
@ -198,7 +198,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
email: notExistUserEmail,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: notExistUserEmail,
|
||||
|
@ -211,7 +211,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('Should fail to sign in with phone and passcode if related user is not exist', async () => {
|
||||
it('should fail to sign in with phone and passcode if related user is not exist', async () => {
|
||||
const notExistUserPhone = generatePhone();
|
||||
|
||||
const client = await initClient();
|
||||
|
@ -224,7 +224,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
phone: notExistUserPhone,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Sms');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
phone: notExistUserPhone,
|
||||
|
@ -237,7 +237,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('Should fail to sign in if related user is suspended', async () => {
|
||||
it('should fail to sign in if related user is suspended', async () => {
|
||||
const {
|
||||
userProfile: { primaryEmail },
|
||||
user: { id: userId },
|
||||
|
@ -254,7 +254,7 @@ describe('Sign-in flow sad path using verification-code identifiers', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: primaryEmail,
|
||||
|
|
|
@ -32,7 +32,7 @@ const happyPath = async (email: string) => {
|
|||
email,
|
||||
});
|
||||
|
||||
const verificationCodeRecord = await readVerificationCode();
|
||||
const verificationCodeRecord = await readVerificationCode('Email');
|
||||
|
||||
expect(verificationCodeRecord).toMatchObject({
|
||||
address: email,
|
||||
|
@ -70,7 +70,7 @@ describe('test sign-in with email passcode identifier with SSO feature', () => {
|
|||
await clearSsoConnectors();
|
||||
});
|
||||
|
||||
it('Should fail to sign in with email and passcode if the email domain is enabled for SSO only', async () => {
|
||||
it('should fail to sign in with email and passcode if the email domain is enabled for SSO only', async () => {
|
||||
const email = generateEmail('sso-sad-path.io');
|
||||
const user = await createUser({ primaryEmail: email });
|
||||
await updateSignInExperience({ singleSignOnEnabled: true });
|
||||
|
@ -91,7 +91,7 @@ describe('test sign-in with email passcode identifier with SSO feature', () => {
|
|||
email,
|
||||
});
|
||||
|
||||
const { code: verificationCode } = await readVerificationCode();
|
||||
const { code: verificationCode } = await readVerificationCode('Email');
|
||||
|
||||
await expectRejects(
|
||||
client.send(patchInteractionIdentifiers, {
|
||||
|
@ -108,7 +108,7 @@ describe('test sign-in with email passcode identifier with SSO feature', () => {
|
|||
await deleteSsoConnectorById(id);
|
||||
});
|
||||
|
||||
it('Should sign-in with email with SSO disabled', async () => {
|
||||
it('should sign-in with email with SSO disabled', async () => {
|
||||
await updateSignInExperience({ singleSignOnEnabled: false });
|
||||
|
||||
const { id } = await createSsoConnector({
|
||||
|
@ -123,7 +123,7 @@ describe('test sign-in with email passcode identifier with SSO feature', () => {
|
|||
await deleteSsoConnectorById(id);
|
||||
});
|
||||
|
||||
it('Should sign-in with email with SSO enabled but no connector found', async () => {
|
||||
it('should sign-in with email with SSO enabled but no connector found', async () => {
|
||||
await updateSignInExperience({ singleSignOnEnabled: true });
|
||||
|
||||
const { id } = await createSsoConnector({
|
||||
|
|
|
@ -121,7 +121,7 @@ describe('Sign-in flow using password identifiers', () => {
|
|||
email: primaryEmail,
|
||||
});
|
||||
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Email');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
email: primaryEmail,
|
||||
|
@ -183,7 +183,7 @@ describe('Sign-in flow using password identifiers', () => {
|
|||
phone: primaryPhone,
|
||||
});
|
||||
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Sms');
|
||||
|
||||
await client.successSend(patchInteractionIdentifiers, {
|
||||
phone: primaryPhone,
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Generic verification code through management API', () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await removeVerificationCode();
|
||||
await Promise.all([removeVerificationCode('Sms'), removeVerificationCode('Email')]);
|
||||
});
|
||||
|
||||
it('should create an email verification code on server side', async () => {
|
||||
|
@ -34,7 +34,7 @@ describe('Generic verification code through management API', () => {
|
|||
const response = await requestVerificationCode(payload);
|
||||
expect(response.statusCode).toBe(204);
|
||||
|
||||
const { code, type, address } = await readVerificationCode();
|
||||
const { code, type, address } = await readVerificationCode('Email');
|
||||
|
||||
expect(type).toBe(TemplateType.Generic);
|
||||
expect(address).toBe(mockEmail);
|
||||
|
@ -46,7 +46,7 @@ describe('Generic verification code through management API', () => {
|
|||
const response = await requestVerificationCode(payload);
|
||||
expect(response.statusCode).toBe(204);
|
||||
|
||||
const { code, type, phone } = await readVerificationCode();
|
||||
const { code, type, phone } = await readVerificationCode('Sms');
|
||||
|
||||
expect(type).toBe(TemplateType.Generic);
|
||||
expect(phone).toBe(mockPhone);
|
||||
|
@ -59,7 +59,8 @@ describe('Generic verification code through management API', () => {
|
|||
statusCode: 400,
|
||||
});
|
||||
|
||||
await expect(readVerificationCode()).rejects.toThrow();
|
||||
await expect(readVerificationCode('Email')).rejects.toThrow();
|
||||
await expect(readVerificationCode('Sms')).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('should fail to send a verification code on server side when no email connector has been set', async () => {
|
||||
|
@ -113,7 +114,7 @@ describe('Generic verification code through management API', () => {
|
|||
it('should be able to verify the email verification code', async () => {
|
||||
await requestVerificationCode({ email: mockEmail });
|
||||
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Email');
|
||||
|
||||
await expect(
|
||||
verifyVerificationCode({ email: mockEmail, verificationCode: code })
|
||||
|
@ -123,7 +124,7 @@ describe('Generic verification code through management API', () => {
|
|||
it('should be able to verify the sms verification code', async () => {
|
||||
await requestVerificationCode({ phone: mockPhone });
|
||||
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode('Sms');
|
||||
|
||||
await expect(
|
||||
verifyVerificationCode({ phone: mockPhone, verificationCode: code })
|
||||
|
@ -132,7 +133,7 @@ describe('Generic verification code through management API', () => {
|
|||
|
||||
it('should throw when the code is not valid', async () => {
|
||||
await requestVerificationCode({ phone: mockPhone });
|
||||
await readVerificationCode();
|
||||
await readVerificationCode('Sms');
|
||||
await expectRejects(verifyVerificationCode({ phone: mockPhone, verificationCode: '666' }), {
|
||||
code: 'verification_code.code_mismatch',
|
||||
statusCode: 400,
|
||||
|
@ -143,7 +144,7 @@ describe('Generic verification code through management API', () => {
|
|||
const phoneToVerify = '666';
|
||||
const phoneToGetCode = mockPhone;
|
||||
await requestVerificationCode({ phone: phoneToGetCode });
|
||||
const { code, phone } = await readVerificationCode();
|
||||
const { code, phone } = await readVerificationCode('Sms');
|
||||
expect(phoneToGetCode).toEqual(phone);
|
||||
await expectRejects(verifyVerificationCode({ phone: phoneToVerify, verificationCode: code }), {
|
||||
code: 'verification_code.not_found',
|
||||
|
@ -155,7 +156,7 @@ describe('Generic verification code through management API', () => {
|
|||
const emailToVerify = 'verify_email@mail.com';
|
||||
const emailToGetCode = mockEmail;
|
||||
await requestVerificationCode({ email: emailToGetCode });
|
||||
const { code, address } = await readVerificationCode();
|
||||
const { code, address } = await readVerificationCode('Email');
|
||||
expect(emailToGetCode).toEqual(address);
|
||||
await expectRejects(verifyVerificationCode({ email: emailToVerify, verificationCode: code }), {
|
||||
code: 'verification_code.not_found',
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('MFA - TOTP', () => {
|
|||
const experience = new ExpectTotpExperience(await browser.newPage());
|
||||
await experience.startWith(demoAppUrl, 'sign-in');
|
||||
await experience.toFillInput('identifier', userProfile.primaryEmail, { submit: true });
|
||||
await experience.toCompleteVerification('sign-in');
|
||||
await experience.toCompleteVerification('sign-in', 'Email');
|
||||
|
||||
// Add missing password
|
||||
await experience.toFillInput('newPassword', 'l0gt0_T3st_P@ssw0rd', { submit: true });
|
||||
|
@ -99,7 +99,7 @@ describe('MFA - TOTP', () => {
|
|||
// Add missing phone number
|
||||
await waitFor(500);
|
||||
await experience.toFillInput('identifier', generatePhone(), { submit: true });
|
||||
await experience.toCompleteVerification('continue');
|
||||
await experience.toCompleteVerification('continue', 'Sms');
|
||||
|
||||
// Bind TOTP
|
||||
await experience.toBindTotp();
|
||||
|
@ -147,7 +147,7 @@ describe('MFA - TOTP', () => {
|
|||
// Add missing email number
|
||||
await waitFor(500);
|
||||
await experience.toFillInput('identifier', generateEmail(), { submit: true });
|
||||
await experience.toCompleteVerification('continue');
|
||||
await experience.toCompleteVerification('continue', 'Email');
|
||||
|
||||
// Bind TOTP
|
||||
await experience.toBindTotp();
|
||||
|
@ -230,7 +230,7 @@ describe('MFA - TOTP', () => {
|
|||
|
||||
// Add missing email
|
||||
await verificationExperience.toFillInput('identifier', generateEmail(), { submit: true });
|
||||
await verificationExperience.toCompleteVerification('continue');
|
||||
await verificationExperience.toCompleteVerification('continue', 'Email');
|
||||
// Wait for the page to load
|
||||
await waitFor(500);
|
||||
await verificationExperience.verifyThenEnd();
|
||||
|
|
|
@ -67,7 +67,7 @@ describe('MFA - TOTP', () => {
|
|||
const experience = new ExpectTotpExperience(await browser.newPage());
|
||||
await experience.startWith(demoAppUrl, 'register');
|
||||
await experience.toFillInput('id', context.userEmail, { submit: true });
|
||||
await experience.toCompleteVerification('register');
|
||||
await experience.toCompleteVerification('register', 'Email');
|
||||
context.setUpTotpSecret(await experience.toBindTotp());
|
||||
await experience.verifyThenEnd();
|
||||
|
||||
|
@ -81,7 +81,7 @@ describe('MFA - TOTP', () => {
|
|||
const experience = new ExpectTotpExperience(await browser.newPage());
|
||||
await experience.startWith(demoAppUrl, 'sign-in');
|
||||
await experience.toFillInput('identifier', context.userEmail, { submit: true });
|
||||
await experience.toCompleteVerification('sign-in');
|
||||
await experience.toCompleteVerification('sign-in', 'Email');
|
||||
await experience.toVerifyTotp(context.totpSecret);
|
||||
const userId = await experience.getUserIdFromDemoAppPage();
|
||||
await experience.verifyThenEnd();
|
||||
|
@ -95,7 +95,7 @@ describe('MFA - TOTP', () => {
|
|||
const experience = new ExpectTotpExperience(await browser.newPage());
|
||||
await experience.startWith(demoAppUrl, 'sign-in');
|
||||
await experience.toFillInput('identifier', userProfile.primaryEmail, { submit: true });
|
||||
await experience.toCompleteVerification('sign-in');
|
||||
await experience.toCompleteVerification('sign-in', 'Email');
|
||||
await experience.toBindTotp();
|
||||
await experience.verifyThenEnd();
|
||||
// Clean up
|
||||
|
@ -147,7 +147,7 @@ describe('MFA - TOTP', () => {
|
|||
const experience = new ExpectTotpExperience(await browser.newPage());
|
||||
await experience.startWith(demoAppUrl, 'register');
|
||||
await experience.toFillInput('id', context.userPhone, { submit: true });
|
||||
await experience.toCompleteVerification('register');
|
||||
await experience.toCompleteVerification('register', 'Sms');
|
||||
|
||||
context.setUpTotpSecret(await experience.toBindTotp());
|
||||
|
||||
|
@ -163,7 +163,7 @@ describe('MFA - TOTP', () => {
|
|||
const experience = new ExpectTotpExperience(await browser.newPage());
|
||||
await experience.startWith(demoAppUrl, 'sign-in');
|
||||
await experience.toFillInput('identifier', context.userPhone, { submit: true });
|
||||
await experience.toCompleteVerification('sign-in');
|
||||
await experience.toCompleteVerification('sign-in', 'Sms');
|
||||
await experience.toVerifyTotp(context.totpSecret);
|
||||
const userId = await experience.getUserIdFromDemoAppPage();
|
||||
await experience.verifyThenEnd();
|
||||
|
@ -179,7 +179,7 @@ describe('MFA - TOTP', () => {
|
|||
await experience.toFillInput('identifier', userProfile.primaryPhone.slice(1), {
|
||||
submit: true,
|
||||
});
|
||||
await experience.toCompleteVerification('sign-in');
|
||||
await experience.toCompleteVerification('sign-in', 'Sms');
|
||||
await experience.toBindTotp();
|
||||
await experience.verifyThenEnd();
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ describe('password policy', () => {
|
|||
|
||||
// Complete verification code flow
|
||||
await experience.toFillInput('id', email, { submit: true });
|
||||
await experience.toCompleteVerification('register');
|
||||
await experience.toCompleteVerification('register', 'Email');
|
||||
|
||||
// Wait for the password page to load
|
||||
await waitFor(100);
|
||||
|
@ -98,7 +98,7 @@ describe('password policy', () => {
|
|||
await experience.toClickSubmit();
|
||||
|
||||
// Complete verification code flow
|
||||
await experience.toCompleteVerification('forgot-password');
|
||||
await experience.toCompleteVerification('forgot-password', 'Email');
|
||||
|
||||
// Wait for the password page to load
|
||||
await waitFor(100);
|
||||
|
|
|
@ -131,9 +131,12 @@ export default class ExpectExperience extends ExpectPage {
|
|||
*
|
||||
* @param type The type of experience to expect.
|
||||
*/
|
||||
async toCompleteVerification(type: ExperienceType) {
|
||||
async toCompleteVerification(
|
||||
type: ExperienceType,
|
||||
connectorType: Parameters<typeof readVerificationCode>['0']
|
||||
) {
|
||||
this.toBeAt(`${type}/verification-code`);
|
||||
const { code } = await readVerificationCode();
|
||||
const { code } = await readVerificationCode(connectorType);
|
||||
await this.toFillVerificationCode(code);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
sendMessagePayloadKeys,
|
||||
type SendMessagePayload,
|
||||
ConnectorType,
|
||||
} from './types/index.js';
|
||||
|
||||
export * from './types/index.js';
|
||||
|
@ -42,8 +43,18 @@ export const parseJsonObject = (...args: Parameters<typeof parseJson>) => {
|
|||
return parsed;
|
||||
};
|
||||
|
||||
/** @deprecated Use {@link mockConnectorFilePaths} instead. */
|
||||
export const mockSmsVerificationCodeFileName = 'logto_mock_verification_code_record.txt';
|
||||
|
||||
/**
|
||||
* The file paths for storing the mock sms/email connector records. You can use these file paths to
|
||||
* read the records for testing.
|
||||
*/
|
||||
export const mockConnectorFilePaths = Object.freeze({
|
||||
[ConnectorType.Sms]: '/tmp/logto_mock_sms_record.txt',
|
||||
[ConnectorType.Email]: '/tmp/logto_mock_email_record.txt',
|
||||
});
|
||||
|
||||
/**
|
||||
* Replace all handlebars that match the keys in {@link SendMessagePayload} with the payload
|
||||
* values. If the payload does not contain the key, the handlebar will be replaced with an empty
|
||||
|
|
Loading…
Reference in a new issue