diff --git a/lib/keyserver-conn/keyserver-connection-handler.js b/lib/keyserver-conn/keyserver-connection-handler.js --- a/lib/keyserver-conn/keyserver-connection-handler.js +++ b/lib/keyserver-conn/keyserver-connection-handler.js @@ -1,5 +1,6 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { useCallKeyserverEndpointContext } from './call-keyserver-endpoint-provider.react.js'; @@ -7,6 +8,7 @@ import { useRawKeyserverAuth } from './keyserver-auth.js'; import type { CallKeyserverEndpoint } from './keyserver-conn-types.js'; import { useKeyserverRecoveryLogIn } from './recovery-utils.js'; +import { useRecreateNotifsOlmSession } from '../actions/keyserver-actions.js'; import { logOutActionTypes, useLogOut } from '../actions/user-actions.js'; import { connectionSelector, @@ -14,6 +16,7 @@ } from '../selectors/keyserver-selectors.js'; import { isLoggedInToKeyserver } from '../selectors/user-selectors.js'; import { useInitialNotificationsEncryptedMessage } from '../shared/crypto-utils.js'; +import { IdentityClientContext } from '../shared/identity-client-context.js'; import type { BaseSocketProps } from '../socket/socket.react.js'; import { logInActionSources, @@ -43,6 +46,10 @@ const { olmAPI } = getConfig(); + const identityContext = React.useContext(IdentityClientContext); + invariant(identityContext, 'Identity context should be set'); + const { identityClient } = identityContext; + const hasConnectionIssue = useSelector( state => !!connectionSelector(keyserverID)(state)?.connectionIssue, ); @@ -298,6 +305,108 @@ performAuth, ]); + const { + initializeCryptoAccount, + getUserPublicKey, + isKeyserverNotificationsSessionInitialized, + ephemeralKeyserverNotifsSessionCreator, + persistEphemeralKeyserverNotifsSession, + } = olmAPI; + + const recreateKeyserverNotifsSessionPromiseRef = + React.useRef>(null); + const recreateNotifsOlmSession = useRecreateNotifsOlmSession(); + + const recreateNotifsOlmSessionWithKeyserver = React.useCallback(async () => { + if ( + !ephemeralKeyserverNotifsSessionCreator || + !isKeyserverNotificationsSessionInitialized || + !persistEphemeralKeyserverNotifsSession + ) { + return; + } + const hasSessionWithKeyserver = + await isKeyserverNotificationsSessionInitialized(keyserverID); + + if (hasSessionWithKeyserver) { + return; + } + + const identityKeysBlobPromise = (async () => { + await initializeCryptoAccount(); + return await getUserPublicKey(); + })(); + + const [ + keyserverKeys, + { primaryIdentityPublicKeys, notificationIdentityPublicKeys }, + ] = await Promise.all([ + identityClient.getKeyserverKeys(keyserverID), + identityKeysBlobPromise, + ]); + + const { initialEncryptedMessage, sessionPersistenceData } = + await ephemeralKeyserverNotifsSessionCreator( + cookie, + keyserverKeys.identityKeysBlob.notificationIdentityPublicKeys, + keyserverKeys.notifInitializationInfo, + keyserverID, + ); + + await recreateNotifsOlmSession({ + identityKeysBlob: { + primaryIdentityPublicKeys, + notificationIdentityPublicKeys, + }, + initialEncryptedMessage, + keyserverID, + }); + + await persistEphemeralKeyserverNotifsSession(sessionPersistenceData); + }, [ + cookie, + ephemeralKeyserverNotifsSessionCreator, + persistEphemeralKeyserverNotifsSession, + getUserPublicKey, + initializeCryptoAccount, + identityClient, + keyserverID, + isKeyserverNotificationsSessionInitialized, + recreateNotifsOlmSession, + ]); + + React.useEffect(() => { + if ( + !ephemeralKeyserverNotifsSessionCreator || + !isKeyserverNotificationsSessionInitialized || + !hasCurrentUserInfo || + !hasAccessToken || + !isUserLoggedInToKeyserver || + authInProgress || + !!recreateKeyserverNotifsSessionPromiseRef.current + ) { + return; + } + + recreateKeyserverNotifsSessionPromiseRef.current = (async () => { + try { + await recreateNotifsOlmSessionWithKeyserver(); + } catch (e) { + console.log(e); + } finally { + recreateKeyserverNotifsSessionPromiseRef.current = null; + } + })(); + }, [ + recreateNotifsOlmSessionWithKeyserver, + isKeyserverNotificationsSessionInitialized, + ephemeralKeyserverNotifsSessionCreator, + hasCurrentUserInfo, + hasAccessToken, + isUserLoggedInToKeyserver, + authInProgress, + ]); + return ; }