-
-
Notifications
You must be signed in to change notification settings - Fork 440
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(experience): migrate the social and sso flow (migration-3) (#…
…6406) * refactor(experience): migrate the social and sso flow migrate the social and sso flow * refactor(experience): migrate profile fulfillment flow (migration-4) (#6414) * refactor(experience): migrate profile fulfillment flow migrate the profile fulfillment flow * refactor(experience): remove unused hook remove unused hook * fix(experience): fix password policy checker fix password policy checker error display * fix(experience): fix the api name fix the api name * refactor(experience): migrate mfa flow (migration-5) (#6417) * refactor(experience): migrate mfa binding flow migrate mfa binding flow * test(experience): update unit tests (migration-6) (#6420) * test(experience): update unit tests update unit tests * chore(experience): remove legacy APIs remove legacy APIs
- Loading branch information
Showing
70 changed files
with
1,272 additions
and
915 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const kyPrefixUrl = '/'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export const prefix = 'api/experience'; | ||
|
||
export const experienceApiRoutes = Object.freeze({ | ||
prefix, | ||
identification: `${prefix}/identification`, | ||
submit: `${prefix}/submit`, | ||
verification: `${prefix}/verification`, | ||
profile: `${prefix}/profile`, | ||
mfa: `${prefix}/profile/mfa`, | ||
}); | ||
|
||
export type VerificationResponse = { | ||
verificationId: string; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { | ||
type InteractionEvent, | ||
type IdentificationApiPayload, | ||
type UpdateProfileApiPayload, | ||
} from '@logto/schemas'; | ||
|
||
import api from '../api'; | ||
|
||
import { experienceApiRoutes } from './const'; | ||
|
||
type SubmitInteractionResponse = { | ||
redirectTo: string; | ||
}; | ||
|
||
export const initInteraction = async (interactionEvent: InteractionEvent) => | ||
api.put(`${experienceApiRoutes.prefix}`, { | ||
json: { | ||
interactionEvent, | ||
}, | ||
}); | ||
|
||
export const identifyUser = async (payload: IdentificationApiPayload = {}) => | ||
api.post(experienceApiRoutes.identification, { json: payload }); | ||
|
||
export const submitInteraction = async () => | ||
api.post(`${experienceApiRoutes.submit}`).json<SubmitInteractionResponse>(); | ||
|
||
export const _updateProfile = async (payload: UpdateProfileApiPayload) => | ||
api.post(experienceApiRoutes.profile, { json: payload }); | ||
|
||
export const updateInteractionEvent = async (interactionEvent: InteractionEvent) => | ||
api.put(`${experienceApiRoutes.prefix}/interaction-event`, { | ||
json: { | ||
interactionEvent, | ||
}, | ||
}); | ||
|
||
export const identifyAndSubmitInteraction = async (payload?: IdentificationApiPayload) => { | ||
await identifyUser(payload); | ||
return submitInteraction(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import { | ||
MfaFactor, | ||
type WebAuthnRegistrationOptions, | ||
type WebAuthnAuthenticationOptions, | ||
type BindMfaPayload, | ||
type VerifyMfaPayload, | ||
} from '@logto/schemas'; | ||
|
||
import api from '../api'; | ||
|
||
import { experienceApiRoutes } from './const'; | ||
import { submitInteraction } from './interaction'; | ||
|
||
/** | ||
* Mfa APIs | ||
*/ | ||
const addMfa = async (type: MfaFactor, verificationId: string) => | ||
api.post(`${experienceApiRoutes.mfa}`, { | ||
json: { | ||
type, | ||
verificationId, | ||
}, | ||
}); | ||
|
||
type TotpSecretResponse = { | ||
verificationId: string; | ||
secret: string; | ||
secretQrCode: string; | ||
}; | ||
export const createTotpSecret = async () => | ||
api.post(`${experienceApiRoutes.verification}/totp/secret`).json<TotpSecretResponse>(); | ||
|
||
export const createWebAuthnRegistration = async () => { | ||
const { verificationId, registrationOptions } = await api | ||
.post(`${experienceApiRoutes.verification}/web-authn/registration`) | ||
.json<{ verificationId: string; registrationOptions: WebAuthnRegistrationOptions }>(); | ||
|
||
return { | ||
verificationId, | ||
options: registrationOptions, | ||
}; | ||
}; | ||
|
||
export const createWebAuthnAuthentication = async () => { | ||
const { verificationId, authenticationOptions } = await api | ||
.post(`${experienceApiRoutes.verification}/web-authn/authentication`) | ||
.json<{ verificationId: string; authenticationOptions: WebAuthnAuthenticationOptions }>(); | ||
|
||
return { | ||
verificationId, | ||
options: authenticationOptions, | ||
}; | ||
}; | ||
|
||
export const createBackupCode = async () => | ||
api.post(`${experienceApiRoutes.verification}/backup-code/generate`).json<{ | ||
verificationId: string; | ||
codes: string[]; | ||
}>(); | ||
|
||
export const skipMfa = async () => { | ||
await api.post(`${experienceApiRoutes.mfa}/mfa-skipped`); | ||
return submitInteraction(); | ||
}; | ||
|
||
export const bindMfa = async (payload: BindMfaPayload, verificationId: string) => { | ||
switch (payload.type) { | ||
case MfaFactor.TOTP: { | ||
const { code } = payload; | ||
await api.post(`${experienceApiRoutes.verification}/totp/verify`, { | ||
json: { | ||
code, | ||
verificationId, | ||
}, | ||
}); | ||
break; | ||
} | ||
case MfaFactor.WebAuthn: { | ||
await api.post(`${experienceApiRoutes.verification}/web-authn/registration/verify`, { | ||
json: { | ||
verificationId, | ||
payload, | ||
}, | ||
}); | ||
break; | ||
} | ||
case MfaFactor.BackupCode: { | ||
// No need to verify backup codes | ||
break; | ||
} | ||
} | ||
|
||
await addMfa(payload.type, verificationId); | ||
return submitInteraction(); | ||
}; | ||
|
||
export const verifyMfa = async (payload: VerifyMfaPayload, verificationId?: string) => { | ||
switch (payload.type) { | ||
case MfaFactor.TOTP: { | ||
const { code } = payload; | ||
await api.post(`${experienceApiRoutes.verification}/totp/verify`, { | ||
json: { | ||
code, | ||
}, | ||
}); | ||
break; | ||
} | ||
case MfaFactor.WebAuthn: { | ||
await api.post(`${experienceApiRoutes.verification}/web-authn/authentication/verify`, { | ||
json: { | ||
verificationId, | ||
payload, | ||
}, | ||
}); | ||
break; | ||
} | ||
case MfaFactor.BackupCode: { | ||
const { code } = payload; | ||
await api.post(`${experienceApiRoutes.verification}/backup-code/verify`, { | ||
json: { | ||
code, | ||
}, | ||
}); | ||
break; | ||
} | ||
} | ||
|
||
return submitInteraction(); | ||
}; |
Oops, something went wrong.