diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -454,14 +454,9 @@ ); } -// Unlike useDeleteAccount, we always dispatch a success here (never throw). -// That's because useDeleteAccount is used in a scenario where the user is -// visibly logged-in, and we don't want to log them out unless we succeeded in -// deleting their account. On the other hand, useDeleteDiscardedIdentityAccount -// is used in a scenario where the user is visibly logged-out, and it's only -// used to reset state (eg. Redux, SQLite) to a logged-out state. The state -// reset only occurs when a success action is dispatched, so we always dispatch -// a success. +// useDeleteDiscardedIdentityAccount is used in a scenario where the user is +// visibly logged-out, and it's only used to reset state (eg. Redux, SQLite) to +// a logged-out state. function useDeleteDiscardedIdentityAccount(): ( password: ?string, ) => Promise { @@ -492,15 +487,15 @@ const deleteUserCall = password ? identityClient.deletePasswordUser(password) : identityClient.deleteWalletUser(); - try { - await Promise.race([ - deleteUserCall, - (async () => { - await sleep(500); - throw new Error('identity delete user call took more than 500ms'); - })(), - ]); - } catch {} + + await Promise.race([ + deleteUserCall, + (async () => { + await sleep(500); + throw new Error('identity delete user call took more than 500ms'); + })(), + ]); + return { currentUserInfo: null, preRequestUserState: { diff --git a/native/account/registration/registration-server-call.js b/native/account/registration/registration-server-call.js --- a/native/account/registration/registration-server-call.js +++ b/native/account/registration/registration-server-call.js @@ -14,10 +14,12 @@ } from 'lib/actions/user-actions.js'; import { useKeyserverAuthWithRetry } from 'lib/keyserver-conn/keyserver-auth.js'; import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; +import { usePreRequestUserState } from 'lib/selectors/account-selectors.js'; import { isLoggedInToKeyserver } from 'lib/selectors/user-selectors.js'; import { type LegacyLogInStartingPayload, logInActionSources, + type LogOutResult, } from 'lib/types/account-types.js'; import { syncedMetadataNames } from 'lib/types/synced-metadata-types.js'; import { getMessageForException } from 'lib/utils/errors.js'; @@ -422,6 +424,10 @@ // We call deleteDiscardedIdentityAccount in order to reset state if identity // registration succeeds but authoritative keyserver auth fails const deleteDiscardedIdentityAccount = useDeleteDiscardedIdentityAccount(); + const preRequestUserState = usePreRequestUserState(); + const commServicesAccessToken = useSelector( + state => state.commServicesAccessToken, + ); const registeringOnAuthoritativeKeyserverRef = React.useRef(false); React.useEffect(() => { @@ -463,39 +469,53 @@ const messageForException = getMessageForException( keyserverAuthException, ); - const discardIdentityAccountPromise = (async () => { - try { - const deletionResult = await deleteDiscardedIdentityAccount( - credentialsToSave?.password, - ); - if (messageForException === 'client_version_unsupported') { - Alert.alert( - appOutOfDateAlertDetails.title, - appOutOfDateAlertDetails.message, - [{ text: 'OK', onPress: onAlertAcknowledged }], - { cancelable: !onAlertAcknowledged }, + const discardIdentityAccountPromise: Promise = + (async () => { + try { + const deletionResult = await deleteDiscardedIdentityAccount( + credentialsToSave?.password, ); - } else { + if (messageForException === 'client_version_unsupported') { + Alert.alert( + appOutOfDateAlertDetails.title, + appOutOfDateAlertDetails.message, + [{ text: 'OK', onPress: onAlertAcknowledged }], + { cancelable: !onAlertAcknowledged }, + ); + } else { + Alert.alert( + unknownErrorAlertDetails.title, + unknownErrorAlertDetails.message, + [{ text: 'OK', onPress: onAlertAcknowledged }], + { cancelable: !onAlertAcknowledged }, + ); + } + return deletionResult; + } catch (deleteException) { + // We swallow the exception here because + // discardIdentityAccountPromise is used in a scenario where the + // user is visibly logged-out, and it's only used to reset state + // (eg. Redux, SQLite) to a logged-out state. The state reset + // only occurs when a success action is dispatched, so by + // swallowing exceptions we ensure that we always dispatch a + // success. Alert.alert( - unknownErrorAlertDetails.title, - unknownErrorAlertDetails.message, + 'Account created but login failed', + 'We were able to create your account, but were unable to log ' + + 'you in. Try going back to the login screen and logging in ' + + 'with your new credentials.', [{ text: 'OK', onPress: onAlertAcknowledged }], { cancelable: !onAlertAcknowledged }, ); + return { + currentUserInfo: null, + preRequestUserState: { + ...preRequestUserState, + commServicesAccessToken, + }, + }; } - return deletionResult; - } catch (deleteException) { - Alert.alert( - 'Account created but login failed', - 'We were able to create your account, but were unable to log ' + - 'you in. Try going back to the login screen and logging in ' + - 'with your new credentials.', - [{ text: 'OK', onPress: onAlertAcknowledged }], - { cancelable: !onAlertAcknowledged }, - ); - throw deleteException; - } - })(); + })(); void dispatchActionPromise( deleteAccountActionTypes, discardIdentityAccountPromise, @@ -513,6 +533,8 @@ keyserverAuth, dispatchActionPromise, deleteDiscardedIdentityAccount, + preRequestUserState, + commServicesAccessToken, ]); // STEP 3: SETTING AVATAR