diff --git a/src/pages/MultifactorAuthentication/ValidateCodePage.tsx b/src/pages/MultifactorAuthentication/ValidateCodePage.tsx index 2d2e9b2675a3a..84d70a56ea1a2 100644 --- a/src/pages/MultifactorAuthentication/ValidateCodePage.tsx +++ b/src/pages/MultifactorAuthentication/ValidateCodePage.tsx @@ -8,6 +8,7 @@ import MagicCodeInput from '@components/MagicCodeInput'; import type {MagicCodeInputHandle} from '@components/MagicCodeInput'; import {DefaultCancelConfirmModal} from '@components/MultifactorAuthentication/components/Modals'; import {useMultifactorAuthentication, useMultifactorAuthenticationActions, useMultifactorAuthenticationState} from '@components/MultifactorAuthentication/Context'; +import addMFABreadcrumb from '@components/MultifactorAuthentication/observability/breadcrumbs'; import MultifactorAuthenticationValidateCodeResendButton from '@components/MultifactorAuthentication/ValidateCodeResendButton'; import type {MultifactorAuthenticationValidateCodeResendButtonHandle} from '@components/MultifactorAuthentication/ValidateCodeResendButton'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -17,12 +18,12 @@ import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; import AccountUtils from '@libs/AccountUtils'; -import {getLatestErrorMessage} from '@libs/ErrorUtils'; +import {getLatestErrorField, getLatestErrorMessage} from '@libs/ErrorUtils'; import VALUES from '@libs/MultifactorAuthentication/VALUES'; import {isValidValidateCode} from '@libs/ValidationUtils'; import Navigation from '@navigation/Navigation'; import {clearAccountMessages} from '@userActions/Session'; -import {resendValidateCode} from '@userActions/User'; +import {clearValidateCodeActionError, requestValidateCodeAction} from '@userActions/User'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -40,7 +41,7 @@ function MultifactorAuthenticationValidateCodePage() { // Onyx data const [account] = useOnyx(ONYXKEYS.ACCOUNT); const [session] = useOnyx(ONYXKEYS.SESSION); - + const [validateActionCode] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE); const contactMethod = account?.primaryLogin ?? ''; // Local state @@ -62,9 +63,25 @@ function MultifactorAuthenticationValidateCodePage() { // Derived state const hasAccountError = !!account && !isEmptyObject(account?.errors); const hasContinuableError = !!continuableError; - const hasError = hasAccountError || hasContinuableError; const isValidateCodeFormSubmitting = AccountUtils.isValidateCodeFormSubmitting(account); const shouldDisableResendCode = isOffline ?? account?.isLoading; + const validateCodeActionError = getLatestErrorField(validateActionCode, 'actionVerified'); + const hasValidateCodeActionError = !isEmptyObject(validateCodeActionError); + const hasError = hasAccountError || hasContinuableError || hasValidateCodeActionError; + const errorMessage = getErrorMessage(); + + function getErrorMessage() { + // Rate limit or other backend error when sending/resending the validate code + if (hasValidateCodeActionError) { + return Object.values(validateCodeActionError).at(0); + } + // Invalid validate code submitted by the user + if (hasContinuableError) { + return translate('validateCodeForm.error.incorrectMagicCode'); + } + // Generic account/session error (e.g. stale errors from a previous flow) + return getLatestErrorMessage(account); + } // Check if this page can handle the continuable error, if not convert to regular error useEffect(() => { @@ -124,16 +141,18 @@ function MultifactorAuthenticationValidateCodePage() { clearAccountMessages(); } - // Clear validateCode and continuable error when user starts typing after an error - // This ensures process() will re-trigger on submit even if user enters the same code + // Clear continuable error when user starts typing after an error if (continuableError) { - dispatch({type: 'SET_VALIDATE_CODE', payload: undefined}); dispatch({type: 'CLEAR_CONTINUABLE_ERROR'}); } }; const resendValidationCode = () => { - resendValidateCode(contactMethod); + if (hasValidateCodeActionError) { + clearValidateCodeActionError('actionVerified'); + } + addMFABreadcrumb('Validate code resend requested'); + requestValidateCodeAction(); inputRef.current?.clear(); setInputCode(''); setFormError({}); @@ -236,8 +255,6 @@ function MultifactorAuthenticationValidateCodePage() { ref={inputRef} maxLength={CONST.MAGIC_CODE_LENGTH} /> - {hasContinuableError && } - {hasAccountError && } -