fix(signal): align Signal Protocol handling with WABA Android behavior (#257)

7 corrections based on reverse-engineering of WhatsApp Business Android:

1. resolveCanonicalJid: PN→LID resolution for transaction lock keys (prevent race conditions)
2. Retain PN session during LID migration (avoid No Session errors)
3. Delayed PreKey deletion with 5-min grace period (prevent Invalid PreKey ID races)
4. Surgical session cleanup: only delete the specific corrupted device, not all devices
5. Identity dual storage: save identity key in both LID and PN addresses
6. MAC error cooldown reduced 10s→1s (faster recovery, aligned with WABA)
7. Allow session recreation on first retry (retryCount >= 1 instead of > 1)

* fix: remove unused jidDecode import from decode-wa-message.ts
* fix: add try/catch to delayed PreKey deletion to prevent unhandled rejection

The setTimeout async callback in removePreKey could cause unhandled promise
rejection if the keystore was destroyed (connection closed) before the
5-min grace period expired.
This commit is contained in:
Renato Alcara
2026-03-04 00:51:20 -03:00
committed by GitHub
parent 8ea7f5434e
commit 52aa6402c0
4 changed files with 88 additions and 60 deletions
+2 -2
View File
@@ -1314,7 +1314,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
let shouldRecreateSession = false
let recreateReason = ''
if (enableAutoSessionRecreation && messageRetryManager && retryCount > 1) {
if (enableAutoSessionRecreation && messageRetryManager && retryCount >= 1) {
try {
// Check if we have a session with this JID
const sessionId = signalRepository.jidToSignalProtocolAddress(fromJid)
@@ -2033,7 +2033,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
let shouldRecreateSession = false
let recreateReason = ''
if (enableAutoSessionRecreation && messageRetryManager && retryCount > 1) {
if (enableAutoSessionRecreation && messageRetryManager && retryCount >= 1) {
try {
const sessionId = signalRepository.jidToSignalProtocolAddress(participant)