@badzz88/baileys 8.4.7 → 8.4.9

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 (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1055 -337
  3. package/WAProto/WAProto.proto +347 -6
  4. package/WAProto/fix-import.js +38 -0
  5. package/WAProto/fix-imports.js +86 -85
  6. package/WAProto/index.d.ts +4913 -25
  7. package/WAProto/index.js +14074 -98
  8. package/package.json +50 -90
  9. package/src/Defaults/index.js +201 -0
  10. package/src/Defaults/phonenumber-mcc.json +223 -0
  11. package/src/Signal/Group/ciphertext-message.js +15 -0
  12. package/src/Signal/Group/group-session-builder.js +92 -0
  13. package/src/Signal/Group/group_cipher.js +89 -0
  14. package/src/Signal/Group/index.js +136 -0
  15. package/src/Signal/Group/keyhelper.js +73 -0
  16. package/src/Signal/Group/sender-chain-key.js +32 -0
  17. package/src/Signal/Group/sender-key-distribution-message.js +66 -0
  18. package/src/Signal/Group/sender-key-message.js +69 -0
  19. package/src/Signal/Group/sender-key-name.js +50 -0
  20. package/src/Signal/Group/sender-key-record.js +44 -0
  21. package/src/Signal/Group/sender-key-state.js +97 -0
  22. package/src/Signal/Group/sender-message-key.js +30 -0
  23. package/src/Signal/libsignal.js +470 -0
  24. package/src/Signal/lid-mapping.js +262 -0
  25. package/src/Socket/Client/index.js +30 -0
  26. package/src/Socket/Client/types.js +13 -0
  27. package/src/Socket/Client/websocket.js +62 -0
  28. package/src/Socket/aigroups.js +240 -0
  29. package/src/Socket/business.js +422 -0
  30. package/src/Socket/chats.js +2374 -0
  31. package/src/Socket/communities.js +580 -0
  32. package/src/Socket/graphql.js +915 -0
  33. package/src/Socket/groups.js +812 -0
  34. package/src/Socket/index.js +37 -0
  35. package/src/Socket/interactive-handler.js +579 -0
  36. package/src/Socket/interop.js +566 -0
  37. package/src/Socket/managed-account.js +214 -0
  38. package/src/Socket/messages-recv.js +3012 -0
  39. package/src/Socket/messages-send.js +2163 -0
  40. package/{lib → src}/Socket/mex.js +11 -5
  41. package/src/Socket/newsletter.js +1057 -0
  42. package/src/Socket/privacy.js +452 -0
  43. package/src/Socket/registration.js +434 -0
  44. package/src/Socket/socket.js +1079 -0
  45. package/src/Socket/text-router.js +67 -0
  46. package/src/Socket/username.js +234 -0
  47. package/src/Store/index.js +36 -0
  48. package/src/Store/make-cache-manager-store.js +90 -0
  49. package/src/Store/make-in-memory-store.js +506 -0
  50. package/src/Store/make-ordered-dictionary.js +81 -0
  51. package/src/Store/object-repository.js +29 -0
  52. package/src/Types/Auth.js +38 -0
  53. package/src/Types/Bussines.js +2 -0
  54. package/src/Types/Call.js +2 -0
  55. package/src/Types/Chat.js +4 -0
  56. package/src/Types/Contact.js +2 -0
  57. package/src/Types/Events.js +2 -0
  58. package/src/Types/GroupMetadata.js +2 -0
  59. package/src/Types/Label.js +27 -0
  60. package/src/Types/LabelAssociation.js +9 -0
  61. package/src/Types/Message.js +95 -0
  62. package/src/Types/Newsletter.js +152 -0
  63. package/src/Types/Product.js +2 -0
  64. package/src/Types/Signal.js +2 -0
  65. package/src/Types/Socket.js +2 -0
  66. package/src/Types/State.js +70 -0
  67. package/src/Types/USync.js +2 -0
  68. package/src/Types/index.js +54 -0
  69. package/src/Utils/auth-utils.js +306 -0
  70. package/src/Utils/browser-utils.js +114 -0
  71. package/src/Utils/business.js +247 -0
  72. package/src/Utils/chat-utils.js +1272 -0
  73. package/src/Utils/consumer-application.js +107 -0
  74. package/src/Utils/crypto.js +125 -0
  75. package/src/Utils/decode-wa-message.js +808 -0
  76. package/src/Utils/event-buffer.js +586 -0
  77. package/src/Utils/generics.js +640 -0
  78. package/src/Utils/group-history.js +60 -0
  79. package/src/Utils/history.js +244 -0
  80. package/src/Utils/identity-change-handler.js +52 -0
  81. package/src/Utils/index.js +53 -0
  82. package/src/Utils/jid-display-normalization.js +218 -0
  83. package/src/Utils/link-preview.js +143 -0
  84. package/src/Utils/logger.js +9 -0
  85. package/src/Utils/lt-hash.js +10 -0
  86. package/src/Utils/make-mutex.js +36 -0
  87. package/src/Utils/message-composer.js +479 -0
  88. package/src/Utils/message-inspect.js +400 -0
  89. package/src/Utils/message-retry-manager.js +231 -0
  90. package/src/Utils/messages-media.js +943 -0
  91. package/src/Utils/messages.js +2490 -0
  92. package/src/Utils/meta-ai-msmsg.js +133 -0
  93. package/src/Utils/noise-handler.js +194 -0
  94. package/src/Utils/offline-node-processor.js +42 -0
  95. package/src/Utils/pre-key-manager.js +107 -0
  96. package/src/Utils/process-message.js +1047 -0
  97. package/src/Utils/reporting-utils.js +262 -0
  98. package/src/Utils/signal.js +192 -0
  99. package/src/Utils/stanza-ack.js +74 -0
  100. package/src/Utils/sync-action-utils.js +54 -0
  101. package/src/Utils/tc-token-utils.js +161 -0
  102. package/src/Utils/use-multi-file-auth-state.js +121 -0
  103. package/src/Utils/validate-connection.js +248 -0
  104. package/src/Utils/voip-rekey.js +22 -0
  105. package/src/WABinary/constants.js +1304 -0
  106. package/src/WABinary/decode.js +377 -0
  107. package/src/WABinary/encode.js +58 -0
  108. package/src/WABinary/generic-utils.js +148 -0
  109. package/src/WABinary/index.js +33 -0
  110. package/src/WABinary/jid-utils.js +374 -0
  111. package/src/WABinary/types.js +2 -0
  112. package/src/WAM/BinaryInfo.js +13 -0
  113. package/src/WAM/constants.js +39486 -0
  114. package/src/WAM/encode.js +142 -0
  115. package/src/WAM/index.js +31 -0
  116. package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +55 -0
  117. package/src/WAUSync/Protocols/USyncBusinessProtocol.js +100 -0
  118. package/src/WAUSync/Protocols/USyncContactProtocol.js +60 -0
  119. package/src/WAUSync/Protocols/USyncDeviceProtocol.js +65 -0
  120. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  121. package/src/WAUSync/Protocols/USyncFeatureProtocol.js +74 -0
  122. package/src/WAUSync/Protocols/USyncLIDProtocol.js +31 -0
  123. package/src/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
  124. package/src/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
  125. package/src/WAUSync/Protocols/USyncStatusProtocol.js +44 -0
  126. package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  127. package/src/WAUSync/Protocols/USyncUsernameProtocol.js +28 -0
  128. package/src/WAUSync/Protocols/index.js +40 -0
  129. package/src/WAUSync/USyncBackoff.js +31 -0
  130. package/src/WAUSync/USyncQuery.js +204 -0
  131. package/src/WAUSync/USyncUser.js +58 -0
  132. package/src/WAUSync/index.js +32 -0
  133. package/src/antiban.js +4726 -0
  134. package/{lib → src}/index.js +48 -15
  135. package/lib/Defaults/index.js +0 -130
  136. package/lib/Signal/Group/ciphertext-message.js +0 -12
  137. package/lib/Signal/Group/group-session-builder.js +0 -30
  138. package/lib/Signal/Group/group_cipher.js +0 -82
  139. package/lib/Signal/Group/index.js +0 -12
  140. package/lib/Signal/Group/keyhelper.js +0 -18
  141. package/lib/Signal/Group/sender-chain-key.js +0 -26
  142. package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
  143. package/lib/Signal/Group/sender-key-message.js +0 -66
  144. package/lib/Signal/Group/sender-key-name.js +0 -48
  145. package/lib/Signal/Group/sender-key-record.js +0 -41
  146. package/lib/Signal/Group/sender-key-state.js +0 -84
  147. package/lib/Signal/Group/sender-message-key.js +0 -26
  148. package/lib/Signal/libsignal.js +0 -431
  149. package/lib/Signal/lid-mapping.js +0 -277
  150. package/lib/Socket/Client/index.js +0 -3
  151. package/lib/Socket/Client/types.js +0 -11
  152. package/lib/Socket/Client/websocket.js +0 -54
  153. package/lib/Socket/business.js +0 -379
  154. package/lib/Socket/chats.js +0 -1193
  155. package/lib/Socket/communities.js +0 -431
  156. package/lib/Socket/groups.js +0 -374
  157. package/lib/Socket/index.js +0 -12
  158. package/lib/Socket/luxu.js +0 -386
  159. package/lib/Socket/messages-recv.js +0 -1916
  160. package/lib/Socket/messages-send.js +0 -1453
  161. package/lib/Socket/newsletter.js +0 -251
  162. package/lib/Socket/socket.js +0 -980
  163. package/lib/Socket/username.js +0 -146
  164. package/lib/Store/index.js +0 -10
  165. package/lib/Store/keyed-db.js +0 -108
  166. package/lib/Store/make-cache-manager-store.js +0 -85
  167. package/lib/Store/make-in-memory-store.js +0 -198
  168. package/lib/Store/make-ordered-dictionary.js +0 -75
  169. package/lib/Store/object-repository.js +0 -32
  170. package/lib/Types/Auth.js +0 -2
  171. package/lib/Types/Bussines.js +0 -2
  172. package/lib/Types/Call.js +0 -2
  173. package/lib/Types/Chat.js +0 -8
  174. package/lib/Types/Contact.js +0 -2
  175. package/lib/Types/Events.js +0 -2
  176. package/lib/Types/GroupMetadata.js +0 -2
  177. package/lib/Types/Label.js +0 -25
  178. package/lib/Types/LabelAssociation.js +0 -7
  179. package/lib/Types/Message.js +0 -11
  180. package/lib/Types/Mex.js +0 -37
  181. package/lib/Types/Product.js +0 -2
  182. package/lib/Types/Signal.js +0 -2
  183. package/lib/Types/Socket.js +0 -3
  184. package/lib/Types/State.js +0 -56
  185. package/lib/Types/USync.js +0 -2
  186. package/lib/Types/index.js +0 -26
  187. package/lib/Utils/auth-utils.js +0 -302
  188. package/lib/Utils/browser-utils.js +0 -49
  189. package/lib/Utils/business.js +0 -231
  190. package/lib/Utils/chat-utils.js +0 -872
  191. package/lib/Utils/companion-reg-client-utils.js +0 -35
  192. package/lib/Utils/crypto.js +0 -118
  193. package/lib/Utils/decode-wa-message.js +0 -350
  194. package/lib/Utils/event-buffer.js +0 -622
  195. package/lib/Utils/generics.js +0 -403
  196. package/lib/Utils/history.js +0 -134
  197. package/lib/Utils/identity-change-handler.js +0 -50
  198. package/lib/Utils/index.js +0 -23
  199. package/lib/Utils/link-preview.js +0 -85
  200. package/lib/Utils/logger.js +0 -3
  201. package/lib/Utils/lt-hash.js +0 -8
  202. package/lib/Utils/make-mutex.js +0 -33
  203. package/lib/Utils/message-composer.js +0 -273
  204. package/lib/Utils/message-retry-manager.js +0 -265
  205. package/lib/Utils/messages-media.js +0 -788
  206. package/lib/Utils/messages.js +0 -1260
  207. package/lib/Utils/noise-handler.js +0 -201
  208. package/lib/Utils/offline-node-processor.js +0 -40
  209. package/lib/Utils/pre-key-manager.js +0 -106
  210. package/lib/Utils/process-message.js +0 -630
  211. package/lib/Utils/reporting-utils.js +0 -258
  212. package/lib/Utils/signal.js +0 -201
  213. package/lib/Utils/stanza-ack.js +0 -38
  214. package/lib/Utils/sync-action-utils.js +0 -49
  215. package/lib/Utils/tc-token-utils.js +0 -163
  216. package/lib/Utils/use-multi-file-auth-state.js +0 -121
  217. package/lib/Utils/validate-connection.js +0 -203
  218. package/lib/WABinary/constants.js +0 -1301
  219. package/lib/WABinary/decode.js +0 -262
  220. package/lib/WABinary/encode.js +0 -220
  221. package/lib/WABinary/generic-utils.js +0 -204
  222. package/lib/WABinary/index.js +0 -6
  223. package/lib/WABinary/jid-utils.js +0 -98
  224. package/lib/WABinary/types.js +0 -2
  225. package/lib/WAM/BinaryInfo.js +0 -10
  226. package/lib/WAM/constants.js +0 -22853
  227. package/lib/WAM/encode.js +0 -150
  228. package/lib/WAM/index.js +0 -4
  229. package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -52
  230. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -54
  231. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -27
  232. package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -263
  233. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -38
  234. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
  235. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -51
  236. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -29
  237. package/lib/WAUSync/Protocols/index.js +0 -6
  238. package/lib/WAUSync/USyncQuery.js +0 -98
  239. package/lib/WAUSync/USyncUser.js +0 -31
  240. package/lib/WAUSync/index.js +0 -4
@@ -0,0 +1,262 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.getMessageReportingToken = exports.shouldIncludeReportingToken = void 0
4
+ const rb = require('whatsapp-rust-bridge-baron')
5
+ const crypto_2 = require('./crypto')
6
+ const reportingFields = [
7
+ { f: 1 },
8
+ {
9
+ f: 3,
10
+ s: [{ f: 2 }, { f: 3 }, { f: 8 }, { f: 11 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }, { f: 25 }]
11
+ },
12
+ { f: 4, s: [{ f: 1 }, { f: 16 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }] },
13
+ { f: 5, s: [{ f: 3 }, { f: 4 }, { f: 5 }, { f: 16 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }] },
14
+ { f: 6, s: [{ f: 1 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }, { f: 30 }] },
15
+ { f: 7, s: [{ f: 2 }, { f: 7 }, { f: 10 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }, { f: 20 }] },
16
+ { f: 8, s: [{ f: 2 }, { f: 7 }, { f: 9 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }, { f: 21 }] },
17
+ { f: 9, s: [{ f: 2 }, { f: 6 }, { f: 7 }, { f: 13 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }, { f: 20 }] },
18
+ { f: 12, s: [{ f: 1 }, { f: 2 }, { f: 14, m: true }, { f: 15 }] },
19
+ { f: 18, s: [{ f: 6 }, { f: 16 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }] },
20
+ { f: 26, s: [{ f: 4 }, { f: 5 }, { f: 8 }, { f: 13 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }] },
21
+ { f: 28, s: [{ f: 1 }, { f: 2 }, { f: 4 }, { f: 5 }, { f: 6 }, { f: 7, s: [{ f: 21 }, { f: 22 }] }] },
22
+ { f: 37, s: [{ f: 1, m: true }] },
23
+ {
24
+ f: 49,
25
+ s: [
26
+ { f: 2 },
27
+ { f: 3, s: [{ f: 1 }, { f: 2 }] },
28
+ { f: 5, s: [{ f: 21 }, { f: 22 }] },
29
+ { f: 8, s: [{ f: 1 }, { f: 2 }] }
30
+ ]
31
+ },
32
+ { f: 53, s: [{ f: 1, m: true }] },
33
+ { f: 55, s: [{ f: 1, m: true }] },
34
+ { f: 58, s: [{ f: 1, m: true }] },
35
+ { f: 59, s: [{ f: 1, m: true }] },
36
+ {
37
+ f: 60,
38
+ s: [
39
+ { f: 2 },
40
+ { f: 3, s: [{ f: 1 }, { f: 2 }] },
41
+ { f: 5, s: [{ f: 21 }, { f: 22 }] },
42
+ { f: 8, s: [{ f: 1 }, { f: 2 }] }
43
+ ]
44
+ },
45
+ {
46
+ f: 64,
47
+ s: [
48
+ { f: 2 },
49
+ { f: 3, s: [{ f: 1 }, { f: 2 }] },
50
+ { f: 5, s: [{ f: 21 }, { f: 22 }] },
51
+ { f: 8, s: [{ f: 1 }, { f: 2 }] }
52
+ ]
53
+ },
54
+ { f: 66, s: [{ f: 2 }, { f: 6 }, { f: 7 }, { f: 13 }, { f: 17, s: [{ f: 21 }, { f: 22 }] }, { f: 20 }] },
55
+ { f: 74, s: [{ f: 1, m: true }] },
56
+ { f: 87, s: [{ f: 1, m: true }] },
57
+ { f: 88, s: [{ f: 1 }, { f: 2, s: [{ f: 1 }] }, { f: 3, s: [{ f: 21 }, { f: 22 }] }] },
58
+ { f: 92, s: [{ f: 1, m: true }] },
59
+ { f: 93, s: [{ f: 1, m: true }] },
60
+ { f: 94, s: [{ f: 1, m: true }] }
61
+ ]
62
+ const compileReportingFields = fields => {
63
+ const map = new Map()
64
+ for (const f of fields) {
65
+ map.set(f.f, {
66
+ m: f.m,
67
+ children: f.s ? compileReportingFields(f.s) : undefined
68
+ })
69
+ }
70
+ return map
71
+ }
72
+ const compiledReportingFields = compileReportingFields(reportingFields)
73
+ const EMPTY_MAP = new Map()
74
+ const ENC_SECRET_REPORT_TOKEN = 'Report Token'
75
+ const WIRE = {
76
+ VARINT: 0,
77
+ FIXED64: 1,
78
+ BYTES: 2,
79
+ FIXED32: 5
80
+ }
81
+ const shouldIncludeReportingToken = message =>
82
+ !message.reactionMessage &&
83
+ !message.encReactionMessage &&
84
+ !message.encEventResponseMessage &&
85
+ !message.pollUpdateMessage
86
+ exports.shouldIncludeReportingToken = shouldIncludeReportingToken
87
+ const generateMsgSecretKey = (modificationType, origMsgId, origMsgSender, modificationSender, origMsgSecret) => {
88
+ const useCaseSecret = Buffer.concat([
89
+ Buffer.from(origMsgId, 'utf8'),
90
+ Buffer.from(origMsgSender, 'utf8'),
91
+ Buffer.from(modificationSender, 'utf8'),
92
+ Buffer.from(modificationType, 'utf8')
93
+ ])
94
+ return (0, crypto_2.hkdf)(origMsgSecret, 32, { info: useCaseSecret.toString('latin1') })
95
+ }
96
+ const extractReportingTokenContent = (data, cfg) => {
97
+ const out = []
98
+ let i = 0
99
+ while (i < data.length) {
100
+ const tag = decodeVarint(data, i)
101
+ if (!tag.ok) {
102
+ return null
103
+ }
104
+ const fieldNum = tag.value >> 3
105
+ const wireType = tag.value & 0x7
106
+ const fieldStart = i
107
+ i += tag.bytes
108
+ const fieldCfg = cfg.get(fieldNum)
109
+ const pushSlice = end => {
110
+ if (end > data.length) {
111
+ return false
112
+ }
113
+ out.push({ num: fieldNum, bytes: data.subarray(fieldStart, end) })
114
+ i = end
115
+ return true
116
+ }
117
+ const skip = end => {
118
+ if (end > data.length) {
119
+ return false
120
+ }
121
+ i = end
122
+ return true
123
+ }
124
+ if (wireType === WIRE.VARINT) {
125
+ const v = decodeVarint(data, i)
126
+ if (!v.ok) {
127
+ return null
128
+ }
129
+ const end = i + v.bytes
130
+ if (!fieldCfg) {
131
+ if (!skip(end)) {
132
+ return null
133
+ }
134
+ continue
135
+ }
136
+ if (!pushSlice(end)) {
137
+ return null
138
+ }
139
+ continue
140
+ }
141
+ if (wireType === WIRE.FIXED64) {
142
+ const end = i + 8
143
+ if (!fieldCfg) {
144
+ if (!skip(end)) {
145
+ return null
146
+ }
147
+ continue
148
+ }
149
+ if (!pushSlice(end)) {
150
+ return null
151
+ }
152
+ continue
153
+ }
154
+ if (wireType === WIRE.FIXED32) {
155
+ const end = i + 4
156
+ if (!fieldCfg) {
157
+ if (!skip(end)) {
158
+ return null
159
+ }
160
+ continue
161
+ }
162
+ if (!pushSlice(end)) {
163
+ return null
164
+ }
165
+ continue
166
+ }
167
+ if (wireType === WIRE.BYTES) {
168
+ const len = decodeVarint(data, i)
169
+ if (!len.ok) {
170
+ return null
171
+ }
172
+ const valStart = i + len.bytes
173
+ const valEnd = valStart + len.value
174
+ if (valEnd > data.length) {
175
+ return null
176
+ }
177
+ if (!fieldCfg) {
178
+ i = valEnd
179
+ continue
180
+ }
181
+ if (fieldCfg.m || fieldCfg.children) {
182
+ const sub = extractReportingTokenContent(data.subarray(valStart, valEnd), fieldCfg.children ?? EMPTY_MAP)
183
+ if (sub === null) {
184
+ return null
185
+ }
186
+ if (sub.length > 0) {
187
+ const newTag = encodeVarint(tag.value)
188
+ const newLen = encodeVarint(sub.length)
189
+ out.push({
190
+ num: fieldNum,
191
+ bytes: Buffer.concat([newTag, newLen, sub])
192
+ })
193
+ }
194
+ i = valEnd
195
+ continue
196
+ }
197
+ out.push({ num: fieldNum, bytes: data.subarray(fieldStart, valEnd) })
198
+ i = valEnd
199
+ continue
200
+ }
201
+ return null
202
+ }
203
+ if (out.length === 0) {
204
+ return Buffer.alloc(0)
205
+ }
206
+ out.sort((a, b) => a.num - b.num)
207
+ return Buffer.concat(out.map(f => f.bytes))
208
+ }
209
+ const decodeVarint = (buffer, offset) => {
210
+ let value = 0
211
+ let bytes = 0
212
+ let shift = 0
213
+ while (offset + bytes < buffer.length) {
214
+ const current = buffer[offset + bytes]
215
+ value |= (current & 0x7f) << shift
216
+ bytes++
217
+ if ((current & 0x80) === 0) {
218
+ return { value, bytes, ok: true }
219
+ }
220
+ shift += 7
221
+ if (shift > 35) {
222
+ return { value: 0, bytes: 0, ok: false }
223
+ }
224
+ }
225
+ return { value: 0, bytes: 0, ok: false }
226
+ }
227
+ const encodeVarint = value => {
228
+ const parts = []
229
+ let remaining = value >>> 0
230
+ while (remaining > 0x7f) {
231
+ parts.push((remaining & 0x7f) | 0x80)
232
+ remaining >>>= 7
233
+ }
234
+ parts.push(remaining)
235
+ return Buffer.from(parts)
236
+ }
237
+ const getMessageReportingToken = async (msgProtobuf, message, key) => {
238
+ const msgSecret = message.messageContextInfo?.messageSecret
239
+ if (!msgSecret || !key.id) {
240
+ return null
241
+ }
242
+ const from = key.fromMe ? key.remoteJid : key.participant || key.remoteJid
243
+ const to = key.fromMe ? key.participant || key.remoteJid : key.remoteJid
244
+ const reportingSecret = generateMsgSecretKey(ENC_SECRET_REPORT_TOKEN, key.id, from, to, msgSecret)
245
+ const content = extractReportingTokenContent(msgProtobuf, compiledReportingFields)
246
+ if (!content || content.length === 0) {
247
+ return null
248
+ }
249
+ const reportingToken = Buffer.from(rb.hmacSign(content, reportingSecret)).subarray(0, 16)
250
+ return {
251
+ tag: 'reporting',
252
+ attrs: {},
253
+ content: [
254
+ {
255
+ tag: 'reporting_token',
256
+ attrs: { v: '2' },
257
+ content: reportingToken
258
+ }
259
+ ]
260
+ }
261
+ }
262
+ exports.getMessageReportingToken = getMessageReportingToken
@@ -0,0 +1,192 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.getNextPreKeysNode =
4
+ exports.getNextPreKeys =
5
+ exports.extractDeviceJids =
6
+ exports.parseAndInjectE2ESessions =
7
+ exports.xmppPreKey =
8
+ exports.xmppSignedPreKey =
9
+ exports.generateOrGetPreKeys =
10
+ exports.getPreKeys =
11
+ exports.createSignalIdentity =
12
+ void 0
13
+ const Defaults_1 = require('../Defaults')
14
+ const WABinary_1 = require('../WABinary')
15
+ const crypto_1 = require('./crypto')
16
+ const generics_1 = require('./generics')
17
+ function chunk(array, size) {
18
+ const chunks = []
19
+ for (let i = 0; i < array.length; i += size) {
20
+ chunks.push(array.slice(i, i + size))
21
+ }
22
+ return chunks
23
+ }
24
+ const createSignalIdentity = (wid, accountSignatureKey) => {
25
+ return {
26
+ identifier: { name: wid, deviceId: 0 },
27
+ identifierKey: (0, crypto_1.generateSignalPubKey)(accountSignatureKey)
28
+ }
29
+ }
30
+ exports.createSignalIdentity = createSignalIdentity
31
+ const getPreKeys = async ({ get }, min, limit) => {
32
+ const idList = []
33
+ for (let id = min; id < limit; id++) {
34
+ idList.push(id.toString())
35
+ }
36
+ return get('pre-key', idList)
37
+ }
38
+ exports.getPreKeys = getPreKeys
39
+ const generateOrGetPreKeys = (creds, range) => {
40
+ const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId
41
+ const remaining = range - avaliable
42
+ const lastPreKeyId = creds.nextPreKeyId + remaining - 1
43
+ const newPreKeys = {}
44
+ if (remaining > 0) {
45
+ for (let i = creds.nextPreKeyId; i <= lastPreKeyId; i++) {
46
+ newPreKeys[i] = crypto_1.Curve.generateKeyPair()
47
+ }
48
+ }
49
+ return {
50
+ newPreKeys,
51
+ lastPreKeyId,
52
+ preKeysRange: [creds.firstUnuploadedPreKeyId, range]
53
+ }
54
+ }
55
+ exports.generateOrGetPreKeys = generateOrGetPreKeys
56
+ // cipherSuite: 0x05 = X25519/Curve25519 (standard Signal), 0x2a = Kyber-1024 (PQXDH) —
57
+ // only pass it when mixing in a non-default cipher; omit for plain Curve25519 uploads.
58
+ const xmppSignedPreKey = (key, cipherSuite) => ({
59
+ tag: 'skey',
60
+ attrs: cipherSuite !== undefined ? { key_cipher_suite: cipherSuite } : {},
61
+ content: [
62
+ { tag: 'id', attrs: {}, content: (0, generics_1.encodeBigEndian)(key.keyId, 3) },
63
+ { tag: 'value', attrs: {}, content: key.keyPair.public },
64
+ { tag: 'signature', attrs: {}, content: key.signature }
65
+ ]
66
+ })
67
+ exports.xmppSignedPreKey = xmppSignedPreKey
68
+ const xmppPreKey = (pair, id, cipherSuite) => ({
69
+ tag: 'key',
70
+ attrs: cipherSuite !== undefined ? { key_cipher_suite: cipherSuite } : {},
71
+ content: [
72
+ { tag: 'id', attrs: {}, content: (0, generics_1.encodeBigEndian)(id, 3) },
73
+ { tag: 'value', attrs: {}, content: pair.public }
74
+ ]
75
+ })
76
+ exports.xmppPreKey = xmppPreKey
77
+ const parseAndInjectE2ESessions = async (node, repository) => {
78
+ const extractKey = key => {
79
+ if (!key) return undefined
80
+ const cipherSuite = key.attrs?.key_cipher_suite
81
+ return {
82
+ keyId: (0, WABinary_1.getBinaryNodeChildUInt)(key, 'id', 3),
83
+ publicKey: (0, crypto_1.generateSignalPubKey)((0, WABinary_1.getBinaryNodeChildBuffer)(key, 'value')),
84
+ signature: (0, WABinary_1.getBinaryNodeChildBuffer)(key, 'signature'),
85
+ // 0x05 = Curve25519 (standard Signal), 0x2a = Kyber-1024 (PQXDH)
86
+ ...(cipherSuite !== undefined ? { cipherSuite } : {})
87
+ }
88
+ }
89
+ const nodes = (0, WABinary_1.getBinaryNodeChildren)((0, WABinary_1.getBinaryNodeChild)(node, 'list'), 'user')
90
+ for (const node of nodes) {
91
+ ;(0, WABinary_1.assertNodeErrorFree)(node)
92
+ }
93
+ // Most of the work in repository.injectE2ESession is CPU intensive, not IO
94
+ // So Promise.all doesn't really help here,
95
+ // but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
96
+ // This way we chunk it in smaller parts and between those parts we can yield to the event loop
97
+ // It's rare case when you need to E2E sessions for so many users, but it's possible
98
+ const chunkSize = 100
99
+ const chunks = chunk(nodes, chunkSize)
100
+ for (const nodesChunk of chunks) {
101
+ for (const node of nodesChunk) {
102
+ const signedKey = (0, WABinary_1.getBinaryNodeChild)(node, 'skey')
103
+ const key = (0, WABinary_1.getBinaryNodeChild)(node, 'key')
104
+ const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(node, 'identity')
105
+ const jid = node.attrs.jid
106
+ const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(node, 'registration', 4)
107
+ await repository.injectE2ESession({
108
+ jid,
109
+ session: {
110
+ registrationId: registrationId,
111
+ identityKey: (0, crypto_1.generateSignalPubKey)(identity),
112
+ signedPreKey: extractKey(signedKey),
113
+ preKey: extractKey(key)
114
+ }
115
+ })
116
+ }
117
+ }
118
+ }
119
+ exports.parseAndInjectE2ESessions = parseAndInjectE2ESessions
120
+ const extractDeviceJids = (result, myJid, myLid, excludeZeroDevices) => {
121
+ const { user: myUser, device: myDevice } = (0, WABinary_1.jidDecode)(myJid)
122
+ const extracted = []
123
+ for (const userResult of result) {
124
+ const { devices, id } = userResult
125
+ const decoded = (0, WABinary_1.jidDecode)(id),
126
+ { user, server } = decoded
127
+ let { domainType } = decoded
128
+ const deviceList = devices?.deviceList
129
+ if (!Array.isArray(deviceList)) continue
130
+ for (const { id: device, keyIndex, isHosted } of deviceList) {
131
+ if (
132
+ (!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
133
+ ((myUser !== user && myLid !== user) || myDevice !== device) && // either different user or if me user, not this device
134
+ (device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
135
+ ) {
136
+ if (isHosted) {
137
+ domainType =
138
+ domainType === WABinary_1.WAJIDDomains.LID
139
+ ? WABinary_1.WAJIDDomains.HOSTED_LID
140
+ : WABinary_1.WAJIDDomains.HOSTED
141
+ }
142
+ extracted.push({
143
+ user,
144
+ device,
145
+ domainType,
146
+ server: (0, WABinary_1.getServerFromDomainType)(server, domainType)
147
+ })
148
+ }
149
+ }
150
+ }
151
+ return extracted
152
+ }
153
+ exports.extractDeviceJids = extractDeviceJids
154
+ /**
155
+ * get the next N keys for upload or processing
156
+ * @param count number of pre-keys to get or generate
157
+ */
158
+ const getNextPreKeys = async ({ creds, keys }, count) => {
159
+ const { newPreKeys, lastPreKeyId, preKeysRange } = (0, exports.generateOrGetPreKeys)(creds, count)
160
+ const update = {
161
+ nextPreKeyId: Math.max(lastPreKeyId + 1, creds.nextPreKeyId),
162
+ firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId + 1)
163
+ }
164
+ await keys.set({ 'pre-key': newPreKeys })
165
+ const preKeys = await (0, exports.getPreKeys)(keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1])
166
+ return { update, preKeys }
167
+ }
168
+ exports.getNextPreKeys = getNextPreKeys
169
+ const getNextPreKeysNode = async (state, count) => {
170
+ const { creds } = state
171
+ const { update, preKeys } = await (0, exports.getNextPreKeys)(state, count)
172
+ const node = {
173
+ tag: 'iq',
174
+ attrs: {
175
+ xmlns: 'encrypt',
176
+ type: 'set',
177
+ to: WABinary_1.S_WHATSAPP_NET
178
+ },
179
+ content: [
180
+ { tag: 'registration', attrs: {}, content: (0, generics_1.encodeBigEndian)(creds.registrationId) },
181
+ { tag: 'type', attrs: {}, content: Defaults_1.KEY_BUNDLE_TYPE },
182
+ { tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
183
+ // key_cipher_suite is only sent when the bundle mixes in a non-default cipher
184
+ // (e.g. Kyber/PQXDH alongside Curve25519) — a plain Curve25519-only upload
185
+ // omits it entirely on real clients, confirmed against live capture.
186
+ { tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => (0, exports.xmppPreKey)(preKeys[+k], +k)) },
187
+ (0, exports.xmppSignedPreKey)(creds.signedPreKey)
188
+ ]
189
+ }
190
+ return { update, node }
191
+ }
192
+ exports.getNextPreKeysNode = getNextPreKeysNode
@@ -0,0 +1,74 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.buildAckStanza = buildAckStanza
4
+ // Standalone call stanzas use class="call" + type=<tag>, not class=<tag>.
5
+ // Kept in sync with messages-recv.js's CALL_STATE_TAGS + CB: registration loop.
6
+ const CALL_STANZA_TAGS = new Set([
7
+ 'offer',
8
+ 'offer_notice',
9
+ 'terminate',
10
+ 'accept',
11
+ 'reject',
12
+ 'preaccept',
13
+ 'transport',
14
+ 'video',
15
+ 'duration',
16
+ 'mute_v2',
17
+ 'lobby',
18
+ 'heartbeat',
19
+ 'relaylatency',
20
+ 'link_query',
21
+ 'group_update',
22
+ 'accept_ack',
23
+ 'enc-rekey',
24
+ 'enc_rekey',
25
+ 'peer_state',
26
+ 'group_info',
27
+ 'video_state',
28
+ 'video_state_ack',
29
+ 'flow_control',
30
+ 'waiting_room_request'
31
+ ])
32
+ /**
33
+ * Builds an ACK stanza for a received node.
34
+ * Pure function -- no I/O, no side effects.
35
+ *
36
+ * Mirrors WhatsApp Web's ACK construction:
37
+ * - WAWebHandleMsgSendAck.sendAck / sendNack
38
+ * - WAWebCreateNackFromStanza.createNackFromStanza
39
+ */
40
+ function buildAckStanza(node, errorCode, meId) {
41
+ const { tag, attrs } = node
42
+ const isCallStanza = CALL_STANZA_TAGS.has(tag)
43
+ const stanza = {
44
+ tag: 'ack',
45
+ attrs: {
46
+ id: attrs.id,
47
+ to: attrs.from,
48
+ class: isCallStanza ? 'call' : tag
49
+ }
50
+ }
51
+ // For standalone call stanzas, WA Web puts the original tag into `type`
52
+ if (isCallStanza) {
53
+ stanza.attrs.type = tag
54
+ }
55
+ if (errorCode) {
56
+ stanza.attrs.error = errorCode.toString()
57
+ }
58
+ if (attrs.participant) {
59
+ stanza.attrs.participant = attrs.participant
60
+ }
61
+ if (attrs.recipient) {
62
+ stanza.attrs.recipient = attrs.recipient
63
+ }
64
+ // WA Web always includes type when present: `n.type || DROP_ATTR`
65
+ // For call stanzas the type is already set to the tag name above; don't override it.
66
+ if (attrs.type && !isCallStanza) {
67
+ stanza.attrs.type = attrs.type
68
+ }
69
+ // WA Web WAWebHandleMsgSendAck.sendAck/sendNack always include `from` for message-class ACKs
70
+ if (tag === 'message' && meId) {
71
+ stanza.attrs.from = meId
72
+ }
73
+ return stanza
74
+ }
@@ -0,0 +1,54 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.emitSyncActionResults = exports.processContactAction = void 0
4
+ const WABinary_1 = require('../WABinary')
5
+ /**
6
+ * Process contactAction and return events to emit.
7
+ * Pure function - no side effects.
8
+ */
9
+ const processContactAction = (action, id, logger) => {
10
+ const results = []
11
+ if (!id) {
12
+ logger?.warn(
13
+ { hasFullName: !!action.fullName, hasLidJid: !!action.lidJid, hasPnJid: !!action.pnJid },
14
+ 'contactAction sync: missing id in index'
15
+ )
16
+ return results
17
+ }
18
+ const lidJid = action.lidJid
19
+ const idIsPn = (0, WABinary_1.isPnUser)(id)
20
+ // PN is in index[1], not in contactAction.pnJid which is usually null
21
+ const phoneNumber = idIsPn ? id : action.pnJid || undefined
22
+ // Always emit contacts.upsert
23
+ results.push({
24
+ event: 'contacts.upsert',
25
+ data: [
26
+ {
27
+ id,
28
+ name: action.fullName || action.firstName || action.username || undefined,
29
+ username: action.username || undefined,
30
+ lid: lidJid || undefined,
31
+ phoneNumber
32
+ }
33
+ ]
34
+ })
35
+ // Emit lid-mapping.update if we have valid LID-PN pair
36
+ if (lidJid && (0, WABinary_1.isLidUser)(lidJid) && idIsPn) {
37
+ results.push({
38
+ event: 'lid-mapping.update',
39
+ data: { lid: lidJid, pn: id }
40
+ })
41
+ }
42
+ return results
43
+ }
44
+ exports.processContactAction = processContactAction
45
+ const emitSyncActionResults = (ev, results) => {
46
+ for (const result of results) {
47
+ if (result.event === 'contacts.upsert') {
48
+ ev.emit('contacts.upsert', result.data)
49
+ } else {
50
+ ev.emit('lid-mapping.update', result.data)
51
+ }
52
+ }
53
+ }
54
+ exports.emitSyncActionResults = emitSyncActionResults