@badzz88/baileys 8.5.4 → 8.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +1 -1
  2. package/WAProto/WAProto.proto +75 -1256
  3. package/WAProto/index.d.ts +19729 -36122
  4. package/WAProto/index.js +132193 -178538
  5. package/engine-requirements.js +15 -7
  6. package/lib/Defaults/index.js +14 -22
  7. package/lib/Signal/Group/group_cipher.js +5 -5
  8. package/lib/Signal/Group/keyhelper.js +4 -4
  9. package/lib/Signal/Group/sender-chain-key.js +2 -2
  10. package/lib/Signal/Group/sender-key-distribution-message.js +1 -1
  11. package/lib/Signal/Group/sender-key-message.js +3 -3
  12. package/lib/Signal/Group/sender-key-record.js +1 -1
  13. package/lib/Signal/Group/sender-message-key.js +5 -5
  14. package/lib/Signal/libsignal.js +28 -39
  15. package/lib/Signal/lid-mapping.js +8 -28
  16. package/lib/Socket/aigroups.js +5 -5
  17. package/lib/Socket/business.js +11 -3
  18. package/lib/Socket/chats.js +319 -668
  19. package/lib/Socket/communities.js +89 -85
  20. package/lib/Socket/graphql.js +228 -435
  21. package/lib/Socket/groups.js +211 -132
  22. package/lib/Socket/index.js +7 -9
  23. package/lib/Socket/interactive-handler.js +60 -117
  24. package/lib/Socket/interop.js +175 -56
  25. package/lib/Socket/luxu.js +387 -0
  26. package/lib/Socket/managed-account.js +48 -79
  27. package/lib/Socket/messages-recv.js +340 -898
  28. package/lib/Socket/messages-send.js +160 -462
  29. package/lib/Socket/mex.js +53 -40
  30. package/lib/Socket/newsletter.js +295 -291
  31. package/lib/Socket/privacy.js +265 -77
  32. package/lib/Socket/registration.js +157 -164
  33. package/lib/Socket/socket.js +199 -181
  34. package/lib/Socket/text-router.js +83 -0
  35. package/lib/Socket/username.js +227 -144
  36. package/lib/Store/keyed-db.js +108 -0
  37. package/lib/Store/make-cache-manager-store.js +2 -2
  38. package/lib/Store/make-in-memory-store.js +141 -25
  39. package/lib/Types/Auth.js +3 -3
  40. package/lib/Types/Label.js +1 -1
  41. package/lib/Types/LabelAssociation.js +1 -1
  42. package/lib/Types/Mex.js +112 -0
  43. package/lib/Types/Newsletter.js +65 -96
  44. package/lib/Types/State.js +4 -4
  45. package/lib/Types/index.js +1 -1
  46. package/lib/Utils/auth-utils.js +57 -52
  47. package/lib/Utils/browser-utils.js +1 -1
  48. package/lib/Utils/business.js +6 -2
  49. package/lib/Utils/chat-utils.js +38 -102
  50. package/lib/Utils/command-loader.d.ts +31 -0
  51. package/lib/Utils/command-loader.js +100 -0
  52. package/lib/Utils/companion-reg-client-utils.js +42 -0
  53. package/lib/Utils/crypto.js +84 -54
  54. package/lib/Utils/curve25519-js.js +275 -0
  55. package/lib/Utils/decode-wa-message.js +83 -316
  56. package/lib/Utils/event-buffer.js +61 -37
  57. package/lib/Utils/generics.js +103 -157
  58. package/lib/Utils/group-history.js +12 -3
  59. package/lib/Utils/history.js +15 -15
  60. package/lib/Utils/index.js +5 -1
  61. package/lib/Utils/link-preview.js +8 -3
  62. package/lib/Utils/lt-hash.js +35 -2
  63. package/lib/Utils/make-mutex.js +1 -1
  64. package/lib/Utils/message-retry-manager.js +92 -27
  65. package/lib/Utils/messages-media.js +130 -159
  66. package/lib/Utils/messages.js +566 -144
  67. package/lib/Utils/meta-ai-msmsg.js +202 -62
  68. package/lib/Utils/native-bridge.js +82 -0
  69. package/lib/Utils/noise-handler.js +21 -19
  70. package/lib/Utils/offline-node-processor.js +8 -3
  71. package/lib/Utils/pre-key-manager.js +23 -13
  72. package/lib/Utils/process-message.js +106 -197
  73. package/lib/Utils/reporting-utils.js +2 -2
  74. package/lib/Utils/session-pool.d.ts +16 -0
  75. package/lib/Utils/session-pool.js +94 -0
  76. package/lib/Utils/signal.js +63 -28
  77. package/lib/Utils/stanza-ack.js +12 -39
  78. package/lib/Utils/sticker.d.ts +17 -0
  79. package/lib/Utils/sticker.js +145 -0
  80. package/lib/Utils/sync-action-utils.js +7 -4
  81. package/lib/Utils/tc-token-utils.js +25 -20
  82. package/lib/Utils/use-multi-file-auth-state.js +14 -30
  83. package/lib/Utils/validate-connection.js +19 -59
  84. package/lib/Utils/view-once-cache.d.ts +9 -0
  85. package/lib/Utils/view-once-cache.js +79 -0
  86. package/lib/WABinary/decode.js +16 -50
  87. package/lib/WABinary/encode.js +224 -54
  88. package/lib/WABinary/generic-utils.js +97 -7
  89. package/lib/WABinary/jid-utils.js +14 -27
  90. package/lib/WAM/encode.js +7 -7
  91. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +1 -58
  92. package/lib/WAUSync/Protocols/USyncContactProtocol.js +1 -7
  93. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +5 -13
  94. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +4 -1
  95. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +7 -20
  96. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +1 -1
  97. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +2 -2
  98. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +2 -7
  99. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +1 -1
  100. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +1 -2
  101. package/lib/WAUSync/Protocols/index.js +0 -1
  102. package/lib/WAUSync/USyncQuery.js +6 -77
  103. package/lib/WAUSync/USyncUser.js +8 -16
  104. package/lib/WAUSync/index.js +0 -1
  105. package/lib/antiban.js +854 -608
  106. package/lib/index.js +1 -1
  107. package/package.json +20 -16
@@ -25,7 +25,7 @@ const makeKeyedMutex = () => {
25
25
  return await entry.mutex.runExclusive(task)
26
26
  } finally {
27
27
  entry.refCount--
28
-
28
+ // only delete it if this is still the current entry
29
29
  if (entry.refCount === 0 && map.get(key) === entry) {
30
30
  map.delete(key)
31
31
  }
@@ -2,24 +2,24 @@
2
2
  Object.defineProperty(exports, '__esModule', { value: true })
3
3
  exports.MessageRetryManager = exports.RetryReason = void 0
4
4
  const lru_cache_1 = require('lru-cache')
5
-
5
+ /** Number of sent messages to cache in memory for handling retry receipts */
6
6
  const RECENT_MESSAGES_SIZE = 512
7
7
  const MESSAGE_KEY_SEPARATOR = '\u0000'
8
-
9
- const RECREATE_SESSION_TIMEOUT = 60 * 60 * 1000
8
+ /** Timeout for session recreation - 1 hour */
9
+ const RECREATE_SESSION_TIMEOUT = 60 * 60 * 1000 // 1 hour in milliseconds
10
10
  const PHONE_REQUEST_DELAY = 3000
11
-
11
+ // Retry reason codes matching WhatsApp Web's Signal error codes.
12
12
  var RetryReason
13
13
  ;(function (RetryReason) {
14
14
  RetryReason[(RetryReason['UnknownError'] = 0)] = 'UnknownError'
15
15
  RetryReason[(RetryReason['SignalErrorNoSession'] = 1)] = 'SignalErrorNoSession'
16
16
  RetryReason[(RetryReason['SignalErrorInvalidKey'] = 2)] = 'SignalErrorInvalidKey'
17
17
  RetryReason[(RetryReason['SignalErrorInvalidKeyId'] = 3)] = 'SignalErrorInvalidKeyId'
18
-
18
+ /** MAC verification failed - most common cause of decryption failures */
19
19
  RetryReason[(RetryReason['SignalErrorInvalidMessage'] = 4)] = 'SignalErrorInvalidMessage'
20
20
  RetryReason[(RetryReason['SignalErrorInvalidSignature'] = 5)] = 'SignalErrorInvalidSignature'
21
21
  RetryReason[(RetryReason['SignalErrorFutureMessage'] = 6)] = 'SignalErrorFutureMessage'
22
-
22
+ /** Explicit MAC failure - session is definitely out of sync */
23
23
  RetryReason[(RetryReason['SignalErrorBadMac'] = 7)] = 'SignalErrorBadMac'
24
24
  RetryReason[(RetryReason['SignalErrorInvalidSession'] = 8)] = 'SignalErrorInvalidSession'
25
25
  RetryReason[(RetryReason['SignalErrorInvalidMsgKey'] = 9)] = 'SignalErrorInvalidMsgKey'
@@ -28,7 +28,7 @@ var RetryReason
28
28
  RetryReason[(RetryReason['AdvFailure'] = 12)] = 'AdvFailure'
29
29
  RetryReason[(RetryReason['StatusRevokeDelay'] = 13)] = 'StatusRevokeDelay'
30
30
  })(RetryReason || (exports.RetryReason = RetryReason = {}))
31
-
31
+ /** Error codes that indicate a MAC failure and require immediate session recreation */
32
32
  const MAC_ERROR_CODES = new Set([RetryReason.SignalErrorInvalidMessage, RetryReason.SignalErrorBadMac])
33
33
  class MessageRetryManager {
34
34
  constructor(logger, maxMsgRetryCount) {
@@ -54,7 +54,12 @@ class MessageRetryManager {
54
54
  ttl: 15 * 60 * 1000,
55
55
  ttlAutopurge: true,
56
56
  updateAgeOnGet: true
57
- })
57
+ }) // 15 minutes TTL
58
+ this.baseKeys = new lru_cache_1.LRUCache({
59
+ max: 1024,
60
+ ttl: 15 * 60 * 1000,
61
+ ttlAutopurge: true
62
+ })
58
63
  this.pendingPhoneRequests = {}
59
64
  this.maxMsgRetryCount = 5
60
65
  this.statistics = {
@@ -67,11 +72,13 @@ class MessageRetryManager {
67
72
  }
68
73
  this.maxMsgRetryCount = maxMsgRetryCount
69
74
  }
70
-
75
+ /**
76
+ * Add a recent message to the cache for retry handling
77
+ */
71
78
  addRecentMessage(to, id, message) {
72
79
  const key = { to, id }
73
80
  const keyStr = this.keyToString(key)
74
-
81
+ // Add new message
75
82
  this.recentMessagesMap.set(keyStr, {
76
83
  message,
77
84
  timestamp: Date.now()
@@ -79,15 +86,20 @@ class MessageRetryManager {
79
86
  this.messageKeyIndex.set(id, keyStr)
80
87
  this.logger.debug(`Added message to retry cache: ${to}/${id}`)
81
88
  }
82
-
89
+ /**
90
+ * Get a recent message from the cache
91
+ */
83
92
  getRecentMessage(to, id) {
84
93
  const key = { to, id }
85
94
  const keyStr = this.keyToString(key)
86
95
  return this.recentMessagesMap.get(keyStr)
87
96
  }
88
-
97
+ /**
98
+ * Check if a session should be recreated based on retry count, history, and error code.
99
+ * MAC errors (codes 4 and 7) trigger immediate session recreation regardless of timeout.
100
+ */
89
101
  shouldRecreateSession(jid, hasSession, errorCode) {
90
-
102
+ // If we don't have a session, always recreate
91
103
  if (!hasSession) {
92
104
  this.sessionRecreateHistory.set(jid, Date.now())
93
105
  this.statistics.sessionRecreations++
@@ -96,7 +108,7 @@ class MessageRetryManager {
96
108
  recreate: true
97
109
  }
98
110
  }
99
-
111
+ // IMMEDIATE recreation for MAC errors - session is definitely out of sync
100
112
  if (errorCode !== undefined && MAC_ERROR_CODES.has(errorCode)) {
101
113
  this.sessionRecreateHistory.set(jid, Date.now())
102
114
  this.statistics.sessionRecreations++
@@ -111,7 +123,7 @@ class MessageRetryManager {
111
123
  }
112
124
  const now = Date.now()
113
125
  const prevTime = this.sessionRecreateHistory.get(jid)
114
-
126
+ // If no previous recreation or it's been more than an hour
115
127
  if (!prevTime || now - prevTime > RECREATE_SESSION_TIMEOUT) {
116
128
  this.sessionRecreateHistory.set(jid, now)
117
129
  this.statistics.sessionRecreations++
@@ -122,7 +134,10 @@ class MessageRetryManager {
122
134
  }
123
135
  return { reason: '', recreate: false }
124
136
  }
125
-
137
+ /**
138
+ * Parse error code from retry receipt's retry node.
139
+ * Returns undefined if no error code is present.
140
+ */
126
141
  parseRetryErrorCode(errorAttr) {
127
142
  if (errorAttr === undefined || errorAttr === '') {
128
143
  return undefined
@@ -131,48 +146,62 @@ class MessageRetryManager {
131
146
  if (Number.isNaN(code)) {
132
147
  return undefined
133
148
  }
134
-
149
+ // Validate it's a known RetryReason
135
150
  if (code >= RetryReason.UnknownError && code <= RetryReason.StatusRevokeDelay) {
136
151
  return code
137
152
  }
138
153
  return RetryReason.UnknownError
139
154
  }
140
-
155
+ /**
156
+ * Check if an error code indicates a MAC failure
157
+ */
141
158
  isMacError(errorCode) {
142
159
  return errorCode !== undefined && MAC_ERROR_CODES.has(errorCode)
143
160
  }
144
-
161
+ /**
162
+ * Increment retry counter for a message
163
+ */
145
164
  incrementRetryCount(messageId) {
146
165
  this.retryCounters.set(messageId, (this.retryCounters.get(messageId) || 0) + 1)
147
166
  this.statistics.totalRetries++
148
167
  return this.retryCounters.get(messageId)
149
168
  }
150
-
169
+ /**
170
+ * Get retry count for a message
171
+ */
151
172
  getRetryCount(messageId) {
152
173
  return this.retryCounters.get(messageId) || 0
153
174
  }
154
-
175
+ /**
176
+ * Check if message has exceeded maximum retry attempts
177
+ */
155
178
  hasExceededMaxRetries(messageId) {
156
179
  return this.getRetryCount(messageId) >= this.maxMsgRetryCount
157
180
  }
158
-
181
+ /**
182
+ * Mark retry as successful
183
+ */
159
184
  markRetrySuccess(messageId) {
160
185
  this.statistics.successfulRetries++
161
-
186
+ // Clean up retry counter for successful message
162
187
  this.retryCounters.delete(messageId)
163
188
  this.cancelPendingPhoneRequest(messageId)
164
189
  this.removeRecentMessage(messageId)
165
190
  }
166
-
191
+ /**
192
+ * Mark retry as failed
193
+ */
167
194
  markRetryFailed(messageId) {
168
195
  this.statistics.failedRetries++
169
196
  this.retryCounters.delete(messageId)
170
197
  this.cancelPendingPhoneRequest(messageId)
171
198
  this.removeRecentMessage(messageId)
172
199
  }
173
-
200
+ /**
201
+ * Schedule a phone request with delay
202
+ */
174
203
  schedulePhoneRequest(messageId, callback, delay = PHONE_REQUEST_DELAY) {
175
-
204
+ // Cancel any existing request for this message
176
205
  this.cancelPendingPhoneRequest(messageId)
177
206
  this.pendingPhoneRequests[messageId] = setTimeout(() => {
178
207
  delete this.pendingPhoneRequests[messageId]
@@ -181,7 +210,9 @@ class MessageRetryManager {
181
210
  }, delay)
182
211
  this.logger.debug(`Scheduled phone request for message ${messageId} with ${delay}ms delay`)
183
212
  }
184
-
213
+ /**
214
+ * Cancel pending phone request
215
+ */
185
216
  cancelPendingPhoneRequest(messageId) {
186
217
  const timeout = this.pendingPhoneRequests[messageId]
187
218
  if (timeout) {
@@ -190,6 +221,40 @@ class MessageRetryManager {
190
221
  this.logger.debug(`Cancelled pending phone request for message ${messageId}`)
191
222
  }
192
223
  }
224
+ clear() {
225
+ this.recentMessagesMap.clear()
226
+ this.messageKeyIndex.clear()
227
+ this.sessionRecreateHistory.clear()
228
+ this.retryCounters.clear()
229
+ this.baseKeys.clear()
230
+ for (const messageId of Object.keys(this.pendingPhoneRequests)) {
231
+ this.cancelPendingPhoneRequest(messageId)
232
+ }
233
+ this.statistics = {
234
+ totalRetries: 0,
235
+ successfulRetries: 0,
236
+ failedRetries: 0,
237
+ mediaRetries: 0,
238
+ sessionRecreations: 0,
239
+ phoneRequests: 0
240
+ }
241
+ }
242
+ saveBaseKey(addr, msgId, baseKey) {
243
+ this.baseKeys.set(`${addr}:${msgId}`, baseKey)
244
+ }
245
+ hasSameBaseKey(addr, msgId, baseKey) {
246
+ const stored = this.baseKeys.get(`${addr}:${msgId}`)
247
+ if (!stored || stored.length !== baseKey.length) {
248
+ return false
249
+ }
250
+ for (let i = 0; i < stored.length; i++) {
251
+ if (stored[i] !== baseKey[i]) return false
252
+ }
253
+ return true
254
+ }
255
+ deleteBaseKey(addr, msgId) {
256
+ this.baseKeys.delete(`${addr}:${msgId}`)
257
+ }
193
258
  keyToString(key) {
194
259
  return `${key.to}${MESSAGE_KEY_SEPARATOR}${key.id}`
195
260
  }