@badzz88/baileys 8.4.7 → 8.5.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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1055 -337
  3. package/WAProto/index.js +5 -5
  4. package/lib/Defaults/index.js +187 -127
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.js +14 -11
  7. package/lib/Signal/Group/group-session-builder.js +91 -29
  8. package/lib/Signal/Group/group_cipher.js +88 -81
  9. package/lib/Signal/Group/index.js +136 -12
  10. package/lib/Signal/Group/keyhelper.js +70 -15
  11. package/lib/Signal/Group/sender-chain-key.js +31 -25
  12. package/lib/Signal/Group/sender-key-distribution-message.js +65 -62
  13. package/lib/Signal/Group/sender-key-message.js +68 -65
  14. package/lib/Signal/Group/sender-key-name.js +43 -41
  15. package/lib/Signal/Group/sender-key-record.js +43 -40
  16. package/lib/Signal/Group/sender-key-state.js +96 -83
  17. package/lib/Signal/Group/sender-message-key.js +29 -25
  18. package/lib/Signal/libsignal.js +483 -424
  19. package/lib/Signal/lid-mapping.js +261 -276
  20. package/lib/Socket/Client/index.js +30 -3
  21. package/lib/Socket/Client/types.js +12 -10
  22. package/lib/Socket/Client/websocket.js +61 -53
  23. package/lib/Socket/aigroups.js +240 -0
  24. package/lib/Socket/business.js +422 -379
  25. package/lib/Socket/chats.js +1816 -1193
  26. package/lib/Socket/communities.js +549 -431
  27. package/lib/Socket/graphql.js +656 -0
  28. package/lib/Socket/groups.js +764 -374
  29. package/lib/Socket/index.js +38 -11
  30. package/lib/Socket/interactive-handler.js +522 -0
  31. package/lib/Socket/interop.js +549 -0
  32. package/lib/Socket/luxu.js +6 -5
  33. package/lib/Socket/managed-account.js +183 -0
  34. package/lib/Socket/messages-recv.js +2439 -1915
  35. package/lib/Socket/messages-send.js +1642 -1242
  36. package/lib/Socket/mex.js +59 -40
  37. package/lib/Socket/newsletter.js +812 -249
  38. package/lib/Socket/privacy.js +449 -0
  39. package/lib/Socket/registration.js +427 -0
  40. package/lib/Socket/socket.js +1077 -965
  41. package/lib/Socket/text-router.js +83 -0
  42. package/lib/Socket/username.js +237 -140
  43. package/lib/Store/index.js +36 -10
  44. package/lib/Store/make-cache-manager-store.js +85 -80
  45. package/lib/Store/make-in-memory-store.js +591 -185
  46. package/lib/Store/make-ordered-dictionary.js +78 -72
  47. package/lib/Store/object-repository.js +25 -28
  48. package/lib/Types/Auth.js +38 -2
  49. package/lib/Types/Bussines.js +2 -2
  50. package/lib/Types/Call.js +2 -2
  51. package/lib/Types/Chat.js +4 -8
  52. package/lib/Types/Contact.js +2 -2
  53. package/lib/Types/Events.js +2 -2
  54. package/lib/Types/GroupMetadata.js +2 -2
  55. package/lib/Types/Label.js +26 -24
  56. package/lib/Types/LabelAssociation.js +8 -6
  57. package/lib/Types/Message.js +95 -11
  58. package/lib/Types/Mex.js +112 -37
  59. package/lib/Types/Newsletter.js +121 -0
  60. package/lib/Types/Product.js +2 -2
  61. package/lib/Types/Signal.js +2 -2
  62. package/lib/Types/Socket.js +2 -3
  63. package/lib/Types/State.js +70 -56
  64. package/lib/Types/USync.js +2 -2
  65. package/lib/Types/index.js +55 -26
  66. package/lib/Utils/auth-utils.js +292 -288
  67. package/lib/Utils/browser-utils.js +113 -48
  68. package/lib/Utils/business.js +240 -224
  69. package/lib/Utils/chat-utils.js +1205 -869
  70. package/lib/Utils/command-loader.d.ts +31 -0
  71. package/lib/Utils/command-loader.js +100 -0
  72. package/lib/Utils/companion-reg-client-utils.js +41 -34
  73. package/lib/Utils/consumer-application.js +107 -0
  74. package/lib/Utils/crypto.js +144 -107
  75. package/lib/Utils/curve25519-js.js +275 -0
  76. package/lib/Utils/decode-wa-message.js +518 -308
  77. package/lib/Utils/event-buffer.js +596 -611
  78. package/lib/Utils/generics.js +514 -354
  79. package/lib/Utils/group-history.js +60 -0
  80. package/lib/Utils/history.js +244 -134
  81. package/lib/Utils/identity-change-handler.js +51 -49
  82. package/lib/Utils/index.js +57 -23
  83. package/lib/Utils/jid-display-normalization.js +218 -0
  84. package/lib/Utils/link-preview.js +135 -77
  85. package/lib/Utils/logger.js +9 -3
  86. package/lib/Utils/lt-hash.js +37 -6
  87. package/lib/Utils/make-mutex.js +36 -33
  88. package/lib/Utils/message-composer.js +439 -233
  89. package/lib/Utils/message-retry-manager.js +265 -260
  90. package/lib/Utils/messages-media.js +855 -747
  91. package/lib/Utils/messages.js +2528 -884
  92. package/lib/Utils/meta-ai-msmsg.js +262 -0
  93. package/lib/Utils/native-bridge.js +82 -0
  94. package/lib/Utils/noise-handler.js +195 -200
  95. package/lib/Utils/offline-node-processor.js +35 -33
  96. package/lib/Utils/pre-key-manager.js +103 -102
  97. package/lib/Utils/process-message.js +978 -560
  98. package/lib/Utils/reporting-utils.js +257 -253
  99. package/lib/Utils/session-pool.d.ts +16 -0
  100. package/lib/Utils/session-pool.js +94 -0
  101. package/lib/Utils/signal.js +218 -195
  102. package/lib/Utils/stanza-ack.js +31 -29
  103. package/lib/Utils/sticker.d.ts +17 -0
  104. package/lib/Utils/sticker.js +145 -0
  105. package/lib/Utils/sync-action-utils.js +50 -45
  106. package/lib/Utils/tc-token-utils.js +137 -139
  107. package/lib/Utils/use-multi-file-auth-state.js +109 -109
  108. package/lib/Utils/validate-connection.js +218 -202
  109. package/lib/Utils/view-once-cache.d.ts +9 -0
  110. package/lib/Utils/view-once-cache.js +79 -0
  111. package/lib/Utils/voip-rekey.js +22 -0
  112. package/lib/WABinary/constants.js +1302 -1299
  113. package/lib/WABinary/decode.js +343 -262
  114. package/lib/WABinary/encode.js +12 -4
  115. package/lib/WABinary/generic-utils.js +223 -187
  116. package/lib/WABinary/index.js +33 -6
  117. package/lib/WABinary/jid-utils.js +351 -88
  118. package/lib/WABinary/types.js +2 -2
  119. package/lib/WAM/BinaryInfo.js +12 -9
  120. package/lib/WAM/constants.js +39486 -22853
  121. package/lib/WAM/encode.js +132 -140
  122. package/lib/WAM/index.js +31 -4
  123. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +55 -0
  124. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
  125. package/lib/WAUSync/Protocols/USyncContactProtocol.js +53 -51
  126. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +56 -53
  127. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +29 -26
  128. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +59 -0
  129. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +31 -0
  130. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
  131. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
  132. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -37
  133. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  134. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +26 -24
  135. package/lib/WAUSync/Protocols/index.js +39 -6
  136. package/lib/WAUSync/USyncQuery.js +132 -97
  137. package/lib/WAUSync/USyncUser.js +49 -30
  138. package/lib/WAUSync/index.js +31 -4
  139. package/lib/antiban.js +4637 -0
  140. package/lib/index.js +48 -15
  141. package/package.json +55 -92
  142. package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -263
  143. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -51
  144. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -29
@@ -1,277 +1,262 @@
1
- import { LRUCache } from 'lru-cache';
2
- import { isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, WAJIDDomains } from '../WABinary/index.js';
3
- export class LIDMappingStore {
4
- constructor(keys, logger, pnToLIDFunc) {
5
- this.mappingCache = new LRUCache({
6
- ttl: 3 * 24 * 60 * 60 * 1000, // 7 days
7
- ttlAutopurge: true,
8
- updateAgeOnGet: true
9
- });
10
- this.inflightLIDLookups = new Map();
11
- this.inflightPNLookups = new Map();
12
- this.keys = keys;
13
- this.pnToLIDFunc = pnToLIDFunc;
14
- this.logger = logger;
15
- }
16
- async storeLIDPNMappings(pairs) {
17
- if (pairs.length === 0)
18
- return;
19
- const validatedPairs = [];
20
- for (const { lid, pn } of pairs) {
21
- if (!((isLidUser(lid) && isPnUser(pn)) || (isPnUser(lid) && isLidUser(pn)))) {
22
- this.logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`);
23
- continue;
24
- }
25
- const lidDecoded = jidDecode(lid);
26
- const pnDecoded = jidDecode(pn);
27
- if (!lidDecoded || !pnDecoded)
28
- continue;
29
- validatedPairs.push({ pnUser: pnDecoded.user, lidUser: lidDecoded.user });
30
- }
31
- if (validatedPairs.length === 0)
32
- return;
33
- const cacheMissSet = new Set();
34
- const existingMappings = new Map();
35
- for (const { pnUser } of validatedPairs) {
36
- const cached = this.mappingCache.get(`pn:${pnUser}`);
37
- if (cached) {
38
- existingMappings.set(pnUser, cached);
39
- }
40
- else {
41
- cacheMissSet.add(pnUser);
42
- }
43
- }
44
- if (cacheMissSet.size > 0) {
45
- const cacheMisses = [...cacheMissSet];
46
- this.logger.trace(`Batch fetching ${cacheMisses.length} LID mappings from database`);
47
- const stored = await this.keys.get('lid-mapping', cacheMisses);
48
- for (const pnUser of cacheMisses) {
49
- const existingLidUser = stored[pnUser];
50
- if (existingLidUser) {
51
- existingMappings.set(pnUser, existingLidUser);
52
- this.mappingCache.set(`pn:${pnUser}`, existingLidUser);
53
- this.mappingCache.set(`lid:${existingLidUser}`, pnUser);
54
- }
55
- }
56
- }
57
- const pairMap = {};
58
- for (const { pnUser, lidUser } of validatedPairs) {
59
- const existingLidUser = existingMappings.get(pnUser);
60
- if (existingLidUser === lidUser) {
61
- this.logger.debug({ pnUser, lidUser }, 'LID mapping already exists, skipping');
62
- continue;
63
- }
64
- pairMap[pnUser] = lidUser;
65
- }
66
- if (Object.keys(pairMap).length === 0)
67
- return;
68
- this.logger.trace({ pairMap }, `Storing ${Object.keys(pairMap).length} pn mappings`);
69
- const batchData = {};
70
- for (const [pnUser, lidUser] of Object.entries(pairMap)) {
71
- batchData[pnUser] = lidUser;
72
- batchData[`${lidUser}_reverse`] = pnUser;
73
- }
74
- await this.keys.transaction(async () => {
75
- await this.keys.set({ 'lid-mapping': batchData });
76
- }, 'lid-mapping');
77
- // Update cache after successful DB write
78
- for (const [pnUser, lidUser] of Object.entries(pairMap)) {
79
- this.mappingCache.set(`pn:${pnUser}`, lidUser);
80
- this.mappingCache.set(`lid:${lidUser}`, pnUser);
81
- }
82
- }
83
- async getLIDForPN(pn) {
84
- return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null;
85
- }
86
- async getLIDsForPNs(pns) {
87
- if (pns.length === 0)
88
- return null;
89
- const sortedPns = [...new Set(pns)].sort();
90
- const cacheKey = sortedPns.join(',');
91
- const inflight = this.inflightLIDLookups.get(cacheKey);
92
- if (inflight) {
93
- this.logger.trace(`Coalescing getLIDsForPNs request for ${sortedPns.length} PNs`);
94
- return inflight;
95
- }
96
- const promise = this._getLIDsForPNsImpl(pns);
97
- this.inflightLIDLookups.set(cacheKey, promise);
98
- try {
99
- return await promise;
100
- }
101
- finally {
102
- this.inflightLIDLookups.delete(cacheKey);
103
- }
104
- }
105
- async _getLIDsForPNsImpl(pns) {
106
- const usyncFetch = {};
107
- const successfulPairs = {};
108
- const pending = [];
109
- const addResolvedPair = (pn, decoded, lidUser) => {
110
- const normalizedLidUser = lidUser.toString();
111
- if (!normalizedLidUser) {
112
- this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`);
113
- return false;
114
- }
115
- // Push the PN device ID to the LID to maintain device separation
116
- const pnDevice = decoded.device !== undefined ? decoded.device : 0;
117
- const deviceSpecificLid = `${normalizedLidUser}${!!pnDevice ? `:${pnDevice}` : ``}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`;
118
- this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`);
119
- successfulPairs[pn] = { lid: deviceSpecificLid, pn };
120
- return true;
121
- };
122
- for (const pn of pns) {
123
- if (!isPnUser(pn) && !isHostedPnUser(pn))
124
- continue;
125
- const decoded = jidDecode(pn);
126
- if (!decoded)
127
- continue;
128
- const pnUser = decoded.user;
129
- const cached = this.mappingCache.get(`pn:${pnUser}`);
130
- if (cached && typeof cached === 'string') {
131
- if (!addResolvedPair(pn, decoded, cached)) {
132
- this.logger.warn(`Invalid entry for ${pn} (pair not resolved)`);
133
- continue;
134
- }
135
- continue;
136
- }
137
- pending.push({ pn, pnUser, decoded });
138
- }
139
- if (pending.length) {
140
- const pnUsers = [...new Set(pending.map(item => item.pnUser))];
141
- const stored = await this.keys.get('lid-mapping', pnUsers);
142
- for (const pnUser of pnUsers) {
143
- const lidUser = stored[pnUser];
144
- if (lidUser && typeof lidUser === 'string') {
145
- this.mappingCache.set(`pn:${pnUser}`, lidUser);
146
- this.mappingCache.set(`lid:${lidUser}`, pnUser);
147
- }
148
- }
149
- for (const { pn, pnUser, decoded } of pending) {
150
- const cached = this.mappingCache.get(`pn:${pnUser}`);
151
- if (cached && typeof cached === 'string') {
152
- if (!addResolvedPair(pn, decoded, cached)) {
153
- this.logger.warn(`Invalid entry for ${pn} (pair not resolved)`);
154
- continue;
155
- }
156
- }
157
- else {
158
- this.logger.trace(`No LID mapping found for PN user ${pnUser}; batch getting from USync`);
159
- const device = decoded.device || 0;
160
- let normalizedPn = jidNormalizedUser(pn);
161
- if (isHostedPnUser(normalizedPn)) {
162
- normalizedPn = `${pnUser}@s.whatsapp.net`;
163
- }
164
- if (!usyncFetch[normalizedPn]) {
165
- usyncFetch[normalizedPn] = [device];
166
- }
167
- else {
168
- usyncFetch[normalizedPn]?.push(device);
169
- }
170
- }
171
- }
172
- }
173
- if (Object.keys(usyncFetch).length > 0) {
174
- const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch)); // this function already adds LIDs to mapping
175
- if (result && result.length > 0) {
176
- await this.storeLIDPNMappings(result);
177
- for (const pair of result) {
178
- const pnDecoded = jidDecode(pair.pn);
179
- const pnUser = pnDecoded?.user;
180
- if (!pnUser)
181
- continue;
182
- const lidUser = jidDecode(pair.lid)?.user;
183
- if (!lidUser)
184
- continue;
185
- for (const device of usyncFetch[pair.pn]) {
186
- const deviceSpecificLid = `${lidUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted.lid' : 'lid'}`;
187
- this.logger.trace(`getLIDForPN: USYNC success for ${pair.pn} → ${deviceSpecificLid} (user mapping with device ${device})`);
188
- const deviceSpecificPn = `${pnUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted' : 's.whatsapp.net'}`;
189
- successfulPairs[deviceSpecificPn] = { lid: deviceSpecificLid, pn: deviceSpecificPn };
190
- }
191
- }
192
- }
193
- else {
194
- this.logger.warn('USync fetch yielded no results for pending PNs');
195
- }
196
- }
197
- return Object.values(successfulPairs).length > 0 ? Object.values(successfulPairs) : null;
198
- }
199
- async getPNForLID(lid) {
200
- return (await this.getPNsForLIDs([lid]))?.[0]?.pn || null;
201
- }
202
- async getPNsForLIDs(lids) {
203
- if (lids.length === 0)
204
- return null;
205
- const sortedLids = [...new Set(lids)].sort();
206
- const cacheKey = sortedLids.join(',');
207
- const inflight = this.inflightPNLookups.get(cacheKey);
208
- if (inflight) {
209
- this.logger.trace(`Coalescing getPNsForLIDs request for ${sortedLids.length} LIDs`);
210
- return inflight;
211
- }
212
- const promise = this._getPNsForLIDsImpl(lids);
213
- this.inflightPNLookups.set(cacheKey, promise);
214
- try {
215
- return await promise;
216
- }
217
- finally {
218
- this.inflightPNLookups.delete(cacheKey);
219
- }
220
- }
221
- async _getPNsForLIDsImpl(lids) {
222
- const successfulPairs = {};
223
- const pending = [];
224
- const addResolvedPair = (lid, decoded, pnUser) => {
225
- if (!pnUser || typeof pnUser !== 'string') {
226
- return false;
227
- }
228
- const lidDevice = decoded.device !== undefined ? decoded.device : 0;
229
- const pnJid = `${pnUser}:${lidDevice}@${decoded.domainType === WAJIDDomains.HOSTED_LID ? 'hosted' : 's.whatsapp.net'}`;
230
- this.logger.trace(`Found reverse mapping: ${lid} → ${pnJid}`);
231
- successfulPairs[lid] = { lid, pn: pnJid };
232
- return true;
233
- };
234
- for (const lid of lids) {
235
- if (!isLidUser(lid))
236
- continue;
237
- const decoded = jidDecode(lid);
238
- if (!decoded)
239
- continue;
240
- const lidUser = decoded.user;
241
- const cached = this.mappingCache.get(`lid:${lidUser}`);
242
- if (cached && typeof cached === 'string') {
243
- addResolvedPair(lid, decoded, cached);
244
- continue;
245
- }
246
- pending.push({ lid, lidUser, decoded });
247
- }
248
- if (pending.length) {
249
- const reverseKeys = [...new Set(pending.map(item => `${item.lidUser}_reverse`))];
250
- const stored = await this.keys.get('lid-mapping', reverseKeys);
251
- for (const { lid, lidUser, decoded } of pending) {
252
- let pnUser = this.mappingCache.get(`lid:${lidUser}`);
253
- if (!pnUser || typeof pnUser !== 'string') {
254
- pnUser = stored[`${lidUser}_reverse`];
255
- if (pnUser && typeof pnUser === 'string') {
256
- this.mappingCache.set(`lid:${lidUser}`, pnUser);
257
- this.mappingCache.set(`pn:${pnUser}`, lidUser);
258
- }
259
- }
260
- if (pnUser && typeof pnUser === 'string') {
261
- addResolvedPair(lid, decoded, pnUser);
262
- }
263
- else {
264
- this.logger.trace(`No reverse mapping found for LID user: ${lidUser}`);
265
- }
266
- }
267
- }
268
- return Object.values(successfulPairs).length ? Object.values(successfulPairs) : null;
269
- }
270
- /**
271
- * Close the cache and release resources
272
- */
273
- close() {
274
- this.mappingCache.clear();
275
- }
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.LIDMappingStore = void 0
4
+ const lru_cache_1 = require('lru-cache')
5
+ const WABinary_1 = require('../WABinary')
6
+ class LIDMappingStore {
7
+ constructor(keys, logger, pnToLIDFunc) {
8
+ this.mappingCache = new lru_cache_1.LRUCache({
9
+ ttl: 3 * 24 * 60 * 60 * 1000, // 7 days
10
+ ttlAutopurge: true,
11
+ updateAgeOnGet: true
12
+ })
13
+ this.inflightLIDLookups = new Map()
14
+ this.inflightPNLookups = new Map()
15
+ this.keys = keys
16
+ this.pnToLIDFunc = pnToLIDFunc
17
+ this.logger = logger
18
+ }
19
+ async storeLIDPNMappings(pairs) {
20
+ if (pairs.length === 0) return
21
+ const validatedPairs = []
22
+ for (const { lid, pn } of pairs) {
23
+ if (
24
+ !(
25
+ ((0, WABinary_1.isLidUser)(lid) && (0, WABinary_1.isPnUser)(pn)) ||
26
+ ((0, WABinary_1.isPnUser)(lid) && (0, WABinary_1.isLidUser)(pn))
27
+ )
28
+ ) {
29
+ this.logger.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`)
30
+ continue
31
+ }
32
+ const lidDecoded = (0, WABinary_1.jidDecode)(lid)
33
+ const pnDecoded = (0, WABinary_1.jidDecode)(pn)
34
+ if (!lidDecoded || !pnDecoded) continue
35
+ validatedPairs.push({ pnUser: pnDecoded.user, lidUser: lidDecoded.user })
36
+ }
37
+ if (validatedPairs.length === 0) return
38
+ const cacheMissSet = new Set()
39
+ const existingMappings = new Map()
40
+ for (const { pnUser } of validatedPairs) {
41
+ const cached = this.mappingCache.get(`pn:${pnUser}`)
42
+ if (cached) {
43
+ existingMappings.set(pnUser, cached)
44
+ } else {
45
+ cacheMissSet.add(pnUser)
46
+ }
47
+ }
48
+ if (cacheMissSet.size > 0) {
49
+ const cacheMisses = [...cacheMissSet]
50
+ this.logger.trace(`Batch fetching ${cacheMisses.length} LID mappings from database`)
51
+ const stored = await this.keys.get('lid-mapping', cacheMisses)
52
+ for (const pnUser of cacheMisses) {
53
+ const existingLidUser = stored[pnUser]
54
+ if (existingLidUser) {
55
+ existingMappings.set(pnUser, existingLidUser)
56
+ this.mappingCache.set(`pn:${pnUser}`, existingLidUser)
57
+ this.mappingCache.set(`lid:${existingLidUser}`, pnUser)
58
+ }
59
+ }
60
+ }
61
+ const pairMap = {}
62
+ for (const { pnUser, lidUser } of validatedPairs) {
63
+ const existingLidUser = existingMappings.get(pnUser)
64
+ if (existingLidUser === lidUser) {
65
+ this.logger.debug({ pnUser, lidUser }, 'LID mapping already exists, skipping')
66
+ continue
67
+ }
68
+ pairMap[pnUser] = lidUser
69
+ }
70
+ if (Object.keys(pairMap).length === 0) return
71
+ this.logger.trace({ pairMap }, `Storing ${Object.keys(pairMap).length} pn mappings`)
72
+ const batchData = {}
73
+ for (const [pnUser, lidUser] of Object.entries(pairMap)) {
74
+ batchData[pnUser] = lidUser
75
+ batchData[`${lidUser}_reverse`] = pnUser
76
+ }
77
+ await this.keys.transaction(async () => {
78
+ await this.keys.set({ 'lid-mapping': batchData })
79
+ }, 'lid-mapping')
80
+ // Update cache after successful DB write
81
+ for (const [pnUser, lidUser] of Object.entries(pairMap)) {
82
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
83
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
84
+ }
85
+ }
86
+ async getLIDForPN(pn) {
87
+ return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null
88
+ }
89
+ async getLIDsForPNs(pns) {
90
+ if (pns.length === 0) return null
91
+ const sortedPns = [...new Set(pns)].sort()
92
+ const cacheKey = sortedPns.join(',')
93
+ const inflight = this.inflightLIDLookups.get(cacheKey)
94
+ if (inflight) {
95
+ this.logger.trace(`Coalescing getLIDsForPNs request for ${sortedPns.length} PNs`)
96
+ return inflight
97
+ }
98
+ const promise = this._getLIDsForPNsImpl(pns)
99
+ this.inflightLIDLookups.set(cacheKey, promise)
100
+ try {
101
+ return await promise
102
+ } finally {
103
+ this.inflightLIDLookups.delete(cacheKey)
104
+ }
105
+ }
106
+ async _getLIDsForPNsImpl(pns) {
107
+ const usyncFetch = {}
108
+ const successfulPairs = {}
109
+ const pending = []
110
+ const addResolvedPair = (pn, decoded, lidUser) => {
111
+ const normalizedLidUser = lidUser.toString()
112
+ if (!normalizedLidUser) {
113
+ this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
114
+ return false
115
+ }
116
+ // Push the PN device ID to the LID to maintain device separation
117
+ const pnDevice = decoded.device !== undefined ? decoded.device : 0
118
+ const deviceSpecificLid = `${normalizedLidUser}${!!pnDevice ? `:${pnDevice}` : ``}@${decoded.server === 'hosted' ? 'hosted.lid' : 'lid'}`
119
+ this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
120
+ successfulPairs[pn] = { lid: deviceSpecificLid, pn }
121
+ return true
122
+ }
123
+ for (const pn of pns) {
124
+ if (!(0, WABinary_1.isPnUser)(pn) && !(0, WABinary_1.isHostedPnUser)(pn)) continue
125
+ const decoded = (0, WABinary_1.jidDecode)(pn)
126
+ if (!decoded) continue
127
+ const pnUser = decoded.user
128
+ const cached = this.mappingCache.get(`pn:${pnUser}`)
129
+ if (cached && typeof cached === 'string') {
130
+ if (!addResolvedPair(pn, decoded, cached)) {
131
+ this.logger.warn(`Invalid entry for ${pn} (pair not resolved)`)
132
+ continue
133
+ }
134
+ continue
135
+ }
136
+ pending.push({ pn, pnUser, decoded })
137
+ }
138
+ if (pending.length) {
139
+ const pnUsers = [...new Set(pending.map(item => item.pnUser))]
140
+ const stored = await this.keys.get('lid-mapping', pnUsers)
141
+ for (const pnUser of pnUsers) {
142
+ const lidUser = stored[pnUser]
143
+ if (lidUser && typeof lidUser === 'string') {
144
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
145
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
146
+ }
147
+ }
148
+ for (const { pn, pnUser, decoded } of pending) {
149
+ const cached = this.mappingCache.get(`pn:${pnUser}`)
150
+ if (cached && typeof cached === 'string') {
151
+ if (!addResolvedPair(pn, decoded, cached)) {
152
+ this.logger.warn(`Invalid entry for ${pn} (pair not resolved)`)
153
+ continue
154
+ }
155
+ } else {
156
+ this.logger.trace(`No LID mapping found for PN user ${pnUser}; batch getting from USync`)
157
+ const device = decoded.device || 0
158
+ let normalizedPn = (0, WABinary_1.jidNormalizedUser)(pn)
159
+ if ((0, WABinary_1.isHostedPnUser)(normalizedPn)) {
160
+ normalizedPn = `${pnUser}@s.whatsapp.net`
161
+ }
162
+ if (!usyncFetch[normalizedPn]) {
163
+ usyncFetch[normalizedPn] = [device]
164
+ } else {
165
+ usyncFetch[normalizedPn]?.push(device)
166
+ }
167
+ }
168
+ }
169
+ }
170
+ if (Object.keys(usyncFetch).length > 0) {
171
+ const result = await this.pnToLIDFunc?.(Object.keys(usyncFetch)) // this function already adds LIDs to mapping
172
+ if (result && result.length > 0) {
173
+ await this.storeLIDPNMappings(result)
174
+ for (const pair of result) {
175
+ const pnDecoded = (0, WABinary_1.jidDecode)(pair.pn)
176
+ const pnUser = pnDecoded?.user
177
+ if (!pnUser) continue
178
+ const lidUser = (0, WABinary_1.jidDecode)(pair.lid)?.user
179
+ if (!lidUser) continue
180
+ for (const device of usyncFetch[pair.pn]) {
181
+ const deviceSpecificLid = `${lidUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted.lid' : 'lid'}`
182
+ this.logger.trace(
183
+ `getLIDForPN: USYNC success for ${pair.pn} → ${deviceSpecificLid} (user mapping with device ${device})`
184
+ )
185
+ const deviceSpecificPn = `${pnUser}${!!device ? `:${device}` : ``}@${device === 99 ? 'hosted' : 's.whatsapp.net'}`
186
+ successfulPairs[deviceSpecificPn] = { lid: deviceSpecificLid, pn: deviceSpecificPn }
187
+ }
188
+ }
189
+ } else {
190
+ this.logger.warn('USync fetch yielded no results for pending PNs')
191
+ }
192
+ }
193
+ return Object.values(successfulPairs).length > 0 ? Object.values(successfulPairs) : null
194
+ }
195
+ async getPNForLID(lid) {
196
+ return (await this.getPNsForLIDs([lid]))?.[0]?.pn || null
197
+ }
198
+ async getPNsForLIDs(lids) {
199
+ if (lids.length === 0) return null
200
+ const sortedLids = [...new Set(lids)].sort()
201
+ const cacheKey = sortedLids.join(',')
202
+ const inflight = this.inflightPNLookups.get(cacheKey)
203
+ if (inflight) {
204
+ this.logger.trace(`Coalescing getPNsForLIDs request for ${sortedLids.length} LIDs`)
205
+ return inflight
206
+ }
207
+ const promise = this._getPNsForLIDsImpl(lids)
208
+ this.inflightPNLookups.set(cacheKey, promise)
209
+ try {
210
+ return await promise
211
+ } finally {
212
+ this.inflightPNLookups.delete(cacheKey)
213
+ }
214
+ }
215
+ async _getPNsForLIDsImpl(lids) {
216
+ const successfulPairs = {}
217
+ const pending = []
218
+ const addResolvedPair = (lid, decoded, pnUser) => {
219
+ if (!pnUser || typeof pnUser !== 'string') {
220
+ return false
221
+ }
222
+ const lidDevice = decoded.device !== undefined ? decoded.device : 0
223
+ const pnJid = `${pnUser}:${lidDevice}@${decoded.domainType === WABinary_1.WAJIDDomains.HOSTED_LID ? 'hosted' : 's.whatsapp.net'}`
224
+ this.logger.trace(`Found reverse mapping: ${lid} → ${pnJid}`)
225
+ successfulPairs[lid] = { lid, pn: pnJid }
226
+ return true
227
+ }
228
+ for (const lid of lids) {
229
+ if (!(0, WABinary_1.isLidUser)(lid)) continue
230
+ const decoded = (0, WABinary_1.jidDecode)(lid)
231
+ if (!decoded) continue
232
+ const lidUser = decoded.user
233
+ const cached = this.mappingCache.get(`lid:${lidUser}`)
234
+ if (cached && typeof cached === 'string') {
235
+ addResolvedPair(lid, decoded, cached)
236
+ continue
237
+ }
238
+ pending.push({ lid, lidUser, decoded })
239
+ }
240
+ if (pending.length) {
241
+ const reverseKeys = [...new Set(pending.map(item => `${item.lidUser}_reverse`))]
242
+ const stored = await this.keys.get('lid-mapping', reverseKeys)
243
+ for (const { lid, lidUser, decoded } of pending) {
244
+ let pnUser = this.mappingCache.get(`lid:${lidUser}`)
245
+ if (!pnUser || typeof pnUser !== 'string') {
246
+ pnUser = stored[`${lidUser}_reverse`]
247
+ if (pnUser && typeof pnUser === 'string') {
248
+ this.mappingCache.set(`lid:${lidUser}`, pnUser)
249
+ this.mappingCache.set(`pn:${pnUser}`, lidUser)
250
+ }
251
+ }
252
+ if (pnUser && typeof pnUser === 'string') {
253
+ addResolvedPair(lid, decoded, pnUser)
254
+ } else {
255
+ this.logger.trace(`No reverse mapping found for LID user: ${lidUser}`)
256
+ }
257
+ }
258
+ }
259
+ return Object.values(successfulPairs).length ? Object.values(successfulPairs) : null
260
+ }
276
261
  }
277
- //# sourceMappingURL=lid-mapping.js.map
262
+ exports.LIDMappingStore = LIDMappingStore
@@ -1,3 +1,30 @@
1
- export * from './types.js';
2
- export * from './websocket.js';
3
- //# sourceMappingURL=index.js.map
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 __exportStar =
23
+ (this && this.__exportStar) ||
24
+ function (m, exports) {
25
+ for (var p in m)
26
+ if (p !== 'default' && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p)
27
+ }
28
+ Object.defineProperty(exports, '__esModule', { value: true })
29
+ __exportStar(require('./types'), exports)
30
+ __exportStar(require('./websocket'), exports)
@@ -1,11 +1,13 @@
1
- import { EventEmitter } from 'events';
2
- import { URL } from 'url';
3
- export class AbstractSocketClient extends EventEmitter {
4
- constructor(url, config) {
5
- super();
6
- this.url = url;
7
- this.config = config;
8
- this.setMaxListeners(0);
9
- }
1
+ 'use strict'
2
+ Object.defineProperty(exports, '__esModule', { value: true })
3
+ exports.AbstractSocketClient = void 0
4
+ const events_1 = require('events')
5
+ class AbstractSocketClient extends events_1.EventEmitter {
6
+ constructor(url, config) {
7
+ super()
8
+ this.url = url
9
+ this.config = config
10
+ this.setMaxListeners(0)
11
+ }
10
12
  }
11
- //# sourceMappingURL=types.js.map
13
+ exports.AbstractSocketClient = AbstractSocketClient