From 9af7afe613693653ae2766b61d0c67124f4e08fd Mon Sep 17 00:00:00 2001 From: vinikjkkj Date: Sun, 28 Dec 2025 13:07:29 -0300 Subject: [PATCH] fix(messages): handle encryption failures per recipient and fail when all fail --- src/Socket/messages-send.ts | 86 +++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 9762c268c0c..715dfea9409 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -510,52 +510,62 @@ export const makeMessagesSocket = (config: SocketConfig) => { const encryptionPromises = (patchedMessages as any).map( async ({ recipientJid: jid, message: patchedMessage }: any) => { - if (!jid) return null - let msgToEncrypt = patchedMessage - if (dsmMessage) { - const { user: targetUser } = jidDecode(jid)! - const { user: ownPnUser } = jidDecode(meId)! - const ownLidUser = meLidUser - const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser) - const isExactSenderDevice = jid === meId || (meLid && jid === meLid) - if (isOwnUser && !isExactSenderDevice) { - msgToEncrypt = dsmMessage - logger.debug({ jid, targetUser }, 'Using DSM for own device') + try { + if (!jid) return null + + let msgToEncrypt = patchedMessage + + if (dsmMessage) { + const { user: targetUser } = jidDecode(jid)! + const { user: ownPnUser } = jidDecode(meId)! + const ownLidUser = meLidUser + + const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser) + const isExactSenderDevice = jid === meId || (meLid && jid === meLid) + + if (isOwnUser && !isExactSenderDevice) { + msgToEncrypt = dsmMessage + logger.debug({ jid, targetUser }, 'Using DSM for own device') + } } - } - const bytes = encodeWAMessage(msgToEncrypt) - const mutexKey = jid - const node = await encryptionMutex.mutex(mutexKey, async () => { - const { type, ciphertext } = await signalRepository.encryptMessage({ - jid, - data: bytes + const bytes = encodeWAMessage(msgToEncrypt) + const mutexKey = jid + + const node = await encryptionMutex.mutex(mutexKey, async () => { + const { type, ciphertext } = await signalRepository.encryptMessage({ jid, data: bytes }) + + if (type === 'pkmsg') { + shouldIncludeDeviceIdentity = true + } + + return { + tag: 'to', + attrs: { jid }, + content: [ + { + tag: 'enc', + attrs: { v: '2', type, ...(extraAttrs || {}) }, + content: ciphertext + } + ] + } }) - if (type === 'pkmsg') { - shouldIncludeDeviceIdentity = true - } - return { - tag: 'to', - attrs: { jid }, - content: [ - { - tag: 'enc', - attrs: { - v: '2', - type, - ...(extraAttrs || {}) - }, - content: ciphertext - } - ] - } - }) - return node + return node + } catch (err) { + logger.error({ jid, err }, 'Failed to encrypt for recipient') + return null + } } ) const nodes = (await Promise.all(encryptionPromises)).filter(node => node !== null) as BinaryNode[] + + if (recipientJids.length > 0 && nodes.length === 0) { + throw new Boom('All encryptions failed', { statusCode: 500 }) + } + return { nodes, shouldIncludeDeviceIdentity } }