Commit Graph

2868 Commits

Author SHA1 Message Date
Renato Alcara d2db4cec97 chore: update WhatsApp Web version to v2.3000.1035595667 (#308)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-20 06:31:30 -03:00
github-actions[bot] be44c5fdb0 chore: update proto/version to v2.3000.1035577069 (#307)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-20 01:30:09 -03:00
Renato Alcara f63f0a766f fix: align Bad MAC retry receipt with WA Desktop behavior
fix: align Bad MAC retry receipt with WA Desktop behavior
2026-03-19 23:48:44 -03:00
Renato Alcara fbefa6a0ad fix: replace magic numbers with RetryReason enum constants
Address remaining Copilot review comments on PR #306:

- Import RetryReason enum from Utils (already re-exported via Utils/index.ts)
- Replace all numeric literals (0/1/2/3/4/7) in retryErrorCode with the
  corresponding enum members (UnknownError / SignalErrorNoSession / etc.)
- Removes inline comments that were only needed to explain magic numbers
- If RetryReason values ever change, the compiler will surface the drift

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:44:34 -03:00
Renato Alcara 9c4cdc3e02 fix: use DECRYPTION_RETRY_CONFIG constants for retry error code derivation
Address Copilot review comments on PR #306:

1. Replace ad-hoc regexes with the canonical DECRYPTION_RETRY_CONFIG error
   lists from decode-wa-message.ts (single source of truth). Any future
   additions to those lists are automatically picked up here.

2. Add coverage for MessageCounterError ('Key used already or never filled')
   which was previously returning code 0. It now correctly maps to code 4
   (SignalErrorInvalidMessage) via corruptedSessionErrors.

3. Broaden session-error matching to also catch libsignal variants like
   'No sessions', 'No open session', 'No sessions available' via the
   /no (open )?sessions?/ regex alongside sessionRecordErrors.

4. Fix comment: clarify that code 7 = BadMac and code 4 = InvalidMessage
   are distinct codes (previous comment conflated them).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:29:46 -03:00
Renato Alcara ba1c1b0fdb fix: align Bad MAC retry receipt with WA Desktop behavior
Three issues corrected in sendRetryRequest (receiver side):

1. BUG — error code hardcoded as '0' (UnknownError) in retry receipt.
   The peer (especially another InfiniteAPI instance) could not detect
   the failure type and would fall back to the 1-hour session recreation
   timeout instead of recreating immediately.
   Fix: derive error code from the actual libsignal decryption error
   message stored in messageStubParameters[0].

2. BUG — shouldRecreateSession block was reading the wrong node: it
   called getBinaryNodeChild(node, 'retry') on the incoming bad-MAC
   message, which never has a <retry> child. errorCode was always
   undefined, so MAC_ERROR_CODES never matched — the logic was dead.

3. BUG (consequence of #2) — when shouldRecreateSession accidentally
   did fire (no-session or 1-hour timeout), it deleted the receiver's
   session BEFORE the sender's pkmsg arrived. This opened a race window
   where concurrent messages would fail with "No Session".
   Fix: remove the entire session-deletion block from sendRetryRequest.
   The Signal Protocol pkmsg automatically overwrites the corrupted
   session — no explicit delete needed on the receiver side.

WA Desktop reference (CDP capture 2026-03-19):
- Retry receipt sent ~99ms after Bad MAC with specific error code
- pkmsg arrives ~304ms later, new session established automatically
- Old session is never deleted; pkmsg overwrites it implicitly
- Full recovery in ~1.3s without any race window

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 23:10:59 -03:00
Renato Alcara 876af2e96c fix: HistorySync LID improvements — raw_id mapping, prekey pool strategy, keepalive jitter, CDN cleanup
fix: HistorySync LID improvements — raw_id mapping, prekey pool strategy, keepalive jitter, CDN cleanup
2026-03-19 18:24:20 -03:00
Renato Alcara 5bb18da6bf fix: address PR #305 review comments — Origin header, lowServerCount threshold, keepalive guard
- history.ts: add Origin: DEFAULT_ORIGIN to CDN DELETE request headers —
  the download path injects it internally but options does not carry it
- socket.ts: fix lowServerCount comparison — was preKeyCount <= topUpAmount
  which triggered uploads even when above MIN_PREKEY_COUNT (e.g. 250 prekeys
  → topUp=550 → 250<=550=true → unnecessary upload). Now uses correct
  threshold: preKeyCount < MIN_PREKEY_COUNT
- socket.ts: guard scheduleNextKeepAlive() with !closed check to prevent
  orphan timers when end() was called concurrently on a different path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:23:41 -03:00
Renato Alcara 52d8ddae32 fix: prevent double prekey upload when concurrent uploads race on count=0
uploadPreKeys() waited for a concurrent upload but then proceeded to upload
again. With top-up logic and count=0, both handleEncryptNotification and
uploadPreKeysToServerIfRequired fire simultaneously, both see count=0, first
wins and uploads 800, second waits then uploads another 800 → 1600 prekeys.

Fix: return immediately after awaiting the concurrent upload — it already
replenished the pool.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:23:41 -03:00
Renato Alcara 8c8c5a312e fix: address PR review comments — CDN DELETE timing, keepalive leak, spread order
- history.ts: move CDN DELETE from downloadHistory() to
  downloadAndProcessHistorySyncNotification(), after processHistoryMessage()
  succeeds — prevents permanent history loss if processing throws post-download
- history.ts: fix fetch spread order: { ...options, method: 'DELETE' } so
  options.method cannot shadow the intended DELETE verb
- socket.ts: add early return after void end() in onKeepAliveTick to prevent
  scheduleNextKeepAlive() from leaking a timer while connection is closing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:23:28 -03:00
Renato Alcara 52756fb50d fix: histsync LID improvements — raw_id mapping, prekeys, keepalive jitter, CDN DELETE
1. USyncQuery: extract raw_id attr from node attrs into rawId field; implement
   side_list parsing (was TODO/commented) reusing shared parseNodeList helper

2. getUSyncDevices: add 4th LID→PN source via raw_id pairing from device-list
   WA Business sends zero phoneNumberToLidMappings in HistorySync — raw_id is
   the only way to resolve LID↔PN for those accounts during message send

3. MIN_PREKEY_COUNT: 5 → 25 (WA Business maintains ~812; 5 was too low a buffer
   before triggering replenishment upload)

4. startKeepAliveRequest: replace fixed setInterval with recursive setTimeout
   + ±15% jitter, matching WA Desktop's ~25-30s variable heartbeat pattern;
   clearInterval → clearTimeout for the handle

5. downloadHistory: fire-and-forget DELETE to CDN after successful download,
   mirroring WA Desktop behaviour (server-side one-time file cleanup)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:23:27 -03:00
Renato Alcara bd8465d9b8 fix: histsync LID improvements — raw_id mapping, prekeys, keepalive j… (#304)
* fix: histsync LID improvements — raw_id mapping, prekeys, keepalive jitter, CDN DELETE

* fix: prekey pool strategy — 800 initial, top-up to 800 when below 200

- INITIAL_PREKEY_COUNT: 812 → 800 (rounded, matches WA Business ~812 from CDP capture)
- MIN_PREKEY_COUNT: 25 → 200 (replenishment trigger threshold)
- uploadPreKeysToServerIfRequired: top-up to INITIAL_PREKEY_COUNT instead of
  uploading a flat MIN_PREKEY_COUNT — restores full 800-key pool on each replenish
- handleEncryptNotification: same top-up logic (INITIAL_PREKEY_COUNT - count)
  so server notification path also restores to 800, not just adds 200

uploadPreKeys(5) in error recovery path intentionally left unchanged.
2026-03-19 17:58:30 -03:00
Renato Alcara 6c52b01ea7 fix: add pastParticipants to HistorySync with LID normalization and deduplication (#303)
Two bugs fixed compared to prior implementation:

1. history.ts — normalize userJid LID→PN
   pastParticipants[].userJid may arrive as a LID identifier (e.g. "46802258641027@lid").
   The consumer expects a phone number. After building the lidPnMap from conversations
   and phoneNumberToLidMappings, each userJid is resolved to its PN equivalent.
   If the mapping is not available the original value is preserved (no data loss).

2. event-buffer.ts — deduplicate by groupJid + userJid across chunks
   Multiple HistorySync chunks can contain the same group. The previous approach
   concatenated blindly, producing duplicate entries. Now a keyed map
   { [groupJid]: IPastParticipant[] } is used so each group appears once and
   each participant within a group appears at most once.

Types updated (Events.ts):
   - messaging-history.set event includes pastParticipants?: IPastParticipants[]
   - BufferedEventData.historySets.pastParticipants typed as keyed map
2026-03-19 16:44:14 -03:00
Renato Alcara a9e926b907 fix: correct w:mex QueryIds and response fields for newsletter operations (#302)
Reverse-engineered from WA Web JS bundle and live CDP interception.
All QueryIds and XWAPaths were wrong; mute/unmute also had wrong variables structure.

- FOLLOW QueryId: 7871414976211147 → 24404358912487870
- UNFOLLOW QueryId: 7238632346214362 → 9767147403369991
- MUTE QueryId: 29766401636284406 → 31938993655691868
- UNMUTE QueryId: 9864994326891137 → 31938993655691868 (same mutation as MUTE)
- xwa2_newsletter_follow: 'xwa2_newsletter_follow' → 'xwa2_newsletter_join_v2'
- xwa2_newsletter_unfollow: 'xwa2_newsletter_unfollow' → 'xwa2_newsletter_leave_v2'
- xwa2_newsletter_mute_v2: 'xwa2_newsletter_mute_v2' → 'xwa2_newsletter_update_user_setting'
- xwa2_newsletter_unmute_v2: 'xwa2_newsletter_unmute_v2' → 'xwa2_newsletter_update_user_setting'
- newsletterMute/Unmute variables: flat {newsletter_id} → {input: {newsletter_id, type, value}}

Fixes #2346
2026-03-19 11:49:42 -03:00
Renato Alcara 71fe69fd21 chore: update WhatsApp Web version to v2.3000.1035504971 (#301)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-19 06:33:42 -03:00
github-actions[bot] eecf6df2a2 chore: update proto/version to v2.3000.1035484955 (#300)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-19 01:48:35 -03:00
Renato Alcara d04a3e1af8 fix: restore working carousel send/render path (#297)
fix: restore working carousel send/render path (#297)
2026-03-18 20:30:18 -03:00
Renato Alcara 21462c26d5 chore: update WhatsApp Web version to v2.3000.1035406580 (#299)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-18 06:42:44 -03:00
github-actions[bot] fc2122b11a chore: update proto/version to v2.3000.1035370989 (#298)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-18 01:49:58 -03:00
Renato Alcara 11eed3aedc chore: update WhatsApp Web version to v2.3000.1035317910 (#296)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-17 06:16:35 -03:00
github-actions[bot] dbc6dd6aed chore: update proto/version to v2.3000.1035302375 (#295)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-17 00:46:29 -03:00
Renato Alcara e152aee740 Fix/pn lid session reuse (#294)
* fix: unify PN and LID session reuse for 1:1 sends

* fix: limit PN/LID reuse changes to session cache
2026-03-16 23:22:05 -03:00
Renato Alcara ff9b84c561 fix: unify PN and LID session reuse for 1:1 sends (#293)
fix: unify PN and LID session reuse for 1:1 sends (#293)
2026-03-16 22:59:28 -03:00
Renato Alcara 50c13398c4 fix: harden carousel live rendering path (#292)
* fix: harden carousel live rendering path

* fix: flatten carousel thumbnail fallback
2026-03-16 22:09:14 -03:00
Renato Alcara d991d0212d fix: add biz node injection and quality_control for carousel WhatsApp Web rendering (#291)
- Add interactive message detection helpers (getButtonType, isCarouselMessage, etc.)
- Inject biz node with interactive/native_flow for non-carousel interactive messages
- Inject biz + quality_control with decision_id for carousel messages
- Skip bot node for native_flow/carousel/catalog (breaks Web rendering)
- Force device-identity inclusion for carousel messages
- Append deferred biz/bot/quality_control nodes after device-identity and tctoken
- Store tctoken under both LID and PN for reliable lookup
2026-03-16 21:25:29 -03:00
Renato Alcara 7c095c84a5 chore: update WhatsApp Web version to v2.3000.1035223526 (#289)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-16 06:20:34 -03:00
github-actions[bot] a25e6740fd chore: update proto/version to v2.3000.1035216863 (#288)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-16 00:58:19 -03:00
Renato Alcara 986ac588a9 chore: update WhatsApp Web version to v2.3000.1035203283 (#287)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-15 06:08:25 -03:00
github-actions[bot] 64c73faab2 chore: update proto/version to v2.3000.1035198198 (#286)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-15 00:56:35 -03:00
Renato Alcara b5464bec73 chore: update WhatsApp Web version to v2.3000.1035176028 (#285)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-14 06:07:31 -03:00
github-actions[bot] 9f8f74fc7a chore: update proto/version to v2.3000.1035169204 (#284)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-14 00:44:33 -03:00
Renato Alcara aaf3bd83eb chore: update WhatsApp Web version to v2.3000.1035102652 (#283)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-13 06:11:31 -03:00
github-actions[bot] 8fe71b03d5 chore: update proto/version to v2.3000.1035083696 (#282)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-13 00:45:20 -03:00
Renato Alcara c2c156d707 chore(deps): update music-metadata from 11.12.0 to 11.12.3 (#281)
Includes security fix for CWE-85 (infinite loop in ASF parsing),
Ogg/Vorbis duration fix, and restored TypeScript declaration files.
2026-03-12 23:52:05 -03:00
Renato Alcara e46b9750c2 chore: update WhatsApp Web version to v2.3000.1035018135 (#280)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 06:13:34 -03:00
github-actions[bot] 542b7a278d chore: update proto/version to v2.3000.1034989030 (#279)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-12 00:45:49 -03:00
Renato Alcara 6d7e0d7b35 chore: update WhatsApp Web version to v2.3000.1034928492 (#278)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 06:12:36 -03:00
github-actions[bot] 9daee4d8fd chore: update proto/version to v2.3000.1034906703 (#277)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-11 00:44:13 -03:00
Renato Alcara d7b2ceb161 chore: update WhatsApp Web version to v2.3000.1034844076 (#276)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 06:12:48 -03:00
github-actions[bot] 2236ef83a9 chore: update proto/version to v2.3000.1034813620 (#275)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-10 00:44:00 -03:00
Renato Alcara 07f775dd18 chore: update WhatsApp Web version to v2.3000.1034756368 (#274)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 06:14:04 -03:00
github-actions[bot] ad81d1535d chore: update proto/version to v2.3000.1034750325 (#273)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-09 00:46:14 -03:00
Renato Alcara 7ecfaefcfa chore: update WhatsApp Web version to v2.3000.1034735671 (#272)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 06:05:18 -03:00
github-actions[bot] ad4f676e2b chore: update proto/version to v2.3000.1034732001 (#271)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-08 00:45:02 -03:00
Renato Alcara 54d6a023a4 chore: update WhatsApp Web version to v2.3000.1034715486 (#270)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 06:05:25 -03:00
github-actions[bot] 935484c790 chore: update proto/version to v2.3000.1034696150 (#269)
Co-authored-by: rsalcara <rsalcara@users.noreply.github.com>
2026-03-07 00:37:49 -03:00
Renato Alcara f2c14f9ad6 fix: carousel renders on WhatsApp Web without F5
Two fixes:
1. Stanza type="media" for carousel messages — WhatsApp Web needs this
   to render carousel in real-time. Without it, only shows header until
   page refresh (F5).
2. Fix jimp detection: typeof Jimp === 'function' (not just 'object')
   so jpegThumbnail is generated for card images.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:25:07 -03:00
Renato Alcara ac2acf3d87 Fix/carousel working minimal (#268)
Fix/carousel working minimal (#268)
2026-03-06 23:58:59 -03:00
Renato Alcara 0b527b0855 fix: inline carousel handler for WhatsApp Web rendering (#267)
fix: inline carousel handler for WhatsApp Web rendering (#267)
2026-03-06 23:26:43 -03:00
Renato Alcara 9f8b603e28 fix: skip biz node for carousel messages (fixes WhatsApp Web rendering) (#265)
fix: skip biz node for carousel messages (fixes WhatsApp Web rendering) (#265)
2026-03-06 21:29:26 -03:00