0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00
logto/packages/experience-legacy/src/hooks/use-webauthn-operation.ts

85 lines
2.8 KiB
TypeScript
Raw Permalink Normal View History

refactor(experience): experience api migration (#6407) * refactor(experience): migrate the password register and sign-in migrate the password register and sign-in flow * fix(experience): update some namings update some namings * refactor(experience): refactor the verification code flow (migration-2) (#6408) * refactor(experience): refactor the verificaiton code flow refactor the verification code flow * 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 * refactor(experience): revert api prefix revert api prefix * fix(experience): update the sso connectors endpoint update the sso connectors endpoint * chore: add changeset add changeset * fix(experience): comments fix comments fix * refactor(experience): refactor the code verificatin api refactor the code verification api * refactor(experience): code refactor refactor some implementation logic * feat(experience, core): add experience legacy package (#6527) add experience legacy package
2024-09-09 10:08:52 +08:00
import {
MfaFactor,
webAuthnRegistrationOptionsGuard,
type WebAuthnAuthenticationOptions,
type WebAuthnRegistrationOptions,
} from '@logto/schemas';
import { trySafe } from '@silverhand/essentials';
import {
browserSupportsWebAuthn,
startAuthentication,
startRegistration,
} from '@simplewebauthn/browser';
import type { RegistrationResponseJSON, AuthenticationResponseJSON } from '@simplewebauthn/types';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { UserMfaFlow } from '@/types';
import useSendMfaPayload from './use-send-mfa-payload';
import useToast from './use-toast';
type WebAuthnOptions = WebAuthnRegistrationOptions | WebAuthnAuthenticationOptions;
const isAuthenticationResponseJSON = (
responseJson: RegistrationResponseJSON | AuthenticationResponseJSON
): responseJson is AuthenticationResponseJSON => {
return 'signature' in responseJson.response;
};
const useWebAuthnOperation = () => {
const { t } = useTranslation();
const { setToast } = useToast();
const sendMfaPayload = useSendMfaPayload();
return useCallback(
/**
* Note:
* Due to limitations in the iOS system, user interaction is required for the use of the WebAuthn API.
* Therefore, we should avoid asynchronous operations before invoking the WebAuthn API or the os may consider the WebAuthn authorization is not initiated by the user.
* So, we need to prepare the necessary WebAuthn options before calling the WebAuthn API, this is why we don't generate the options in this function.
*/
async (options: WebAuthnOptions) => {
if (!browserSupportsWebAuthn()) {
setToast(t('mfa.webauthn_not_supported'));
return;
}
const parsedRegistrationOptions = webAuthnRegistrationOptionsGuard.safeParse(options);
const response = await trySafe(
async () =>
parsedRegistrationOptions.success
? startRegistration(parsedRegistrationOptions.data)
: startAuthentication(options),
() => {
setToast(
t(
parsedRegistrationOptions.success
? 'mfa.webauthn_failed_to_create'
: 'mfa.webauthn_failed_to_verify'
)
);
}
);
if (response) {
/**
* Assert type manually to get the correct type
*/
await sendMfaPayload(
refactor(experience): experience api migration (#6407) * refactor(experience): migrate the password register and sign-in migrate the password register and sign-in flow * fix(experience): update some namings update some namings * refactor(experience): refactor the verification code flow (migration-2) (#6408) * refactor(experience): refactor the verificaiton code flow refactor the verification code flow * 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 * refactor(experience): revert api prefix revert api prefix * fix(experience): update the sso connectors endpoint update the sso connectors endpoint * chore: add changeset add changeset * fix(experience): comments fix comments fix * refactor(experience): refactor the code verificatin api refactor the code verification api * refactor(experience): code refactor refactor some implementation logic * feat(experience, core): add experience legacy package (#6527) add experience legacy package
2024-09-09 10:08:52 +08:00
isAuthenticationResponseJSON(response)
? {
flow: UserMfaFlow.MfaVerification,
payload: { ...response, type: MfaFactor.WebAuthn },
}
: { flow: UserMfaFlow.MfaBinding, payload: { ...response, type: MfaFactor.WebAuthn } }
);
}
},
[sendMfaPayload, setToast, t]
);
};
export default useWebAuthnOperation;