refactor(retry): improve message encryption and retry logic (#2055)

This commit is contained in:
vini
2025-11-19 10:13:51 -03:00
committed by GitHub
parent 9b012baa5c
commit b4863b624e
4 changed files with 66 additions and 50 deletions
+53 -47
View File
@@ -572,6 +572,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
const isStatus = jid === statusJid
const isLid = server === 'lid'
const isNewsletter = server === 'newsletter'
const isGroupOrStatus = isGroup || isStatus
const finalJid = jid
msgId = msgId || generateMessageIDV2(meId)
@@ -639,7 +640,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
extraAttrs['decrypt-fail'] = 'hide' // todo: expand for reactions and other types
}
if (isGroup || isStatus) {
if (isGroupOrStatus && !isRetryResend) {
const [groupData, senderKeyMap] = await Promise.all([
(async () => {
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined // todo: should we rely on the cache specially if the cache is outdated and the metadata has new fields?
@@ -663,28 +664,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
})()
])
if (!participant) {
const participantsList = []
if (isStatus) {
if (statusJidList?.length) participantsList.push(...statusJidList)
} else {
// default to LID based groups
let groupAddressingMode = 'lid'
if (groupData) {
participantsList.push(...groupData.participants.map(p => p.id))
groupAddressingMode = groupData?.addressingMode || groupAddressingMode
}
// default to lid addressing mode in a group
additionalAttributes = {
...additionalAttributes,
addressing_mode: groupAddressingMode
}
}
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
devices.push(...additionalDevices)
}
const participantsList = groupData ? groupData.participants.map(p => p.id) : []
if (groupData?.ephemeralDuration && groupData.ephemeralDuration > 0) {
additionalAttributes = {
@@ -693,6 +673,20 @@ export const makeMessagesSocket = (config: SocketConfig) => {
}
}
if (isStatus && statusJidList) {
participantsList.push(...statusJidList)
}
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
devices.push(...additionalDevices)
if (isGroup) {
additionalAttributes = {
...additionalAttributes,
addressing_mode: groupData?.addressingMode || 'lid'
}
}
const patched = await patchMessageBeforeSending(message)
if (Array.isArray(patched)) {
throw new Boom('Per-jid patching is not supported in groups')
@@ -744,30 +738,13 @@ export const makeMessagesSocket = (config: SocketConfig) => {
participants.push(...result.nodes)
}
if (isRetryResend) {
const { type, ciphertext: encryptedContent } = await signalRepository.encryptMessage({
data: bytes,
jid: participant?.jid!
})
binaryNodeContent.push({
tag: 'enc',
attrs: { v: '2', type: 'skmsg', ...extraAttrs },
content: ciphertext
})
binaryNodeContent.push({
tag: 'enc',
attrs: {
v: '2',
type,
count: participant!.count.toString()
},
content: encryptedContent
})
} else {
binaryNodeContent.push({
tag: 'enc',
attrs: { v: '2', type: 'skmsg', ...extraAttrs },
content: ciphertext
})
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } })
}
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } })
} else {
// ADDRESSING CONSISTENCY: Match own identity to conversation context
// TODO: investigate if this is true
@@ -781,7 +758,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
const { user: ownUser } = jidDecode(ownId)!
if (!participant) {
if (!isRetryResend) {
const targetUserServer = isLid ? 'lid' : 's.whatsapp.net'
devices.push({
user,
@@ -869,6 +846,35 @@ export const makeMessagesSocket = (config: SocketConfig) => {
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2
}
if (isRetryResend) {
const isParticipantLid = isLidUser(participant!.jid)
const isMe = areJidsSameUser(participant!.jid, isParticipantLid ? meLid : meId)
const encodedMessageToSend = isMe
? encodeWAMessage({
deviceSentMessage: {
destinationJid,
message
}
})
: encodeWAMessage(message)
const { type, ciphertext: encryptedContent } = await signalRepository.encryptMessage({
data: encodedMessageToSend,
jid: participant!.jid
})
binaryNodeContent.push({
tag: 'enc',
attrs: {
v: '2',
type,
count: participant!.count.toString()
},
content: encryptedContent
})
}
if (participants.length) {
if (additionalAttributes?.['category'] === 'peer') {
const peerNode = participants[0]?.content?.[0] as BinaryNode