diff --git a/lib/tunnelbroker/use-peer-to-peer-message-handler.js b/lib/tunnelbroker/use-peer-to-peer-message-handler.js --- a/lib/tunnelbroker/use-peer-to-peer-message-handler.js +++ b/lib/tunnelbroker/use-peer-to-peer-message-handler.js @@ -8,6 +8,7 @@ import { removePeerUsersActionType } from '../actions/aux-user-actions.js'; import { invalidateTunnelbrokerDeviceTokenActionType } from '../actions/tunnelbroker-actions.js'; import { logOutActionTypes, useLogOut } from '../actions/user-actions.js'; +import { usePeerOlmSessionsCreatorContext } from '../components/peer-olm-session-creator-provider.react.js'; import { useBroadcastDeviceListUpdates, useBroadcastAccountDeletion, @@ -37,7 +38,11 @@ import { getConfig } from '../utils/config.js'; import { getContentSigningKey } from '../utils/crypto-utils.js'; import { getMessageForException } from '../utils/errors.js'; -import { hasHigherDeviceID, olmSessionErrors } from '../utils/olm-utils.js'; +import { + hasHigherDeviceID, + OLM_SESSION_ERROR_PREFIX, + olmSessionErrors, +} from '../utils/olm-utils.js'; import { getClientMessageIDFromTunnelbrokerMessageID } from '../utils/peer-to-peer-communication-utils.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useDispatch, useSelector } from '../utils/redux-utils.js'; @@ -173,6 +178,7 @@ const handleOlmMessageToDevice = useHandleOlmMessageToDevice(); const resendPeerToPeerMessages = useResendPeerToPeerMessages(); + const { createOlmSessionsWithPeer } = usePeerOlmSessionsCreatorContext(); return React.useCallback( async (message: PeerToPeerMessage, messageID: string) => { @@ -271,17 +277,30 @@ console.log('Failed processing Olm P2P message:', e); } } catch (e) { - if (e.message?.includes(olmSessionErrors.messageAlreadyDecrypted)) { + if (e.message?.includes(olmSessionErrors.invalidSessionVersion)) { console.log( - 'Received already decrypted message from device ' + + 'Received message decrypted with different session from ' + `${message.senderInfo.deviceID}.`, ); - } else { - console.log( - 'Error decrypting message from device ' + - `${message.senderInfo.deviceID}: ${e.message}`, - ); + return; + } + console.log( + 'Error decrypting message from device ' + + `${message.senderInfo.deviceID}: ${e.message}`, + ); + + if (!e.message?.includes(OLM_SESSION_ERROR_PREFIX)) { + throw e; } + + await createOlmSessionsWithPeer( + message.senderInfo.userID, + message.senderInfo.deviceID, + { + overwriteContentSession: true, + }, + ); + await resendPeerToPeerMessages(message.senderInfo.deviceID); } } else if (message.type === peerToPeerMessageTypes.REFRESH_KEY_REQUEST) { try { @@ -376,6 +395,7 @@ }, [ broadcastDeviceListUpdates, + createOlmSessionsWithPeer, dispatch, foreignPeerDevices, getAndUpdateDeviceListsForUsers, diff --git a/lib/utils/crypto-utils.js b/lib/utils/crypto-utils.js --- a/lib/utils/crypto-utils.js +++ b/lib/utils/crypto-utils.js @@ -109,7 +109,7 @@ export type SessionCreationOptions = { +overwriteNotifSession?: boolean, - +overwriteontentSession?: boolean, + +overwriteContentSession?: boolean, }; async function createOlmSessionWithPeer( authMetadata: AuthMetadata, @@ -123,7 +123,7 @@ await olmAPI.initializeCryptoAccount(); const [hasContentSession, hasNotifsSession] = await Promise.all([ (async () => { - if (options?.overwriteontentSession) { + if (options?.overwriteContentSession) { return false; } return await olmAPI.isContentSessionInitialized(deviceID); diff --git a/lib/utils/olm-utils.js b/lib/utils/olm-utils.js --- a/lib/utils/olm-utils.js +++ b/lib/utils/olm-utils.js @@ -116,6 +116,7 @@ return { identityKeys, prekey, prekeySignature }; } +export const OLM_SESSION_ERROR_PREFIX = 'OLM_'; const olmSessionErrors = Object.freeze({ // Two clients send the session request to each other at the same time, // we choose which session to keep based on `deviceID`. @@ -123,10 +124,6 @@ // The client received a session request with a lower session version, // this request can be ignored. alreadyCreated: 'OLM_SESSION_ALREADY_CREATED', - // If using sequential decrypt this error means that message was decrypted. - // Otherwise, it could mean that the receiver chain advance beyond and the key - // to decrypt that message was discarded. - messageAlreadyDecrypted: 'OLM_ALREADY_DECRYPTED_OR_KEYS_SKIPPED', // Error thrown when attempting to encrypt/decrypt, indicating that // the session for a given deviceID is not created. // This definition should remain in sync with the value defined in