diff --git a/lib/hooks/login-hooks.js b/lib/hooks/login-hooks.js --- a/lib/hooks/login-hooks.js +++ b/lib/hooks/login-hooks.js @@ -10,7 +10,7 @@ logOutActionTypes, useIdentityLogOut, } from '../actions/user-actions.js'; -import { useKeyserverAuth } from '../keyserver-conn/keyserver-auth.js'; +import { useKeyserverAuthWithRetry } from '../keyserver-conn/keyserver-auth.js'; import { logInActionSources } from '../types/account-types.js'; import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; @@ -92,7 +92,7 @@ ], ); - const keyserverAuth = useKeyserverAuth(authoritativeKeyserverID()); + const keyserverAuth = useKeyserverAuthWithRetry(authoritativeKeyserverID()); const isRegisteredOnIdentity = useSelector( state => diff --git a/lib/keyserver-conn/keyserver-auth.js b/lib/keyserver-conn/keyserver-auth.js --- a/lib/keyserver-conn/keyserver-auth.js +++ b/lib/keyserver-conn/keyserver-auth.js @@ -22,6 +22,7 @@ import type { AuthActionSource } from '../types/account-types.js'; import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js'; import { getConfig } from '../utils/config.js'; +import { getMessageForException } from '../utils/errors.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector } from '../utils/redux-utils.js'; import sleep from '../utils/sleep.js'; @@ -175,14 +176,24 @@ type KeyserverAuthFunc = KeyserverAuthInputs => Promise; -function useKeyserverAuth(keyserverID: string): KeyserverAuthFunc { +function useKeyserverAuthWithRetry(keyserverID: string): KeyserverAuthFunc { const rawKeyserverAuth = useRawKeyserverAuth(keyserverID); const { callKeyserverEndpoint } = useCallKeyserverEndpointContext(); return React.useCallback( - (inputs: KeyserverAuthInputs) => - rawKeyserverAuth(inputs)(callKeyserverEndpoint), + async (inputs: KeyserverAuthInputs) => { + try { + return await rawKeyserverAuth(inputs)(callKeyserverEndpoint); + } catch (e) { + if (getMessageForException(e) === 'olm_session_creation_failure') { + // We retry in case we were accidentally vended an invalid OTK the + // first time + return await rawKeyserverAuth(inputs)(callKeyserverEndpoint); + } + throw e; + } + }, [rawKeyserverAuth, callKeyserverEndpoint], ); } -export { useRawKeyserverAuth, useKeyserverAuth }; +export { useRawKeyserverAuth, useKeyserverAuthWithRetry }; 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 @@ -12,7 +12,7 @@ deleteAccountActionTypes, useDeleteDiscardedIdentityAccount, } from 'lib/actions/user-actions.js'; -import { useKeyserverAuth } from 'lib/keyserver-conn/keyserver-auth.js'; +import { useKeyserverAuthWithRetry } from 'lib/keyserver-conn/keyserver-auth.js'; import { useLegacyAshoatKeyserverCall } from 'lib/keyserver-conn/legacy-keyserver-call.js'; import { isLoggedInToKeyserver } from 'lib/selectors/user-selectors.js'; import { @@ -308,7 +308,7 @@ // STEP 2: REGISTERING ON AUTHORITATIVE KEYSERVER - const keyserverAuth = useKeyserverAuth(authoritativeKeyserverID); + const keyserverAuth = useKeyserverAuthWithRetry(authoritativeKeyserverID); const isRegisteredOnIdentity = useSelector( state =>