@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
@@ -13,12 +13,12 @@ exports.getBinaryNodeMessages =
13
13
  exports.binaryNodeToString = binaryNodeToString
14
14
  const boom_1 = require('@hapi/boom')
15
15
  const index_js_1 = require('../../WAProto/index.js')
16
-
16
+ // some extra useful utilities
17
17
  const indexCache = new WeakMap()
18
18
  const getBinaryNodeChildren = (node, childTag) => {
19
19
  if (!node || !Array.isArray(node.content)) return []
20
20
  let index = indexCache.get(node)
21
-
21
+ // Build the index once per node
22
22
  if (!index) {
23
23
  index = new Map()
24
24
  for (const child of node.content) {
@@ -28,7 +28,7 @@ const getBinaryNodeChildren = (node, childTag) => {
28
28
  }
29
29
  indexCache.set(node, index)
30
30
  }
31
-
31
+ // Return first matching child
32
32
  return index.get(childTag) || []
33
33
  }
34
34
  exports.getBinaryNodeChildren = getBinaryNodeChildren
@@ -53,7 +53,7 @@ exports.getBinaryNodeChildBuffer = getBinaryNodeChildBuffer
53
53
  const getBinaryNodeChildString = (node, childTag) => {
54
54
  const child = (0, exports.getBinaryNodeChild)(node, childTag)?.content
55
55
  if (Buffer.isBuffer(child) || child instanceof Uint8Array) {
56
- return Buffer.from(child).toString('utf8')
56
+ return Buffer.from(child).toString('utf-8')
57
57
  } else if (typeof child === 'string') {
58
58
  return child
59
59
  }
@@ -61,9 +61,7 @@ const getBinaryNodeChildString = (node, childTag) => {
61
61
  exports.getBinaryNodeChildString = getBinaryNodeChildString
62
62
  const getBinaryNodeChildUInt = (node, childTag, length) => {
63
63
  const buff = (0, exports.getBinaryNodeChildBuffer)(node, childTag)
64
-
65
-
66
- if (buff && buff.length >= length) {
64
+ if (buff) {
67
65
  return bufferToUInt(buff, length)
68
66
  }
69
67
  }
@@ -119,6 +117,98 @@ const getBinaryFilteredBizBot = nodeContent => {
119
117
  }
120
118
  exports.getBinaryFilteredBizBot = getBinaryFilteredBizBot
121
119
 
120
+ const getAdditionalNode = name => {
121
+ if (name) name = name.toLowerCase()
122
+ const ts = Math.floor(Date.now() / 1000) - 77980457
123
+ const order_response_name = {
124
+ review_and_pay: 'order_details',
125
+ review_order: 'order_status',
126
+ order_status: 'order_status',
127
+ payment_info: 'payment_info',
128
+ payment_status: 'payment_status',
129
+ payment_method: 'payment_method',
130
+ catalog_message: 'catalog_message'
131
+ }
132
+ const flow_name = {
133
+ cta_catalog: 'cta_catalog',
134
+ mpm: 'mpm',
135
+ call_request: 'call_permission_request',
136
+ view_catalog: 'automated_greeting_message_view_catalog',
137
+ wa_pay_detail: 'wa_payment_transaction_details',
138
+ send_location: 'send_location',
139
+ payment_key_info: 'payment_key_info'
140
+ }
141
+ if (order_response_name[name]) {
142
+ return [
143
+ {
144
+ tag: 'biz',
145
+ attrs: {
146
+ native_flow_name: order_response_name[name]
147
+ },
148
+ content: []
149
+ }
150
+ ]
151
+ } else if (flow_name[name] || name === 'interactive' || name === 'buttons') {
152
+ return [
153
+ {
154
+ tag: 'biz',
155
+ attrs: {
156
+ actual_actors: '2',
157
+ host_storage: '2',
158
+ privacy_mode_ts: `${ts}`
159
+ },
160
+ content: [
161
+ {
162
+ tag: 'engagement',
163
+ attrs: {
164
+ customer_service_state: 'open',
165
+ conversation_state: 'open'
166
+ }
167
+ },
168
+ {
169
+ tag: 'interactive',
170
+ attrs: {
171
+ type: 'native_flow',
172
+ v: '1'
173
+ },
174
+ content: [
175
+ {
176
+ tag: 'native_flow',
177
+ attrs: {
178
+ v: '9',
179
+ name: flow_name[name] ?? 'mixed'
180
+ },
181
+ content: []
182
+ }
183
+ ]
184
+ }
185
+ ]
186
+ }
187
+ ]
188
+ } else {
189
+ return [
190
+ {
191
+ tag: 'biz',
192
+ attrs: {
193
+ actual_actors: '2',
194
+ host_storage: '2',
195
+ privacy_mode_ts: `${ts}`
196
+ },
197
+ content: [
198
+ {
199
+ tag: 'engagement',
200
+ attrs: {
201
+ customer_service_state: 'open',
202
+ conversation_state: 'open'
203
+ }
204
+ }
205
+ ]
206
+ }
207
+ ]
208
+ }
209
+ }
210
+ exports.getAdditionalNode = getAdditionalNode
211
+
122
212
  function bufferToUInt(e, t) {
123
213
  let a = 0
124
214
  for (let i = 0; i < t; i++) {
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, '__esModule', { value: true })
3
3
  exports.transferDevice =
4
4
  exports.jidNormalizedUser =
5
- exports.isJidLid =
6
5
  exports.isJidBot =
7
6
  exports.isHostedLidUser =
8
7
  exports.isHostedPnUser =
@@ -24,13 +23,9 @@ exports.transferDevice =
24
23
  exports.PSA_WID =
25
24
  exports.SERVER_JID =
26
25
  exports.OFFICIAL_BIZ_JID =
27
- exports.BOT_WHATSAPP_NET =
28
- exports.BOT_SERVER =
29
26
  exports.S_WHATSAPP_NET =
30
27
  void 0
31
28
  exports.S_WHATSAPP_NET = '@s.whatsapp.net'
32
- exports.BOT_WHATSAPP_NET = '@bot.whatsapp.net'
33
- exports.BOT_SERVER = '@bot'
34
29
  exports.OFFICIAL_BIZ_JID = '16505361212@c.us'
35
30
  exports.SERVER_JID = 'server@c.us'
36
31
  exports.PSA_WID = '0@c.us'
@@ -40,7 +35,6 @@ var WAJIDDomains
40
35
  ;(function (WAJIDDomains) {
41
36
  WAJIDDomains[(WAJIDDomains['WHATSAPP'] = 0)] = 'WHATSAPP'
42
37
  WAJIDDomains[(WAJIDDomains['LID'] = 1)] = 'LID'
43
- WAJIDDomains[(WAJIDDomains['BOT'] = 2)] = 'BOT'
44
38
  WAJIDDomains[(WAJIDDomains['HOSTED'] = 128)] = 'HOSTED'
45
39
  WAJIDDomains[(WAJIDDomains['HOSTED_LID'] = 129)] = 'HOSTED_LID'
46
40
  })(WAJIDDomains || (exports.WAJIDDomains = WAJIDDomains = {}))
@@ -48,8 +42,6 @@ const getServerFromDomainType = (initialServer, domainType) => {
48
42
  switch (domainType) {
49
43
  case WAJIDDomains.LID:
50
44
  return 'lid'
51
- case WAJIDDomains.BOT:
52
- return 'bot'
53
45
  case WAJIDDomains.HOSTED:
54
46
  return 'hosted'
55
47
  case WAJIDDomains.HOSTED_LID:
@@ -288,6 +280,7 @@ const jidEncode = (user, server, device, agent) => {
288
280
  }
289
281
  exports.jidEncode = jidEncode
290
282
  const jidDecode = jid => {
283
+ // todo: investigate how to implement hosted ids in this case
291
284
  const sepIdx = typeof jid === 'string' ? jid.indexOf('@') : -1
292
285
  if (sepIdx < 0) {
293
286
  return undefined
@@ -299,14 +292,12 @@ const jidDecode = jid => {
299
292
  let domainType = WAJIDDomains.WHATSAPP
300
293
  if (server === 'lid') {
301
294
  domainType = WAJIDDomains.LID
302
- } else if (server === 'bot') {
303
- domainType = WAJIDDomains.BOT
304
295
  } else if (server === 'hosted') {
305
296
  domainType = WAJIDDomains.HOSTED
306
297
  } else if (server === 'hosted.lid') {
307
298
  domainType = WAJIDDomains.HOSTED_LID
308
299
  } else if (agent) {
309
- domainType = parseInt(agent, 10)
300
+ domainType = parseInt(agent)
310
301
  }
311
302
  return {
312
303
  server: server,
@@ -316,45 +307,41 @@ const jidDecode = jid => {
316
307
  }
317
308
  }
318
309
  exports.jidDecode = jidDecode
319
-
310
+ /** is the jid a user */
320
311
  const areJidsSameUser = (jid1, jid2) => (0, exports.jidDecode)(jid1)?.user === (0, exports.jidDecode)(jid2)?.user
321
312
  exports.areJidsSameUser = areJidsSameUser
322
-
313
+ /** is the jid Meta AI */
323
314
  const isJidMetaAI = jid => jid?.endsWith('@bot')
324
315
  exports.isJidMetaAI = isJidMetaAI
325
-
316
+ /** is the jid a PN user */
326
317
  const isPnUser = jid => jid?.endsWith('@s.whatsapp.net')
327
318
  exports.isPnUser = isPnUser
328
-
319
+ /** is the jid an interop (BirdyChat/Haiket) user */
329
320
  const isInteropUser = jid => jid?.endsWith('@interop')
330
321
  exports.isInteropUser = isInteropUser
331
-
322
+ /** is the jid a LID */
332
323
  const isLidUser = jid => jid?.endsWith('@lid')
333
324
  exports.isLidUser = isLidUser
334
-
335
- const isJidLid = jid => jid?.endsWith('@lid')
336
- exports.isJidLid = isJidLid
337
-
325
+ /** is the jid a broadcast */
338
326
  const isJidBroadcast = jid => jid?.endsWith('@broadcast')
339
327
  exports.isJidBroadcast = isJidBroadcast
340
-
328
+ /** is the jid a group */
341
329
  const isJidGroup = jid => jid?.endsWith('@g.us')
342
330
  exports.isJidGroup = isJidGroup
343
-
331
+ /** is the jid the status broadcast */
344
332
  const isJidStatusBroadcast = jid => jid === 'status@broadcast'
345
333
  exports.isJidStatusBroadcast = isJidStatusBroadcast
346
-
334
+ /** is the jid a newsletter */
347
335
  const isJidNewsletter = jid => jid?.endsWith('@newsletter')
348
336
  exports.isJidNewsletter = isJidNewsletter
349
-
337
+ /** is the jid a hosted PN */
350
338
  const isHostedPnUser = jid => jid?.endsWith('@hosted')
351
339
  exports.isHostedPnUser = isHostedPnUser
352
-
340
+ /** is the jid a hosted LID */
353
341
  const isHostedLidUser = jid => jid?.endsWith('@hosted.lid')
354
342
  exports.isHostedLidUser = isHostedLidUser
355
343
  const botRegexp = /^1313555\d{4}$|^131655500\d{2}$/
356
-
357
- const isJidBot = jid => jid && ((botRegexp.test(jid.split('@')[0]) && jid.endsWith('@c.us')) || jid.endsWith('@bot'))
344
+ const isJidBot = jid => jid && botRegexp.test(jid.split('@')[0]) && jid.endsWith('@c.us')
358
345
  exports.isJidBot = isJidBot
359
346
  const jidNormalizedUser = jid => {
360
347
  const result = (0, exports.jidDecode)(jid)
package/lib/WAM/encode.js CHANGED
@@ -18,12 +18,12 @@ const encodeWAM = binaryInfo => {
18
18
  }
19
19
  exports.encodeWAM = encodeWAM
20
20
  function encodeWAMHeader(binaryInfo) {
21
- const headerBuffer = Buffer.alloc(8)
21
+ const headerBuffer = Buffer.alloc(8) // starting buffer
22
22
  headerBuffer.write('WAM', 0, 'utf8')
23
23
  headerBuffer.writeUInt8(binaryInfo.protocolVersion, 3)
24
- headerBuffer.writeUInt8(1, 4)
24
+ headerBuffer.writeUInt8(1, 4) //random flag
25
25
  headerBuffer.writeUInt16BE(binaryInfo.sequence, 5)
26
- headerBuffer.writeUInt8(0, 7)
26
+ headerBuffer.writeUInt8(0, 7) // regular channel
27
27
  binaryInfo.buffer.push(headerBuffer)
28
28
  }
29
29
  function encodeGlobalAttributes(binaryInfo, globals) {
@@ -71,7 +71,7 @@ function serializeData(key, value, flag) {
71
71
  return buffer
72
72
  }
73
73
  } else if (typeof value === 'number' && Number.isInteger(value)) {
74
-
74
+ // is number
75
75
  if (value === 0 || value === 1) {
76
76
  buffer = Buffer.alloc(bufferLength)
77
77
  offset = serializeHeader(buffer, offset, key, flag | ((value + 1) << 4))
@@ -98,13 +98,13 @@ function serializeData(key, value, flag) {
98
98
  return buffer
99
99
  }
100
100
  } else if (typeof value === 'number') {
101
-
101
+ // is float
102
102
  buffer = Buffer.alloc(bufferLength + 8)
103
103
  offset = serializeHeader(buffer, offset, key, flag | (7 << 4))
104
104
  buffer.writeDoubleLE(value, offset)
105
105
  return buffer
106
106
  } else if (typeof value === 'string') {
107
-
107
+ // is string
108
108
  const utf8Bytes = Buffer.byteLength(value, 'utf8')
109
109
  if (utf8Bytes < 256) {
110
110
  buffer = Buffer.alloc(bufferLength + 1 + utf8Bytes)
@@ -124,7 +124,7 @@ function serializeData(key, value, flag) {
124
124
  buffer.write(value, offset, 'utf8')
125
125
  return buffer
126
126
  }
127
- throw new Error(`WAM serializeData: unsupported value type ${typeof value} for key ${key}`)
127
+ throw 'missing'
128
128
  }
129
129
  function serializeHeader(buffer, offset, key, flag) {
130
130
  if (key < 256) {
@@ -32,68 +32,11 @@ class USyncBusinessProtocol {
32
32
  ;(0, WABinary_1.assertNodeErrorFree)(node)
33
33
  const verifiedNameNode = (0, WABinary_1.getBinaryNodeChild)(node, 'verified_name')
34
34
  const profileNode = (0, WABinary_1.getBinaryNodeChild)(node, 'profile')
35
-
36
-
37
- let businessHours = undefined
38
- if (profileNode) {
39
- const businessHoursNode = (0, WABinary_1.getBinaryNodeChild)(profileNode, 'business_hours')
40
- if (businessHoursNode) {
41
- const configs = (0, WABinary_1.getBinaryNodeChildren)(businessHoursNode, 'business_hours_config')
42
- businessHours = {
43
- timezone: businessHoursNode.attrs?.timezone ?? null,
44
- config: configs.map(({ attrs }) => ({
45
- dayOfWeek: attrs?.day_of_week ?? null,
46
- openTime: attrs?.open_time ?? null,
47
- closeTime: attrs?.close_time ?? null,
48
- mode: attrs?.mode ?? null
49
- }))
50
- }
51
- }
52
- }
53
-
54
-
55
- const addressNode = profileNode ? (0, WABinary_1.getBinaryNodeChild)(profileNode, 'address') : null
56
- const businessAddress = addressNode?.content
57
- ? Buffer.isBuffer(addressNode.content)
58
- ? addressNode.content.toString()
59
- : String(addressNode.content)
60
- : (profileNode?.attrs?.address ?? null)
61
-
62
-
63
- const catalogStatus = profileNode
64
- ? {
65
- exists: profileNode.attrs?.catalog_exists === 'true' || profileNode.attrs?.catalog_exists === true,
66
- sendAll: profileNode.attrs?.catalog_send_all === 'true' || profileNode.attrs?.catalog_send_all === true
67
- }
68
- : null
69
-
70
-
71
- const cartEnabled =
72
- profileNode?.attrs?.cart_enabled !== undefined
73
- ? profileNode.attrs.cart_enabled === 'true' || profileNode.attrs.cart_enabled === true
74
- : null
75
- const webCartEnabled =
76
- profileNode?.attrs?.web_cart_enabled !== undefined
77
- ? profileNode.attrs.web_cart_enabled === 'true' || profileNode.attrs.web_cart_enabled === true
78
- : null
79
- const webCartOnOff = profileNode?.attrs?.web_cart_on_off ?? null
80
-
81
-
82
- const commerceExperience = profileNode?.attrs?.commerce_experience ?? null
83
-
84
35
  return {
85
36
  verifiedName: verifiedNameNode?.content ?? null,
86
37
  verifiedLevel: verifiedNameNode?.attrs?.verified_level ?? null,
87
- verifiedNameLevel: verifiedNameNode?.attrs?.verified_level ?? null,
88
38
  profileTag: profileNode?.attrs?.tag ?? null,
89
- pnJid: node.attrs?.pn_jid ?? null,
90
- businessHours: businessHours ?? null,
91
- businessAddress,
92
- catalogStatus,
93
- cartEnabled,
94
- webCartEnabled,
95
- webCartOnOff,
96
- commerceExperience
39
+ pnJid: node.attrs?.pn_jid ?? null
97
40
  }
98
41
  }
99
42
  }
@@ -46,13 +46,7 @@ class USyncContactProtocol {
46
46
  parser(node) {
47
47
  if (node.tag === 'contact') {
48
48
  ;(0, WABinary_1.assertNodeErrorFree)(node)
49
- const inWA = node?.attrs?.type === 'in'
50
- const restrictionType = node?.attrs?.stella_addressbook_restriction_type
51
- if (restrictionType !== undefined) {
52
-
53
- return { inWA, stellaAddressbookRestrictionType: restrictionType }
54
- }
55
- return inWA
49
+ return node?.attrs?.type === 'in'
56
50
  }
57
51
  return false
58
52
  }
@@ -14,19 +14,11 @@ class USyncDeviceProtocol {
14
14
  }
15
15
  }
16
16
  }
17
- getUserElement(user) {
18
- const { deviceHash, ts, expectedTs } = user
19
- if (deviceHash == null && ts == null && expectedTs == null) {
20
- return null
21
- }
22
- const attrs = {}
23
- if (deviceHash != null) attrs.device_hash = deviceHash
24
- if (ts != null) attrs.ts = String(ts)
25
- if (expectedTs != null) attrs.expected_ts = String(expectedTs)
26
- return {
27
- tag: 'devices',
28
- attrs
29
- }
17
+ getUserElement(/* user: USyncUser */) {
18
+ //TODO: Implement device phashing, ts and expectedTs
19
+ //TODO: if all are not present, return null <- current behavior
20
+ //TODO: otherwise return a node w tag 'devices' w those as attrs
21
+ return null
30
22
  }
31
23
  parser(node) {
32
24
  const deviceList = []
@@ -20,7 +20,10 @@ class USyncDisappearingModeProtocol {
20
20
  ;(0, WABinary_1.assertNodeErrorFree)(node)
21
21
  const duration = +node?.attrs.duration
22
22
  const setAt = new Date(+(node?.attrs.t || 0) * 1000)
23
- return { duration, setAt }
23
+ return {
24
+ duration,
25
+ setAt
26
+ }
24
27
  }
25
28
  }
26
29
  }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, '__esModule', { value: true })
3
3
  exports.USyncFeatureProtocol = exports.USYNC_FEATURES = void 0
4
4
  const WABinary_1 = require('../../WABinary')
5
-
6
-
5
+ // Device feature flags that can be queried, ported from WhatsApp Web's
6
+ // WAWebUsyncFeature module.
7
7
  exports.USYNC_FEATURES = [
8
8
  'document',
9
9
  'encrypt',
@@ -15,12 +15,12 @@ exports.USYNC_FEATURES = [
15
15
  'encrypt_url',
16
16
  'encrypt_v2',
17
17
  'voip',
18
- 'voip_legacy',
19
- 'multi_agent',
20
- 'bot_eligible'
18
+ 'multi_agent'
21
19
  ]
22
20
  class USyncFeatureProtocol {
23
-
21
+ /**
22
+ * @param {string[]} [features] feature names to query (defaults to all known)
23
+ */
24
24
  constructor(features) {
25
25
  this.name = 'feature'
26
26
  this.features = features && features.length ? features : exports.USYNC_FEATURES
@@ -46,24 +46,11 @@ class USyncFeatureProtocol {
46
46
  errorText: errorNode.attrs?.text
47
47
  }
48
48
  }
49
- const CAMEL_MAP = {
50
- encrypt_v2: 'encryptV2',
51
- voip_legacy: 'voipLegacy',
52
- multi_agent: 'multiAgent',
53
- bot_eligible: 'botEligible',
54
- encrypt_blist: 'encryptBlist',
55
- encrypt_contact: 'encryptContact',
56
- encrypt_group_gen2: 'encryptGroupGen2',
57
- encrypt_image: 'encryptImage',
58
- encrypt_location: 'encryptLocation',
59
- encrypt_url: 'encryptUrl'
60
- }
61
49
  const features = {}
62
50
  const children = Array.isArray(node.content) ? node.content : []
63
51
  for (const child of children) {
64
52
  if (child?.attrs && child.attrs.value !== undefined) {
65
- const key = CAMEL_MAP[child.tag] || child.tag
66
- features[key] = child.attrs.value
53
+ features[child.tag] = child.attrs.value
67
54
  }
68
55
  }
69
56
  return features
@@ -5,7 +5,7 @@ const WABinary_1 = require('../../WABinary')
5
5
  class USyncPictureProtocol {
6
6
  constructor(type = 'image') {
7
7
  this.name = 'picture'
8
-
8
+ // "image" for full resolution, "preview" for thumbnail
9
9
  this.type = type
10
10
  }
11
11
  getQueryElement() {
@@ -5,7 +5,7 @@ const WABinary_1 = require('../../WABinary')
5
5
  class USyncSidelistProtocol {
6
6
  constructor(useLidAddressing = true) {
7
7
  this.name = 'sidelist'
8
-
8
+ // When true, sends addressing_mode="lid" — required for interop/LID-mode contacts
9
9
  this.useLidAddressing = useLidAddressing
10
10
  }
11
11
  getQueryElement() {
@@ -22,7 +22,7 @@ class USyncSidelistProtocol {
22
22
  parser(node) {
23
23
  if (node.tag !== 'sidelist' && node.tag !== 'side_list') return null
24
24
  ;(0, WABinary_1.assertNodeErrorFree)(node)
25
-
25
+ // Returns minimal parsed data; the full side_list is parsed in USyncQuery
26
26
  return { type: node.attrs?.type ?? null }
27
27
  }
28
28
  }
@@ -12,13 +12,8 @@ class USyncStatusProtocol {
12
12
  attrs: {}
13
13
  }
14
14
  }
15
- getUserElement(user) {
16
- if (!user?.tcToken) return null
17
- return {
18
- tag: 'tctoken',
19
- attrs: {},
20
- content: user.tcToken
21
- }
15
+ getUserElement() {
16
+ return null
22
17
  }
23
18
  parser(node) {
24
19
  if (node.tag === 'status') {
@@ -23,7 +23,7 @@ class USyncTextStatusProtocol {
23
23
  const text = node.attrs?.text ?? null
24
24
  const emojiNode = (0, WABinary_1.getBinaryNodeChild)(node, 'emoji')
25
25
  const emoji = emojiNode?.attrs?.content ?? null
26
-
26
+ // expiry is lastUpdateTime + ephemeralDuration (both in ms); 0 means no expiry
27
27
  const expiresAt = ephemeralDurationSec > 0
28
28
  ? new Date((lastUpdateTimeSec + ephemeralDurationSec) * 1000)
29
29
  : null
@@ -19,8 +19,7 @@ class USyncUsernameProtocol {
19
19
  parser(node) {
20
20
  if (node.tag === 'username') {
21
21
  ;(0, WABinary_1.assertNodeErrorFree)(node)
22
- const username = node.content != null ? node.content.toString() : null
23
- return username && username.length > 0 ? username : null
22
+ return typeof node.content === 'string' ? node.content : null
24
23
  }
25
24
  return null
26
25
  }
@@ -35,6 +35,5 @@ __exportStar(require('./USyncBotProfileProtocol'), exports)
35
35
  __exportStar(require('./USyncBusinessProtocol'), exports)
36
36
  __exportStar(require('./USyncPictureProtocol'), exports)
37
37
  __exportStar(require('./USyncTextStatusProtocol'), exports)
38
- __exportStar(require('./USyncLIDProtocol'), exports)
39
38
  __exportStar(require('./USyncSidelistProtocol'), exports)
40
39
  __exportStar(require('./USyncFeatureProtocol'), exports)
@@ -5,10 +5,10 @@ const WABinary_1 = require('../WABinary')
5
5
  const USyncBotProfileProtocol_1 = require('./Protocols/USyncBotProfileProtocol')
6
6
  const USyncLIDProtocol_1 = require('./Protocols/USyncLIDProtocol')
7
7
  const USyncBusinessProtocol_1 = require('./Protocols/USyncBusinessProtocol')
8
- const USyncFeatureProtocol_1 = require('./Protocols/USyncFeatureProtocol')
9
8
  const USyncPictureProtocol_1 = require('./Protocols/USyncPictureProtocol')
10
9
  const USyncTextStatusProtocol_1 = require('./Protocols/USyncTextStatusProtocol')
11
10
  const USyncSidelistProtocol_1 = require('./Protocols/USyncSidelistProtocol')
11
+ const USyncFeatureProtocol_1 = require('./Protocols/USyncFeatureProtocol')
12
12
  const Protocols_1 = require('./Protocols')
13
13
  class USyncQuery {
14
14
  constructor() {
@@ -39,85 +39,26 @@ class USyncQuery {
39
39
  })
40
40
  )
41
41
  const queryResult = {
42
- errors: {},
43
- refresh: {},
42
+ // TODO: implement errors etc.
44
43
  list: [],
45
44
  sideList: []
46
45
  }
47
46
  const usyncNode = (0, WABinary_1.getBinaryNodeChild)(result, 'usync')
48
-
49
-
50
-
51
-
52
- const resultNode = usyncNode ? (0, WABinary_1.getBinaryNodeChild)(usyncNode, 'result') : undefined
53
- if (resultNode) {
54
- for (const protocol of this.protocols) {
55
- const protocolNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, protocol.name)
56
- if (!protocolNode) continue
57
- const errorNode = (0, WABinary_1.getBinaryNodeChild)(protocolNode, 'error')
58
- if (errorNode) {
59
- queryResult.errors[protocol.name] = {
60
- errorCode: errorNode.attrs.code ? +errorNode.attrs.code : undefined,
61
- errorText: errorNode.attrs.text,
62
- errorBackoff: errorNode.attrs.backoff ? +errorNode.attrs.backoff : undefined
63
- }
64
- } else if (protocolNode.attrs.refresh !== undefined) {
65
- queryResult.refresh[protocol.name] = +protocolNode.attrs.refresh
66
- }
67
- }
68
- }
47
+ //TODO: implement error backoff, refresh etc.
48
+ //TODO: see if there are any errors in the result node
49
+ //const resultNode = getBinaryNodeChild(usyncNode, 'result')
69
50
  const parseUserNodes = nodes => {
70
51
  return nodes.reduce((acc, node) => {
71
52
  const id = node?.attrs.jid
72
53
  if (id) {
73
-
74
-
75
- const userErrorCode = node?.attrs?.error ? parseInt(node.attrs.error, 10) : 0
76
- const isBlockedByAttr = userErrorCode === 401 || userErrorCode === 403 || userErrorCode === 405
77
-
78
54
  const data = Array.isArray(node?.content)
79
55
  ? Object.fromEntries(
80
56
  node.content
81
57
  .map(content => {
82
58
  const protocol = content.tag
83
-
84
-
85
-
86
- if (protocol === 'privacy') {
87
- const tokenNode = (0, WABinary_1.getBinaryNodeChild)(content, 'token')
88
- const modeTsNode = (0, WABinary_1.getBinaryNodeChild)(content, 'mode_ts')
89
-
90
- const tokenVal = tokenNode?.content || content.attrs?.token
91
- const modeTsVal =
92
- modeTsNode?.content?.toString?.() || modeTsNode?.attrs?.value || content.attrs?.mode_ts || null
93
- if (tokenVal) {
94
- return [
95
- 'privacy',
96
- {
97
- token:
98
- Buffer.isBuffer(tokenVal) || tokenVal instanceof Uint8Array
99
- ? Buffer.from(tokenVal)
100
- : tokenVal,
101
- modeTs: modeTsVal
102
- }
103
- ]
104
- }
105
- return ['privacy', null]
106
- }
107
-
108
59
  const parser = protocolMap[protocol]
109
60
  if (parser) {
110
- try {
111
- return [protocol, parser(content)]
112
- } catch (err) {
113
-
114
-
115
- const errCode = err?.data ?? err?.output?.payload?.data
116
- if (errCode === 401 || errCode === 403 || errCode === 405) {
117
- return ['isBlockedByContact', true]
118
- }
119
- throw err
120
- }
61
+ return [protocol, parser(content)]
121
62
  } else {
122
63
  return [protocol, null]
123
64
  }
@@ -125,18 +66,6 @@ class USyncQuery {
125
66
  .filter(([, b]) => b !== null)
126
67
  )
127
68
  : {}
128
-
129
-
130
- if (isBlockedByAttr) {
131
- data.isBlockedByContact = true
132
- }
133
-
134
-
135
- if ('disappearing_mode' in data) {
136
- data.disappearingMode = data.disappearing_mode
137
- delete data.disappearing_mode
138
- }
139
-
140
69
  acc.push({ ...data, id })
141
70
  }
142
71
  return acc