refactor(retry): improve message encryption and retry logic (#2055)
This commit is contained in:
@@ -1200,7 +1200,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
await processingMutex.mutex(async () => {
|
||||
await decrypt()
|
||||
// message failed to decrypt
|
||||
if (msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) {
|
||||
if (msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT && msg.category !== 'peer') {
|
||||
if (msg?.messageStubParameters?.[0] === MISSING_KEYS_ERROR_TEXT) {
|
||||
return sendMessageAck(node, NACK_REASONS.ParsingError)
|
||||
}
|
||||
|
||||
+53
-47
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user