UNPKG

@aws-amplify/ui

Version:

`@aws-amplify/ui` contains low-level logic & styles for stand-alone usage or re-use in framework-specific implementations.

131 lines (129 loc) 6.33 kB
const SIGN_IN_STEP_MFA_CONFIRMATION = [ 'CONFIRM_SIGN_IN_WITH_SMS_CODE', 'CONFIRM_SIGN_IN_WITH_TOTP_CODE', 'CONFIRM_SIGN_IN_WITH_EMAIL_CODE', ]; // response next step guards const shouldConfirmSignInWithNewPassword = (_, { data }) => data?.nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED'; const shouldResetPasswordFromSignIn = (_, { data }) => data?.nextStep?.signInStep === 'RESET_PASSWORD'; const shouldConfirmSignUpFromSignIn = (_, { data }) => data?.nextStep.signInStep === 'CONFIRM_SIGN_UP'; const shouldAutoSignIn = (_, { data }) => data?.nextStep.signUpStep === 'COMPLETE_AUTO_SIGN_IN'; const hasCompletedSignIn = (_, { data }) => data?.nextStep.signInStep === 'DONE'; const hasCompletedSignUp = (_, { data }) => data?.nextStep.signUpStep === 'DONE'; const hasCompletedResetPassword = (_, { data }) => data?.nextStep.resetPasswordStep === 'DONE'; // actor done guards read `step` from actor exit event const hasCompletedAttributeConfirmation = (_, { data }) => data?.step === 'CONFIRM_ATTRIBUTE_COMPLETE'; const isConfirmUserAttributeStep = (_, { data }) => data?.step === 'CONFIRM_ATTRIBUTE_WITH_CODE'; const isShouldConfirmUserAttributeStep = (_, { data }) => data?.step === 'SHOULD_CONFIRM_USER_ATTRIBUTE'; const isResetPasswordStep = (_, { data }) => data?.step === 'RESET_PASSWORD'; const isConfirmSignUpStep = (_, { data }) => data?.step === 'CONFIRM_SIGN_UP'; // actor entry guards read `step` from actor context const shouldConfirmSignIn = ({ step }) => SIGN_IN_STEP_MFA_CONFIRMATION.includes(step); const shouldSetupTotp = ({ step }) => step === 'CONTINUE_SIGN_IN_WITH_TOTP_SETUP'; const shouldSetupEmail = ({ step }) => step === 'CONTINUE_SIGN_IN_WITH_EMAIL_SETUP'; const shouldSelectMfaType = ({ step }) => [ 'CONTINUE_SIGN_IN_WITH_MFA_SELECTION', 'CONTINUE_SIGN_IN_WITH_MFA_SETUP_SELECTION', ].includes(step); const shouldResetPassword = ({ step }) => step === 'RESET_PASSWORD'; const shouldConfirmResetPassword = ({ step }) => step === 'CONFIRM_RESET_PASSWORD_WITH_CODE'; const shouldConfirmSignUp = ({ step }) => step === 'CONFIRM_SIGN_UP'; // miscellaneous guards const shouldVerifyAttribute = (context, event) => { // Try to get data from event first (for backward compatibility), then from context const data = (event.data || context.fetchedUserAttributes); if (!data) return false; const { email, phone_number, phone_number_verified, email_verified } = data; // if neither email nor phone_number exist // there is nothing to verify if (!email && !phone_number) return false; // email/phone_verified is returned as a string const emailNotVerified = email_verified === undefined || email_verified === 'false'; const phoneNotVerified = phone_number_verified === undefined || phone_number_verified === 'false'; // only request verification if both email and phone are not verified return emailNotVerified && phoneNotVerified; }; /** * This guard covers an edge case that exists in the current state of the UI. * As of now, our ConfirmSignUp screen only supports showing an input for a * confirmation code. However, a Cognito UserPool can instead verify users * through a link that gets emailed to them. If a user verifies through the * link and then they click on the "Resend Code" button, they will get an error * saying that the user has already been confirmed. If we encounter that error, * we want to just funnel them through the rest of the flow. In the future, we will * want to update our UI to support both confirmation codes and links. * * https://github.com/aws-amplify/amplify-ui/issues/219 */ const isUserAlreadyConfirmed = (_, { data }) => data.message === 'User is already confirmed.'; // passwordless guards const shouldSelectAuthMethod = ({ availableAuthMethods, preferredChallenge, selectedAuthMethod, }) => { // Show selection if: // 1. Multiple methods available // 2. AND either no preferredChallenge OR selectedAuthMethod is explicitly cleared (null) const hasMultipleMethods = availableAuthMethods && availableAuthMethods.length > 1; const shouldShowSelection = !preferredChallenge || selectedAuthMethod === null; return hasMultipleMethods && shouldShowSelection; }; const shouldPromptPasskeyRegistration = ({ passwordless, hasExistingPasskeys, }) => { const { passkeyRegistrationPrompts } = passwordless || {}; if (!passkeyRegistrationPrompts) { return false; } // Don't prompt if user already has passkeys if (hasExistingPasskeys) { return false; } if (typeof passkeyRegistrationPrompts === 'boolean') { return passkeyRegistrationPrompts; } return passkeyRegistrationPrompts.afterSignin === 'ALWAYS'; }; const shouldPromptPasskeyRegistrationAfterSignup = ({ passwordless, hasExistingPasskeys, }) => { const { passkeyRegistrationPrompts } = passwordless || {}; if (!passkeyRegistrationPrompts) { return false; } // Don't prompt if user already has passkeys if (hasExistingPasskeys) { return false; } if (typeof passkeyRegistrationPrompts === 'boolean') { return passkeyRegistrationPrompts; } return passkeyRegistrationPrompts.afterSignup === 'ALWAYS'; }; const hasPasskeyRegistrationPrompts = ({ passwordless }) => passwordless?.passkeyRegistrationPrompts != null; const shouldReturnToSelectMethod = ({ selectedAuthMethod, step, }) => selectedAuthMethod != null && step === 'SELECT_AUTH_METHOD'; const GUARDS = { hasCompletedAttributeConfirmation, hasCompletedResetPassword, hasCompletedSignIn, hasCompletedSignUp, hasPasskeyRegistrationPrompts, isConfirmSignUpStep, isConfirmUserAttributeStep, isResetPasswordStep, isShouldConfirmUserAttributeStep, isUserAlreadyConfirmed, shouldAutoSignIn, shouldConfirmResetPassword, shouldConfirmSignIn, shouldConfirmSignInWithNewPassword, shouldConfirmSignUp, shouldConfirmSignUpFromSignIn, shouldResetPassword, shouldResetPasswordFromSignIn, shouldReturnToSelectMethod, shouldSelectAuthMethod, shouldSetupTotp, shouldSetupEmail, shouldSelectMfaType, shouldVerifyAttribute, shouldPromptPasskeyRegistration, shouldPromptPasskeyRegistrationAfterSignup, }; export { GUARDS as default };