diff --git a/CHANGELOG.md b/CHANGELOG.md index 207d8fd8..0f80550d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- fixed: Correctly handle challenge errors during light account creation. + ## 3.22.2 (2024-09-26) - fixed: Spinner showing on pin dots before biometric is read diff --git a/src/components/modals/ChallengeModal.tsx b/src/components/modals/ChallengeModal.tsx index 8e6e89c2..5fad1505 100644 --- a/src/components/modals/ChallengeModal.tsx +++ b/src/components/modals/ChallengeModal.tsx @@ -22,13 +22,13 @@ interface Props { * and the user successfully solves the challenge. */ export async function retryOnChallenge(opts: { - task: (challengeId?: string) => Promise - onCancel: () => C - onSuccess?: (challengeId: string) => void + cancelValue: C + saveChallenge?: (challengeId: string) => void + task: (challengeId: string | undefined) => Promise }): Promise { - const { task, onCancel, onSuccess } = opts + const { cancelValue, saveChallenge, task } = opts - return await task().catch(async error => { + return await task(undefined).catch(async error => { const challengeError = asMaybeChallengeError?.(error) if (challengeError != null) { const result = await Airship.show(bridge => ( @@ -37,9 +37,9 @@ export async function retryOnChallenge(opts: { challengeUri={challengeError.challengeUri} /> )) - if (result == null) return onCancel() + if (result == null) return cancelValue if (result) { - onSuccess?.(challengeError.challengeId) + saveChallenge?.(challengeError.challengeId) return await task(challengeError.challengeId) } } diff --git a/src/components/scenes/OtpErrorScene.tsx b/src/components/scenes/OtpErrorScene.tsx index 6a6b8827..a6864f9e 100644 --- a/src/components/scenes/OtpErrorScene.tsx +++ b/src/components/scenes/OtpErrorScene.tsx @@ -104,6 +104,7 @@ export function OtpErrorScene(props: Props) { inModal.current = true const handleSubmit = async (otpKey: string): Promise => await retryOnChallenge({ + cancelValue: lstrings.failed_captcha_error, async task(challengeId) { const account = await attemptLogin( context, @@ -117,9 +118,6 @@ export function OtpErrorScene(props: Props) { ) dispatch(completeLogin(account)) return true - }, - onCancel() { - return lstrings.failed_captcha_error } }).catch(error => { // Translate known errors: diff --git a/src/components/scenes/PasswordLoginScene.tsx b/src/components/scenes/PasswordLoginScene.tsx index ab705b60..06f028b1 100644 --- a/src/components/scenes/PasswordLoginScene.tsx +++ b/src/components/scenes/PasswordLoginScene.tsx @@ -189,6 +189,7 @@ export const PasswordLoginScene = (props: Props) => { setSpinner(true) retryOnChallenge({ + cancelValue: undefined, async task(challengeId) { Keyboard.dismiss() const account = await attemptLogin( @@ -203,9 +204,6 @@ export const PasswordLoginScene = (props: Props) => { onPerfEvent({ name: 'passwordLoginEnd' }) onLogEvent('Pasword_Login') await dispatch(completeLogin(account)) - }, - onCancel() { - return undefined } }) .catch(async error => { diff --git a/src/components/scenes/newAccount/NewAccountUsernameScene.tsx b/src/components/scenes/newAccount/NewAccountUsernameScene.tsx index d44f7295..930ffa99 100644 --- a/src/components/scenes/newAccount/NewAccountUsernameScene.tsx +++ b/src/components/scenes/newAccount/NewAccountUsernameScene.tsx @@ -176,12 +176,12 @@ export const ChangeUsernameComponent = (props: Props) => { setIsFetchingAvailability(true) retryOnChallenge({ + cancelValue: undefined, + saveChallenge(challengeId) { + dispatch({ type: 'CREATE_CHALLENGE', data: challengeId }) + }, async task(challengeId = lastChallengeId) { return await context.usernameAvailable(text, { challengeId }) - }, - onCancel() {}, - onSuccess(challengeId) { - dispatch({ type: 'CREATE_CHALLENGE', data: challengeId }) } }).then( isAvailable => { diff --git a/src/hooks/useCreateAccount.ts b/src/hooks/useCreateAccount.ts index 33b10b33..cfd264c7 100644 --- a/src/hooks/useCreateAccount.ts +++ b/src/hooks/useCreateAccount.ts @@ -8,7 +8,8 @@ import { useImports } from './useImports' export const useCreateAccountHandler = () => { const { context, accountOptions } = useImports() const dispatch = useDispatch() - const challengeId = useSelector(state => state.createChallengeId) ?? undefined + const savedChallengeId = + useSelector(state => state.createChallengeId) ?? undefined const handleCreateAccount = useHandler( async (createAccountParams: { @@ -19,7 +20,8 @@ export const useCreateAccountHandler = () => { const { username, password, pin } = createAccountParams return await retryOnChallenge({ - async task() { + cancelValue: undefined, + async task(challengeId = savedChallengeId) { const account = await context.createAccount({ ...accountOptions, challengeId, @@ -36,8 +38,7 @@ export const useCreateAccountHandler = () => { dispatch(loadTouchState()) return account - }, - onCancel() {} + } }) } )