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

test: add sad paths for sign-in with passcode flow (#4296)

This commit is contained in:
Xiao Yijun 2023-08-09 11:17:25 +08:00 committed by GitHub
parent ae0322621f
commit 2660a1e132
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 270 additions and 1 deletions

View file

@ -29,6 +29,9 @@ export const updateUser = async (userId: string, payload: Partial<User>) =>
}) })
.json<User>(); .json<User>();
export const suspendUser = async (userId: string, isSuspended: boolean) =>
authedAdminApi.patch(`users/${userId}/is-suspended`, { json: { isSuspended } }).json<User>();
export const deleteUser = async (userId: string) => authedAdminApi.delete(`users/${userId}`); export const deleteUser = async (userId: string) => authedAdminApi.delete(`users/${userId}`);
export const updateUserPassword = async (userId: string, password: string) => export const updateUserPassword = async (userId: string, password: string) =>

View file

@ -20,13 +20,14 @@ import { enableAllVerificationCodeSignInMethods } from '#src/helpers/sign-in-exp
import { generateNewUser, generateNewUserProfile } from '#src/helpers/user.js'; import { generateNewUser, generateNewUserProfile } from '#src/helpers/user.js';
import { generateEmail, generatePhone } from '#src/utils.js'; import { generateEmail, generatePhone } from '#src/utils.js';
describe('Sign-In flow using verification-code identifiers', () => { describe('Sign-in flow using verification-code identifiers', () => {
beforeAll(async () => { beforeAll(async () => {
await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]); await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]);
await setEmailConnector(); await setEmailConnector();
await setSmsConnector(); await setSmsConnector();
await enableAllVerificationCodeSignInMethods(); await enableAllVerificationCodeSignInMethods();
}); });
afterAll(async () => { afterAll(async () => {
await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]); await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]);
}); });

View file

@ -0,0 +1,265 @@
import { ConnectorType } from '@logto/connector-kit';
import { InteractionEvent, SignInMode } from '@logto/schemas';
import { suspendUser } from '#src/api/admin-user.js';
import {
patchInteractionIdentifiers,
putInteraction,
sendVerificationCode,
} from '#src/api/interaction.js';
import { updateSignInExperience } from '#src/api/sign-in-experience.js';
import { initClient } from '#src/helpers/client.js';
import {
clearConnectorsByTypes,
setEmailConnector,
setSmsConnector,
} from '#src/helpers/connector.js';
import { expectRejects, readVerificationCode } from '#src/helpers/index.js';
import { enableAllVerificationCodeSignInMethods } from '#src/helpers/sign-in-experience.js';
import { generateNewUser } from '#src/helpers/user.js';
import { generateEmail, generatePhone } from '#src/utils.js';
describe('Sign-in flow sad path using verification-code identifiers', () => {
beforeAll(async () => {
await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]);
await setEmailConnector();
await setSmsConnector();
await enableAllVerificationCodeSignInMethods();
});
afterAll(async () => {
await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]);
});
afterEach(async () => {
await enableAllVerificationCodeSignInMethods();
});
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();
await expectRejects(
client.send(putInteraction, {
event: InteractionEvent.SignIn,
}),
{
code: 'auth.forbidden',
statusCode: 403,
}
);
});
it('Should fail to sign in if related identifiers are not enabled', async () => {
await updateSignInExperience({
signIn: {
methods: [],
},
});
const client = await initClient();
const {
userProfile: { primaryEmail, primaryPhone },
} = await generateNewUser({ primaryEmail: true, primaryPhone: true });
await client.successSend(putInteraction, {
event: InteractionEvent.SignIn,
});
// Email
await client.successSend(sendVerificationCode, {
email: primaryEmail,
});
const { code: emailVerificationCode } = await readVerificationCode();
await expectRejects(
client.send(patchInteractionIdentifiers, {
email: primaryEmail,
verificationCode: emailVerificationCode,
}),
{
code: 'user.sign_in_method_not_enabled',
statusCode: 422,
}
);
// Phone
await client.successSend(sendVerificationCode, {
phone: primaryPhone,
});
const { code: phoneVerificationCode } = await readVerificationCode();
await expectRejects(
client.send(patchInteractionIdentifiers, {
phone: primaryPhone,
verificationCode: phoneVerificationCode,
}),
{
code: 'user.sign_in_method_not_enabled',
statusCode: 422,
}
);
});
it('Should fail to update sign in email identifier if verification code is incorrect or mismatch', async () => {
const {
userProfile: { primaryEmail },
} = await generateNewUser({ primaryEmail: true });
const client = await initClient();
await client.successSend(putInteraction, {
event: InteractionEvent.SignIn,
});
await client.successSend(sendVerificationCode, {
email: primaryEmail,
});
const { code: verificationCode } = await readVerificationCode();
await expectRejects(
client.send(patchInteractionIdentifiers, {
email: primaryEmail,
verificationCode: `${verificationCode}-incorrect`,
}),
{
code: 'verification_code.code_mismatch',
statusCode: 400,
}
);
await expectRejects(
client.send(patchInteractionIdentifiers, {
email: `${primaryEmail}-incorrect`,
verificationCode,
}),
{
code: 'verification_code.email_mismatch',
statusCode: 400,
}
);
});
it('Should fail to update sign in phone identifier if verification code is incorrect or mismatch', async () => {
const {
userProfile: { primaryPhone },
} = await generateNewUser({ primaryPhone: true });
const client = await initClient();
await client.successSend(putInteraction, {
event: InteractionEvent.SignIn,
});
await client.successSend(sendVerificationCode, {
phone: primaryPhone,
});
const { code: verificationCode } = await readVerificationCode();
await expectRejects(
client.send(patchInteractionIdentifiers, {
phone: primaryPhone,
verificationCode: `${verificationCode}-incorrect`,
}),
{
code: 'verification_code.code_mismatch',
statusCode: 400,
}
);
await expectRejects(
client.send(patchInteractionIdentifiers, {
phone: `${primaryPhone}001`,
verificationCode,
}),
{
code: 'verification_code.phone_mismatch',
statusCode: 400,
}
);
});
it('Should fail to sign in with email and passcode if related user is not exist', async () => {
const notExistUserEmail = generateEmail();
const client = await initClient();
await client.successSend(putInteraction, {
event: InteractionEvent.SignIn,
});
await client.successSend(sendVerificationCode, {
email: notExistUserEmail,
});
const { code: verificationCode } = await readVerificationCode();
await client.successSend(patchInteractionIdentifiers, {
email: notExistUserEmail,
verificationCode,
});
await expectRejects(client.submitInteraction(), {
code: 'user.user_not_exist',
statusCode: 404,
});
});
it('Should fail to sign in with phone and passcode if related user is not exist', async () => {
const notExistUserPhone = generatePhone();
const client = await initClient();
await client.successSend(putInteraction, {
event: InteractionEvent.SignIn,
});
await client.successSend(sendVerificationCode, {
phone: notExistUserPhone,
});
const { code: verificationCode } = await readVerificationCode();
await client.successSend(patchInteractionIdentifiers, {
phone: notExistUserPhone,
verificationCode,
});
await expectRejects(client.submitInteraction(), {
code: 'user.user_not_exist',
statusCode: 404,
});
});
it('Should fail to sign in if related user is suspended', async () => {
const {
userProfile: { primaryEmail },
user: { id: userId },
} = await generateNewUser({ primaryEmail: true });
await suspendUser(userId, true);
const client = await initClient();
await client.successSend(putInteraction, {
event: InteractionEvent.SignIn,
});
await client.successSend(sendVerificationCode, {
email: primaryEmail,
});
const { code: verificationCode } = await readVerificationCode();
await client.successSend(patchInteractionIdentifiers, {
email: primaryEmail,
verificationCode,
});
await expectRejects(client.submitInteraction(), {
code: 'user.suspended',
statusCode: 401,
});
});
});