@rexxhayanasi/elaina-baileys 1.0.9 → 1.1.0-DEV.1

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.
@@ -40,6 +40,19 @@ const makeSocket = (config) => {
40
40
  routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
41
41
  });
42
42
  const { creds } = authState;
43
+ if (!creds.noiseKey?.public) {
44
+ creds.noiseKey = Utils_1.Curve.generateKeyPair()
45
+ }
46
+
47
+ if (!creds.signedIdentityKey?.public) {
48
+ creds.signedIdentityKey = Utils_1.Curve.generateKeyPair()
49
+ }
50
+
51
+ if (!creds.advSecretKey) {
52
+ creds.advSecretKey = (0, crypto_1.randomBytes)(32).toString('base64')
53
+ }
54
+
55
+ ev.emit('creds.update', creds)
43
56
  // add transaction capability
44
57
  const keys = (0, Utils_1.addTransactionCapability)(authState.keys, logger, transactionOpts);
45
58
  const signalRepository = makeSignalRepository({ creds, keys });
@@ -53,20 +66,26 @@ const makeSocket = (config) => {
53
66
  const sendPromise = (0, util_1.promisify)(ws.send);
54
67
  /** send a raw buffer */
55
68
  const sendRawMessage = async (data) => {
56
- if (!ws.isOpen) {
57
- throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
58
- }
59
- const bytes = noise.encodeFrame(data);
60
- await (0, Utils_1.promiseTimeout)(connectTimeoutMs, async (resolve, reject) => {
69
+ if (!ws || ws.isClosed || ws.isClosing || !ws.isOpen) {
70
+ throw new boom_1.Boom('Connection Closed', {
71
+ statusCode: Types_1.DisconnectReason.connectionClosed
72
+ })
73
+ }
74
+
75
+ const bytes = noise.encodeFrame(data)
76
+
77
+ await (0, Utils_1.promiseTimeout)(
78
+ connectTimeoutMs,
79
+ async (resolve, reject) => {
61
80
  try {
62
- await sendPromise.call(ws, bytes);
63
- resolve();
64
- }
65
- catch (error) {
66
- reject(error);
81
+ await sendPromise.call(ws, bytes)
82
+ resolve()
83
+ } catch (error) {
84
+ reject(error)
67
85
  }
68
- });
69
- };
86
+ }
87
+ )
88
+ };
70
89
  /** send a binary node */
71
90
  const sendNode = (frame) => {
72
91
  if (logger.level === 'trace') {
@@ -261,34 +280,46 @@ const makeSocket = (config) => {
261
280
  }
262
281
  });
263
282
  };
264
- const end = (error) => {
265
- if (closed) {
266
- logger.trace({ trace: error === null || error === void 0 ? void 0 : error.stack }, 'connection already closed');
267
- return;
268
- }
269
- closed = true;
270
- logger.info({ trace: error === null || error === void 0 ? void 0 : error.stack }, error ? 'connection errored' : 'connection closed');
271
- clearInterval(keepAliveReq);
272
- clearTimeout(qrTimer);
273
- ws.removeAllListeners('close');
274
- ws.removeAllListeners('error');
275
- ws.removeAllListeners('open');
276
- ws.removeAllListeners('message');
277
- if (!ws.isClosed && !ws.isClosing) {
278
- try {
279
- ws.close();
280
- }
281
- catch (_a) { }
282
- }
283
+ const end = (error) => {
284
+ if (closed) return
285
+ closed = true
286
+
287
+ try { clearInterval(keepAliveReq) } catch {}
288
+ try { clearTimeout(qrTimer) } catch {}
289
+
290
+ try {
291
+ ws.off('message', onMessageReceived)
292
+ ws.removeAllListeners?.()
293
+ } catch {}
294
+
295
+ try {
296
+ if (ws.terminate) {
297
+ ws.terminate()
298
+ } else {
299
+ ws.close()
300
+ }
301
+ } catch {}
302
+
303
+ try {
283
304
  ev.emit('connection.update', {
284
305
  connection: 'close',
285
306
  lastDisconnect: {
286
307
  error,
287
308
  date: new Date()
288
309
  }
289
- });
290
- ev.removeAllListeners('connection.update');
291
- };
310
+ })
311
+ } catch {}
312
+
313
+ try { ev.flush?.() } catch {}
314
+ try { ev.removeAllListeners?.() } catch {}
315
+
316
+ try {
317
+ if (authState?.creds?.isConnecting) {
318
+ authState.creds.isConnecting = false
319
+ ev.emit?.('creds.update', authState.creds)
320
+ }
321
+ } catch {}
322
+ };
292
323
  const waitForSocketOpen = async () => {
293
324
  if (ws.isOpen) {
294
325
  return;
@@ -381,74 +412,123 @@ const makeSocket = (config) => {
381
412
  }
382
413
  end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
383
414
  };
415
+
416
+ const getPairingJid = () => {
417
+ if (authState.creds?.me?.id) {
418
+ return authState.creds.me.id
419
+ }
420
+
421
+ if (!authState.creds?.pairingPhone) {
422
+ throw new Error('pairingPhone belum tersedia')
423
+ }
424
+
425
+ const phone = authState.creds.pairingPhone.replace(/\D/g, '')
426
+ return `${phone}@s.whatsapp.net`
427
+ }
384
428
  const requestPairingCode = async (phoneNumber, pairKey = "ELAINAMD") => {
385
- if (pairKey) {
386
- authState.creds.pairingCode = pairKey.toUpperCase();
387
- }
388
- else {
389
- authState.creds.pairingCode = (0, Utils_1.bytesToCrockford)((0, crypto_1.randomBytes)(5));
390
- }
391
- authState.creds.me = {
392
- id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
393
- name: '~'
394
- };
395
- ev.emit('creds.update', authState.creds);
396
- await sendNode({
397
- tag: 'iq',
398
- attrs: {
399
- to: WABinary_1.S_WHATSAPP_NET,
400
- type: 'set',
401
- id: generateMessageTag(),
402
- xmlns: 'md'
403
- },
404
- content: [
405
- {
406
- tag: 'link_code_companion_reg',
407
- attrs: {
408
- jid: authState.creds.me.id,
409
- stage: 'companion_hello',
410
- // eslint-disable-next-line camelcase
411
- should_show_push_notification: 'true'
429
+ // FIX: normalisasi nomor (WA v6 wajib)
430
+ authState.creds.pairingPhone = phoneNumber.replace(/\D/g, '')
431
+ ev.emit('creds.update', authState.creds)
432
+
433
+ if (!authState.creds.noiseKey?.public) {
434
+ authState.creds.noiseKey = Utils_1.Curve.generateKeyPair()
435
+ ev.emit('creds.update', authState.creds)
436
+ }
437
+
438
+ // FIX: pairingEphemeralKeyPair HARUS STABIL
439
+ if (!authState.creds.pairingEphemeralKeyPair) {
440
+ authState.creds.pairingEphemeralKeyPair = Utils_1.Curve.generateKeyPair()
441
+ ev.emit('creds.update', authState.creds)
442
+ }
443
+
444
+ // FIX: pairing code konsisten
445
+ authState.creds.pairingCode = pairKey
446
+ ? pairKey.toUpperCase()
447
+ : (0, Utils_1.bytesToCrockford)((0, crypto_1.randomBytes)(5))
448
+
449
+ // FIX: salt pairing harus stabil
450
+ if (!authState.creds.pairingSalt) {
451
+ authState.creds.pairingSalt = (0, crypto_1.randomBytes)(32)
452
+ ev.emit('creds.update', authState.creds)
453
+ }
454
+
455
+ await sendNode({
456
+ tag: 'iq',
457
+ attrs: {
458
+ to: WABinary_1.S_WHATSAPP_NET,
459
+ type: 'set',
460
+ id: generateMessageTag(),
461
+ xmlns: 'md'
462
+ },
463
+ content: [
464
+ {
465
+ tag: 'link_code_companion_reg',
466
+ attrs: {
467
+ // FIX PALING PENTING (Baileys v6)
468
+ jid: getPairingJid(),
469
+ stage: 'companion_hello',
470
+ should_show_push_notification: 'true'
471
+ },
472
+ content: [
473
+ {
474
+ tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
475
+ attrs: {},
476
+ content: await generatePairingKey()
412
477
  },
413
- content: [
414
- {
415
- tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
416
- attrs: {},
417
- content: await generatePairingKey()
418
- },
419
- {
420
- tag: 'companion_server_auth_key_pub',
421
- attrs: {},
422
- content: authState.creds.noiseKey.public
423
- },
424
- {
425
- tag: 'companion_platform_id',
426
- attrs: {},
427
- content: (0, Utils_1.getPlatformId)(browser[1])
428
- },
429
- {
430
- tag: 'companion_platform_display',
431
- attrs: {},
432
- content: `${browser[1]} (${browser[0]})`
433
- },
434
- {
435
- tag: 'link_code_pairing_nonce',
436
- attrs: {},
437
- content: '0'
438
- }
439
- ]
440
- }
441
- ]
442
- });
443
- return authState.creds.pairingCode;
444
- };
478
+ {
479
+ tag: 'companion_server_auth_key_pub',
480
+ attrs: {},
481
+ content: authState.creds.noiseKey.public
482
+ },
483
+ {
484
+ tag: 'companion_platform_id',
485
+ attrs: {},
486
+ content: (0, Utils_1.getPlatformId)(browser[1])
487
+ },
488
+ {
489
+ tag: 'companion_platform_display',
490
+ attrs: {},
491
+ content: `${browser[1]} (${browser[0]})`
492
+ },
493
+ {
494
+ tag: 'link_code_pairing_nonce',
495
+ attrs: {},
496
+ content: Buffer.from([0])
497
+ }
498
+ ]
499
+ }
500
+ ]
501
+ })
502
+
503
+ return authState.creds.pairingCode
504
+ }
505
+
445
506
  async function generatePairingKey() {
446
- const salt = (0, crypto_1.randomBytes)(32);
447
- const randomIv = (0, crypto_1.randomBytes)(16);
448
- const key = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
449
- const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
450
- return Buffer.concat([salt, randomIv, ciphered]);
507
+ if (!authState.creds.pairingEphemeralKeyPair?.public) {
508
+ throw new Error('pairingEphemeralKeyPair tidak tersedia')
451
509
  }
510
+
511
+ if (!authState.creds.pairingCode) {
512
+ throw new Error('pairingCode belum tersedia')
513
+ }
514
+
515
+ // FIX: pakai salt yang sama
516
+ const salt = authState.creds.pairingSalt
517
+ const iv = (0, crypto_1.randomBytes)(16)
518
+
519
+ const key = await (0, Utils_1.derivePairingCodeKey)(
520
+ authState.creds.pairingCode,
521
+ salt
522
+ )
523
+
524
+ const ciphered = (0, Utils_1.aesEncryptCTR)(
525
+ authState.creds.pairingEphemeralKeyPair.public,
526
+ key,
527
+ iv
528
+ )
529
+
530
+ return Buffer.concat([salt, iv, ciphered])
531
+ }
452
532
  const sendWAMBuffer = (wamBuffer) => {
453
533
  return query({
454
534
  tag: 'iq',
@@ -468,14 +548,19 @@ const makeSocket = (config) => {
468
548
  };
469
549
  ws.on('message', onMessageReceived);
470
550
  ws.on('open', async () => {
471
- try {
472
- await validateConnection();
473
- }
474
- catch (err) {
475
- logger.error({ err }, 'error in validating connection');
476
- end(err);
551
+ try {
552
+ if (!authState.creds.isConnecting) {
553
+ authState.creds.isConnecting = true;
554
+ ev.emit('creds.update', authState.creds);
477
555
  }
478
- });
556
+
557
+ await validateConnection();
558
+ }
559
+ catch (err) {
560
+ logger.error({ err }, 'error in validating connection');
561
+ end(err);
562
+ }
563
+ });
479
564
  ws.on('error', mapWebSocketError(end));
480
565
  ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
481
566
  // the server terminated the connection
@@ -517,34 +602,39 @@ const makeSocket = (config) => {
517
602
  // device paired for the first time
518
603
  // if device pairs successfully, the server asks to restart the connection
519
604
  ws.on('CB:iq,,pair-success', async (stanza) => {
520
- logger.debug('pair success recv');
521
- try {
522
- const { reply, creds: updatedCreds } = (0, Utils_1.configureSuccessfulPairing)(stanza, creds);
523
- logger.info({ me: updatedCreds.me, platform: updatedCreds.platform }, 'pairing configured successfully, expect to restart the connection...');
524
- ev.emit('creds.update', updatedCreds);
525
- ev.emit('connection.update', { isNewLogin: true, qr: undefined });
526
- await sendNode(reply);
527
- }
528
- catch (error) {
529
- logger.info({ trace: error.stack }, 'error in pairing');
530
- end(error);
531
- }
532
- });
605
+ try {
606
+ const { reply, creds: updatedCreds } =
607
+ (0, Utils_1.configureSuccessfulPairing)(stanza, creds)
608
+
609
+ // FIX: reset state pairing
610
+ delete updatedCreds.pairingCode
611
+ delete updatedCreds.pairingPhone
612
+ delete updatedCreds.pairingSalt
613
+ delete updatedCreds.pairingEphemeralKeyPair
614
+ updatedCreds.isConnecting = false
615
+
616
+ ev.emit('creds.update', updatedCreds)
617
+ ev.emit('connection.update', { isNewLogin: true, qr: undefined })
618
+
619
+ await sendNode(reply)
620
+ } catch (err) {
621
+ end(err)
622
+ }
623
+ });
533
624
  // login complete
534
625
  ws.on('CB:success', async (node) => {
535
- try {
536
- await uploadPreKeysToServerIfRequired();
537
- await sendPassiveIq('active');
538
- logger.info('opened connection to WA');
539
- clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
540
- ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
541
- ev.emit('connection.update', { connection: 'open' });
542
- }
543
- catch (err) {
544
- logger.error({ err }, 'error opening connection');
545
- end(err);
546
- }
547
- });
626
+ try {
627
+ await uploadPreKeysToServerIfRequired()
628
+ await sendPassiveIq('active')
629
+
630
+ authState.creds.isConnecting = false
631
+ ev.emit('creds.update', authState.creds)
632
+
633
+ ev.emit('connection.update', { connection: 'open' })
634
+ } catch (err) {
635
+ end(err)
636
+ }
637
+ });
548
638
  ws.on('CB:stream:error', (node) => {
549
639
  logger.error({ node }, 'stream errored out');
550
640
  const { reason, statusCode } = (0, Utils_1.getErrorCodeFromStreamError)(node);
package/lib/index.js CHANGED
@@ -53,5 +53,6 @@ __exportStar(require("./WABinary"), exports);
53
53
  __exportStar(require("./WAM"), exports);
54
54
  __exportStar(require("./WAUSync"), exports);
55
55
  __exportStar(require("./Api"), exports);
56
+ __exportStar(require("./Auth"), exports);
56
57
 
57
58
  exports.default = Socket_1.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rexxhayanasi/elaina-baileys",
3
- "version": "1.0.9",
3
+ "version": "1.1.0-DEV.1",
4
4
  "description": "Custom Baileys WhatsApp API",
5
5
  "keywords": [
6
6
  "baileys",
@@ -47,6 +47,7 @@
47
47
  "@hapi/boom": "^9.1.3",
48
48
  "async-mutex": "^0.5.0",
49
49
  "axios": "^1.6.0",
50
+ "better-sqlite3": "^12.5.0",
50
51
  "chalk": "^4.1.2",
51
52
  "gradient-string": "^2.0.2",
52
53
  "cache-manager": "^5.7.6",
@@ -70,7 +71,7 @@
70
71
  "conventional-changelog-cli": "^2.2.2",
71
72
  "eslint": "^8.0.0",
72
73
  "jest": "^27.0.6",
73
- "jimp": "^0.16.1",
74
+ "jimp": "^1.6.0",
74
75
  "json": "^11.0.0",
75
76
  "link-preview-js": "^3.0.0",
76
77
  "open": "^8.4.2",
@@ -84,7 +85,7 @@
84
85
  },
85
86
  "peerDependencies": {
86
87
  "audio-decode": "^2.1.3",
87
- "jimp": "^0.16.1",
88
+ "jimp": "^0.22.10",
88
89
  "link-preview-js": "^3.0.0",
89
90
  "qrcode-terminal": "^0.12.0",
90
91
  "sharp": "^0.34.1"