diff --git a/lib/hooks/peer-list-hooks.js b/lib/hooks/peer-list-hooks.js --- a/lib/hooks/peer-list-hooks.js +++ b/lib/hooks/peer-list-hooks.js @@ -14,15 +14,16 @@ UsersRawDeviceLists, UsersDevicesPlatformDetails, SignedDeviceList, - RawDeviceList, } from '../types/identity-service-types.js'; import { type DeviceListUpdated, peerToPeerMessageTypes, } from '../types/tunnelbroker/peer-to-peer-message-types.js'; -import { getContentSigningKey } from '../utils/crypto-utils.js'; +import { + createOlmSessionWithPeer, + getContentSigningKey, +} from '../utils/crypto-utils.js'; import { convertSignedDeviceListsToRawDeviceLists } from '../utils/device-list-utils.js'; -import { values } from '../utils/objects.js'; import { useDispatch, useSelector } from '../utils/redux-utils.js'; function useCreateInitialPeerList(): () => Promise { @@ -80,6 +81,31 @@ ); } +function useOlmSessionCreation(): ( + userID: string, + deviceID: string, +) => Promise { + const identityContext = React.useContext(IdentityClientContext); + invariant(identityContext, 'Identity context should be set'); + const { getAuthMetadata, identityClient } = identityContext; + + const { sendMessage } = useTunnelbroker(); + + return React.useCallback( + async (userID: string, deviceID: string) => { + const authMetadata = await getAuthMetadata(); + return createOlmSessionWithPeer( + authMetadata, + identityClient, + sendMessage, + userID, + deviceID, + ); + }, + [getAuthMetadata, identityClient, sendMessage], + ); +} + function useGetAndUpdateDeviceListsForUsers(): ( userIDs: $ReadOnlyArray, broadcastUpdates: ?boolean, @@ -87,6 +113,7 @@ const getDeviceListsForUsers = useGetDeviceListsForUsers(); const dispatch = useDispatch(); const broadcastDeviceListUpdates = useBroadcastDeviceListUpdates(); + const olmSessionCreation = useOlmSessionCreation(); const allPeerDevices = useSelector(getAllPeerDevices); @@ -102,27 +129,45 @@ payload: { deviceLists, usersPlatformDetails }, }); - if (!broadcastUpdates) { - return; - } - const ownDeviceID = await getContentSigningKey(); - const newDevices = values(deviceLists) - .map((deviceList: RawDeviceList) => deviceList.devices) - .flat() - .filter( - deviceID => - !allPeerDevices.includes(deviceID) && deviceID !== ownDeviceID, + const newPeers: { +deviceID: string, +userID: string }[] = []; + + for (const userID in deviceLists) { + deviceLists[userID].devices.forEach(deviceID => + newPeers.push({ userID, deviceID }), ); + } + + const promises = newPeers.map(async data => { + try { + await olmSessionCreation(data.userID, data.deviceID); + } catch (e) { + console.log( + 'Error creating olm session with ' + + `device ${data.deviceID}: ${e.message}`, + ); + } + }); - await broadcastDeviceListUpdates(newDevices); + if (broadcastUpdates) { + const newDevices = newPeers + .map(data => data.deviceID) + .filter( + deviceID => + !allPeerDevices.includes(deviceID) && deviceID !== ownDeviceID, + ); + promises.push(broadcastDeviceListUpdates(newDevices)); + } + + await Promise.all(promises); }, [ allPeerDevices, broadcastDeviceListUpdates, dispatch, getDeviceListsForUsers, + olmSessionCreation, ], ); }