diff --git a/lib/components/platform-details-synchronizer.react.js b/lib/components/platform-details-synchronizer.react.js index ce3a26003..564cbf18c 100644 --- a/lib/components/platform-details-synchronizer.react.js +++ b/lib/components/platform-details-synchronizer.react.js @@ -1,42 +1,49 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { isLoggedIn } from '../selectors/user-selectors.js'; import { IdentityClientContext } from '../shared/identity-client-context.js'; import { useSelector } from '../utils/redux-utils.js'; import { usingCommServicesAccessToken } from '../utils/services-utils.js'; function PlatformDetailsSynchronizer(): React.Node { const client = React.useContext(IdentityClientContext); - const identityClient = client?.identityClient; + invariant(client, 'Identity context should be set'); + const identityClient = client.identityClient; + const getAuthMetadata = client.getAuthMetadata; const loggedIn = useSelector(isLoggedIn); const syncPlatformDetails = React.useCallback(async () => { if (!identityClient) { throw new Error('Identity service client is not initialized'); } if (!loggedIn) { return; } + const authMetadata = await getAuthMetadata(); + if (!authMetadata) { + return; + } try { await identityClient.syncPlatformDetails(); } catch (error) { console.log('Error syncing platform details:', error); } - }, [identityClient, loggedIn]); + }, [identityClient, loggedIn, getAuthMetadata]); const hasRun = React.useRef(false); React.useEffect(() => { if (!usingCommServicesAccessToken || hasRun.current) { return; } hasRun.current = true; void syncPlatformDetails(); }, [syncPlatformDetails]); return null; } export default PlatformDetailsSynchronizer; diff --git a/lib/components/prekeys-handler.react.js b/lib/components/prekeys-handler.react.js index fa0e692e4..13e2110fd 100644 --- a/lib/components/prekeys-handler.react.js +++ b/lib/components/prekeys-handler.react.js @@ -1,42 +1,48 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { isLoggedIn } from '../selectors/user-selectors.js'; import { IdentityClientContext } from '../shared/identity-client-context.js'; import { getConfig } from '../utils/config.js'; import { useSelector } from '../utils/redux-utils.js'; +import { usingCommServicesAccessToken } from '../utils/services-utils.js'; // Time after which rotation is started const PREKEY_ROTATION_TIMEOUT = 3 * 1000; // in milliseconds function PrekeysHandler(): null { const loggedIn = useSelector(isLoggedIn); const identityContext = React.useContext(IdentityClientContext); invariant(identityContext, 'Identity context should be set'); React.useEffect(() => { if (!loggedIn) { return undefined; } + if (!usingCommServicesAccessToken) { + return undefined; + } const timeoutID = setTimeout(async () => { try { const authMetadata = await identityContext.getAuthMetadata(); - + if (!authMetadata) { + return; + } const { olmAPI } = getConfig(); await olmAPI.validateAndUploadPrekeys(authMetadata); } catch (e) { console.log('Prekey validation error: ', e.message); } }, PREKEY_ROTATION_TIMEOUT); return () => clearTimeout(timeoutID); }, [identityContext, loggedIn]); return null; } export default PrekeysHandler; diff --git a/lib/handlers/user-infos-handler.react.js b/lib/handlers/user-infos-handler.react.js index 850d8ac5e..5046b1d2f 100644 --- a/lib/handlers/user-infos-handler.react.js +++ b/lib/handlers/user-infos-handler.react.js @@ -1,132 +1,150 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { updateRelationships, updateRelationshipsActionTypes, } from '../actions/relationship-actions.js'; import { useFindUserIdentities, findUserIdentitiesActionTypes, } from '../actions/user-actions.js'; import { useIsLoggedInToAuthoritativeKeyserver } from '../hooks/account-hooks.js'; import { useGetAndUpdateDeviceListsForUsers } from '../hooks/peer-list-hooks.js'; import { useLegacyAshoatKeyserverCall } from '../keyserver-conn/legacy-keyserver-call.js'; import { usersWithMissingDeviceListSelector } from '../selectors/user-selectors.js'; +import { IdentityClientContext } from '../shared/identity-client-context.js'; import { useTunnelbroker } from '../tunnelbroker/tunnelbroker-context.js'; import { relationshipActions } from '../types/relationship-types.js'; import { getMessageForException } from '../utils/errors.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useSelector } from '../utils/redux-utils.js'; import { relyingOnAuthoritativeKeyserver, usingCommServicesAccessToken, } from '../utils/services-utils.js'; function UserInfosHandler(): React.Node { + const client = React.useContext(IdentityClientContext); + invariant(client, 'Identity context should be set'); + const { getAuthMetadata } = client; + const userInfos = useSelector(state => state.userStore.userInfos); const userInfosWithMissingUsernames = React.useMemo(() => { const entriesWithoutUsernames = Object.entries(userInfos).filter( ([, value]) => !value.username, ); return Object.fromEntries(entriesWithoutUsernames); }, [userInfos]); const dispatchActionPromise = useDispatchActionPromise(); const findUserIdentities = useFindUserIdentities(); const requestedIDsRef = React.useRef(new Set()); const callUpdateRelationships = useLegacyAshoatKeyserverCall(updateRelationships); const currentUserInfo = useSelector(state => state.currentUserInfo); const loggedInToAuthKeyserver = useIsLoggedInToAuthoritativeKeyserver(); React.useEffect(() => { if (!loggedInToAuthKeyserver) { return; } const newUserIDs = Object.keys(userInfosWithMissingUsernames).filter( id => !requestedIDsRef.current.has(id), ); if (!usingCommServicesAccessToken || newUserIDs.length === 0) { return; } - // 1. Fetch usernames from identity - const promise = (async () => { - newUserIDs.forEach(id => requestedIDsRef.current.add(id)); - const identities = await findUserIdentities(newUserIDs); - newUserIDs.forEach(id => requestedIDsRef.current.delete(id)); + void (async () => { + const authMetadata = await getAuthMetadata(); + if (!authMetadata) { + return; + } + // 1. Fetch usernames from identity + const promise = (async () => { + newUserIDs.forEach(id => requestedIDsRef.current.add(id)); + const identities = await findUserIdentities(newUserIDs); + newUserIDs.forEach(id => requestedIDsRef.current.delete(id)); - const newUserInfos = []; - for (const id in identities) { - newUserInfos.push({ - id, - username: identities[id].username, - }); + const newUserInfos = []; + for (const id in identities) { + newUserInfos.push({ + id, + username: identities[id].username, + }); + } + return { userInfos: newUserInfos }; + })(); + void dispatchActionPromise(findUserIdentitiesActionTypes, promise); + // 2. Fetch avatars from auth keyserver + if (relyingOnAuthoritativeKeyserver) { + const userIDsWithoutOwnID = newUserIDs.filter( + id => id !== currentUserInfo?.id, + ); + if (userIDsWithoutOwnID.length === 0) { + return; + } + void dispatchActionPromise( + updateRelationshipsActionTypes, + callUpdateRelationships({ + action: relationshipActions.ACKNOWLEDGE, + userIDs: userIDsWithoutOwnID, + }), + ); } - return { userInfos: newUserInfos }; })(); - void dispatchActionPromise(findUserIdentitiesActionTypes, promise); - // 2. Fetch avatars from auth keyserver - if (relyingOnAuthoritativeKeyserver) { - const userIDsWithoutOwnID = newUserIDs.filter( - id => id !== currentUserInfo?.id, - ); - if (userIDsWithoutOwnID.length === 0) { - return; - } - void dispatchActionPromise( - updateRelationshipsActionTypes, - callUpdateRelationships({ - action: relationshipActions.ACKNOWLEDGE, - userIDs: userIDsWithoutOwnID, - }), - ); - } }, [ + getAuthMetadata, callUpdateRelationships, currentUserInfo?.id, dispatchActionPromise, findUserIdentities, userInfos, userInfosWithMissingUsernames, loggedInToAuthKeyserver, ]); const usersWithMissingDeviceList = useSelector( usersWithMissingDeviceListSelector, ); const getAndUpdateDeviceListsForUsers = useGetAndUpdateDeviceListsForUsers(); const { socketState } = useTunnelbroker(); React.useEffect(() => { if ( !usingCommServicesAccessToken || usersWithMissingDeviceList.length === 0 || !socketState.isAuthorized ) { return; } void (async () => { + const authMetadata = await getAuthMetadata(); + if (!authMetadata) { + return; + } try { await getAndUpdateDeviceListsForUsers(usersWithMissingDeviceList, true); } catch (e) { console.log( `Error getting and setting peer device list: ${ getMessageForException(e) ?? 'unknown' }`, ); } })(); }, [ + getAuthMetadata, socketState.isAuthorized, getAndUpdateDeviceListsForUsers, usersWithMissingDeviceList, ]); } export { UserInfosHandler };