@dyyxyzz/baileys-mod 6.0.49 → 6.0.50
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.
- package/lib/Socket/socket.js +64 -60
- package/package.json +1 -1
package/lib/Socket/socket.js
CHANGED
|
@@ -78,36 +78,40 @@ const makeSocket = (config) => {
|
|
|
78
78
|
return sendRawMessage(buff);
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const delay = async (ms) => {
|
|
86
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
87
|
-
};
|
|
81
|
+
const toLid = async (pn) => {
|
|
82
|
+
return pn;
|
|
83
|
+
};
|
|
88
84
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
const delay = async (ms) => {
|
|
86
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
87
|
+
}
|
|
92
88
|
|
|
89
|
+
const toPn = async (pn) => {
|
|
90
|
+
return pn;
|
|
91
|
+
};
|
|
93
92
|
/** log & process any unexpected errors */
|
|
94
93
|
const onUnexpectedError = (err, msg) => {
|
|
95
94
|
logger.error({ err }, `unexpected error in '${msg}'`);
|
|
96
95
|
const message = (err && ((err.stack || err.message) || String(err))).toLowerCase();
|
|
96
|
+
// auto recover from cryptographic desyncs by re-uploading prekeys
|
|
97
97
|
if (message.includes('bad mac') || (message.includes('mac') && message.includes('invalid'))) {
|
|
98
98
|
try {
|
|
99
99
|
uploadPreKeysToServerIfRequired(true)
|
|
100
100
|
.catch(e => logger.warn({ e }, 'failed to re-upload prekeys after bad mac'));
|
|
101
101
|
}
|
|
102
|
-
catch (_e) {
|
|
102
|
+
catch (_e) {
|
|
103
|
+
// ignore
|
|
104
|
+
}
|
|
103
105
|
}
|
|
106
|
+
// gently back off when encountering rate limits (429)
|
|
104
107
|
if (message.includes('429') || message.includes('rate limit')) {
|
|
105
108
|
const wait = Math.min(30000, (config.backoffDelayMs || 5000));
|
|
106
109
|
logger.info({ wait }, 'backing off due to rate limit');
|
|
107
|
-
setTimeout(() => {
|
|
110
|
+
setTimeout(() => {
|
|
111
|
+
// intentionally empty; wait to delay further sends
|
|
112
|
+
}, wait);
|
|
108
113
|
}
|
|
109
114
|
};
|
|
110
|
-
|
|
111
115
|
/** await the next incoming message */
|
|
112
116
|
const awaitNextMessage = async (sendMsg) => {
|
|
113
117
|
if (!ws.isOpen) {
|
|
@@ -134,7 +138,11 @@ const makeSocket = (config) => {
|
|
|
134
138
|
}
|
|
135
139
|
return result;
|
|
136
140
|
};
|
|
137
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Wait for a message with a certain tag to be received
|
|
143
|
+
* @param msgId the message tag to await
|
|
144
|
+
* @param timeoutMs timeout after which the promise will reject
|
|
145
|
+
*/
|
|
138
146
|
const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
|
|
139
147
|
let onRecv;
|
|
140
148
|
let onErr;
|
|
@@ -145,18 +153,18 @@ const makeSocket = (config) => {
|
|
|
145
153
|
reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
|
|
146
154
|
};
|
|
147
155
|
ws.on(`TAG:${msgId}`, onRecv);
|
|
148
|
-
ws.on('close', onErr);
|
|
156
|
+
ws.on('close', onErr); // if the socket closes, you'll never receive the message
|
|
149
157
|
ws.off('error', onErr);
|
|
150
158
|
});
|
|
151
159
|
return result;
|
|
152
160
|
}
|
|
153
161
|
finally {
|
|
154
162
|
ws.off(`TAG:${msgId}`, onRecv);
|
|
155
|
-
ws.off('close', onErr);
|
|
163
|
+
ws.off('close', onErr); // if the socket closes, you'll never receive the message
|
|
156
164
|
ws.off('error', onErr);
|
|
157
165
|
}
|
|
158
166
|
};
|
|
159
|
-
|
|
167
|
+
/** send a query, and wait for its response. auto-generates message ID if not provided */
|
|
160
168
|
const query = async (node, timeoutMs) => {
|
|
161
169
|
if (!node.attrs.id) {
|
|
162
170
|
node.attrs.id = generateMessageTag();
|
|
@@ -171,7 +179,6 @@ const makeSocket = (config) => {
|
|
|
171
179
|
}
|
|
172
180
|
return result;
|
|
173
181
|
};
|
|
174
|
-
|
|
175
182
|
/** connection handshake */
|
|
176
183
|
const validateConnection = async () => {
|
|
177
184
|
let helloMsg = {
|
|
@@ -203,7 +210,6 @@ const makeSocket = (config) => {
|
|
|
203
210
|
noise.finishInit();
|
|
204
211
|
startKeepAliveRequest();
|
|
205
212
|
};
|
|
206
|
-
|
|
207
213
|
const getAvailablePreKeysOnServer = async () => {
|
|
208
214
|
const result = await query({
|
|
209
215
|
tag: 'iq',
|
|
@@ -220,7 +226,7 @@ const makeSocket = (config) => {
|
|
|
220
226
|
const countChild = (0, WABinary_1.getBinaryNodeChild)(result, 'count');
|
|
221
227
|
return +countChild.attrs.value;
|
|
222
228
|
};
|
|
223
|
-
|
|
229
|
+
/** generates and uploads a set of pre-keys to the server */
|
|
224
230
|
const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
|
|
225
231
|
await keys.transaction(async () => {
|
|
226
232
|
logger.info({ count }, 'uploading pre-keys');
|
|
@@ -230,7 +236,6 @@ const makeSocket = (config) => {
|
|
|
230
236
|
logger.info({ count }, 'uploaded pre-keys');
|
|
231
237
|
});
|
|
232
238
|
};
|
|
233
|
-
|
|
234
239
|
const uploadPreKeysToServerIfRequired = async () => {
|
|
235
240
|
const preKeyCount = await getAvailablePreKeysOnServer();
|
|
236
241
|
logger.info(`${preKeyCount} pre-keys found on server`);
|
|
@@ -238,19 +243,22 @@ const makeSocket = (config) => {
|
|
|
238
243
|
await uploadPreKeys();
|
|
239
244
|
}
|
|
240
245
|
};
|
|
241
|
-
|
|
242
246
|
const onMessageReceived = (data) => {
|
|
243
247
|
noise.decodeFrame(data, frame => {
|
|
244
248
|
var _a;
|
|
249
|
+
// reset ping timeout
|
|
245
250
|
lastDateRecv = new Date();
|
|
246
251
|
let anyTriggered = false;
|
|
247
252
|
anyTriggered = ws.emit('frame', frame);
|
|
253
|
+
// if it's a binary node
|
|
248
254
|
if (!(frame instanceof Uint8Array)) {
|
|
249
255
|
const msgId = frame.attrs.id;
|
|
250
256
|
if (logger.level === 'trace') {
|
|
251
257
|
logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
|
|
252
258
|
}
|
|
259
|
+
/* Check if this is a response to a message we sent */
|
|
253
260
|
anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
|
|
261
|
+
/* Check if this is a response to a message we are expecting */
|
|
254
262
|
const l0 = frame.tag;
|
|
255
263
|
const l1 = frame.attrs || {};
|
|
256
264
|
const l2 = Array.isArray(frame.content) ? (_a = frame.content[0]) === null || _a === void 0 ? void 0 : _a.tag : '';
|
|
@@ -267,7 +275,6 @@ const makeSocket = (config) => {
|
|
|
267
275
|
}
|
|
268
276
|
});
|
|
269
277
|
};
|
|
270
|
-
|
|
271
278
|
const end = (error) => {
|
|
272
279
|
if (closed) {
|
|
273
280
|
logger.trace({ trace: error === null || error === void 0 ? void 0 : error.stack }, 'connection already closed');
|
|
@@ -296,7 +303,6 @@ const makeSocket = (config) => {
|
|
|
296
303
|
});
|
|
297
304
|
ev.removeAllListeners('connection.update');
|
|
298
305
|
};
|
|
299
|
-
|
|
300
306
|
const waitForSocketOpen = async () => {
|
|
301
307
|
if (ws.isOpen) {
|
|
302
308
|
return;
|
|
@@ -319,16 +325,20 @@ const makeSocket = (config) => {
|
|
|
319
325
|
ws.off('error', onClose);
|
|
320
326
|
});
|
|
321
327
|
};
|
|
322
|
-
|
|
323
328
|
const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
|
|
324
329
|
if (!lastDateRecv) {
|
|
325
330
|
lastDateRecv = new Date();
|
|
326
331
|
}
|
|
327
332
|
const diff = Date.now() - lastDateRecv.getTime();
|
|
333
|
+
/*
|
|
334
|
+
check if it's been a suspicious amount of time since the server responded with our last seen
|
|
335
|
+
it could be that the network is down
|
|
336
|
+
*/
|
|
328
337
|
if (diff > keepAliveIntervalMs + 5000) {
|
|
329
338
|
end(new boom_1.Boom('Connection was lost', { statusCode: Types_1.DisconnectReason.connectionLost }));
|
|
330
339
|
}
|
|
331
340
|
else if (ws.isOpen) {
|
|
341
|
+
// if its all good, send a keep alive request
|
|
332
342
|
query({
|
|
333
343
|
tag: 'iq',
|
|
334
344
|
attrs: {
|
|
@@ -347,7 +357,7 @@ const makeSocket = (config) => {
|
|
|
347
357
|
logger.warn('keep alive called when WS not open');
|
|
348
358
|
}
|
|
349
359
|
}, keepAliveIntervalMs));
|
|
350
|
-
|
|
360
|
+
/** i have no idea why this exists. pls enlighten me */
|
|
351
361
|
const sendPassiveIq = (tag) => (query({
|
|
352
362
|
tag: 'iq',
|
|
353
363
|
attrs: {
|
|
@@ -359,7 +369,7 @@ const makeSocket = (config) => {
|
|
|
359
369
|
{ tag, attrs: {} }
|
|
360
370
|
]
|
|
361
371
|
}));
|
|
362
|
-
|
|
372
|
+
/** logout & invalidate connection */
|
|
363
373
|
const logout = async (msg) => {
|
|
364
374
|
var _a;
|
|
365
375
|
const jid = (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -385,7 +395,7 @@ const makeSocket = (config) => {
|
|
|
385
395
|
}
|
|
386
396
|
end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
|
|
387
397
|
};
|
|
388
|
-
|
|
398
|
+
|
|
389
399
|
/** This method was created by snowi, and implemented by KyuuRzy */
|
|
390
400
|
/** hey bro, if you delete this text */
|
|
391
401
|
/** you are the most cursed human being who likes to claim other people's property 😹🙌🏻 */
|
|
@@ -402,13 +412,7 @@ const makeSocket = (config) => {
|
|
|
402
412
|
};
|
|
403
413
|
|
|
404
414
|
ev.emit('creds.update', authState.creds);
|
|
405
|
-
|
|
406
|
-
// ── FIX: Platform ID 1 = Chrome, dikenali WA sebagai companion browser valid ──
|
|
407
|
-
// Sebelumnya pakai getPlatformId(browser[1]) yang return nilai tidak dikenal
|
|
408
|
-
// untuk string 'Android' sehingga WA tidak mengirimkan push notif pairing ke HP
|
|
409
|
-
const PLATFORM_ID = Buffer.from([1]); // 1 = Chrome/Browser companion
|
|
410
|
-
const PLATFORM_DISPLAY = Buffer.from('Chrome (Linux)', 'utf-8');
|
|
411
|
-
|
|
415
|
+
|
|
412
416
|
await sendNode({
|
|
413
417
|
tag: 'iq',
|
|
414
418
|
attrs: {
|
|
@@ -439,26 +443,25 @@ const makeSocket = (config) => {
|
|
|
439
443
|
{
|
|
440
444
|
tag: 'companion_platform_id',
|
|
441
445
|
attrs: {},
|
|
442
|
-
content:
|
|
446
|
+
content: (0, Utils_1.getPlatformId)(browser[1])
|
|
443
447
|
},
|
|
444
448
|
{
|
|
445
449
|
tag: 'companion_platform_display',
|
|
446
450
|
attrs: {},
|
|
447
|
-
content:
|
|
451
|
+
content: `${browser[1]} (${browser[0]})`
|
|
448
452
|
},
|
|
449
453
|
{
|
|
450
454
|
tag: 'link_code_pairing_nonce',
|
|
451
455
|
attrs: {},
|
|
452
|
-
content:
|
|
456
|
+
content: "0"
|
|
453
457
|
}
|
|
454
458
|
]
|
|
455
459
|
}
|
|
456
460
|
]
|
|
457
461
|
});
|
|
458
|
-
|
|
462
|
+
|
|
459
463
|
return authState.creds.pairingCode;
|
|
460
|
-
}
|
|
461
|
-
|
|
464
|
+
}
|
|
462
465
|
async function generatePairingKey() {
|
|
463
466
|
const salt = (0, crypto_1.randomBytes)(32);
|
|
464
467
|
const randomIv = (0, crypto_1.randomBytes)(16);
|
|
@@ -466,7 +469,6 @@ const makeSocket = (config) => {
|
|
|
466
469
|
const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
|
|
467
470
|
return Buffer.concat([salt, randomIv, ciphered]);
|
|
468
471
|
}
|
|
469
|
-
|
|
470
472
|
const sendWAMBuffer = (wamBuffer) => {
|
|
471
473
|
return query({
|
|
472
474
|
tag: 'iq',
|
|
@@ -484,7 +486,6 @@ const makeSocket = (config) => {
|
|
|
484
486
|
]
|
|
485
487
|
});
|
|
486
488
|
};
|
|
487
|
-
|
|
488
489
|
ws.on('message', onMessageReceived);
|
|
489
490
|
ws.on('open', async () => {
|
|
490
491
|
try {
|
|
@@ -497,8 +498,9 @@ const makeSocket = (config) => {
|
|
|
497
498
|
});
|
|
498
499
|
ws.on('error', mapWebSocketError(end));
|
|
499
500
|
ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
|
|
501
|
+
// the server terminated the connection
|
|
500
502
|
ws.on('CB:xmlstreamend', () => end(new boom_1.Boom('Connection Terminated by Server', { statusCode: Types_1.DisconnectReason.connectionClosed })));
|
|
501
|
-
|
|
503
|
+
// QR gen
|
|
502
504
|
ws.on('CB:iq,type:set,pair-device', async (stanza) => {
|
|
503
505
|
const iq = {
|
|
504
506
|
tag: 'iq',
|
|
@@ -514,7 +516,7 @@ const makeSocket = (config) => {
|
|
|
514
516
|
const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64');
|
|
515
517
|
const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64');
|
|
516
518
|
const advB64 = creds.advSecretKey;
|
|
517
|
-
let qrMs = qrTimeout || 60000;
|
|
519
|
+
let qrMs = qrTimeout || 60000; // time to let a QR live
|
|
518
520
|
const genPairQR = () => {
|
|
519
521
|
if (!ws.isOpen) {
|
|
520
522
|
return;
|
|
@@ -528,11 +530,12 @@ const makeSocket = (config) => {
|
|
|
528
530
|
const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',');
|
|
529
531
|
ev.emit('connection.update', { qr });
|
|
530
532
|
qrTimer = setTimeout(genPairQR, qrMs);
|
|
531
|
-
qrMs = qrTimeout || 20000;
|
|
533
|
+
qrMs = qrTimeout || 20000; // shorter subsequent qrs
|
|
532
534
|
};
|
|
533
535
|
genPairQR();
|
|
534
536
|
});
|
|
535
|
-
|
|
537
|
+
// device paired for the first time
|
|
538
|
+
// if device pairs successfully, the server asks to restart the connection
|
|
536
539
|
ws.on('CB:iq,,pair-success', async (stanza) => {
|
|
537
540
|
logger.debug('pair success recv');
|
|
538
541
|
try {
|
|
@@ -547,13 +550,13 @@ const makeSocket = (config) => {
|
|
|
547
550
|
end(error);
|
|
548
551
|
}
|
|
549
552
|
});
|
|
550
|
-
|
|
553
|
+
// login complete
|
|
551
554
|
ws.on('CB:success', async (node) => {
|
|
552
555
|
try {
|
|
553
556
|
await uploadPreKeysToServerIfRequired();
|
|
554
557
|
await sendPassiveIq('active');
|
|
555
558
|
logger.info('opened connection to WA');
|
|
556
|
-
clearTimeout(qrTimer);
|
|
559
|
+
clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
|
|
557
560
|
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
|
|
558
561
|
ev.emit('connection.update', { connection: 'open' });
|
|
559
562
|
}
|
|
@@ -562,22 +565,19 @@ const makeSocket = (config) => {
|
|
|
562
565
|
end(err);
|
|
563
566
|
}
|
|
564
567
|
});
|
|
565
|
-
|
|
566
568
|
ws.on('CB:stream:error', (node) => {
|
|
567
569
|
logger.error({ node }, 'stream errored out');
|
|
568
570
|
const { reason, statusCode } = (0, Utils_1.getErrorCodeFromStreamError)(node);
|
|
569
571
|
end(new boom_1.Boom(`Stream Errored (${reason})`, { statusCode, data: node }));
|
|
570
572
|
});
|
|
571
|
-
|
|
573
|
+
// stream fail, possible logout
|
|
572
574
|
ws.on('CB:failure', (node) => {
|
|
573
575
|
const reason = +(node.attrs.reason || 500);
|
|
574
576
|
end(new boom_1.Boom('Connection Failure', { statusCode: reason, data: node.attrs }));
|
|
575
577
|
});
|
|
576
|
-
|
|
577
578
|
ws.on('CB:ib,,downgrade_webclient', () => {
|
|
578
579
|
end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
|
|
579
580
|
});
|
|
580
|
-
|
|
581
581
|
ws.on('CB:ib,,offline_preview', (node) => {
|
|
582
582
|
logger.info('offline preview received', JSON.stringify(node));
|
|
583
583
|
sendNode({
|
|
@@ -586,7 +586,6 @@ const makeSocket = (config) => {
|
|
|
586
586
|
content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
|
|
587
587
|
});
|
|
588
588
|
});
|
|
589
|
-
|
|
590
589
|
ws.on('CB:ib,,edge_routing', (node) => {
|
|
591
590
|
const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
|
|
592
591
|
const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
|
|
@@ -595,17 +594,18 @@ const makeSocket = (config) => {
|
|
|
595
594
|
ev.emit('creds.update', authState.creds);
|
|
596
595
|
}
|
|
597
596
|
});
|
|
598
|
-
|
|
599
597
|
let didStartBuffer = false;
|
|
600
598
|
process.nextTick(() => {
|
|
601
599
|
var _a;
|
|
602
600
|
if ((_a = creds.me) === null || _a === void 0 ? void 0 : _a.id) {
|
|
601
|
+
// start buffering important events
|
|
602
|
+
// if we're logged in
|
|
603
603
|
ev.buffer();
|
|
604
604
|
didStartBuffer = true;
|
|
605
605
|
}
|
|
606
606
|
ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined });
|
|
607
607
|
});
|
|
608
|
-
|
|
608
|
+
// called when all offline notifs are handled
|
|
609
609
|
ws.on('CB:ib,,offline', (node) => {
|
|
610
610
|
const child = (0, WABinary_1.getBinaryNodeChild)(node, 'offline');
|
|
611
611
|
const offlineNotifs = +((child === null || child === void 0 ? void 0 : child.attrs.count) || 0);
|
|
@@ -616,10 +616,11 @@ const makeSocket = (config) => {
|
|
|
616
616
|
}
|
|
617
617
|
ev.emit('connection.update', { receivedPendingNotifications: true });
|
|
618
618
|
});
|
|
619
|
-
|
|
619
|
+
// update credentials when required
|
|
620
620
|
ev.on('creds.update', update => {
|
|
621
621
|
var _a, _b;
|
|
622
622
|
const name = (_a = update.me) === null || _a === void 0 ? void 0 : _a.name;
|
|
623
|
+
// if name has just been received
|
|
623
624
|
if (((_b = creds.me) === null || _b === void 0 ? void 0 : _b.name) !== name) {
|
|
624
625
|
logger.debug({ name }, 'updated pushName');
|
|
625
626
|
sendNode({
|
|
@@ -632,11 +633,9 @@ const makeSocket = (config) => {
|
|
|
632
633
|
}
|
|
633
634
|
Object.assign(creds, update);
|
|
634
635
|
});
|
|
635
|
-
|
|
636
636
|
if (printQRInTerminal) {
|
|
637
637
|
(0, Utils_1.printQRIfNecessaryListener)(ev, logger);
|
|
638
638
|
}
|
|
639
|
-
|
|
640
639
|
return {
|
|
641
640
|
type: 'md',
|
|
642
641
|
ws,
|
|
@@ -664,14 +663,19 @@ const makeSocket = (config) => {
|
|
|
664
663
|
uploadPreKeys,
|
|
665
664
|
uploadPreKeysToServerIfRequired,
|
|
666
665
|
requestPairingCode,
|
|
666
|
+
/** Waits for the connection to WA to reach a state */
|
|
667
667
|
waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
|
|
668
668
|
sendWAMBuffer,
|
|
669
669
|
};
|
|
670
670
|
};
|
|
671
671
|
exports.makeSocket = makeSocket;
|
|
672
|
-
|
|
672
|
+
/**
|
|
673
|
+
* map the websocket error to the right type
|
|
674
|
+
* so it can be retried by the caller
|
|
675
|
+
* */
|
|
673
676
|
function mapWebSocketError(handler) {
|
|
674
677
|
return (error) => {
|
|
675
678
|
handler(new boom_1.Boom(`WebSocket Error (${error === null || error === void 0 ? void 0 : error.message})`, { statusCode: (0, Utils_1.getCodeFromWSError)(error), data: error }));
|
|
676
679
|
};
|
|
677
680
|
}
|
|
681
|
+
|