@celestial-community/baileys 0.0.1-security → 1.0.0

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.

Potentially problematic release.


This version of @celestial-community/baileys might be problematic. Click here for more details.

Files changed (175) hide show
  1. package/WAProto/index.js +138933 -0
  2. package/engine-requirements.js +10 -0
  3. package/lib/Defaults/baileys-version.json +7 -0
  4. package/lib/Defaults/index.js +157 -0
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.js +94 -0
  8. package/lib/Signal/Group/group_cipher.js +118 -0
  9. package/lib/Signal/Group/index.js +138 -0
  10. package/lib/Signal/Group/keyhelper.js +75 -0
  11. package/lib/Signal/Group/queue-job.js +54 -0
  12. package/lib/Signal/Group/sender-chain-key.js +39 -0
  13. package/lib/Signal/Group/sender-key-distribution-message.js +71 -0
  14. package/lib/Signal/Group/sender-key-message.js +76 -0
  15. package/lib/Signal/Group/sender-key-name.js +50 -0
  16. package/lib/Signal/Group/sender-key-record.js +65 -0
  17. package/lib/Signal/Group/sender-key-state.js +114 -0
  18. package/lib/Signal/Group/sender-message-key.js +33 -0
  19. package/lib/Signal/libsignal.js +204 -0
  20. package/lib/Signal/lid-mapping.js +267 -0
  21. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  22. package/lib/Socket/Client/index.js +32 -0
  23. package/lib/Socket/Client/mobile-socket-client.js +82 -0
  24. package/lib/Socket/Client/web-socket-client.js +89 -0
  25. package/lib/Socket/Denzy-ZeroDay.js +805 -0
  26. package/lib/Socket/business.js +279 -0
  27. package/lib/Socket/chats.js +1169 -0
  28. package/lib/Socket/community.d.ts +120 -0
  29. package/lib/Socket/community.js +388 -0
  30. package/lib/Socket/graphql.js +1122 -0
  31. package/lib/Socket/groups.js +345 -0
  32. package/lib/Socket/index.js +22 -0
  33. package/lib/Socket/interop.js +265 -0
  34. package/lib/Socket/lid-mapping.js +111 -0
  35. package/lib/Socket/messages-recv.js +1385 -0
  36. package/lib/Socket/messages-send.js +956 -0
  37. package/lib/Socket/mex.js +69 -0
  38. package/lib/Socket/newsletter.js +424 -0
  39. package/lib/Socket/privacy.js +229 -0
  40. package/lib/Socket/registration.js +190 -0
  41. package/lib/Socket/socket.js +783 -0
  42. package/lib/Socket/username.d.ts +185 -0
  43. package/lib/Socket/username.js +168 -0
  44. package/lib/Socket/usync.js +80 -0
  45. package/lib/Store/index.js +14 -0
  46. package/lib/Store/keyed-db.js +158 -0
  47. package/lib/Store/make-cache-manager-store.js +88 -0
  48. package/lib/Store/make-in-memory-store.js +484 -0
  49. package/lib/Store/make-ordered-dictionary.js +78 -0
  50. package/lib/Store/object-repository.js +27 -0
  51. package/lib/Types/Auth.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +10 -0
  54. package/lib/Types/Contact.js +2 -0
  55. package/lib/Types/Events.js +2 -0
  56. package/lib/Types/GroupMetadata.js +2 -0
  57. package/lib/Types/Label.js +27 -0
  58. package/lib/Types/LabelAssociation.js +9 -0
  59. package/lib/Types/Message.js +14 -0
  60. package/lib/Types/MexUpdates.js +19 -0
  61. package/lib/Types/Newsletter.js +38 -0
  62. package/lib/Types/Product.js +2 -0
  63. package/lib/Types/RichType.js +30 -0
  64. package/lib/Types/Signal.js +2 -0
  65. package/lib/Types/Socket.js +2 -0
  66. package/lib/Types/State.js +2 -0
  67. package/lib/Types/USync.js +2 -0
  68. package/lib/Types/index.js +58 -0
  69. package/lib/Utils/anti-ban.js +339 -0
  70. package/lib/Utils/anti-delete.d.ts +158 -0
  71. package/lib/Utils/anti-delete.js +293 -0
  72. package/lib/Utils/antiban-presets.js +91 -0
  73. package/lib/Utils/antiban-profiles.js +43 -0
  74. package/lib/Utils/auth-utils.js +210 -0
  75. package/lib/Utils/baileys-event-stream.js +66 -0
  76. package/lib/Utils/browser-utils.js +52 -0
  77. package/lib/Utils/business.js +261 -0
  78. package/lib/Utils/chat-control.d.ts +113 -0
  79. package/lib/Utils/chat-control.js +230 -0
  80. package/lib/Utils/chat-utils.js +922 -0
  81. package/lib/Utils/companion-reg-client-utils.js +37 -0
  82. package/lib/Utils/contact-graph-warmer.js +208 -0
  83. package/lib/Utils/crypto.js +196 -0
  84. package/lib/Utils/decode-wa-message.js +208 -0
  85. package/lib/Utils/delivery-tracker.js +110 -0
  86. package/lib/Utils/device-fingerprint.js +135 -0
  87. package/lib/Utils/event-buffer.js +531 -0
  88. package/lib/Utils/generics.js +571 -0
  89. package/lib/Utils/group-operation-guard.js +147 -0
  90. package/lib/Utils/health-monitor.js +207 -0
  91. package/lib/Utils/history.js +122 -0
  92. package/lib/Utils/human-entropy.js +226 -0
  93. package/lib/Utils/identity-change-handler.js +72 -0
  94. package/lib/Utils/index.js +83 -0
  95. package/lib/Utils/interactive-message.d.ts +139 -0
  96. package/lib/Utils/interactive-message.js +273 -0
  97. package/lib/Utils/legitimacy-signal-injector.js +180 -0
  98. package/lib/Utils/link-preview.js +106 -0
  99. package/lib/Utils/logger.d.ts +13 -0
  100. package/lib/Utils/logger.js +9 -0
  101. package/lib/Utils/lt-hash.js +54 -0
  102. package/lib/Utils/make-mutex.js +41 -0
  103. package/lib/Utils/message-composer.d.ts +106 -0
  104. package/lib/Utils/message-composer.js +721 -0
  105. package/lib/Utils/message-retry-manager.d.ts +88 -0
  106. package/lib/Utils/message-retry-manager.js +160 -0
  107. package/lib/Utils/message-search.d.ts +52 -0
  108. package/lib/Utils/message-search.js +226 -0
  109. package/lib/Utils/messages-media.js +899 -0
  110. package/lib/Utils/messages.js +2698 -0
  111. package/lib/Utils/noise-handler.js +175 -0
  112. package/lib/Utils/offline-node-processor.js +45 -0
  113. package/lib/Utils/pre-key-manager.js +131 -0
  114. package/lib/Utils/presence-choreographer.js +438 -0
  115. package/lib/Utils/process-message.js +423 -0
  116. package/lib/Utils/rate-limiter.js +232 -0
  117. package/lib/Utils/reconnect-throttle.js +157 -0
  118. package/lib/Utils/reply-ratio-guard.js +137 -0
  119. package/lib/Utils/reporting-utils.js +307 -0
  120. package/lib/Utils/retry-reason-tracker.js +140 -0
  121. package/lib/Utils/rich-message-utils.d.ts +48 -0
  122. package/lib/Utils/rich-message-utils.js +400 -0
  123. package/lib/Utils/rich-response-utils.js +461 -0
  124. package/lib/Utils/scheduling.d.ts +135 -0
  125. package/lib/Utils/scheduling.js +246 -0
  126. package/lib/Utils/session-fingerprint.js +226 -0
  127. package/lib/Utils/session-stability.js +224 -0
  128. package/lib/Utils/signal.js +188 -0
  129. package/lib/Utils/stanza-ack.js +38 -0
  130. package/lib/Utils/state-manager.js +91 -0
  131. package/lib/Utils/status-posting.d.ts +81 -0
  132. package/lib/Utils/status-posting.js +187 -0
  133. package/lib/Utils/stealth-connect.js +124 -0
  134. package/lib/Utils/sync-action-utils.js +55 -0
  135. package/lib/Utils/tc-token-utils.js +171 -0
  136. package/lib/Utils/templates.d.ts +54 -0
  137. package/lib/Utils/templates.js +244 -0
  138. package/lib/Utils/timelock-guard.js +162 -0
  139. package/lib/Utils/use-mongo-file-auth-state.d.ts +6 -0
  140. package/lib/Utils/use-mongo-file-auth-state.js +81 -0
  141. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  142. package/lib/Utils/use-single-file-auth-state.d.ts +13 -0
  143. package/lib/Utils/use-single-file-auth-state.js +86 -0
  144. package/lib/Utils/use-sqlite-auth-state.js +187 -0
  145. package/lib/Utils/vCard.d.ts +71 -0
  146. package/lib/Utils/vCard.js +196 -0
  147. package/lib/Utils/validate-connection.js +253 -0
  148. package/lib/Utils/warmup.js +154 -0
  149. package/lib/WABinary/constants.js +1303 -0
  150. package/lib/WABinary/decode.js +270 -0
  151. package/lib/WABinary/encode.js +279 -0
  152. package/lib/WABinary/generic-utils.js +223 -0
  153. package/lib/WABinary/index.js +34 -0
  154. package/lib/WABinary/jid-utils.js +84 -0
  155. package/lib/WABinary/types.js +2 -0
  156. package/lib/WAM/BinaryInfo.js +13 -0
  157. package/lib/WAM/constants.js +15254 -0
  158. package/lib/WAM/encode.js +149 -0
  159. package/lib/WAM/index.js +32 -0
  160. package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -0
  161. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +71 -0
  162. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +32 -0
  163. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +49 -0
  164. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
  165. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +58 -0
  166. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  167. package/lib/WAUSync/Protocols/index.js +34 -0
  168. package/lib/WAUSync/USyncQuery.js +99 -0
  169. package/lib/WAUSync/USyncUser.js +26 -0
  170. package/lib/WAUSync/USyncUsernameProtocol.d.ts +9 -0
  171. package/lib/WAUSync/USyncUsernameProtocol.js +37 -0
  172. package/lib/WAUSync/index.js +32 -0
  173. package/lib/index.js +59 -0
  174. package/package.json +105 -5
  175. package/README.md +0 -5
@@ -0,0 +1,37 @@
1
+ export var CompanionWebClientType
2
+ ;(function (CompanionWebClientType) {
3
+ CompanionWebClientType[(CompanionWebClientType['UNKNOWN'] = 0)] = 'UNKNOWN'
4
+ CompanionWebClientType[(CompanionWebClientType['CHROME'] = 1)] = 'CHROME'
5
+ CompanionWebClientType[(CompanionWebClientType['EDGE'] = 2)] = 'EDGE'
6
+ CompanionWebClientType[(CompanionWebClientType['FIREFOX'] = 3)] = 'FIREFOX'
7
+ CompanionWebClientType[(CompanionWebClientType['IE'] = 4)] = 'IE'
8
+ CompanionWebClientType[(CompanionWebClientType['OPERA'] = 5)] = 'OPERA'
9
+ CompanionWebClientType[(CompanionWebClientType['SAFARI'] = 6)] = 'SAFARI'
10
+ CompanionWebClientType[(CompanionWebClientType['ELECTRON'] = 7)] = 'ELECTRON'
11
+ CompanionWebClientType[(CompanionWebClientType['UWP'] = 8)] = 'UWP'
12
+ CompanionWebClientType[(CompanionWebClientType['OTHER_WEB_CLIENT'] = 9)] = 'OTHER_WEB_CLIENT'
13
+ })(CompanionWebClientType || (CompanionWebClientType = {}))
14
+ const BROWSER_TO_COMPANION_WEB_CLIENT = {
15
+ Chrome: CompanionWebClientType.CHROME,
16
+ Edge: CompanionWebClientType.EDGE,
17
+ Firefox: CompanionWebClientType.FIREFOX,
18
+ IE: CompanionWebClientType.IE,
19
+ Opera: CompanionWebClientType.OPERA,
20
+ Safari: CompanionWebClientType.SAFARI
21
+ }
22
+ const getCompanionWebClientType = ([os, browserName]) => {
23
+ if (browserName === 'Desktop') {
24
+ return os === 'Windows' ? CompanionWebClientType.UWP : CompanionWebClientType.ELECTRON
25
+ }
26
+ return BROWSER_TO_COMPANION_WEB_CLIENT[browserName] || CompanionWebClientType.OTHER_WEB_CLIENT
27
+ }
28
+ const getCompanionPlatformId = (browser) => {
29
+ return getCompanionWebClientType(browser).toString()
30
+ }
31
+ const buildPairingQRData = (ref, noiseKeyB64, identityKeyB64, advB64, browser) => {
32
+ return (
33
+ 'https://wa.me/settings/linked_devices#' +
34
+ [ref, noiseKeyB64, identityKeyB64, advB64, getCompanionPlatformId(browser)].join(',')
35
+ )
36
+ }
37
+ //# sourceMappingURL=companion-reg-client-utils.js.map
@@ -0,0 +1,208 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.contact_graph_warmer = void 0
4
+
5
+ /**
6
+ * @file contact-graph-warmer.js
7
+ * @description Enforces handshake progression before messaging strangers,
8
+ * and a lurk period before sending in newly-joined groups — mimics how
9
+ * a real human builds up a contact graph instead of blasting messages
10
+ * to unknown recipients immediately. Off by default.
11
+ * @author Denzy ZeroDay
12
+ */
13
+
14
+ const default_config = {
15
+ enabled: false,
16
+ require_handshake_before_group_send: true,
17
+ handshake_min_delay_ms: 3600000, // 1 hour
18
+ group_lurk_period_ms: 43200000, // 12 hours
19
+ max_stranger_messages_per_day: 5,
20
+ auto_register_on_incoming: true
21
+ }
22
+
23
+ class contact_graph_warmer {
24
+ constructor(config = {}) {
25
+ this.config = { ...default_config, ...config }
26
+ this.contacts = new Map()
27
+ this.groups = new Map()
28
+ this.stranger_messages_today = 0
29
+ this.last_stranger_reset_day = this.get_current_day()
30
+ }
31
+
32
+ /**
33
+ * Check if message can be sent to this contact/group.
34
+ * Returns { allowed: false, needs_handshake: true } if handshake required.
35
+ */
36
+ can_message(jid) {
37
+ if (!this.config.enabled) return { allowed: true }
38
+
39
+ const current_day = this.get_current_day()
40
+ if (current_day !== this.last_stranger_reset_day) {
41
+ this.stranger_messages_today = 0
42
+ this.last_stranger_reset_day = current_day
43
+ }
44
+
45
+ if (this.is_group(jid)) return this.check_group_message(jid)
46
+ return this.check_individual_message(jid)
47
+ }
48
+
49
+ /** Mark handshake as sent to this contact */
50
+ mark_handshake_sent(jid) {
51
+ if (!this.config.enabled) return
52
+ if (this.is_group(jid)) return
53
+ const record = this.contacts.get(jid) || { state: 'stranger' }
54
+ record.state = 'handshake_sent'
55
+ record.handshakeSentAt = Date.now()
56
+ this.contacts.set(jid, record)
57
+ }
58
+
59
+ /** Mark handshake as complete with this contact */
60
+ mark_handshake_complete(jid) {
61
+ if (!this.config.enabled) return
62
+ if (this.is_group(jid)) return
63
+ const record = this.contacts.get(jid) || { state: 'stranger' }
64
+ record.state = 'handshake_complete'
65
+ this.contacts.set(jid, record)
66
+ }
67
+
68
+ /** Register a contact as known (skip handshake requirement) */
69
+ register_known_contact(jid) {
70
+ if (!this.config.enabled) return
71
+ if (this.is_group(jid)) return
72
+ const record = this.contacts.get(jid) || { state: 'stranger' }
73
+ record.state = 'known'
74
+ this.contacts.set(jid, record)
75
+ }
76
+
77
+ /** Register a group join event */
78
+ register_group_join(group_jid) {
79
+ if (!this.config.enabled) return
80
+ if (!this.is_group(group_jid)) return
81
+ this.groups.set(group_jid, { joinedAt: Date.now() })
82
+ }
83
+
84
+ /** Get contact state */
85
+ get_contact_state(jid) {
86
+ if (this.is_group(jid)) return 'known'
87
+ return this.contacts.get(jid)?.state || 'stranger'
88
+ }
89
+
90
+ /** Handle incoming message — auto-register if enabled */
91
+ on_incoming_message(jid) {
92
+ if (!this.config.enabled) return
93
+ if (this.is_group(jid)) return
94
+ if (this.config.auto_register_on_incoming) this.register_known_contact(jid)
95
+ }
96
+
97
+ /** Get statistics */
98
+ get_stats() {
99
+ const known_contacts = Array.from(this.contacts.values()).filter(
100
+ (c) => c.state === 'known'
101
+ ).length
102
+ const pending_handshakes = Array.from(this.contacts.values()).filter(
103
+ (c) => c.state === 'handshake_sent'
104
+ ).length
105
+ const groups_joined = Array.from(this.groups.entries()).map(([group_jid, record]) => ({
106
+ groupJid: group_jid,
107
+ joinedAt: record.joinedAt,
108
+ firstSendUnlocksAt: record.joinedAt + this.config.group_lurk_period_ms
109
+ }))
110
+
111
+ return {
112
+ known_contacts,
113
+ pending_handshakes,
114
+ strangers_today: this.stranger_messages_today,
115
+ groups_joined
116
+ }
117
+ }
118
+
119
+ /** Reset all state */
120
+ reset() {
121
+ this.contacts.clear()
122
+ this.groups.clear()
123
+ this.stranger_messages_today = 0
124
+ this.last_stranger_reset_day = this.get_current_day()
125
+ }
126
+
127
+ /** Export state for persistence */
128
+ export_state() {
129
+ return {
130
+ contacts: Array.from(this.contacts.entries()),
131
+ groups: Array.from(this.groups.entries()),
132
+ strangerMessagesToday: this.stranger_messages_today,
133
+ lastStrangerResetDay: this.last_stranger_reset_day
134
+ }
135
+ }
136
+
137
+ /** Restore state from persistence */
138
+ restore_state(state) {
139
+ if (state?.contacts && Array.isArray(state.contacts))
140
+ this.contacts = new Map(state.contacts)
141
+ if (state?.groups && Array.isArray(state.groups)) this.groups = new Map(state.groups)
142
+ if (typeof state?.strangerMessagesToday === 'number')
143
+ this.stranger_messages_today = state.strangerMessagesToday
144
+ if (typeof state?.lastStrangerResetDay === 'number')
145
+ this.last_stranger_reset_day = state.lastStrangerResetDay
146
+ }
147
+
148
+ // Private helpers
149
+ is_group(jid) {
150
+ return jid.endsWith('@g.us')
151
+ }
152
+
153
+ get_current_day() {
154
+ return Math.floor(Date.now() / 86400000)
155
+ }
156
+
157
+ check_group_message(group_jid) {
158
+ const record = this.groups.get(group_jid)
159
+ if (!record) return { allowed: true }
160
+
161
+ const lurk_ends_at = record.joinedAt + this.config.group_lurk_period_ms
162
+ if (Date.now() < lurk_ends_at) {
163
+ const minutes_left = Math.ceil((lurk_ends_at - Date.now()) / 60000)
164
+ return {
165
+ allowed: false,
166
+ reason: `Group lurk period not elapsed — wait ${minutes_left} minutes`
167
+ }
168
+ }
169
+ return { allowed: true }
170
+ }
171
+
172
+ check_individual_message(jid) {
173
+ const record = this.contacts.get(jid)
174
+
175
+ if (!record || record.state === 'stranger') {
176
+ if (this.config.require_handshake_before_group_send) {
177
+ if (this.stranger_messages_today >= this.config.max_stranger_messages_per_day) {
178
+ return {
179
+ allowed: false,
180
+ reason: `Daily new-contact limit reached (${this.config.max_stranger_messages_per_day})`,
181
+ needs_handshake: true
182
+ }
183
+ }
184
+ this.stranger_messages_today++
185
+ }
186
+ return { allowed: true, needs_handshake: true }
187
+ }
188
+
189
+ if (record.state === 'handshake_sent') {
190
+ if (!record.handshakeSentAt) return { allowed: true }
191
+ const elapsed = Date.now() - record.handshakeSentAt
192
+ if (elapsed < this.config.handshake_min_delay_ms) {
193
+ const minutes_left = Math.ceil(
194
+ (this.config.handshake_min_delay_ms - elapsed) / 60000
195
+ )
196
+ return {
197
+ allowed: false,
198
+ reason: `Handshake too recent — wait ${minutes_left} minutes`
199
+ }
200
+ }
201
+ }
202
+
203
+ return { allowed: true }
204
+ }
205
+ }
206
+
207
+ exports.contact_graph_warmer = contact_graph_warmer
208
+ module.exports = { contact_graph_warmer }
@@ -0,0 +1,196 @@
1
+ 'use strict'
2
+ var __createBinding =
3
+ (this && this.__createBinding) ||
4
+ (Object.create
5
+ ? function (o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k
7
+ var desc = Object.getOwnPropertyDescriptor(m, k)
8
+ if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = {
10
+ enumerable: true,
11
+ get: function () {
12
+ return m[k]
13
+ }
14
+ }
15
+ }
16
+ Object.defineProperty(o, k2, desc)
17
+ }
18
+ : function (o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k
20
+ o[k2] = m[k]
21
+ })
22
+ var __setModuleDefault =
23
+ (this && this.__setModuleDefault) ||
24
+ (Object.create
25
+ ? function (o, v) {
26
+ Object.defineProperty(o, 'default', { enumerable: true, value: v })
27
+ }
28
+ : function (o, v) {
29
+ o['default'] = v
30
+ })
31
+ var __importStar =
32
+ (this && this.__importStar) ||
33
+ function (mod) {
34
+ if (mod && mod.__esModule) return mod
35
+ var result = {}
36
+ if (mod != null)
37
+ for (var k in mod)
38
+ if (k !== 'default' && Object.prototype.hasOwnProperty.call(mod, k))
39
+ __createBinding(result, mod, k)
40
+ __setModuleDefault(result, mod)
41
+ return result
42
+ }
43
+ var __importDefault =
44
+ (this && this.__importDefault) ||
45
+ function (mod) {
46
+ return mod && mod.__esModule ? mod : { default: mod }
47
+ }
48
+ Object.defineProperty(exports, '__esModule', { value: true })
49
+ exports.derivePairingCodeKey =
50
+ exports.hkdf =
51
+ exports.md5 =
52
+ exports.sha256 =
53
+ exports.hmacSign =
54
+ exports.aesEncrypWithIV =
55
+ exports.aesEncrypt =
56
+ exports.aesDecryptWithIV =
57
+ exports.aesDecrypt =
58
+ exports.aesDecryptCTR =
59
+ exports.aesEncryptCTR =
60
+ exports.aesDecryptGCM =
61
+ exports.aesEncryptGCM =
62
+ exports.signedKeyPair =
63
+ exports.Curve =
64
+ exports.generateSignalPubKey =
65
+ void 0
66
+ const crypto_1 = require('crypto')
67
+ const futoin_hkdf_1 = __importDefault(require('futoin-hkdf'))
68
+ const libsignal = __importStar(require('libsignal'))
69
+ const Defaults_1 = require('../Defaults')
70
+ /** prefix version byte to the pub keys, required for some curve crypto functions */
71
+ const generateSignalPubKey = (pubKey) =>
72
+ pubKey.length === 33 ? pubKey : Buffer.concat([Defaults_1.KEY_BUNDLE_TYPE, pubKey])
73
+ exports.generateSignalPubKey = generateSignalPubKey
74
+ exports.Curve = {
75
+ generateKeyPair: () => {
76
+ const { pubKey, privKey } = libsignal.curve.generateKeyPair()
77
+ return {
78
+ private: Buffer.from(privKey),
79
+ // remove version byte
80
+ public: Buffer.from(pubKey.slice(1))
81
+ }
82
+ },
83
+ sharedKey: (privateKey, publicKey) => {
84
+ const shared = libsignal.curve.calculateAgreement(
85
+ (0, exports.generateSignalPubKey)(publicKey),
86
+ privateKey
87
+ )
88
+ return Buffer.from(shared)
89
+ },
90
+ sign: (privateKey, buf) => libsignal.curve.calculateSignature(privateKey, buf),
91
+ verify: (pubKey, message, signature) => {
92
+ try {
93
+ libsignal.curve.verifySignature(
94
+ (0, exports.generateSignalPubKey)(pubKey),
95
+ message,
96
+ signature
97
+ )
98
+ return true
99
+ } catch (error) {
100
+ return false
101
+ }
102
+ }
103
+ }
104
+ const signedKeyPair = (identityKeyPair, keyId) => {
105
+ const preKey = exports.Curve.generateKeyPair()
106
+ const pubKey = (0, exports.generateSignalPubKey)(preKey.public)
107
+ const signature = exports.Curve.sign(identityKeyPair.private, pubKey)
108
+ return { keyPair: preKey, signature, keyId }
109
+ }
110
+ exports.signedKeyPair = signedKeyPair
111
+ const GCM_TAG_LENGTH = 128 >> 3
112
+ /**
113
+ * encrypt AES 256 GCM;
114
+ * where the tag tag is suffixed to the ciphertext
115
+ * */
116
+ function aesEncryptGCM(plaintext, key, iv, additionalData) {
117
+ const cipher = (0, crypto_1.createCipheriv)('aes-256-gcm', key, iv)
118
+ cipher.setAAD(additionalData)
119
+ return Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()])
120
+ }
121
+ exports.aesEncryptGCM = aesEncryptGCM
122
+ /**
123
+ * decrypt AES 256 GCM;
124
+ * where the auth tag is suffixed to the ciphertext
125
+ * */
126
+ function aesDecryptGCM(ciphertext, key, iv, additionalData) {
127
+ const decipher = (0, crypto_1.createDecipheriv)('aes-256-gcm', key, iv)
128
+ // decrypt additional adata
129
+ const enc = ciphertext.slice(0, ciphertext.length - GCM_TAG_LENGTH)
130
+ const tag = ciphertext.slice(ciphertext.length - GCM_TAG_LENGTH)
131
+ // set additional data
132
+ decipher.setAAD(additionalData)
133
+ decipher.setAuthTag(tag)
134
+ return Buffer.concat([decipher.update(enc), decipher.final()])
135
+ }
136
+ exports.aesDecryptGCM = aesDecryptGCM
137
+ function aesEncryptCTR(plaintext, key, iv) {
138
+ const cipher = (0, crypto_1.createCipheriv)('aes-256-ctr', key, iv)
139
+ return Buffer.concat([cipher.update(plaintext), cipher.final()])
140
+ }
141
+ exports.aesEncryptCTR = aesEncryptCTR
142
+ function aesDecryptCTR(ciphertext, key, iv) {
143
+ const decipher = (0, crypto_1.createDecipheriv)('aes-256-ctr', key, iv)
144
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()])
145
+ }
146
+ exports.aesDecryptCTR = aesDecryptCTR
147
+ /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
148
+ function aesDecrypt(buffer, key) {
149
+ return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16))
150
+ }
151
+ exports.aesDecrypt = aesDecrypt
152
+ /** decrypt AES 256 CBC */
153
+ function aesDecryptWithIV(buffer, key, IV) {
154
+ const aes = (0, crypto_1.createDecipheriv)('aes-256-cbc', key, IV)
155
+ return Buffer.concat([aes.update(buffer), aes.final()])
156
+ }
157
+ exports.aesDecryptWithIV = aesDecryptWithIV
158
+ // encrypt AES 256 CBC; where a random IV is prefixed to the buffer
159
+ function aesEncrypt(buffer, key) {
160
+ const IV = (0, crypto_1.randomBytes)(16)
161
+ const aes = (0, crypto_1.createCipheriv)('aes-256-cbc', key, IV)
162
+ return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer
163
+ }
164
+ exports.aesEncrypt = aesEncrypt
165
+ // encrypt AES 256 CBC with a given IV
166
+ function aesEncrypWithIV(buffer, key, IV) {
167
+ const aes = (0, crypto_1.createCipheriv)('aes-256-cbc', key, IV)
168
+ return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer
169
+ }
170
+ exports.aesEncrypWithIV = aesEncrypWithIV
171
+ // sign HMAC using SHA 256
172
+ function hmacSign(buffer, key, variant = 'sha256') {
173
+ return (0, crypto_1.createHmac)(variant, key).update(buffer).digest()
174
+ }
175
+ exports.hmacSign = hmacSign
176
+ function sha256(buffer) {
177
+ return (0, crypto_1.createHash)('sha256').update(buffer).digest()
178
+ }
179
+ exports.sha256 = sha256
180
+ function md5(buffer) {
181
+ return (0, crypto_1.createHash)('md5').update(buffer).digest()
182
+ }
183
+ exports.md5 = md5
184
+ // HKDF key expansion
185
+ function hkdf(buffer, expandedLength, info) {
186
+ return (0, futoin_hkdf_1.default)(
187
+ !Buffer.isBuffer(buffer) ? Buffer.from(buffer) : buffer,
188
+ expandedLength,
189
+ info
190
+ )
191
+ }
192
+ exports.hkdf = hkdf
193
+ function derivePairingCodeKey(pairingCode, salt) {
194
+ return (0, crypto_1.pbkdf2Sync)(pairingCode, salt, 2 << 16, 32, 'sha256')
195
+ }
196
+ exports.derivePairingCodeKey = derivePairingCodeKey
@@ -0,0 +1,208 @@
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.decryptMessageNode = exports.decodeMessageNode = void 0
4
+ const boom_1 = require('@hapi/boom')
5
+ const WAProto_1 = require('../../WAProto')
6
+ const WABinary_1 = require('../WABinary')
7
+ const generics_1 = require('./generics')
8
+ const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node'
9
+ /**
10
+ * Decode the received node as a message.
11
+ * @note this will only parse the message, not decrypt it
12
+ */
13
+ function decodeMessageNode(stanza, meId, meLid) {
14
+ var _a, _b
15
+ let msgType
16
+ let chatId
17
+ let author
18
+ const msgId = stanza.attrs.id
19
+ const from = stanza.attrs.from
20
+ const participant = stanza.attrs.participant
21
+ const recipient = stanza.attrs.recipient
22
+ const isMe = (jid) => (0, WABinary_1.areJidsSameUser)(jid, meId)
23
+ const isMeLid = (jid) => (0, WABinary_1.areJidsSameUser)(jid, meLid)
24
+ if ((0, WABinary_1.isJidUser)(from)) {
25
+ if (recipient) {
26
+ if (!isMe(from)) {
27
+ throw new boom_1.Boom('receipient present, but msg not from me', { data: stanza })
28
+ }
29
+ chatId = recipient
30
+ } else {
31
+ chatId = from
32
+ }
33
+ msgType = 'chat'
34
+ author = from
35
+ } else if ((0, WABinary_1.isLidUser)(from)) {
36
+ if (recipient) {
37
+ if (!isMeLid(from)) {
38
+ throw new boom_1.Boom('receipient present, but msg not from me', { data: stanza })
39
+ }
40
+ chatId = recipient
41
+ } else {
42
+ chatId = from
43
+ }
44
+ msgType = 'chat'
45
+ author = from
46
+ } else if ((0, WABinary_1.isJidGroup)(from)) {
47
+ if (!participant) {
48
+ throw new boom_1.Boom('No participant in group message')
49
+ }
50
+ msgType = 'group'
51
+ author = participant
52
+ chatId = from
53
+ } else if ((0, WABinary_1.isJidBroadcast)(from)) {
54
+ if (!participant) {
55
+ throw new boom_1.Boom('No participant in group message')
56
+ }
57
+ const isParticipantMe = isMe(participant)
58
+ if ((0, WABinary_1.isJidStatusBroadcast)(from)) {
59
+ msgType = isParticipantMe ? 'direct_peer_status' : 'other_status'
60
+ } else {
61
+ msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast'
62
+ }
63
+ chatId = from
64
+ author = participant
65
+ } else if ((0, WABinary_1.isJidNewsLetter)(from)) {
66
+ msgType = 'newsletter'
67
+ author = from
68
+ chatId = from
69
+ } else {
70
+ throw new boom_1.Boom('Unknown message type', { data: stanza })
71
+ }
72
+ const fromMe = (0, WABinary_1.isJidNewsLetter)(from)
73
+ ? !!((_a = stanza.attrs) === null || _a === void 0 ? void 0 : _a.is_sender)
74
+ : ((0, WABinary_1.isLidUser)(from) ? isMeLid : isMe)(
75
+ stanza.attrs.participant || stanza.attrs.from
76
+ )
77
+ const pushname = stanza.attrs.notify
78
+ const key = {
79
+ remoteJid: chatId,
80
+ fromMe,
81
+ id: msgId,
82
+ participant
83
+ }
84
+ const fullMessage = {
85
+ key,
86
+ messageTimestamp: +stanza.attrs.t,
87
+ pushName: pushname,
88
+ broadcast: (0, WABinary_1.isJidBroadcast)(from)
89
+ }
90
+ if (msgType === 'newsletter') {
91
+ fullMessage.newsletterServerId = +((_b = stanza.attrs) === null || _b === void 0
92
+ ? void 0
93
+ : _b.server_id)
94
+ }
95
+ if (key.fromMe) {
96
+ fullMessage.status = WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK
97
+ }
98
+ return {
99
+ fullMessage,
100
+ author,
101
+ sender: msgType === 'chat' ? author : chatId
102
+ }
103
+ }
104
+ exports.decodeMessageNode = decodeMessageNode
105
+ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
106
+ const { fullMessage, author, sender } = decodeMessageNode(stanza, meId, meLid)
107
+ return {
108
+ fullMessage,
109
+ category: stanza.attrs.category,
110
+ author,
111
+ async decrypt() {
112
+ var _a
113
+ let decryptables = 0
114
+ async function processSenderKeyDistribution(msg) {
115
+ if (msg.senderKeyDistributionMessage) {
116
+ try {
117
+ await repository.processSenderKeyDistributionMessage({
118
+ authorJid: author,
119
+ item: msg.senderKeyDistributionMessage
120
+ })
121
+ } catch (err) {
122
+ logger.error(
123
+ { key: fullMessage.key, err },
124
+ 'failed to process senderKeyDistribution'
125
+ )
126
+ }
127
+ }
128
+ }
129
+ if ((0, WABinary_1.isJidNewsLetter)(fullMessage.key.remoteJid)) {
130
+ const node = (0, WABinary_1.getBinaryNodeChild)(stanza, 'plaintext')
131
+ const msg = WAProto_1.proto.Message.decode(
132
+ node === null || node === void 0 ? void 0 : node.content
133
+ )
134
+ await processSenderKeyDistribution(msg)
135
+ fullMessage.message = msg
136
+ decryptables += 1
137
+ } else if (Array.isArray(stanza.content)) {
138
+ for (const { tag, attrs, content } of stanza.content) {
139
+ if (tag === 'verified_name' && content instanceof Uint8Array) {
140
+ const cert = WAProto_1.proto.VerifiedNameCertificate.decode(content)
141
+ const details = WAProto_1.proto.VerifiedNameCertificate.Details.decode(
142
+ cert.details
143
+ )
144
+ fullMessage.verifiedBizName = details.verifiedName
145
+ }
146
+ if (tag !== 'enc') {
147
+ continue
148
+ }
149
+ if (!(content instanceof Uint8Array)) {
150
+ continue
151
+ }
152
+ decryptables += 1
153
+ let msgBuffer
154
+ try {
155
+ const e2eType = attrs.type
156
+ switch (e2eType) {
157
+ case 'skmsg':
158
+ msgBuffer = await repository.decryptGroupMessage({
159
+ group: sender,
160
+ authorJid: author,
161
+ msg: content
162
+ })
163
+ break
164
+ case 'pkmsg':
165
+ case 'msg':
166
+ const user = (0, WABinary_1.isJidUser)(sender) ? sender : author
167
+ msgBuffer = await repository.decryptMessage({
168
+ jid: user,
169
+ type: e2eType,
170
+ ciphertext: content
171
+ })
172
+ break
173
+ default:
174
+ throw new Error(`Unknown e2e type: ${e2eType}`)
175
+ }
176
+ let msg = WAProto_1.proto.Message.decode(
177
+ (0, generics_1.unpadRandomMax16)(msgBuffer)
178
+ )
179
+ msg =
180
+ ((_a = msg.deviceSentMessage) === null || _a === void 0
181
+ ? void 0
182
+ : _a.message) || msg
183
+ await processSenderKeyDistribution(msg)
184
+ if (fullMessage.message) {
185
+ Object.assign(fullMessage.message, msg)
186
+ } else {
187
+ fullMessage.message = msg
188
+ }
189
+ } catch (err) {
190
+ logger.error({ key: fullMessage.key, err }, 'failed to decrypt message')
191
+ fullMessage.messageStubType =
192
+ WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT
193
+ fullMessage.messageStubParameters = [err.message]
194
+ }
195
+ }
196
+ }
197
+ // if nothing was found to decrypt
198
+ if (!decryptables) {
199
+ fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT
200
+ fullMessage.messageStubParameters = [
201
+ NO_MESSAGE_FOUND_ERROR_TEXT,
202
+ JSON.stringify(stanza, generics_1.BufferJSON.replacer)
203
+ ]
204
+ }
205
+ }
206
+ }
207
+ }
208
+ exports.decryptMessageNode = decryptMessageNode