mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
feat(test): add fulfill user profile integration tests (#2710)
This commit is contained in:
parent
dc2c8ece22
commit
54b0574e18
9 changed files with 499 additions and 19 deletions
|
@ -227,6 +227,17 @@ describe('session -> interactionRoutes', () => {
|
||||||
provider: createMockProvider(jest.fn().mockResolvedValue(baseProviderMock)),
|
provider: createMockProvider(jest.fn().mockResolvedValue(baseProviderMock)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('PUT /interaction/profile', async () => {
|
||||||
|
const body = {
|
||||||
|
email: 'email@logto.io',
|
||||||
|
};
|
||||||
|
const response = await sessionRequest.put(path).send(body);
|
||||||
|
expect(verifyProfileSettings).toBeCalled();
|
||||||
|
expect(getInteractionStorage).toBeCalled();
|
||||||
|
expect(storeInteractionResult).toBeCalled();
|
||||||
|
expect(response.status).toEqual(204);
|
||||||
|
});
|
||||||
|
|
||||||
it('PATCH /interaction/profile', async () => {
|
it('PATCH /interaction/profile', async () => {
|
||||||
const body = {
|
const body = {
|
||||||
email: 'email@logto.io',
|
email: 'email@logto.io',
|
||||||
|
|
|
@ -166,6 +166,37 @@ export default function interactionRoutes<T extends AnonymousRouter>(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Replace Interaction Profile
|
||||||
|
router.put(
|
||||||
|
`${interactionPrefix}/profile`,
|
||||||
|
koaGuard({
|
||||||
|
body: profileGuard,
|
||||||
|
}),
|
||||||
|
koaInteractionSie(),
|
||||||
|
async (ctx, next) => {
|
||||||
|
const profilePayload = ctx.guard.body;
|
||||||
|
|
||||||
|
const { signInExperience, interactionDetails } = ctx;
|
||||||
|
verifyProfileSettings(profilePayload, signInExperience);
|
||||||
|
|
||||||
|
// Check interaction exists
|
||||||
|
getInteractionStorage(interactionDetails.result);
|
||||||
|
|
||||||
|
await storeInteractionResult(
|
||||||
|
{
|
||||||
|
profile: profilePayload,
|
||||||
|
},
|
||||||
|
ctx,
|
||||||
|
provider,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.status = 204;
|
||||||
|
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Update Interaction Profile
|
// Update Interaction Profile
|
||||||
router.patch(
|
router.patch(
|
||||||
`${interactionPrefix}/profile`,
|
`${interactionPrefix}/profile`,
|
||||||
|
|
|
@ -44,6 +44,15 @@ export const patchInteractionProfile = async (cookie: string, payload: Profile)
|
||||||
})
|
})
|
||||||
.json();
|
.json();
|
||||||
|
|
||||||
|
export const putInteractionProfile = async (cookie: string, payload: Profile) =>
|
||||||
|
api
|
||||||
|
.put('interaction/profile', {
|
||||||
|
headers: { cookie },
|
||||||
|
json: payload,
|
||||||
|
followRedirect: false,
|
||||||
|
})
|
||||||
|
.json();
|
||||||
|
|
||||||
export const deleteInteractionProfile = async (cookie: string) =>
|
export const deleteInteractionProfile = async (cookie: string) =>
|
||||||
api
|
api
|
||||||
.delete('interaction/profile', {
|
.delete('interaction/profile', {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
sendVerificationPasscode,
|
sendVerificationPasscode,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
patchInteractionIdentifiers,
|
patchInteractionIdentifiers,
|
||||||
|
putInteractionProfile,
|
||||||
patchInteractionProfile,
|
patchInteractionProfile,
|
||||||
} from '#src/api/index.js';
|
} from '#src/api/index.js';
|
||||||
import { expectRejects, readPasscode } from '#src/helpers.js';
|
import { expectRejects, readPasscode } from '#src/helpers.js';
|
||||||
|
@ -61,7 +62,7 @@ describe('reset password', () => {
|
||||||
|
|
||||||
await expectRejects(client.submitInteraction(), 'user.new_password_required_in_profile');
|
await expectRejects(client.submitInteraction(), 'user.new_password_required_in_profile');
|
||||||
|
|
||||||
await client.successSend(patchInteractionProfile, { password: userProfile.password });
|
await client.successSend(putInteractionProfile, { password: userProfile.password });
|
||||||
|
|
||||||
await expectRejects(client.submitInteraction(), 'user.same_password');
|
await expectRejects(client.submitInteraction(), 'user.same_password');
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ describe('reset password', () => {
|
||||||
|
|
||||||
await expectRejects(client.submitInteraction(), 'user.new_password_required_in_profile');
|
await expectRejects(client.submitInteraction(), 'user.new_password_required_in_profile');
|
||||||
|
|
||||||
await client.successSend(patchInteractionProfile, { password: userProfile.password });
|
await client.successSend(putInteractionProfile, { password: userProfile.password });
|
||||||
|
|
||||||
await expectRejects(client.submitInteraction(), 'user.same_password');
|
await expectRejects(client.submitInteraction(), 'user.same_password');
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
putInteraction,
|
putInteraction,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
patchInteractionIdentifiers,
|
patchInteractionIdentifiers,
|
||||||
|
putInteractionProfile,
|
||||||
patchInteractionProfile,
|
patchInteractionProfile,
|
||||||
deleteInteractionProfile,
|
deleteInteractionProfile,
|
||||||
putInteractionEvent,
|
putInteractionEvent,
|
||||||
|
@ -90,7 +91,7 @@ describe('Register with passwordless identifier', () => {
|
||||||
passcode: code,
|
passcode: code,
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.successSend(patchInteractionProfile, {
|
await client.successSend(putInteractionProfile, {
|
||||||
email: primaryEmail,
|
email: primaryEmail,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -101,6 +102,68 @@ describe('Register with passwordless identifier', () => {
|
||||||
await deleteUser(id);
|
await deleteUser(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('register with email and fulfill password', async () => {
|
||||||
|
await enableAllPasscodeSignInMethods({
|
||||||
|
identifiers: [SignInIdentifier.Email],
|
||||||
|
password: true,
|
||||||
|
verify: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { primaryEmail, password } = generateNewUserProfile({
|
||||||
|
primaryEmail: true,
|
||||||
|
password: true,
|
||||||
|
});
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.Register,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.Register,
|
||||||
|
email: primaryEmail,
|
||||||
|
});
|
||||||
|
|
||||||
|
const passcodeRecord = await readPasscode();
|
||||||
|
|
||||||
|
const { code } = passcodeRecord;
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
email: primaryEmail,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
email: primaryEmail,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionProfile, {
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
// SignIn with email and password
|
||||||
|
await client.initSession();
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
email: primaryEmail,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo: redirectTo2 } = await client.submitInteraction();
|
||||||
|
const id = await processSession(client, redirectTo2);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
await deleteUser(id);
|
||||||
|
});
|
||||||
|
|
||||||
it('register with phone', async () => {
|
it('register with phone', async () => {
|
||||||
await enableAllPasscodeSignInMethods({
|
await enableAllPasscodeSignInMethods({
|
||||||
identifiers: [SignInIdentifier.Sms],
|
identifiers: [SignInIdentifier.Sms],
|
||||||
|
@ -134,7 +197,7 @@ describe('Register with passwordless identifier', () => {
|
||||||
passcode: code,
|
passcode: code,
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.successSend(patchInteractionProfile, {
|
await client.successSend(putInteractionProfile, {
|
||||||
phone: primaryPhone,
|
phone: primaryPhone,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -145,6 +208,67 @@ describe('Register with passwordless identifier', () => {
|
||||||
await deleteUser(id);
|
await deleteUser(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('register with phone and fulfill password', async () => {
|
||||||
|
await enableAllPasscodeSignInMethods({
|
||||||
|
identifiers: [SignInIdentifier.Sms],
|
||||||
|
password: true,
|
||||||
|
verify: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { primaryPhone, password } = generateNewUserProfile({
|
||||||
|
primaryPhone: true,
|
||||||
|
password: true,
|
||||||
|
});
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.Register,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.Register,
|
||||||
|
phone: primaryPhone,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code } = await readPasscode();
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
phone: primaryPhone,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
phone: primaryPhone,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionProfile, {
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
// SignIn with phone and password
|
||||||
|
await client.initSession();
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
phone: primaryPhone,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo: redirectTo2 } = await client.submitInteraction();
|
||||||
|
const id = await processSession(client, redirectTo2);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
await deleteUser(id);
|
||||||
|
});
|
||||||
|
|
||||||
it('register with exiting email', async () => {
|
it('register with exiting email', async () => {
|
||||||
const {
|
const {
|
||||||
user,
|
user,
|
||||||
|
@ -182,7 +306,7 @@ describe('Register with passwordless identifier', () => {
|
||||||
passcode: code,
|
passcode: code,
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.successSend(patchInteractionProfile, {
|
await client.successSend(putInteractionProfile, {
|
||||||
email: primaryEmail,
|
email: primaryEmail,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -235,7 +359,7 @@ describe('Register with passwordless identifier', () => {
|
||||||
passcode: code,
|
passcode: code,
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.successSend(patchInteractionProfile, {
|
await client.successSend(putInteractionProfile, {
|
||||||
phone: primaryPhone,
|
phone: primaryPhone,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
sendVerificationPasscode,
|
sendVerificationPasscode,
|
||||||
putInteraction,
|
putInteraction,
|
||||||
putInteractionEvent,
|
putInteractionEvent,
|
||||||
patchInteractionProfile,
|
putInteractionProfile,
|
||||||
patchInteractionIdentifiers,
|
patchInteractionIdentifiers,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
updateSignInExperience,
|
updateSignInExperience,
|
||||||
|
@ -15,7 +15,7 @@ import { generateEmail, generatePhone } from '#src/utils.js';
|
||||||
import { initClient, processSession, logoutClient } from './utils/client.js';
|
import { initClient, processSession, logoutClient } from './utils/client.js';
|
||||||
import { clearConnectorsByTypes, setEmailConnector, setSmsConnector } from './utils/connector.js';
|
import { clearConnectorsByTypes, setEmailConnector, setSmsConnector } from './utils/connector.js';
|
||||||
import { enableAllPasscodeSignInMethods } from './utils/sign-in-experience.js';
|
import { enableAllPasscodeSignInMethods } from './utils/sign-in-experience.js';
|
||||||
import { generateNewUser } from './utils/user.js';
|
import { generateNewUser, generateNewUserProfile } from './utils/user.js';
|
||||||
|
|
||||||
describe('Sign-In flow using passcode identifiers', () => {
|
describe('Sign-In flow using passcode identifiers', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
@ -127,7 +127,7 @@ describe('Sign-In flow using passcode identifiers', () => {
|
||||||
await expectRejects(client.submitInteraction(), 'user.user_not_exist');
|
await expectRejects(client.submitInteraction(), 'user.user_not_exist');
|
||||||
|
|
||||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||||
await client.successSend(patchInteractionProfile, { email: newEmail });
|
await client.successSend(putInteractionProfile, { email: newEmail });
|
||||||
|
|
||||||
const { redirectTo } = await client.submitInteraction();
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ describe('Sign-In flow using passcode identifiers', () => {
|
||||||
await expectRejects(client.submitInteraction(), 'user.user_not_exist');
|
await expectRejects(client.submitInteraction(), 'user.user_not_exist');
|
||||||
|
|
||||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||||
await client.successSend(patchInteractionProfile, { phone: newPhone });
|
await client.successSend(putInteractionProfile, { phone: newPhone });
|
||||||
|
|
||||||
const { redirectTo } = await client.submitInteraction();
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
@ -175,4 +175,170 @@ describe('Sign-In flow using passcode identifiers', () => {
|
||||||
await logoutClient(client);
|
await logoutClient(client);
|
||||||
await deleteUser(id);
|
await deleteUser(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fulfill the username and password
|
||||||
|
it('email passcode sign-in', async () => {
|
||||||
|
await updateSignInExperience({
|
||||||
|
signUp: {
|
||||||
|
identifiers: [SignInIdentifier.Username],
|
||||||
|
password: true,
|
||||||
|
verify: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { userProfile, user } = await generateNewUser({ primaryEmail: true });
|
||||||
|
const { username, password } = generateNewUserProfile({ username: true, password: true });
|
||||||
|
|
||||||
|
// SignIn with email
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
email: userProfile.primaryEmail,
|
||||||
|
});
|
||||||
|
const { code } = await readPasscode();
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
email: userProfile.primaryEmail,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
// Fulfill user profile
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
await client.initSession();
|
||||||
|
// SignIn with username and password
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo: redirectTo2 } = await client.submitInteraction();
|
||||||
|
await processSession(client, redirectTo2);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
await deleteUser(user.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('email passcode sign-in with existing password', async () => {
|
||||||
|
await updateSignInExperience({
|
||||||
|
signUp: {
|
||||||
|
identifiers: [SignInIdentifier.Username],
|
||||||
|
password: true,
|
||||||
|
verify: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { userProfile, user } = await generateNewUser({ primaryEmail: true, password: true });
|
||||||
|
const { username, password } = generateNewUserProfile({ username: true, password: true });
|
||||||
|
|
||||||
|
// SignIn with email
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
email: userProfile.primaryEmail,
|
||||||
|
});
|
||||||
|
const { code } = await readPasscode();
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
email: userProfile.primaryEmail,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
// Fulfill user profile with existing password
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.password_exists_in_profile');
|
||||||
|
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
await deleteUser(user.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('email passcode sign-in with registered username', async () => {
|
||||||
|
await updateSignInExperience({
|
||||||
|
signUp: {
|
||||||
|
identifiers: [SignInIdentifier.Username],
|
||||||
|
password: true,
|
||||||
|
verify: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { userProfile, user } = await generateNewUser({ primaryEmail: true });
|
||||||
|
const { userProfile: userProfile2, user: user2 } = await generateNewUser({ username: true });
|
||||||
|
const { username, password } = generateNewUserProfile({ username: true, password: true });
|
||||||
|
|
||||||
|
// SignIn with email
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
email: userProfile.primaryEmail,
|
||||||
|
});
|
||||||
|
const { code } = await readPasscode();
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
email: userProfile.primaryEmail,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
// Fulfill user profile with existing password
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
username: userProfile2.username,
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.username_already_in_use');
|
||||||
|
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
await deleteUser(user.id);
|
||||||
|
await deleteUser(user2.id);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,32 @@
|
||||||
import { InteractionEvent } from '@logto/schemas';
|
import { InteractionEvent, ConnectorType, SignInIdentifier } from '@logto/schemas';
|
||||||
|
|
||||||
import { putInteraction, deleteUser } from '#src/api/index.js';
|
import {
|
||||||
|
putInteraction,
|
||||||
|
sendVerificationPasscode,
|
||||||
|
patchInteractionIdentifiers,
|
||||||
|
putInteractionProfile,
|
||||||
|
deleteUser,
|
||||||
|
} from '#src/api/index.js';
|
||||||
|
import { readPasscode, expectRejects } from '#src/helpers.js';
|
||||||
|
|
||||||
import { initClient, processSession, logoutClient } from './utils/client.js';
|
import { initClient, processSession, logoutClient } from './utils/client.js';
|
||||||
import { enableAllPasswordSignInMethods } from './utils/sign-in-experience.js';
|
import { clearConnectorsByTypes, setSmsConnector, setEmailConnector } from './utils/connector.js';
|
||||||
import { generateNewUser } from './utils/user.js';
|
import {
|
||||||
|
enableAllPasswordSignInMethods,
|
||||||
|
enableAllPasscodeSignInMethods,
|
||||||
|
} from './utils/sign-in-experience.js';
|
||||||
|
import { generateNewUser, generateNewUserProfile } from './utils/user.js';
|
||||||
|
|
||||||
describe('Sign-In flow using password identifiers', () => {
|
describe('Sign-In flow using password identifiers', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await enableAllPasswordSignInMethods();
|
await enableAllPasswordSignInMethods();
|
||||||
|
await clearConnectorsByTypes([ConnectorType.Sms, ConnectorType.Email]);
|
||||||
|
await setSmsConnector();
|
||||||
|
await setEmailConnector();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await clearConnectorsByTypes([ConnectorType.Sms, ConnectorType.Email]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sign-in with username and password', async () => {
|
it('sign-in with username and password', async () => {
|
||||||
|
@ -70,4 +88,124 @@ describe('Sign-In flow using password identifiers', () => {
|
||||||
|
|
||||||
await deleteUser(user.id);
|
await deleteUser(user.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fulfill the email address
|
||||||
|
it('sign-in with username and password and fulfill the email', async () => {
|
||||||
|
await enableAllPasscodeSignInMethods({
|
||||||
|
identifiers: [SignInIdentifier.Email],
|
||||||
|
password: true,
|
||||||
|
verify: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { userProfile, user } = await generateNewUser({ username: true, password: true });
|
||||||
|
const { primaryEmail } = generateNewUserProfile({ primaryEmail: true });
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
username: userProfile.username,
|
||||||
|
password: userProfile.password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
email: primaryEmail,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code } = await readPasscode();
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
email: primaryEmail,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
email: primaryEmail,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
// SignIn with email and password
|
||||||
|
await client.initSession();
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
email: primaryEmail,
|
||||||
|
password: userProfile.password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo: redirectTo2 } = await client.submitInteraction();
|
||||||
|
await processSession(client, redirectTo2);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
await deleteUser(user.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fulfill the phone number
|
||||||
|
it('sign-in with username and password and fulfill the phone number', async () => {
|
||||||
|
await enableAllPasscodeSignInMethods({
|
||||||
|
identifiers: [SignInIdentifier.Sms, SignInIdentifier.Email],
|
||||||
|
password: true,
|
||||||
|
verify: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { userProfile, user } = await generateNewUser({ username: true, password: true });
|
||||||
|
const { primaryPhone } = generateNewUserProfile({ primaryPhone: true });
|
||||||
|
const client = await initClient();
|
||||||
|
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
username: userProfile.username,
|
||||||
|
password: userProfile.password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await expectRejects(client.submitInteraction(), 'user.missing_profile');
|
||||||
|
|
||||||
|
await client.successSend(sendVerificationPasscode, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
phone: primaryPhone,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code } = await readPasscode();
|
||||||
|
|
||||||
|
await client.successSend(patchInteractionIdentifiers, {
|
||||||
|
phone: primaryPhone,
|
||||||
|
passcode: code,
|
||||||
|
});
|
||||||
|
|
||||||
|
await client.successSend(putInteractionProfile, {
|
||||||
|
phone: primaryPhone,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
await processSession(client, redirectTo);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
// SignIn with new phone and password
|
||||||
|
await client.initSession();
|
||||||
|
await client.successSend(putInteraction, {
|
||||||
|
event: InteractionEvent.SignIn,
|
||||||
|
identifier: {
|
||||||
|
phone: primaryPhone,
|
||||||
|
password: userProfile.password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { redirectTo: redirectTo2 } = await client.submitInteraction();
|
||||||
|
await processSession(client, redirectTo2);
|
||||||
|
await logoutClient(client);
|
||||||
|
|
||||||
|
await deleteUser(user.id);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
deleteUser,
|
deleteUser,
|
||||||
putInteractionEvent,
|
putInteractionEvent,
|
||||||
patchInteractionIdentifiers,
|
patchInteractionIdentifiers,
|
||||||
patchInteractionProfile,
|
putInteractionProfile,
|
||||||
} from '#src/api/index.js';
|
} from '#src/api/index.js';
|
||||||
import { expectRejects } from '#src/helpers.js';
|
import { expectRejects } from '#src/helpers.js';
|
||||||
import { generateUserId } from '#src/utils.js';
|
import { generateUserId } from '#src/utils.js';
|
||||||
|
@ -61,7 +61,7 @@ describe('Social Identifier Interactions', () => {
|
||||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||||
|
|
||||||
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
await client.successSend(putInteractionEvent, { event: InteractionEvent.Register });
|
||||||
await client.successSend(patchInteractionProfile, { connectorId });
|
await client.successSend(putInteractionProfile, { connectorId });
|
||||||
|
|
||||||
const { redirectTo } = await client.submitInteraction();
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ describe('Social Identifier Interactions', () => {
|
||||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||||
|
|
||||||
await client.successSend(patchInteractionIdentifiers, { username, password });
|
await client.successSend(patchInteractionIdentifiers, { username, password });
|
||||||
await client.successSend(patchInteractionProfile, { connectorId });
|
await client.successSend(putInteractionProfile, { connectorId });
|
||||||
|
|
||||||
const { redirectTo } = await client.submitInteraction();
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ describe('Social Identifier Interactions', () => {
|
||||||
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
await expectRejects(client.submitInteraction(), 'user.identity_not_exist');
|
||||||
|
|
||||||
await client.successSend(patchInteractionIdentifiers, { connectorId, identityType: 'email' });
|
await client.successSend(patchInteractionIdentifiers, { connectorId, identityType: 'email' });
|
||||||
await client.successSend(patchInteractionProfile, { connectorId });
|
await client.successSend(putInteractionProfile, { connectorId });
|
||||||
|
|
||||||
const { redirectTo } = await client.submitInteraction();
|
const { redirectTo } = await client.submitInteraction();
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ const defaultPasscodeSignInMethods = [
|
||||||
identifier: SignInIdentifier.Username,
|
identifier: SignInIdentifier.Username,
|
||||||
password: true,
|
password: true,
|
||||||
verificationCode: false,
|
verificationCode: false,
|
||||||
isPasswordPrimary: false,
|
isPasswordPrimary: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: SignInIdentifier.Email,
|
identifier: SignInIdentifier.Email,
|
||||||
|
|
Loading…
Reference in a new issue