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 @@ -143,6 +143,76 @@ ); } +// Sends Olm-encrypted message to multiple peers +function useBroadcastOlmMessage(): ( + contentPayload: string, + recipients: $ReadOnlyArray<{ +userID: string, +deviceID: string }>, +) => Promise { + const identityContext = React.useContext(IdentityClientContext); + if (!identityContext) { + throw new Error('Identity service client is not initialized'); + } + const { getAuthMetadata } = identityContext; + + const { sendMessageToDevice } = useTunnelbroker(); + const { createOlmSessionsWithPeer } = usePeerOlmSessionsCreatorContext(); + + return React.useCallback( + async (contentPayload, recipients) => { + const authMetadata = await getAuthMetadata(); + const { userID: thisUserID, deviceID: thisDeviceID } = authMetadata; + if (!thisDeviceID || !thisUserID) { + throw new Error('No auth metadata'); + } + const { olmAPI } = getConfig(); + await olmAPI.initializeCryptoAccount(); + for (const recipient of recipients) { + try { + const encryptedData = await olmAPI.encrypt( + contentPayload, + recipient.deviceID, + ); + const encryptedMessage: EncryptedMessage = { + type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE, + senderInfo: { deviceID: thisDeviceID, userID: thisUserID }, + encryptedData, + }; + await sendMessageToDevice({ + deviceID: recipient.deviceID, + payload: JSON.stringify(encryptedMessage), + }); + } catch { + try { + await createOlmSessionsWithPeer( + recipient.userID, + recipient.deviceID, + ); + const encryptedData = await olmAPI.encrypt( + contentPayload, + recipient.deviceID, + ); + const encryptedMessage: EncryptedMessage = { + type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE, + senderInfo: { deviceID: thisDeviceID, userID: thisUserID }, + encryptedData, + }; + await sendMessageToDevice({ + deviceID: recipient.deviceID, + payload: JSON.stringify(encryptedMessage), + }); + } catch (err) { + console.warn( + `Error sending Olm-encrypted message to device ${recipient.deviceID}:`, + err, + ); + } + } + } + }, + [createOlmSessionsWithPeer, getAuthMetadata, sendMessageToDevice], + ); +} + function useBroadcastAccountDeletion( options: { broadcastToOwnDevices?: boolean } = {}, ): () => Promise { @@ -225,4 +295,5 @@ useBroadcastDeviceListUpdates, useGetAndUpdateDeviceListsForUsers, useBroadcastAccountDeletion, + useBroadcastOlmMessage, };