mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(core): rename account prefix to my-account (#6821)
This commit is contained in:
parent
9a3f78d342
commit
9795412f43
8 changed files with 48 additions and 243 deletions
|
@ -1 +1 @@
|
||||||
export const accountApiPrefix = '/account';
|
export const accountApiPrefix = '/my-account';
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"tags": [
|
"tags": [
|
||||||
{
|
{
|
||||||
"name": "Account",
|
"name": "My account",
|
||||||
"description": "Account routes provide functionality for managing user profile for the end user to interact directly with access tokens."
|
"description": "Account routes provide functionality for managing user profile for the end user to interact directly with access tokens."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"/api/account": {
|
"/api/my-account": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "GetProfile",
|
"operationId": "GetProfile",
|
||||||
"summary": "Get profile",
|
"summary": "Get profile",
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/account/profile": {
|
"/api/my-account/profile": {
|
||||||
"patch": {
|
"patch": {
|
||||||
"operationId": "UpdateOtherProfile",
|
"operationId": "UpdateOtherProfile",
|
||||||
"summary": "Update other profile",
|
"summary": "Update other profile",
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/account/password": {
|
"/api/my-account/password": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "UpdatePassword",
|
"operationId": "UpdatePassword",
|
||||||
"summary": "Update password",
|
"summary": "Update password",
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/account/primary-email": {
|
"/api/my-account/primary-email": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "UpdatePrimaryEmail",
|
"operationId": "UpdatePrimaryEmail",
|
||||||
"summary": "Update primary email",
|
"summary": "Update primary email",
|
||||||
|
@ -183,7 +183,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/account/primary-phone": {
|
"/api/my-account/primary-phone": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "UpdatePrimaryPhone",
|
"operationId": "UpdatePrimaryPhone",
|
||||||
"summary": "Update primary phone",
|
"summary": "Update primary phone",
|
||||||
|
@ -227,7 +227,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/account/identities": {
|
"/api/my-account/identities": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "AddUserIdentities",
|
"operationId": "AddUserIdentities",
|
||||||
"summary": "Add a user identity",
|
"summary": "Add a user identity",
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/account/identities/{target}": {
|
"/api/my-account/identities/{target}": {
|
||||||
"delete": {
|
"delete": {
|
||||||
"operationId": "DeleteIdentity",
|
"operationId": "DeleteIdentity",
|
||||||
"summary": "Delete a user identity",
|
"summary": "Delete a user identity",
|
||||||
|
|
|
@ -4,6 +4,9 @@ import pluralize from 'pluralize';
|
||||||
|
|
||||||
import { EnvSet } from '#src/env-set/index.js';
|
import { EnvSet } from '#src/env-set/index.js';
|
||||||
|
|
||||||
|
import { accountApiPrefix } from '../../account/constants.js';
|
||||||
|
import { verificationApiPrefix } from '../../verification/index.js';
|
||||||
|
|
||||||
import { shouldThrow } from './general.js';
|
import { shouldThrow } from './general.js';
|
||||||
|
|
||||||
const chunk = <T>(array: T[], chunkSize: number): T[][] =>
|
const chunk = <T>(array: T[], chunkSize: number): T[][] =>
|
||||||
|
@ -124,8 +127,8 @@ const exceptionPrefixes = Object.freeze([
|
||||||
'/interaction',
|
'/interaction',
|
||||||
'/experience',
|
'/experience',
|
||||||
'/sign-in-exp/default/check-password',
|
'/sign-in-exp/default/check-password',
|
||||||
'/account',
|
accountApiPrefix,
|
||||||
'/verifications',
|
verificationApiPrefix,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const isPathParameter = (segment?: string) =>
|
const isPathParameter = (segment?: string) =>
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const updatePassword = async (
|
||||||
verificationRecordId: string,
|
verificationRecordId: string,
|
||||||
password: string
|
password: string
|
||||||
) =>
|
) =>
|
||||||
api.post('api/account/password', {
|
api.post('api/my-account/password', {
|
||||||
json: { password },
|
json: { password },
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
@ -19,13 +19,13 @@ export const updatePrimaryEmail = async (
|
||||||
verificationRecordId: string,
|
verificationRecordId: string,
|
||||||
newIdentifierVerificationRecordId: string
|
newIdentifierVerificationRecordId: string
|
||||||
) =>
|
) =>
|
||||||
api.post('api/account/primary-email', {
|
api.post('api/my-account/primary-email', {
|
||||||
json: { email, newIdentifierVerificationRecordId },
|
json: { email, newIdentifierVerificationRecordId },
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const deletePrimaryEmail = async (api: KyInstance, verificationRecordId: string) =>
|
export const deletePrimaryEmail = async (api: KyInstance, verificationRecordId: string) =>
|
||||||
api.delete('api/account/primary-email', {
|
api.delete('api/my-account/primary-email', {
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -35,13 +35,13 @@ export const updatePrimaryPhone = async (
|
||||||
verificationRecordId: string,
|
verificationRecordId: string,
|
||||||
newIdentifierVerificationRecordId: string
|
newIdentifierVerificationRecordId: string
|
||||||
) =>
|
) =>
|
||||||
api.post('api/account/primary-phone', {
|
api.post('api/my-account/primary-phone', {
|
||||||
json: { phone, newIdentifierVerificationRecordId },
|
json: { phone, newIdentifierVerificationRecordId },
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const deletePrimaryPhone = async (api: KyInstance, verificationRecordId: string) =>
|
export const deletePrimaryPhone = async (api: KyInstance, verificationRecordId: string) =>
|
||||||
api.delete('api/account/primary-phone', {
|
api.delete('api/my-account/primary-phone', {
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export const updateIdentities = async (
|
||||||
verificationRecordId: string,
|
verificationRecordId: string,
|
||||||
newIdentifierVerificationRecordId: string
|
newIdentifierVerificationRecordId: string
|
||||||
) =>
|
) =>
|
||||||
api.post('api/account/identities', {
|
api.post('api/my-account/identities', {
|
||||||
json: { newIdentifierVerificationRecordId },
|
json: { newIdentifierVerificationRecordId },
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
@ -60,15 +60,17 @@ export const deleteIdentity = async (
|
||||||
target: string,
|
target: string,
|
||||||
verificationRecordId: string
|
verificationRecordId: string
|
||||||
) =>
|
) =>
|
||||||
api.delete(`api/account/identities/${target}`, {
|
api.delete(`api/my-account/identities/${target}`, {
|
||||||
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
headers: { [verificationRecordIdHeader]: verificationRecordId },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const updateUser = async (api: KyInstance, body: Record<string, unknown>) =>
|
export const updateUser = async (api: KyInstance, body: Record<string, unknown>) =>
|
||||||
api.patch('api/account', { json: body }).json<Partial<UserProfileResponse>>();
|
api.patch('api/my-account', { json: body }).json<Partial<UserProfileResponse>>();
|
||||||
|
|
||||||
export const updateOtherProfile = async (api: KyInstance, body: Record<string, unknown>) =>
|
export const updateOtherProfile = async (api: KyInstance, body: Record<string, unknown>) =>
|
||||||
api.patch('api/account/profile', { json: body }).json<Partial<UserProfileResponse['profile']>>();
|
api
|
||||||
|
.patch('api/my-account/profile', { json: body })
|
||||||
|
.json<Partial<UserProfileResponse['profile']>>();
|
||||||
|
|
||||||
export const getUserInfo = async (api: KyInstance) =>
|
export const getUserInfo = async (api: KyInstance) =>
|
||||||
api.get('api/account').json<Partial<UserProfileResponse>>();
|
api.get('api/my-account').json<Partial<UserProfileResponse>>();
|
|
@ -12,7 +12,7 @@ import {
|
||||||
updatePrimaryEmail,
|
updatePrimaryEmail,
|
||||||
updatePrimaryPhone,
|
updatePrimaryPhone,
|
||||||
updateUser,
|
updateUser,
|
||||||
} from '#src/api/profile.js';
|
} from '#src/api/my-account.js';
|
||||||
import { createVerificationRecordByPassword } from '#src/api/verification-record.js';
|
import { createVerificationRecordByPassword } from '#src/api/verification-record.js';
|
||||||
import { expectRejects } from '#src/helpers/index.js';
|
import { expectRejects } from '#src/helpers/index.js';
|
||||||
import {
|
import {
|
||||||
|
@ -40,7 +40,7 @@ describe('account center fields disabled', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return only name in GET /account', async () => {
|
it('should return only name in GET /my-account', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
const api = await signInAndGetUserApi(username, password, {
|
||||||
scopes: [UserScope.Email],
|
scopes: [UserScope.Email],
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/* eslint-disable max-lines */
|
|
||||||
import { UserScope } from '@logto/core-kit';
|
import { UserScope } from '@logto/core-kit';
|
||||||
import { SignInIdentifier } from '@logto/schemas';
|
import { SignInIdentifier } from '@logto/schemas';
|
||||||
|
|
||||||
|
@ -10,7 +9,7 @@ import {
|
||||||
getUserInfo,
|
getUserInfo,
|
||||||
updatePrimaryEmail,
|
updatePrimaryEmail,
|
||||||
updatePrimaryPhone,
|
updatePrimaryPhone,
|
||||||
} from '#src/api/profile.js';
|
} from '#src/api/my-account.js';
|
||||||
import {
|
import {
|
||||||
createAndVerifyVerificationCode,
|
createAndVerifyVerificationCode,
|
||||||
createVerificationRecordByPassword,
|
createVerificationRecordByPassword,
|
||||||
|
@ -33,7 +32,7 @@ describe('account (email and phone)', () => {
|
||||||
await enableAllAccountCenterFields(authedAdminApi);
|
await enableAllAccountCenterFields(authedAdminApi);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /account/primary-email', () => {
|
describe('POST /my-account/primary-email', () => {
|
||||||
it('should fail if scope is missing', async () => {
|
it('should fail if scope is missing', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -140,7 +139,7 @@ describe('account (email and phone)', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /account/primary-email', () => {
|
describe('DELETE /my-account/primary-email', () => {
|
||||||
it('should fail if scope is missing', async () => {
|
it('should fail if scope is missing', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -236,103 +235,7 @@ describe('account (email and phone)', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /account/primary-phone', () => {
|
describe('POST /my-account/primary-phone', () => {
|
||||||
it('should fail if scope is missing', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password);
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
|
|
||||||
await expectRejects(deletePrimaryEmail(api, verificationRecordId), {
|
|
||||||
code: 'auth.unauthorized',
|
|
||||||
status: 400,
|
|
||||||
});
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if verification record is invalid', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Email],
|
|
||||||
});
|
|
||||||
|
|
||||||
await expectRejects(deletePrimaryEmail(api, 'invalid-verification-record-id'), {
|
|
||||||
code: 'verification_record.permission_denied',
|
|
||||||
status: 401,
|
|
||||||
});
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if email is the only sign-up identifier', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Email],
|
|
||||||
});
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
await enableAllPasswordSignInMethods({
|
|
||||||
identifiers: [SignInIdentifier.Email],
|
|
||||||
password: true,
|
|
||||||
verify: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
await expectRejects(deletePrimaryEmail(api, verificationRecordId), {
|
|
||||||
code: 'user.email_required',
|
|
||||||
status: 400,
|
|
||||||
});
|
|
||||||
|
|
||||||
await enableAllPasswordSignInMethods();
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if email or phone is the sign-up identifier', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Email],
|
|
||||||
});
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
await enableAllPasswordSignInMethods({
|
|
||||||
identifiers: [SignInIdentifier.Email, SignInIdentifier.Phone],
|
|
||||||
password: true,
|
|
||||||
verify: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
await expectRejects(deletePrimaryEmail(api, verificationRecordId), {
|
|
||||||
code: 'user.email_or_phone_required',
|
|
||||||
status: 400,
|
|
||||||
});
|
|
||||||
|
|
||||||
await enableAllPasswordSignInMethods();
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to delete primary email', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Email],
|
|
||||||
});
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
const newEmail = generateEmail();
|
|
||||||
const newVerificationRecordId = await createAndVerifyVerificationCode(api, {
|
|
||||||
type: SignInIdentifier.Email,
|
|
||||||
value: newEmail,
|
|
||||||
});
|
|
||||||
|
|
||||||
await updatePrimaryEmail(api, newEmail, verificationRecordId, newVerificationRecordId);
|
|
||||||
|
|
||||||
const userInfo = await getUserInfo(api);
|
|
||||||
expect(userInfo).toHaveProperty('primaryEmail', newEmail);
|
|
||||||
|
|
||||||
await deletePrimaryEmail(api, verificationRecordId);
|
|
||||||
|
|
||||||
const userInfoAfterDelete = await getUserInfo(api);
|
|
||||||
expect(userInfoAfterDelete).toHaveProperty('primaryEmail', null);
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DELETE /account/primary-phone', () => {
|
|
||||||
it('should fail if scope is missing', async () => {
|
it('should fail if scope is missing', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -402,113 +305,6 @@ describe('account (email and phone)', () => {
|
||||||
await deleteDefaultTenantUser(user.id);
|
await deleteDefaultTenantUser(user.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /account/primary-phone', () => {
|
|
||||||
it('should fail if scope is missing', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password);
|
|
||||||
const newPhone = generatePhone();
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
|
|
||||||
await expectRejects(
|
|
||||||
updatePrimaryPhone(api, newPhone, verificationRecordId, 'new-verification-record-id'),
|
|
||||||
{
|
|
||||||
code: 'auth.unauthorized',
|
|
||||||
status: 400,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if verification record is invalid', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Phone],
|
|
||||||
});
|
|
||||||
const newPhone = generatePhone();
|
|
||||||
|
|
||||||
await expectRejects(
|
|
||||||
updatePrimaryPhone(
|
|
||||||
api,
|
|
||||||
newPhone,
|
|
||||||
'invalid-verification-record-id',
|
|
||||||
'new-verification-record-id'
|
|
||||||
),
|
|
||||||
{
|
|
||||||
code: 'verification_record.permission_denied',
|
|
||||||
status: 401,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if new identifier verification record is invalid', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Phone],
|
|
||||||
});
|
|
||||||
const newPhone = generatePhone();
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
|
|
||||||
await expectRejects(
|
|
||||||
updatePrimaryPhone(api, newPhone, verificationRecordId, 'new-verification-record-id'),
|
|
||||||
{
|
|
||||||
code: 'verification_record.not_found',
|
|
||||||
status: 400,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to update primary phone by verifying password', async () => {
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Phone],
|
|
||||||
});
|
|
||||||
const newPhone = generatePhone();
|
|
||||||
const verificationRecordId = await createVerificationRecordByPassword(api, password);
|
|
||||||
const newVerificationRecordId = await createAndVerifyVerificationCode(api, {
|
|
||||||
type: SignInIdentifier.Phone,
|
|
||||||
value: newPhone,
|
|
||||||
});
|
|
||||||
|
|
||||||
await updatePrimaryPhone(api, newPhone, verificationRecordId, newVerificationRecordId);
|
|
||||||
|
|
||||||
const userInfo = await getUserInfo(api);
|
|
||||||
expect(userInfo).toHaveProperty('primaryPhone', newPhone);
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to update primary phone by verifying existing phone', async () => {
|
|
||||||
const primaryPhone = generatePhone();
|
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword({
|
|
||||||
primaryPhone,
|
|
||||||
});
|
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
|
||||||
scopes: [UserScope.Profile, UserScope.Phone],
|
|
||||||
});
|
|
||||||
const newPhone = generatePhone();
|
|
||||||
const verificationRecordId = await createAndVerifyVerificationCode(api, {
|
|
||||||
type: SignInIdentifier.Phone,
|
|
||||||
value: primaryPhone,
|
|
||||||
});
|
|
||||||
const newVerificationRecordId = await createAndVerifyVerificationCode(api, {
|
|
||||||
type: SignInIdentifier.Phone,
|
|
||||||
value: newPhone,
|
|
||||||
});
|
|
||||||
|
|
||||||
await updatePrimaryPhone(api, newPhone, verificationRecordId, newVerificationRecordId);
|
|
||||||
|
|
||||||
const userInfo = await getUserInfo(api);
|
|
||||||
expect(userInfo).toHaveProperty('primaryPhone', newPhone);
|
|
||||||
|
|
||||||
await deleteDefaultTenantUser(user.id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to delete primary phone', async () => {
|
it('should be able to delete primary phone', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password, {
|
const api = await signInAndGetUserApi(username, password, {
|
||||||
|
@ -535,7 +331,7 @@ describe('account (email and phone)', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /account/primary-phone', () => {
|
describe('DELETE /my-account/primary-phone', () => {
|
||||||
it('should fail if scope is missing', async () => {
|
it('should fail if scope is missing', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -631,4 +427,3 @@ describe('account (email and phone)', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
/* eslint-enable max-lines */
|
|
||||||
|
|
|
@ -2,7 +2,12 @@ import { UserScope } from '@logto/core-kit';
|
||||||
import { hookEvents, SignInIdentifier } from '@logto/schemas';
|
import { hookEvents, SignInIdentifier } from '@logto/schemas';
|
||||||
|
|
||||||
import { enableAllAccountCenterFields } from '#src/api/account-center.js';
|
import { enableAllAccountCenterFields } from '#src/api/account-center.js';
|
||||||
import { getUserInfo, updateOtherProfile, updatePassword, updateUser } from '#src/api/profile.js';
|
import {
|
||||||
|
getUserInfo,
|
||||||
|
updateOtherProfile,
|
||||||
|
updatePassword,
|
||||||
|
updateUser,
|
||||||
|
} from '#src/api/my-account.js';
|
||||||
import { updateSignInExperience } from '#src/api/sign-in-experience.js';
|
import { updateSignInExperience } from '#src/api/sign-in-experience.js';
|
||||||
import { createVerificationRecordByPassword } from '#src/api/verification-record.js';
|
import { createVerificationRecordByPassword } from '#src/api/verification-record.js';
|
||||||
import { WebHookApiTest } from '#src/helpers/hook.js';
|
import { WebHookApiTest } from '#src/helpers/hook.js';
|
||||||
|
@ -46,11 +51,11 @@ describe('account', () => {
|
||||||
await webHookApi.cleanUp();
|
await webHookApi.cleanUp();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /account', () => {
|
describe('GET /my-account', () => {
|
||||||
it('should allow all origins', async () => {
|
it('should allow all origins', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
const response = await api.get('api/account');
|
const response = await api.get('api/my-account');
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
expect(response.headers.get('Access-Control-Allow-Origin')).toBe('*');
|
expect(response.headers.get('Access-Control-Allow-Origin')).toBe('*');
|
||||||
|
|
||||||
|
@ -119,7 +124,7 @@ describe('account', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /account', () => {
|
describe('PATCH /my-account', () => {
|
||||||
it('should be able to update name', async () => {
|
it('should be able to update name', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -209,7 +214,7 @@ describe('account', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /account/profile', () => {
|
describe('PATCH /my-account/profile', () => {
|
||||||
it('should be able to update other profile', async () => {
|
it('should be able to update other profile', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -256,7 +261,7 @@ describe('account', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /account/password', () => {
|
describe('POST /my-account/password', () => {
|
||||||
it('should fail if verification record is invalid', async () => {
|
it('should fail if verification record is invalid', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
mockSocialConnectorTarget,
|
mockSocialConnectorTarget,
|
||||||
} from '#src/__mocks__/connectors-mock.js';
|
} from '#src/__mocks__/connectors-mock.js';
|
||||||
import { enableAllAccountCenterFields } from '#src/api/account-center.js';
|
import { enableAllAccountCenterFields } from '#src/api/account-center.js';
|
||||||
import { deleteIdentity, getUserInfo, updateIdentities } from '#src/api/profile.js';
|
import { deleteIdentity, getUserInfo, updateIdentities } from '#src/api/my-account.js';
|
||||||
import {
|
import {
|
||||||
createSocialVerificationRecord,
|
createSocialVerificationRecord,
|
||||||
createVerificationRecordByPassword,
|
createVerificationRecordByPassword,
|
||||||
|
@ -26,7 +26,7 @@ import {
|
||||||
} from '#src/helpers/profile.js';
|
} from '#src/helpers/profile.js';
|
||||||
import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js';
|
import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js';
|
||||||
|
|
||||||
describe('account (social)', () => {
|
describe('my-account (social)', () => {
|
||||||
const state = 'fake_state';
|
const state = 'fake_state';
|
||||||
const redirectUri = 'http://localhost:3000/redirect';
|
const redirectUri = 'http://localhost:3000/redirect';
|
||||||
const authorizationCode = 'fake_code';
|
const authorizationCode = 'fake_code';
|
||||||
|
@ -47,7 +47,7 @@ describe('account (social)', () => {
|
||||||
await clearConnectorsByTypes([ConnectorType.Social, ConnectorType.Email]);
|
await clearConnectorsByTypes([ConnectorType.Social, ConnectorType.Email]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /account/identities', () => {
|
describe('POST /my-account/identities', () => {
|
||||||
it('should fail if scope is missing', async () => {
|
it('should fail if scope is missing', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
@ -166,7 +166,7 @@ describe('account (social)', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /account/identities/:target', () => {
|
describe('DELETE /my-account/identities/:target', () => {
|
||||||
it('should fail if scope is missing', async () => {
|
it('should fail if scope is missing', async () => {
|
||||||
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
const { user, username, password } = await createDefaultTenantUserWithPassword();
|
||||||
const api = await signInAndGetUserApi(username, password);
|
const api = await signInAndGetUserApi(username, password);
|
||||||
|
|
Loading…
Reference in a new issue