@badzz88/baileys 8.4.6 → 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 (250) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1055 -337
  3. package/WAProto/WAProto.proto +850 -32
  4. package/WAProto/index.d.ts +4913 -25
  5. package/WAProto/index.js +14074 -98
  6. package/package.json +96 -131
  7. package/src/Defaults/index.js +201 -0
  8. package/src/Defaults/phonenumber-mcc.json +223 -0
  9. package/src/Signal/Group/ciphertext-message.js +15 -0
  10. package/src/Signal/Group/group-session-builder.js +92 -0
  11. package/src/Signal/Group/group_cipher.js +89 -0
  12. package/src/Signal/Group/index.js +136 -0
  13. package/src/Signal/Group/keyhelper.js +73 -0
  14. package/src/Signal/Group/sender-chain-key.js +32 -0
  15. package/src/Signal/Group/sender-key-distribution-message.js +66 -0
  16. package/src/Signal/Group/sender-key-message.js +69 -0
  17. package/src/Signal/Group/sender-key-name.js +50 -0
  18. package/src/Signal/Group/sender-key-record.js +44 -0
  19. package/src/Signal/Group/sender-key-state.js +97 -0
  20. package/src/Signal/Group/sender-message-key.js +30 -0
  21. package/src/Signal/libsignal.js +470 -0
  22. package/src/Signal/lid-mapping.js +262 -0
  23. package/src/Socket/Client/index.js +30 -0
  24. package/src/Socket/Client/types.js +13 -0
  25. package/src/Socket/Client/websocket.js +62 -0
  26. package/src/Socket/aigroups.js +240 -0
  27. package/src/Socket/business.js +422 -0
  28. package/src/Socket/chats.js +2374 -0
  29. package/src/Socket/communities.js +580 -0
  30. package/src/Socket/graphql.js +915 -0
  31. package/src/Socket/groups.js +812 -0
  32. package/src/Socket/index.js +37 -0
  33. package/src/Socket/interactive-handler.js +579 -0
  34. package/src/Socket/interop.js +566 -0
  35. package/src/Socket/managed-account.js +214 -0
  36. package/src/Socket/messages-recv.js +3012 -0
  37. package/src/Socket/messages-send.js +2163 -0
  38. package/{lib → src}/Socket/mex.js +11 -5
  39. package/src/Socket/newsletter.js +1057 -0
  40. package/src/Socket/privacy.js +452 -0
  41. package/src/Socket/registration.js +434 -0
  42. package/src/Socket/socket.js +1079 -0
  43. package/src/Socket/text-router.js +67 -0
  44. package/src/Socket/username.js +234 -0
  45. package/src/Store/index.js +36 -0
  46. package/src/Store/make-cache-manager-store.js +90 -0
  47. package/src/Store/make-in-memory-store.js +506 -0
  48. package/src/Store/make-ordered-dictionary.js +81 -0
  49. package/src/Store/object-repository.js +29 -0
  50. package/src/Types/Auth.js +38 -0
  51. package/src/Types/Bussines.js +2 -0
  52. package/src/Types/Call.js +2 -0
  53. package/src/Types/Chat.js +4 -0
  54. package/src/Types/Contact.js +2 -0
  55. package/src/Types/Events.js +2 -0
  56. package/src/Types/GroupMetadata.js +2 -0
  57. package/src/Types/Label.js +27 -0
  58. package/src/Types/LabelAssociation.js +9 -0
  59. package/src/Types/Message.js +95 -0
  60. package/src/Types/Newsletter.js +152 -0
  61. package/src/Types/Product.js +2 -0
  62. package/src/Types/Signal.js +2 -0
  63. package/src/Types/Socket.js +2 -0
  64. package/src/Types/State.js +70 -0
  65. package/src/Types/USync.js +2 -0
  66. package/src/Types/index.js +54 -0
  67. package/src/Utils/auth-utils.js +306 -0
  68. package/src/Utils/browser-utils.js +114 -0
  69. package/src/Utils/business.js +247 -0
  70. package/src/Utils/chat-utils.js +1272 -0
  71. package/src/Utils/consumer-application.js +107 -0
  72. package/src/Utils/crypto.js +125 -0
  73. package/src/Utils/decode-wa-message.js +808 -0
  74. package/src/Utils/event-buffer.js +586 -0
  75. package/src/Utils/generics.js +640 -0
  76. package/src/Utils/group-history.js +60 -0
  77. package/src/Utils/history.js +244 -0
  78. package/src/Utils/identity-change-handler.js +52 -0
  79. package/src/Utils/index.js +53 -0
  80. package/src/Utils/jid-display-normalization.js +218 -0
  81. package/src/Utils/link-preview.js +143 -0
  82. package/src/Utils/logger.js +9 -0
  83. package/src/Utils/lt-hash.js +10 -0
  84. package/src/Utils/make-mutex.js +36 -0
  85. package/src/Utils/message-composer.js +479 -0
  86. package/src/Utils/message-inspect.js +400 -0
  87. package/src/Utils/message-retry-manager.js +231 -0
  88. package/src/Utils/messages-media.js +943 -0
  89. package/src/Utils/messages.js +2490 -0
  90. package/src/Utils/meta-ai-msmsg.js +133 -0
  91. package/src/Utils/noise-handler.js +194 -0
  92. package/src/Utils/offline-node-processor.js +42 -0
  93. package/src/Utils/pre-key-manager.js +107 -0
  94. package/src/Utils/process-message.js +1047 -0
  95. package/src/Utils/reporting-utils.js +262 -0
  96. package/src/Utils/signal.js +192 -0
  97. package/src/Utils/stanza-ack.js +74 -0
  98. package/src/Utils/sync-action-utils.js +54 -0
  99. package/src/Utils/tc-token-utils.js +161 -0
  100. package/src/Utils/use-multi-file-auth-state.js +121 -0
  101. package/src/Utils/validate-connection.js +248 -0
  102. package/src/Utils/voip-rekey.js +22 -0
  103. package/src/WABinary/constants.js +1304 -0
  104. package/src/WABinary/decode.js +377 -0
  105. package/src/WABinary/encode.js +58 -0
  106. package/src/WABinary/generic-utils.js +148 -0
  107. package/src/WABinary/index.js +33 -0
  108. package/src/WABinary/jid-utils.js +374 -0
  109. package/src/WABinary/types.js +2 -0
  110. package/src/WAM/BinaryInfo.js +13 -0
  111. package/src/WAM/constants.js +39486 -0
  112. package/src/WAM/encode.js +142 -0
  113. package/src/WAM/index.js +31 -0
  114. package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +55 -0
  115. package/src/WAUSync/Protocols/USyncBusinessProtocol.js +100 -0
  116. package/src/WAUSync/Protocols/USyncContactProtocol.js +60 -0
  117. package/src/WAUSync/Protocols/USyncDeviceProtocol.js +65 -0
  118. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  119. package/src/WAUSync/Protocols/USyncFeatureProtocol.js +74 -0
  120. package/src/WAUSync/Protocols/USyncLIDProtocol.js +31 -0
  121. package/src/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
  122. package/src/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
  123. package/src/WAUSync/Protocols/USyncStatusProtocol.js +44 -0
  124. package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  125. package/src/WAUSync/Protocols/USyncUsernameProtocol.js +28 -0
  126. package/src/WAUSync/Protocols/index.js +40 -0
  127. package/src/WAUSync/USyncBackoff.js +31 -0
  128. package/src/WAUSync/USyncQuery.js +204 -0
  129. package/src/WAUSync/USyncUser.js +58 -0
  130. package/src/WAUSync/index.js +32 -0
  131. package/src/antiban.js +4726 -0
  132. package/{lib → src}/index.js +48 -16
  133. package/lib/Defaults/baileys-version.json +0 -3
  134. package/lib/Defaults/index.js +0 -137
  135. package/lib/Defaults/phonenumber-mcc.json +0 -223
  136. package/lib/Signal/Group/Protocols.js +0 -269
  137. package/lib/Signal/Group/ciphertext-message.js +0 -12
  138. package/lib/Signal/Group/group-session-builder.js +0 -30
  139. package/lib/Signal/Group/group_cipher.js +0 -82
  140. package/lib/Signal/Group/index.js +0 -12
  141. package/lib/Signal/Group/keyhelper.js +0 -18
  142. package/lib/Signal/Group/queue-job.js +0 -57
  143. package/lib/Signal/Group/sender-chain-key.js +0 -26
  144. package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
  145. package/lib/Signal/Group/sender-key-message.js +0 -66
  146. package/lib/Signal/Group/sender-key-name.js +0 -48
  147. package/lib/Signal/Group/sender-key-record.js +0 -41
  148. package/lib/Signal/Group/sender-key-state.js +0 -84
  149. package/lib/Signal/Group/sender-message-key.js +0 -26
  150. package/lib/Signal/libsignal.js +0 -432
  151. package/lib/Signal/lid-mapping.js +0 -277
  152. package/lib/Socket/Client/abstract-socket-client.js +0 -13
  153. package/lib/Socket/Client/index.js +0 -3
  154. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  155. package/lib/Socket/Client/types.js +0 -11
  156. package/lib/Socket/Client/web-socket-client.js +0 -62
  157. package/lib/Socket/Client/websocket.js +0 -54
  158. package/lib/Socket/business.js +0 -379
  159. package/lib/Socket/chats.js +0 -1193
  160. package/lib/Socket/communities.js +0 -431
  161. package/lib/Socket/community.js +0 -392
  162. package/lib/Socket/dugong.js +0 -637
  163. package/lib/Socket/groups.js +0 -374
  164. package/lib/Socket/index.js +0 -12
  165. package/lib/Socket/luxu.js +0 -387
  166. package/lib/Socket/messages-recv.js +0 -1916
  167. package/lib/Socket/messages-send.js +0 -1459
  168. package/lib/Socket/newsletter.js +0 -253
  169. package/lib/Socket/registration.js +0 -167
  170. package/lib/Socket/socket.js +0 -950
  171. package/lib/Socket/username.js +0 -146
  172. package/lib/Socket/usync.js +0 -69
  173. package/lib/Store/index.js +0 -10
  174. package/lib/Store/keyed-db.js +0 -108
  175. package/lib/Store/make-cache-manager-store.js +0 -85
  176. package/lib/Store/make-in-memory-store.js +0 -198
  177. package/lib/Store/make-ordered-dictionary.js +0 -75
  178. package/lib/Store/object-repository.js +0 -32
  179. package/lib/Types/Auth.js +0 -2
  180. package/lib/Types/Bussines.js +0 -2
  181. package/lib/Types/Call.js +0 -2
  182. package/lib/Types/Chat.js +0 -8
  183. package/lib/Types/Contact.js +0 -2
  184. package/lib/Types/Events.js +0 -2
  185. package/lib/Types/GroupMetadata.js +0 -2
  186. package/lib/Types/Label.js +0 -25
  187. package/lib/Types/LabelAssociation.js +0 -7
  188. package/lib/Types/Message.js +0 -11
  189. package/lib/Types/Mex.js +0 -37
  190. package/lib/Types/Newsletter.js +0 -38
  191. package/lib/Types/Product.js +0 -2
  192. package/lib/Types/Signal.js +0 -2
  193. package/lib/Types/Socket.js +0 -3
  194. package/lib/Types/State.js +0 -56
  195. package/lib/Types/USync.js +0 -2
  196. package/lib/Types/index.js +0 -26
  197. package/lib/Utils/auth-utils.js +0 -302
  198. package/lib/Utils/baileys-event-stream.js +0 -63
  199. package/lib/Utils/browser-utils.js +0 -48
  200. package/lib/Utils/business.js +0 -231
  201. package/lib/Utils/chat-utils.js +0 -873
  202. package/lib/Utils/companion-reg-client-utils.js +0 -35
  203. package/lib/Utils/crypto.js +0 -118
  204. package/lib/Utils/decode-wa-message.js +0 -350
  205. package/lib/Utils/event-buffer.js +0 -622
  206. package/lib/Utils/generics.js +0 -399
  207. package/lib/Utils/history.js +0 -134
  208. package/lib/Utils/identity-change-handler.js +0 -50
  209. package/lib/Utils/index.js +0 -23
  210. package/lib/Utils/link-preview.js +0 -85
  211. package/lib/Utils/logger.js +0 -3
  212. package/lib/Utils/lt-hash.js +0 -8
  213. package/lib/Utils/make-mutex.js +0 -33
  214. package/lib/Utils/message-composer.js +0 -273
  215. package/lib/Utils/message-retry-manager.js +0 -265
  216. package/lib/Utils/messages-media.js +0 -788
  217. package/lib/Utils/messages.js +0 -1260
  218. package/lib/Utils/noise-handler.js +0 -201
  219. package/lib/Utils/offline-node-processor.js +0 -40
  220. package/lib/Utils/pre-key-manager.js +0 -106
  221. package/lib/Utils/process-message.js +0 -630
  222. package/lib/Utils/reporting-utils.js +0 -258
  223. package/lib/Utils/signal.js +0 -202
  224. package/lib/Utils/stanza-ack.js +0 -38
  225. package/lib/Utils/sync-action-utils.js +0 -49
  226. package/lib/Utils/tc-token-utils.js +0 -163
  227. package/lib/Utils/use-multi-file-auth-state.js +0 -121
  228. package/lib/Utils/validate-connection.js +0 -204
  229. package/lib/WABinary/constants.js +0 -1301
  230. package/lib/WABinary/decode.js +0 -262
  231. package/lib/WABinary/encode.js +0 -220
  232. package/lib/WABinary/generic-utils.js +0 -204
  233. package/lib/WABinary/index.js +0 -6
  234. package/lib/WABinary/jid-utils.js +0 -98
  235. package/lib/WABinary/types.js +0 -2
  236. package/lib/WAM/BinaryInfo.js +0 -10
  237. package/lib/WAM/constants.js +0 -22853
  238. package/lib/WAM/encode.js +0 -150
  239. package/lib/WAM/index.js +0 -4
  240. package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -52
  241. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -54
  242. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -27
  243. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -38
  244. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
  245. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -51
  246. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -29
  247. package/lib/WAUSync/Protocols/index.js +0 -6
  248. package/lib/WAUSync/USyncQuery.js +0 -98
  249. package/lib/WAUSync/USyncUser.js +0 -31
  250. 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