diff --git a/web/account/siwe-login-form.react.js b/web/account/siwe-login-form.react.js --- a/web/account/siwe-login-form.react.js +++ b/web/account/siwe-login-form.react.js @@ -36,7 +36,7 @@ import LoadingIndicator from '../loading-indicator.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { webLogInExtraInfoSelector } from '../selectors/account-selectors.js'; -import { signedIdentityKeysBlobSelector } from '../selectors/socket-selectors.js'; +import { getSignedIdentityKeysBlobSelector } from '../selectors/socket-selectors.js'; type SIWELoginFormProps = { +cancelSIWEAuthFlow: () => void, @@ -78,9 +78,26 @@ state => state.cryptoStore.primaryIdentityKeys, ); - const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = useSelector( - signedIdentityKeysBlobSelector, - ); + const getSignedIdentityKeysBlob: ?() => Promise = + useSelector(getSignedIdentityKeysBlobSelector); + + const [signedIdentityKeysBlob, setSignedIdentityKeysBlob] = + React.useState(null); + + React.useEffect(() => { + (async () => { + if ( + getSignedIdentityKeysBlob === null || + getSignedIdentityKeysBlob === undefined + ) { + setSignedIdentityKeysBlob(null); + return; + } + const resolvedSignedIdentityKeysBlob: SignedIdentityKeysBlob = + await getSignedIdentityKeysBlob(); + setSignedIdentityKeysBlob(resolvedSignedIdentityKeysBlob); + })(); + }, [getSignedIdentityKeysBlob]); const callSIWEAuthEndpoint = React.useCallback( (message: string, signature: string, extraInfo) => { diff --git a/web/account/traditional-login-form.react.js b/web/account/traditional-login-form.react.js --- a/web/account/traditional-login-form.react.js +++ b/web/account/traditional-login-form.react.js @@ -29,7 +29,7 @@ import Input from '../modals/input.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { webLogInExtraInfoSelector } from '../selectors/account-selectors.js'; -import { signedIdentityKeysBlobSelector } from '../selectors/socket-selectors.js'; +import { getSignedIdentityKeysBlobSelector } from '../selectors/socket-selectors.js'; const loadingStatusSelector = createLoadingStatusSelector(logInActionTypes); function TraditionalLoginForm(): React.Node { @@ -39,9 +39,26 @@ const dispatchActionPromise = useDispatchActionPromise(); const modalContext = useModalContext(); - const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = useSelector( - signedIdentityKeysBlobSelector, - ); + const getSignedIdentityKeysBlob: ?() => Promise = + useSelector(getSignedIdentityKeysBlobSelector); + + const [signedIdentityKeysBlob, setSignedIdentityKeysBlob] = + React.useState(null); + + React.useEffect(() => { + (async () => { + if ( + getSignedIdentityKeysBlob === null || + getSignedIdentityKeysBlob === undefined + ) { + setSignedIdentityKeysBlob(null); + return; + } + const resolvedSignedIdentityKeysBlob: SignedIdentityKeysBlob = + await getSignedIdentityKeysBlob(); + setSignedIdentityKeysBlob(resolvedSignedIdentityKeysBlob); + })(); + }, [getSignedIdentityKeysBlob]); const usernameInputRef = React.useRef(); React.useEffect(() => { diff --git a/web/selectors/socket-selectors.js b/web/selectors/socket-selectors.js --- a/web/selectors/socket-selectors.js +++ b/web/selectors/socket-selectors.js @@ -24,6 +24,7 @@ } from 'lib/types/session-types.js'; import type { OneTimeKeyGenerator } from 'lib/types/socket-types.js'; +import { initOlm } from '../olm/olm-utils.js'; import type { AppState } from '../redux/redux-setup.js'; const openSocketSelector: (state: AppState) => () => WebSocket = createSelector( @@ -38,9 +39,9 @@ (sessionID: ?string): SessionIdentification => ({ sessionID }), ); -const signedIdentityKeysBlobSelector: ( +const getSignedIdentityKeysBlobSelector: ( state: AppState, -) => ?SignedIdentityKeysBlob = createSelector( +) => ?() => Promise = createSelector( (state: AppState) => state.cryptoStore.primaryAccount, (state: AppState) => state.cryptoStore.primaryIdentityKeys, (state: AppState) => state.cryptoStore.notificationIdentityKeys, @@ -53,36 +54,27 @@ return null; } - const primaryOLMAccount = new olm.Account(); - primaryOLMAccount.unpickle( - primaryAccount.picklingKey, - primaryAccount.pickledAccount, - ); + return async () => { + await initOlm(); + const primaryOLMAccount = new olm.Account(); + primaryOLMAccount.unpickle( + primaryAccount.picklingKey, + primaryAccount.pickledAccount, + ); - const identityKeysBlob: IdentityKeysBlob = { - primaryIdentityPublicKeys: primaryIdentityKeys, - notificationIdentityPublicKeys: notificationIdentityKeys, - }; + const identityKeysBlob: IdentityKeysBlob = { + primaryIdentityPublicKeys: primaryIdentityKeys, + notificationIdentityPublicKeys: notificationIdentityKeys, + }; - const payloadToBeSigned: string = JSON.stringify(identityKeysBlob); - const signedIdentityKeysBlob: SignedIdentityKeysBlob = { - payload: payloadToBeSigned, - signature: primaryOLMAccount.sign(payloadToBeSigned), - }; - - return signedIdentityKeysBlob; - }, -); + const payloadToBeSigned: string = JSON.stringify(identityKeysBlob); + const signedIdentityKeysBlob: SignedIdentityKeysBlob = { + payload: payloadToBeSigned, + signature: primaryOLMAccount.sign(payloadToBeSigned), + }; -const getSignedIdentityKeysBlobSelector: ( - state: AppState, -) => ?() => Promise = createSelector( - signedIdentityKeysBlobSelector, - (signedIdentityKeysBlob: ?SignedIdentityKeysBlob) => { - if (!signedIdentityKeysBlob) { - return null; - } - return async () => signedIdentityKeysBlob; + return signedIdentityKeysBlob; + }; }, ); @@ -128,7 +120,7 @@ export { openSocketSelector, sessionIdentificationSelector, - signedIdentityKeysBlobSelector, + getSignedIdentityKeysBlobSelector, webGetClientResponsesSelector, webSessionStateFuncSelector, };