diff --git a/web/account/account-hooks.js b/web/account/account-hooks.js new file mode 100644 --- /dev/null +++ b/web/account/account-hooks.js @@ -0,0 +1,35 @@ +// @flow + +import * as React from 'react'; + +import type { SignedIdentityKeysBlob } from 'lib/types/crypto-types.js'; + +import { useSelector } from '../redux/redux-utils.js'; +import { getSignedIdentityKeysBlobSelector } from '../selectors/socket-selectors.js'; + +function useSignedIdentityKeysBlob(): ?SignedIdentityKeysBlob { + 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]); + + return signedIdentityKeysBlob; +} + +export { useSignedIdentityKeysBlob }; 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 @@ -29,6 +29,7 @@ siweMessageSigningExplanationStatements, } from 'lib/utils/siwe-utils.js'; +import { useSignedIdentityKeysBlob } from './account-hooks.js'; import HeaderSeparator from './header-separator.react.js'; import css from './siwe.css'; import Button from '../components/button.react.js'; @@ -36,7 +37,6 @@ 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'; type SIWELoginFormProps = { +cancelSIWEAuthFlow: () => void, @@ -78,9 +78,8 @@ state => state.cryptoStore.primaryIdentityKeys, ); - const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = useSelector( - signedIdentityKeysBlobSelector, - ); + const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = + useSignedIdentityKeysBlob(); 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 @@ -21,6 +21,7 @@ useServerCall, } from 'lib/utils/action-utils.js'; +import { useSignedIdentityKeysBlob } from './account-hooks.js'; import HeaderSeparator from './header-separator.react.js'; import css from './log-in-form.css'; import PasswordInput from './password-input.react.js'; @@ -29,7 +30,6 @@ 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'; const loadingStatusSelector = createLoadingStatusSelector(logInActionTypes); function TraditionalLoginForm(): React.Node { @@ -39,9 +39,8 @@ const dispatchActionPromise = useDispatchActionPromise(); const modalContext = useModalContext(); - const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = useSelector( - signedIdentityKeysBlobSelector, - ); + const signedIdentityKeysBlob: ?SignedIdentityKeysBlob = + useSignedIdentityKeysBlob(); 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, };