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 @@ -436,19 +436,6 @@ }; }; -function useKeyserverAuth(): ( - input: KeyserverAuthInfo, -) => Promise { - const preRequestUserInfo = useSelector(state => state.currentUserInfo); - const callKeyserverAuth = useKeyserverCall(keyserverAuth); - - return React.useCallback( - (input: KeyserverAuthInfo) => - callKeyserverAuth({ preRequestUserInfo, ...input }), - [callKeyserverAuth, preRequestUserInfo], - ); -} - const identityRegisterActionTypes = Object.freeze({ started: 'IDENTITY_REGISTER_STARTED', success: 'IDENTITY_REGISTER_SUCCESS', @@ -888,7 +875,7 @@ deleteAccountActionTypes, useDeleteAccount, keyserverAuthActionTypes, - useKeyserverAuth, + keyserverAuth as keyserverAuthRawAction, identityRegisterActionTypes, useIdentityPasswordRegister, useIdentityWalletRegister, diff --git a/lib/components/keyserver-connection-handler.js b/lib/components/keyserver-connection-handler.js --- a/lib/components/keyserver-connection-handler.js +++ b/lib/components/keyserver-connection-handler.js @@ -6,9 +6,10 @@ import { keyserverAuthActionTypes, logOutActionTypes, - useKeyserverAuth, + keyserverAuthRawAction, useLogOut, } from '../actions/user-actions.js'; +import { useCallKeyserverEndpointContext } from '../keyserver-conn/call-keyserver-endpoint-provider.react.js'; import { extractKeyserverIDFromID } from '../keyserver-conn/keyserver-call-utils.js'; import { CANCELLED_ERROR, @@ -28,6 +29,7 @@ import { logInActionSources, type RecoveryActionSource, + type AuthActionSource, } from '../types/account-types.js'; import { authoritativeKeyserverID } from '../utils/authoritative-keyserver.js'; import type { CallSingleKeyserverEndpoint } from '../utils/call-single-keyserver-endpoint.js'; @@ -53,7 +55,6 @@ const dispatchActionPromise = useDispatchActionPromise(); const callLogOut = useLogOut(); - const keyserverAuth = useKeyserverAuth(); const hasConnectionIssue = useSelector( state => !!connectionSelector(keyserverID)(state)?.connectionIssue, @@ -101,7 +102,100 @@ const { olmAPI } = getConfig(); + const preRequestUserInfo = useSelector(state => state.currentUserInfo); + const innerPerformAuth = React.useCallback( + ( + authActionSource: AuthActionSource, + setInProgress: boolean => mixed, + hasBeenCancelled: () => boolean, + doNotRegister: boolean, + ) => + async (innerCallKeyserverEndpoint: CallKeyserverEndpoint) => { + try { + const [keyserverKeys] = await Promise.all([ + identityClient.getKeyserverKeys(keyserverID), + olmAPI.initializeCryptoAccount(), + ]); + + if (hasBeenCancelled()) { + throw new Error(CANCELLED_ERROR); + } + + const [notifsSession, contentSession, { userID, deviceID }] = + await Promise.all([ + olmAPI.notificationsSessionCreator( + cookie, + keyserverKeys.identityKeysBlob.notificationIdentityPublicKeys, + keyserverKeys.notifInitializationInfo, + keyserverID, + ), + olmAPI.contentOutboundSessionCreator( + keyserverKeys.identityKeysBlob.primaryIdentityPublicKeys, + keyserverKeys.contentInitializationInfo, + ), + getAuthMetadata(), + ]); + + invariant(userID, 'userID should be set'); + invariant(deviceID, 'deviceID should be set'); + + const deviceTokenUpdateInput = deviceToken + ? { [keyserverID]: { deviceToken } } + : {}; + + if (hasBeenCancelled()) { + throw new Error(CANCELLED_ERROR); + } + + await dispatchActionPromise( + keyserverAuthActionTypes, + keyserverAuthRawAction(innerCallKeyserverEndpoint)({ + userID, + deviceID, + doNotRegister, + calendarQuery, + deviceTokenUpdateInput, + authActionSource, + keyserverData: { + [keyserverID]: { + initialContentEncryptedMessage: contentSession, + initialNotificationsEncryptedMessage: notifsSession, + }, + }, + preRequestUserInfo, + }), + ); + } catch (e) { + if (hasBeenCancelled()) { + return; + } + console.log( + `Error while authenticating to keyserver with id ${keyserverID}`, + e, + ); + throw e; + } finally { + if (!hasBeenCancelled()) { + await sleep(AUTH_RETRY_DELAY_MS); + setInProgress(false); + } + } + }, + [ + calendarQuery, + cookie, + deviceToken, + dispatchActionPromise, + getAuthMetadata, + identityClient, + keyserverID, + olmAPI, + preRequestUserInfo, + ], + ); + const [authInProgress, setAuthInProgress] = React.useState(false); + const { callKeyserverEndpoint } = useCallKeyserverEndpointContext(); const performAuth = React.useCallback(() => { setAuthInProgress(true); @@ -110,73 +204,19 @@ cancelled = true; setAuthInProgress(false); }; + const hasBeenCancelled = () => cancelled; const promise = (async () => { try { - const [keyserverKeys] = await Promise.all([ - identityClient.getKeyserverKeys(keyserverID), - olmAPI.initializeCryptoAccount(), - ]); - - if (cancelled) { - throw new Error(CANCELLED_ERROR); - } - - const [notifsSession, contentSession, { userID, deviceID }] = - await Promise.all([ - olmAPI.notificationsSessionCreator( - cookie, - keyserverKeys.identityKeysBlob.notificationIdentityPublicKeys, - keyserverKeys.notifInitializationInfo, - keyserverID, - ), - olmAPI.contentOutboundSessionCreator( - keyserverKeys.identityKeysBlob.primaryIdentityPublicKeys, - keyserverKeys.contentInitializationInfo, - ), - getAuthMetadata(), - ]); - - invariant(userID, 'userID should be set'); - invariant(deviceID, 'deviceID should be set'); - - const deviceTokenUpdateInput = deviceToken - ? { [keyserverID]: { deviceToken } } - : {}; - - if (cancelled) { - throw new Error(CANCELLED_ERROR); - } - - await dispatchActionPromise( - keyserverAuthActionTypes, - keyserverAuth({ - userID, - deviceID, - doNotRegister: false, - calendarQuery, - deviceTokenUpdateInput, - authActionSource: process.env.BROWSER - ? logInActionSources.keyserverAuthFromWeb - : logInActionSources.keyserverAuthFromNative, - keyserverData: { - [keyserverID]: { - initialContentEncryptedMessage: contentSession, - initialNotificationsEncryptedMessage: notifsSession, - }, - }, - }), - ); + await innerPerformAuth( + process.env.BROWSER + ? logInActionSources.keyserverAuthFromWeb + : logInActionSources.keyserverAuthFromNative, + setAuthInProgress, + hasBeenCancelled, + false, + )(callKeyserverEndpoint); } catch (e) { - if (cancelled) { - return; - } - - console.log( - `Error while authenticating to keyserver with id ${keyserverID}`, - e, - ); - if ( !dataLoaded && keyserverID === authoritativeKeyserverID() && @@ -184,26 +224,17 @@ ) { await dispatchActionPromise(logOutActionTypes, callLogOut()); } - } finally { - if (!cancelled) { - await sleep(AUTH_RETRY_DELAY_MS); - setAuthInProgress(false); - } } })(); + return [promise, cancel]; }, [ - calendarQuery, - callLogOut, - cookie, + innerPerformAuth, + callKeyserverEndpoint, dataLoaded, - deviceToken, - dispatchActionPromise, - getAuthMetadata, - identityClient, - keyserverAuth, keyserverID, - olmAPI, + dispatchActionPromise, + callLogOut, ]); const activeSessionRecovery = useSelector( @@ -226,14 +257,14 @@ ) => async ( callSingleKeyserverEndpoint: CallSingleKeyserverEndpoint, - callKeyserverEndpoint: CallKeyserverEndpoint, + innerCallKeyserverEndpoint: CallKeyserverEndpoint, ) => { if (!resolveKeyserverSessionInvalidationUsingNativeCredentials) { return; } await resolveKeyserverSessionInvalidationUsingNativeCredentials( callSingleKeyserverEndpoint, - callKeyserverEndpoint, + innerCallKeyserverEndpoint, dispatchActionPromise, recoveryActionSource, keyserverID,