@hbmodsofc/baileys 1.5.2 → 1.7.6

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 (156) hide show
  1. package/LICENSE +1 -1
  2. package/WAProto/index.js +19671 -152026
  3. package/engine-requirements.js +4 -4
  4. package/lib/Defaults/index.d.ts +12 -8
  5. package/lib/Defaults/index.js +90 -124
  6. package/lib/Signal/Group/group_cipher.d.ts +0 -1
  7. package/lib/Signal/Group/group_cipher.js +28 -39
  8. package/lib/Signal/Group/sender-chain-key.d.ts +1 -1
  9. package/lib/Signal/Group/sender-chain-key.js +9 -2
  10. package/lib/Signal/Group/sender-key-distribution-message.js +3 -3
  11. package/lib/Signal/Group/sender-key-message.js +3 -3
  12. package/lib/Signal/Group/sender-key-state.d.ts +4 -4
  13. package/lib/Signal/Group/sender-key-state.js +47 -16
  14. package/lib/Signal/libsignal.d.ts +7 -3
  15. package/lib/Signal/libsignal.js +224 -39
  16. package/lib/Signal/lid-mapping.d.ts +26 -0
  17. package/lib/Signal/lid-mapping.js +146 -0
  18. package/lib/Socket/Client/index.d.ts +2 -3
  19. package/lib/Socket/Client/index.js +2 -3
  20. package/lib/Socket/Client/{abstract-socket-client.d.ts → types.d.ts} +1 -3
  21. package/lib/Socket/Client/{web-socket-client.d.ts → websocket.d.ts} +1 -1
  22. package/lib/Socket/Client/{web-socket-client.js → websocket.js} +10 -16
  23. package/lib/Socket/business.d.ts +94 -78
  24. package/lib/Socket/business.js +130 -11
  25. package/lib/Socket/chats.d.ts +63 -233
  26. package/lib/Socket/chats.js +234 -184
  27. package/lib/Socket/communities.d.ts +232 -0
  28. package/lib/Socket/communities.js +402 -0
  29. package/lib/Socket/groups.d.ts +62 -41
  30. package/lib/Socket/groups.js +76 -64
  31. package/lib/Socket/index.d.ts +129 -83
  32. package/lib/Socket/index.js +13 -6
  33. package/lib/Socket/messages-recv.d.ts +59 -48
  34. package/lib/Socket/messages-recv.js +516 -371
  35. package/lib/Socket/messages-send.d.ts +86 -67
  36. package/lib/Socket/messages-send.js +1091 -1
  37. package/lib/Socket/mex.d.ts +2 -0
  38. package/lib/Socket/mex.js +45 -0
  39. package/lib/Socket/newsletter.d.ts +76 -64
  40. package/lib/Socket/newsletter.js +184 -1
  41. package/lib/Socket/socket.d.ts +19 -13
  42. package/lib/Socket/socket.js +805 -1
  43. package/lib/Types/Auth.d.ts +4 -10
  44. package/lib/Types/Bussines.d.ts +24 -0
  45. package/lib/Types/Bussines.js +2 -0
  46. package/lib/Types/Call.d.ts +1 -1
  47. package/lib/Types/Chat.d.ts +29 -9
  48. package/lib/Types/Chat.js +7 -1
  49. package/lib/Types/Contact.d.ts +5 -1
  50. package/lib/Types/Events.d.ts +55 -14
  51. package/lib/Types/GroupMetadata.d.ts +15 -5
  52. package/lib/Types/Label.d.ts +11 -0
  53. package/lib/Types/Label.js +1 -1
  54. package/lib/Types/LabelAssociation.js +1 -1
  55. package/lib/Types/Message.d.ts +75 -49
  56. package/lib/Types/Message.js +10 -7
  57. package/lib/Types/Newsletter.d.ts +129 -98
  58. package/lib/Types/Newsletter.js +33 -38
  59. package/lib/Types/Product.d.ts +1 -1
  60. package/lib/Types/Signal.d.ts +29 -1
  61. package/lib/Types/Socket.d.ts +48 -22
  62. package/lib/Types/State.d.ts +13 -2
  63. package/lib/Types/State.js +12 -0
  64. package/lib/Types/USync.d.ts +1 -1
  65. package/lib/Types/index.d.ts +10 -3
  66. package/lib/Types/index.js +2 -2
  67. package/lib/Utils/auth-utils.d.ts +3 -3
  68. package/lib/Utils/auth-utils.js +378 -102
  69. package/lib/Utils/baileys-event-stream.js +1 -1
  70. package/lib/Utils/business.d.ts +2 -2
  71. package/lib/Utils/business.js +19 -13
  72. package/lib/Utils/chat-utils.d.ts +21 -22
  73. package/lib/Utils/chat-utils.js +201 -154
  74. package/lib/Utils/crypto.d.ts +18 -19
  75. package/lib/Utils/crypto.js +78 -37
  76. package/lib/Utils/decode-wa-message.d.ts +34 -7
  77. package/lib/Utils/decode-wa-message.js +138 -66
  78. package/lib/Utils/event-buffer.d.ts +6 -8
  79. package/lib/Utils/event-buffer.js +81 -43
  80. package/lib/Utils/generics.d.ts +27 -27
  81. package/lib/Utils/generics.js +128 -133
  82. package/lib/Utils/history.d.ts +9 -5
  83. package/lib/Utils/history.js +17 -23
  84. package/lib/Utils/index.d.ts +2 -0
  85. package/lib/Utils/index.js +2 -0
  86. package/lib/Utils/lidToJid-test.d.ts +11 -0
  87. package/lib/Utils/lidToJid-test.js +27 -0
  88. package/lib/Utils/link-preview.d.ts +4 -4
  89. package/lib/Utils/link-preview.js +40 -12
  90. package/lib/Utils/logger.d.ts +11 -3
  91. package/lib/Utils/lt-hash.d.ts +8 -8
  92. package/lib/Utils/lt-hash.js +23 -24
  93. package/lib/Utils/make-mutex.d.ts +2 -2
  94. package/lib/Utils/make-mutex.js +3 -2
  95. package/lib/Utils/message-retry-manager.d.ts +81 -0
  96. package/lib/Utils/message-retry-manager.js +152 -0
  97. package/lib/Utils/messages-media.d.ts +37 -41
  98. package/lib/Utils/messages-media.js +252 -368
  99. package/lib/Utils/messages.d.ts +13 -15
  100. package/lib/Utils/messages.js +274 -261
  101. package/lib/Utils/noise-handler.d.ts +13 -15
  102. package/lib/Utils/noise-handler.js +20 -26
  103. package/lib/Utils/process-message.d.ts +9 -8
  104. package/lib/Utils/process-message.js +157 -93
  105. package/lib/Utils/signal.d.ts +6 -5
  106. package/lib/Utils/signal.js +37 -29
  107. package/lib/Utils/use-multi-file-auth-state.d.ts +1 -2
  108. package/lib/Utils/use-multi-file-auth-state.js +12 -7
  109. package/lib/Utils/validate-connection.d.ts +5 -6
  110. package/lib/Utils/validate-connection.js +39 -97
  111. package/lib/WABinary/constants.d.ts +24 -27
  112. package/lib/WABinary/constants.js +1276 -13
  113. package/lib/WABinary/decode.d.ts +3 -4
  114. package/lib/WABinary/decode.js +28 -14
  115. package/lib/WABinary/encode.d.ts +1 -2
  116. package/lib/WABinary/encode.js +134 -147
  117. package/lib/WABinary/generic-utils.d.ts +4 -7
  118. package/lib/WABinary/generic-utils.js +40 -125
  119. package/lib/WABinary/jid-utils.d.ts +13 -8
  120. package/lib/WABinary/jid-utils.js +27 -16
  121. package/lib/WAM/BinaryInfo.d.ts +2 -11
  122. package/lib/WAM/constants.d.ts +3 -2
  123. package/lib/WAM/constants.js +2252 -2359
  124. package/lib/WAM/encode.d.ts +1 -2
  125. package/lib/WAM/encode.js +8 -11
  126. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +2 -2
  127. package/lib/WAUSync/Protocols/USyncContactProtocol.js +3 -4
  128. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -2
  129. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +5 -5
  130. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -2
  131. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +5 -5
  132. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -2
  133. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +5 -6
  134. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +2 -2
  135. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +1 -1
  136. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +4 -3
  137. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +11 -3
  138. package/lib/WAUSync/USyncQuery.d.ts +2 -2
  139. package/lib/WAUSync/USyncQuery.js +19 -15
  140. package/lib/WAUSync/USyncUser.d.ts +5 -5
  141. package/lib/WAUSync/index.d.ts +1 -1
  142. package/lib/WAUSync/index.js +1 -1
  143. package/package.json +102 -102
  144. package/lib/Defaults/baileys-version.json +0 -3
  145. package/lib/Defaults/phonenumber-mcc.json +0 -223
  146. package/lib/Signal/Group/queue-job.d.ts +0 -1
  147. package/lib/Signal/Group/queue-job.js +0 -57
  148. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  149. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  150. package/lib/Socket/hbmods.d.ts +0 -253
  151. package/lib/Socket/hbmods.js +0 -1
  152. package/lib/Socket/registration.d.ts +0 -267
  153. package/lib/Socket/registration.js +0 -166
  154. package/lib/Socket/usync.d.ts +0 -36
  155. package/lib/Socket/usync.js +0 -70
  156. /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
@@ -1,41 +1,40 @@
1
- /// <reference types="node" />
2
- import { KeyPair } from '../Types';
1
+ import type { KeyPair } from '../Types';
3
2
  /** prefix version byte to the pub keys, required for some curve crypto functions */
4
- export declare const generateSignalPubKey: (pubKey: Uint8Array | Buffer) => Uint8Array | Buffer;
3
+ export declare const generateSignalPubKey: (pubKey: Uint8Array | Buffer) => Uint8Array<ArrayBufferLike> | Buffer<ArrayBufferLike>;
5
4
  export declare const Curve: {
6
5
  generateKeyPair: () => KeyPair;
7
- sharedKey: (privateKey: Uint8Array, publicKey: Uint8Array) => Buffer;
8
- sign: (privateKey: Uint8Array, buf: Uint8Array) => any;
6
+ sharedKey: (privateKey: Uint8Array, publicKey: Uint8Array) => Buffer<ArrayBuffer>;
7
+ sign: (privateKey: Uint8Array, buf: Uint8Array) => Uint8Array<ArrayBufferLike>;
9
8
  verify: (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => boolean;
10
9
  };
11
10
  export declare const signedKeyPair: (identityKeyPair: KeyPair, keyId: number) => {
12
11
  keyPair: KeyPair;
13
- signature: any;
12
+ signature: Uint8Array<ArrayBufferLike>;
14
13
  keyId: number;
15
14
  };
16
15
  /**
17
16
  * encrypt AES 256 GCM;
18
17
  * where the tag tag is suffixed to the ciphertext
19
18
  * */
20
- export declare function aesEncryptGCM(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer;
19
+ export declare function aesEncryptGCM(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer<ArrayBuffer>;
21
20
  /**
22
21
  * decrypt AES 256 GCM;
23
22
  * where the auth tag is suffixed to the ciphertext
24
23
  * */
25
- export declare function aesDecryptGCM(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer;
26
- export declare function aesEncryptCTR(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array): Buffer;
27
- export declare function aesDecryptCTR(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array): Buffer;
24
+ export declare function aesDecryptGCM(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer<ArrayBuffer>;
25
+ export declare function aesEncryptCTR(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array): Buffer<ArrayBuffer>;
26
+ export declare function aesDecryptCTR(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array): Buffer<ArrayBuffer>;
28
27
  /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
29
- export declare function aesDecrypt(buffer: Buffer, key: Buffer): Buffer;
28
+ export declare function aesDecrypt(buffer: Buffer, key: Buffer): Buffer<ArrayBuffer>;
30
29
  /** decrypt AES 256 CBC */
31
- export declare function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer): Buffer;
32
- export declare function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer): Buffer;
33
- export declare function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer): Buffer;
34
- export declare function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant?: 'sha256' | 'sha512'): Buffer;
35
- export declare function sha256(buffer: Buffer): Buffer;
36
- export declare function md5(buffer: Buffer): Buffer;
30
+ export declare function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer): Buffer<ArrayBuffer>;
31
+ export declare function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer): Buffer<ArrayBuffer>;
32
+ export declare function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer): Buffer<ArrayBuffer>;
33
+ export declare function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant?: 'sha256' | 'sha512'): Buffer<ArrayBufferLike>;
34
+ export declare function sha256(buffer: Buffer): Buffer<ArrayBufferLike>;
35
+ export declare function md5(buffer: Buffer): Buffer<ArrayBufferLike>;
37
36
  export declare function hkdf(buffer: Uint8Array | Buffer, expandedLength: number, info: {
38
37
  salt?: Buffer;
39
38
  info?: string;
40
- }): Buffer;
41
- export declare function derivePairingCodeKey(pairingCode: string, salt: Buffer): Buffer;
39
+ }): Promise<Buffer>;
40
+ export declare function derivePairingCodeKey(pairingCode: string, salt: Buffer): Promise<Buffer>;
@@ -15,30 +15,49 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
28
35
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.derivePairingCodeKey = exports.hkdf = exports.md5 = exports.sha256 = exports.hmacSign = exports.aesEncrypWithIV = exports.aesEncrypt = exports.aesDecryptWithIV = exports.aesDecrypt = exports.aesDecryptCTR = exports.aesEncryptCTR = exports.aesDecryptGCM = exports.aesEncryptGCM = exports.signedKeyPair = exports.Curve = exports.generateSignalPubKey = void 0;
36
+ exports.signedKeyPair = exports.Curve = exports.generateSignalPubKey = void 0;
37
+ exports.aesEncryptGCM = aesEncryptGCM;
38
+ exports.aesDecryptGCM = aesDecryptGCM;
39
+ exports.aesEncryptCTR = aesEncryptCTR;
40
+ exports.aesDecryptCTR = aesDecryptCTR;
41
+ exports.aesDecrypt = aesDecrypt;
42
+ exports.aesDecryptWithIV = aesDecryptWithIV;
43
+ exports.aesEncrypt = aesEncrypt;
44
+ exports.aesEncrypWithIV = aesEncrypWithIV;
45
+ exports.hmacSign = hmacSign;
46
+ exports.sha256 = sha256;
47
+ exports.md5 = md5;
48
+ exports.hkdf = hkdf;
49
+ exports.derivePairingCodeKey = derivePairingCodeKey;
30
50
  const crypto_1 = require("crypto");
31
- const futoin_hkdf_1 = __importDefault(require("futoin-hkdf"));
32
- const libsignal = __importStar(require("libsignal"));
51
+ const curve = __importStar(require("libsignal/src/curve"));
33
52
  const Defaults_1 = require("../Defaults");
53
+ // insure browser & node compatibility
54
+ const { subtle } = globalThis.crypto;
34
55
  /** prefix version byte to the pub keys, required for some curve crypto functions */
35
- const generateSignalPubKey = (pubKey) => (pubKey.length === 33
36
- ? pubKey
37
- : Buffer.concat([Defaults_1.KEY_BUNDLE_TYPE, pubKey]));
56
+ const generateSignalPubKey = (pubKey) => pubKey.length === 33 ? pubKey : Buffer.concat([Defaults_1.KEY_BUNDLE_TYPE, pubKey]);
38
57
  exports.generateSignalPubKey = generateSignalPubKey;
39
58
  exports.Curve = {
40
59
  generateKeyPair: () => {
41
- const { pubKey, privKey } = libsignal.curve.generateKeyPair();
60
+ const { pubKey, privKey } = curve.generateKeyPair();
42
61
  return {
43
62
  private: Buffer.from(privKey),
44
63
  // remove version byte
@@ -46,13 +65,13 @@ exports.Curve = {
46
65
  };
47
66
  },
48
67
  sharedKey: (privateKey, publicKey) => {
49
- const shared = libsignal.curve.calculateAgreement((0, exports.generateSignalPubKey)(publicKey), privateKey);
68
+ const shared = curve.calculateAgreement((0, exports.generateSignalPubKey)(publicKey), privateKey);
50
69
  return Buffer.from(shared);
51
70
  },
52
- sign: (privateKey, buf) => (libsignal.curve.calculateSignature(privateKey, buf)),
71
+ sign: (privateKey, buf) => curve.calculateSignature(privateKey, buf),
53
72
  verify: (pubKey, message, signature) => {
54
73
  try {
55
- libsignal.curve.verifySignature((0, exports.generateSignalPubKey)(pubKey), message, signature);
74
+ curve.verifySignature((0, exports.generateSignalPubKey)(pubKey), message, signature);
56
75
  return true;
57
76
  }
58
77
  catch (error) {
@@ -77,7 +96,6 @@ function aesEncryptGCM(plaintext, key, iv, additionalData) {
77
96
  cipher.setAAD(additionalData);
78
97
  return Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]);
79
98
  }
80
- exports.aesEncryptGCM = aesEncryptGCM;
81
99
  /**
82
100
  * decrypt AES 256 GCM;
83
101
  * where the auth tag is suffixed to the ciphertext
@@ -92,60 +110,83 @@ function aesDecryptGCM(ciphertext, key, iv, additionalData) {
92
110
  decipher.setAuthTag(tag);
93
111
  return Buffer.concat([decipher.update(enc), decipher.final()]);
94
112
  }
95
- exports.aesDecryptGCM = aesDecryptGCM;
96
113
  function aesEncryptCTR(plaintext, key, iv) {
97
114
  const cipher = (0, crypto_1.createCipheriv)('aes-256-ctr', key, iv);
98
115
  return Buffer.concat([cipher.update(plaintext), cipher.final()]);
99
116
  }
100
- exports.aesEncryptCTR = aesEncryptCTR;
101
117
  function aesDecryptCTR(ciphertext, key, iv) {
102
118
  const decipher = (0, crypto_1.createDecipheriv)('aes-256-ctr', key, iv);
103
119
  return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
104
120
  }
105
- exports.aesDecryptCTR = aesDecryptCTR;
106
121
  /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
107
122
  function aesDecrypt(buffer, key) {
108
123
  return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16));
109
124
  }
110
- exports.aesDecrypt = aesDecrypt;
111
125
  /** decrypt AES 256 CBC */
112
126
  function aesDecryptWithIV(buffer, key, IV) {
113
127
  const aes = (0, crypto_1.createDecipheriv)('aes-256-cbc', key, IV);
114
128
  return Buffer.concat([aes.update(buffer), aes.final()]);
115
129
  }
116
- exports.aesDecryptWithIV = aesDecryptWithIV;
117
130
  // encrypt AES 256 CBC; where a random IV is prefixed to the buffer
118
131
  function aesEncrypt(buffer, key) {
119
132
  const IV = (0, crypto_1.randomBytes)(16);
120
133
  const aes = (0, crypto_1.createCipheriv)('aes-256-cbc', key, IV);
121
134
  return Buffer.concat([IV, aes.update(buffer), aes.final()]); // prefix IV to the buffer
122
135
  }
123
- exports.aesEncrypt = aesEncrypt;
124
136
  // encrypt AES 256 CBC with a given IV
125
137
  function aesEncrypWithIV(buffer, key, IV) {
126
138
  const aes = (0, crypto_1.createCipheriv)('aes-256-cbc', key, IV);
127
139
  return Buffer.concat([aes.update(buffer), aes.final()]); // prefix IV to the buffer
128
140
  }
129
- exports.aesEncrypWithIV = aesEncrypWithIV;
130
141
  // sign HMAC using SHA 256
131
142
  function hmacSign(buffer, key, variant = 'sha256') {
132
143
  return (0, crypto_1.createHmac)(variant, key).update(buffer).digest();
133
144
  }
134
- exports.hmacSign = hmacSign;
135
145
  function sha256(buffer) {
136
146
  return (0, crypto_1.createHash)('sha256').update(buffer).digest();
137
147
  }
138
- exports.sha256 = sha256;
139
148
  function md5(buffer) {
140
149
  return (0, crypto_1.createHash)('md5').update(buffer).digest();
141
150
  }
142
- exports.md5 = md5;
143
151
  // HKDF key expansion
144
- function hkdf(buffer, expandedLength, info) {
145
- return (0, futoin_hkdf_1.default)(!Buffer.isBuffer(buffer) ? Buffer.from(buffer) : buffer, expandedLength, info);
152
+ async function hkdf(buffer, expandedLength, info) {
153
+ // Normalize to a Uint8Array whose underlying buffer is a regular ArrayBuffer (not ArrayBufferLike)
154
+ // Cloning via new Uint8Array(...) guarantees the generic parameter is ArrayBuffer which satisfies WebCrypto types.
155
+ const inputKeyMaterial = new Uint8Array(buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer));
156
+ // Set default values if not provided
157
+ const salt = info.salt ? new Uint8Array(info.salt) : new Uint8Array(0);
158
+ const infoBytes = info.info ? new TextEncoder().encode(info.info) : new Uint8Array(0);
159
+ // Import the input key material (cast to BufferSource to appease TS DOM typings)
160
+ const importedKey = await subtle.importKey('raw', inputKeyMaterial, { name: 'HKDF' }, false, [
161
+ 'deriveBits'
162
+ ]);
163
+ // Derive bits using HKDF
164
+ const derivedBits = await subtle.deriveBits({
165
+ name: 'HKDF',
166
+ hash: 'SHA-256',
167
+ salt: salt,
168
+ info: infoBytes
169
+ }, importedKey, expandedLength * 8 // Convert bytes to bits
170
+ );
171
+ return Buffer.from(derivedBits);
146
172
  }
147
- exports.hkdf = hkdf;
148
- function derivePairingCodeKey(pairingCode, salt) {
149
- return (0, crypto_1.pbkdf2Sync)(pairingCode, salt, 2 << 16, 32, 'sha256');
173
+ async function derivePairingCodeKey(pairingCode, salt) {
174
+ // Convert inputs to formats Web Crypto API can work with
175
+ const encoder = new TextEncoder();
176
+ const pairingCodeBuffer = encoder.encode(pairingCode);
177
+ const saltBuffer = new Uint8Array(salt instanceof Uint8Array ? salt : new Uint8Array(salt));
178
+ // Import the pairing code as key material
179
+ const keyMaterial = await subtle.importKey('raw', pairingCodeBuffer, { name: 'PBKDF2' }, false, [
180
+ 'deriveBits'
181
+ ]);
182
+ // Derive bits using PBKDF2 with the same parameters
183
+ // 2 << 16 = 131,072 iterations
184
+ const derivedBits = await subtle.deriveBits({
185
+ name: 'PBKDF2',
186
+ salt: saltBuffer,
187
+ iterations: 2 << 16,
188
+ hash: 'SHA-256'
189
+ }, keyMaterial, 32 * 8 // 32 bytes * 8 = 256 bits
190
+ );
191
+ return Buffer.from(derivedBits);
150
192
  }
151
- exports.derivePairingCodeKey = derivePairingCodeKey;
@@ -1,18 +1,45 @@
1
- import { Logger } from 'pino';
2
- import { proto } from '../../WAProto';
3
- import { SignalRepository } from '../Types';
4
- import { BinaryNode } from '../WABinary';
1
+ import type { WAMessage } from '../Types';
2
+ import type { SignalRepositoryWithLIDStore } from '../Types/Signal';
3
+ import { type BinaryNode } from '../WABinary';
4
+ import type { ILogger } from './logger';
5
+ export declare const NO_MESSAGE_FOUND_ERROR_TEXT = "Message absent from node";
6
+ export declare const MISSING_KEYS_ERROR_TEXT = "Key used already or never filled";
7
+ export declare const DECRYPTION_RETRY_CONFIG: {
8
+ maxRetries: number;
9
+ baseDelayMs: number;
10
+ sessionRecordErrors: string[];
11
+ };
12
+ export declare const NACK_REASONS: {
13
+ ParsingError: number;
14
+ UnrecognizedStanza: number;
15
+ UnrecognizedStanzaClass: number;
16
+ UnrecognizedStanzaType: number;
17
+ InvalidProtobuf: number;
18
+ InvalidHostedCompanionStanza: number;
19
+ MissingMessageSecret: number;
20
+ SignalErrorOldCounter: number;
21
+ MessageDeletedOnPeer: number;
22
+ UnhandledError: number;
23
+ UnsupportedAdminRevoke: number;
24
+ UnsupportedLIDGroup: number;
25
+ DBOperationFailed: number;
26
+ };
27
+ export declare const extractAddressingContext: (stanza: BinaryNode) => {
28
+ addressingMode: string;
29
+ senderAlt: string;
30
+ recipientAlt: string;
31
+ };
5
32
  /**
6
33
  * Decode the received node as a message.
7
34
  * @note this will only parse the message, not decrypt it
8
35
  */
9
36
  export declare function decodeMessageNode(stanza: BinaryNode, meId: string, meLid: string): {
10
- fullMessage: proto.IWebMessageInfo;
37
+ fullMessage: WAMessage;
11
38
  author: string;
12
39
  sender: string;
13
40
  };
14
- export declare const decryptMessageNode: (stanza: BinaryNode, meId: string, meLid: string, repository: SignalRepository, logger: Logger) => {
15
- fullMessage: proto.IWebMessageInfo;
41
+ export declare const decryptMessageNode: (stanza: BinaryNode, meId: string, meLid: string, repository: SignalRepositoryWithLIDStore, logger: ILogger) => {
42
+ fullMessage: WAMessage;
16
43
  category: string;
17
44
  author: string;
18
45
  decrypt(): Promise<void>;
@@ -1,17 +1,87 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.decryptMessageNode = exports.decodeMessageNode = void 0;
3
+ exports.decryptMessageNode = exports.extractAddressingContext = exports.NACK_REASONS = exports.DECRYPTION_RETRY_CONFIG = exports.MISSING_KEYS_ERROR_TEXT = exports.NO_MESSAGE_FOUND_ERROR_TEXT = void 0;
4
+ exports.decodeMessageNode = decodeMessageNode;
4
5
  const boom_1 = require("@hapi/boom");
5
- const WAProto_1 = require("../../WAProto");
6
+ const index_js_1 = require("../../WAProto/index.js");
6
7
  const WABinary_1 = require("../WABinary");
7
8
  const generics_1 = require("./generics");
8
- const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node';
9
+ const getDecryptionJid = async (sender, repository) => {
10
+ if (!sender.includes('@s.whatsapp.net')) {
11
+ return sender;
12
+ }
13
+ return (await repository.lidMapping.getLIDForPN(sender));
14
+ };
15
+ const storeMappingFromEnvelope = async (stanza, sender, decryptionJid, repository, logger) => {
16
+ const { senderAlt } = (0, exports.extractAddressingContext)(stanza);
17
+ if (senderAlt && (0, WABinary_1.isLidUser)(senderAlt) && (0, WABinary_1.isPnUser)(sender) && decryptionJid === sender) {
18
+ try {
19
+ await repository.lidMapping.storeLIDPNMappings([{ lid: senderAlt, pn: sender }]);
20
+ logger.debug({ sender, senderAlt }, 'Stored LID mapping from envelope');
21
+ }
22
+ catch (error) {
23
+ logger.warn({ sender, senderAlt, error }, 'Failed to store LID mapping');
24
+ }
25
+ }
26
+ };
27
+ exports.NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node';
28
+ exports.MISSING_KEYS_ERROR_TEXT = 'Key used already or never filled';
29
+ // Retry configuration for failed decryption
30
+ exports.DECRYPTION_RETRY_CONFIG = {
31
+ maxRetries: 3,
32
+ baseDelayMs: 100,
33
+ sessionRecordErrors: ['No session record', 'SessionError: No session record']
34
+ };
35
+ exports.NACK_REASONS = {
36
+ ParsingError: 487,
37
+ UnrecognizedStanza: 488,
38
+ UnrecognizedStanzaClass: 489,
39
+ UnrecognizedStanzaType: 490,
40
+ InvalidProtobuf: 491,
41
+ InvalidHostedCompanionStanza: 493,
42
+ MissingMessageSecret: 495,
43
+ SignalErrorOldCounter: 496,
44
+ MessageDeletedOnPeer: 499,
45
+ UnhandledError: 500,
46
+ UnsupportedAdminRevoke: 550,
47
+ UnsupportedLIDGroup: 551,
48
+ DBOperationFailed: 552
49
+ };
50
+ const extractAddressingContext = (stanza) => {
51
+ let senderAlt;
52
+ let recipientAlt;
53
+ const sender = stanza.attrs.participant || stanza.attrs.from;
54
+ const addressingMode = stanza.attrs.addressing_mode || (sender?.endsWith('lid') ? 'lid' : 'pn');
55
+ if (addressingMode === 'lid') {
56
+ // Message is LID-addressed: sender is LID, extract corresponding PN
57
+ // without device data
58
+ senderAlt = stanza.attrs.participant_pn || stanza.attrs.sender_pn || stanza.attrs.peer_recipient_pn;
59
+ recipientAlt = stanza.attrs.recipient_pn;
60
+ // with device data
61
+ if (sender && senderAlt)
62
+ senderAlt = (0, WABinary_1.transferDevice)(sender, senderAlt);
63
+ }
64
+ else {
65
+ // Message is PN-addressed: sender is PN, extract corresponding LID
66
+ // without device data
67
+ senderAlt = stanza.attrs.participant_lid || stanza.attrs.sender_lid || stanza.attrs.peer_recipient_lid;
68
+ recipientAlt = stanza.attrs.recipient_lid;
69
+ //with device data
70
+ if (sender && senderAlt)
71
+ senderAlt = (0, WABinary_1.transferDevice)(sender, senderAlt);
72
+ }
73
+ return {
74
+ addressingMode,
75
+ senderAlt,
76
+ recipientAlt
77
+ };
78
+ };
79
+ exports.extractAddressingContext = extractAddressingContext;
9
80
  /**
10
81
  * Decode the received node as a message.
11
82
  * @note this will only parse the message, not decrypt it
12
83
  */
13
84
  function decodeMessageNode(stanza, meId, meLid) {
14
- var _a, _b;
15
85
  let msgType;
16
86
  let chatId;
17
87
  let author;
@@ -19,24 +89,12 @@ function decodeMessageNode(stanza, meId, meLid) {
19
89
  const from = stanza.attrs.from;
20
90
  const participant = stanza.attrs.participant;
21
91
  const recipient = stanza.attrs.recipient;
92
+ const addressingContext = (0, exports.extractAddressingContext)(stanza);
22
93
  const isMe = (jid) => (0, WABinary_1.areJidsSameUser)(jid, meId);
23
94
  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
- }
31
- else {
32
- chatId = from;
33
- }
34
- msgType = 'chat';
35
- author = from;
36
- }
37
- else if ((0, WABinary_1.isLidUser)(from)) {
38
- if (recipient) {
39
- if (!isMeLid(from)) {
95
+ if ((0, WABinary_1.isPnUser)(from) || (0, WABinary_1.isLidUser)(from)) {
96
+ if (recipient && !(0, WABinary_1.isJidMetaAI)(recipient)) {
97
+ if (!isMe(from) && !isMeLid(from)) {
40
98
  throw new boom_1.Boom('receipient present, but msg not from me', { data: stanza });
41
99
  }
42
100
  chatId = recipient;
@@ -69,21 +127,24 @@ function decodeMessageNode(stanza, meId, meLid) {
69
127
  chatId = from;
70
128
  author = participant;
71
129
  }
72
- else if ((0, WABinary_1.isJidNewsLetter)(from)) {
130
+ else if ((0, WABinary_1.isJidNewsletter)(from)) {
73
131
  msgType = 'newsletter';
74
- author = from;
75
132
  chatId = from;
133
+ author = from;
76
134
  }
77
135
  else {
78
136
  throw new boom_1.Boom('Unknown message type', { data: stanza });
79
137
  }
80
- const fromMe = (0, WABinary_1.isJidNewsLetter)(from) ? !!((_a = stanza.attrs) === null || _a === void 0 ? void 0 : _a.is_sender) : ((0, WABinary_1.isLidUser)(from) ? isMeLid : isMe)(stanza.attrs.participant || stanza.attrs.from);
81
- const pushname = stanza.attrs.notify;
138
+ const fromMe = ((0, WABinary_1.isLidUser)(from) ? isMeLid : isMe)((stanza.attrs.participant || stanza.attrs.from));
139
+ const pushname = stanza?.attrs?.notify;
82
140
  const key = {
83
141
  remoteJid: chatId,
142
+ remoteJidAlt: !(0, WABinary_1.isJidGroup)(chatId) ? addressingContext.senderAlt : undefined,
84
143
  fromMe,
85
144
  id: msgId,
86
- participant
145
+ participant,
146
+ participantAlt: (0, WABinary_1.isJidGroup)(chatId) ? addressingContext.senderAlt : undefined,
147
+ ...(msgType === 'newsletter' && stanza.attrs.server_id ? { server_id: stanza.attrs.server_id } : {})
87
148
  };
88
149
  const fullMessage = {
89
150
  key,
@@ -91,11 +152,8 @@ function decodeMessageNode(stanza, meId, meLid) {
91
152
  pushName: pushname,
92
153
  broadcast: (0, WABinary_1.isJidBroadcast)(from)
93
154
  };
94
- if (msgType === 'newsletter') {
95
- fullMessage.newsletterServerId = +((_b = stanza.attrs) === null || _b === void 0 ? void 0 : _b.server_id);
96
- }
97
155
  if (key.fromMe) {
98
- fullMessage.status = WAProto_1.proto.WebMessageInfo.Status.SERVER_ACK;
156
+ fullMessage.status = index_js_1.proto.WebMessageInfo.Status.SERVER_ACK;
99
157
  }
100
158
  return {
101
159
  fullMessage,
@@ -103,7 +161,6 @@ function decodeMessageNode(stanza, meId, meLid) {
103
161
  sender: msgType === 'chat' ? author : chatId
104
162
  };
105
163
  }
106
- exports.decodeMessageNode = decodeMessageNode;
107
164
  const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
108
165
  const { fullMessage, author, sender } = decodeMessageNode(stanza, meId, meLid);
109
166
  return {
@@ -111,36 +168,18 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
111
168
  category: stanza.attrs.category,
112
169
  author,
113
170
  async decrypt() {
114
- var _a;
115
171
  let decryptables = 0;
116
- async function processSenderKeyDistribution(msg) {
117
- if (msg.senderKeyDistributionMessage) {
118
- try {
119
- await repository.processSenderKeyDistributionMessage({
120
- authorJid: author,
121
- item: msg.senderKeyDistributionMessage
122
- });
123
- }
124
- catch (err) {
125
- logger.error({ key: fullMessage.key, err }, 'failed to process senderKeyDistribution');
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(node === null || node === void 0 ? void 0 : node.content);
132
- await processSenderKeyDistribution(msg);
133
- fullMessage.message = msg;
134
- decryptables += 1;
135
- }
136
- else if (Array.isArray(stanza.content)) {
172
+ if (Array.isArray(stanza.content)) {
137
173
  for (const { tag, attrs, content } of stanza.content) {
138
174
  if (tag === 'verified_name' && content instanceof Uint8Array) {
139
- const cert = WAProto_1.proto.VerifiedNameCertificate.decode(content);
140
- const details = WAProto_1.proto.VerifiedNameCertificate.Details.decode(cert.details);
175
+ const cert = index_js_1.proto.VerifiedNameCertificate.decode(content);
176
+ const details = index_js_1.proto.VerifiedNameCertificate.Details.decode(cert.details);
141
177
  fullMessage.verifiedBizName = details.verifiedName;
142
178
  }
143
- if (tag !== 'enc') {
179
+ if (tag === 'unavailable' && attrs.type === 'view_once') {
180
+ fullMessage.key.isViewOnce = true; // TODO: remove from here and add a STUB TYPE
181
+ }
182
+ if (tag !== 'enc' && tag !== 'plaintext') {
144
183
  continue;
145
184
  }
146
185
  if (!(content instanceof Uint8Array)) {
@@ -148,8 +187,13 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
148
187
  }
149
188
  decryptables += 1;
150
189
  let msgBuffer;
190
+ const user = (0, WABinary_1.isPnUser)(sender) ? sender : author; // TODO: flaky logic
191
+ const decryptionJid = await getDecryptionJid(user, repository);
192
+ if (tag !== 'plaintext') {
193
+ await storeMappingFromEnvelope(stanza, user, decryptionJid, repository, logger);
194
+ }
151
195
  try {
152
- const e2eType = attrs.type;
196
+ const e2eType = tag === 'plaintext' ? 'plaintext' : attrs.type;
153
197
  switch (e2eType) {
154
198
  case 'skmsg':
155
199
  msgBuffer = await repository.decryptGroupMessage({
@@ -160,19 +204,32 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
160
204
  break;
161
205
  case 'pkmsg':
162
206
  case 'msg':
163
- const user = (0, WABinary_1.isJidUser)(sender) ? sender : author;
164
207
  msgBuffer = await repository.decryptMessage({
165
- jid: user,
208
+ jid: decryptionJid,
166
209
  type: e2eType,
167
210
  ciphertext: content
168
211
  });
169
212
  break;
213
+ case 'plaintext':
214
+ msgBuffer = content;
215
+ break;
170
216
  default:
171
217
  throw new Error(`Unknown e2e type: ${e2eType}`);
172
218
  }
173
- let msg = WAProto_1.proto.Message.decode((0, generics_1.unpadRandomMax16)(msgBuffer));
174
- msg = ((_a = msg.deviceSentMessage) === null || _a === void 0 ? void 0 : _a.message) || msg;
175
- await processSenderKeyDistribution(msg);
219
+ let msg = index_js_1.proto.Message.decode(e2eType !== 'plaintext' ? (0, generics_1.unpadRandomMax16)(msgBuffer) : msgBuffer);
220
+ msg = msg.deviceSentMessage?.message || msg;
221
+ if (msg.senderKeyDistributionMessage) {
222
+ //eslint-disable-next-line max-depth
223
+ try {
224
+ await repository.processSenderKeyDistributionMessage({
225
+ authorJid: author,
226
+ item: msg.senderKeyDistributionMessage
227
+ });
228
+ }
229
+ catch (err) {
230
+ logger.error({ key: fullMessage.key, err }, 'failed to process sender key distribution message');
231
+ }
232
+ }
176
233
  if (fullMessage.message) {
177
234
  Object.assign(fullMessage.message, msg);
178
235
  }
@@ -181,18 +238,33 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
181
238
  }
182
239
  }
183
240
  catch (err) {
184
- logger.error({ key: fullMessage.key, err }, 'failed to decrypt message');
185
- fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
186
- fullMessage.messageStubParameters = [err.message];
241
+ const errorContext = {
242
+ key: fullMessage.key,
243
+ err,
244
+ messageType: tag === 'plaintext' ? 'plaintext' : attrs.type,
245
+ sender,
246
+ author,
247
+ isSessionRecordError: isSessionRecordError(err)
248
+ };
249
+ logger.error(errorContext, 'failed to decrypt message');
250
+ fullMessage.messageStubType = index_js_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
251
+ fullMessage.messageStubParameters = [err.message.toString()];
187
252
  }
188
253
  }
189
254
  }
190
255
  // if nothing was found to decrypt
191
256
  if (!decryptables) {
192
- fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
193
- fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT, JSON.stringify(stanza, generics_1.BufferJSON.replacer)];
257
+ fullMessage.messageStubType = index_js_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
258
+ fullMessage.messageStubParameters = [exports.NO_MESSAGE_FOUND_ERROR_TEXT];
194
259
  }
195
260
  }
196
261
  };
197
262
  };
198
263
  exports.decryptMessageNode = decryptMessageNode;
264
+ /**
265
+ * Utility function to check if an error is related to missing session record
266
+ */
267
+ function isSessionRecordError(error) {
268
+ const errorMessage = error?.message || error?.toString() || '';
269
+ return exports.DECRYPTION_RETRY_CONFIG.sessionRecordErrors.some(errorPattern => errorMessage.includes(errorPattern));
270
+ }
@@ -1,5 +1,5 @@
1
- import { Logger } from 'pino';
2
- import { BaileysEventEmitter, BaileysEventMap } from '../Types';
1
+ import type { BaileysEventEmitter, BaileysEventMap } from '../Types';
2
+ import type { ILogger } from './logger';
3
3
  /**
4
4
  * A map that contains a list of all events that have been triggered
5
5
  *
@@ -10,26 +10,24 @@ import { BaileysEventEmitter, BaileysEventMap } from '../Types';
10
10
  type BaileysEventData = Partial<BaileysEventMap>;
11
11
  type BaileysBufferableEventEmitter = BaileysEventEmitter & {
12
12
  /** Use to process events in a batch */
13
- process(handler: (events: BaileysEventData) => void | Promise<void>): (() => void);
13
+ process(handler: (events: BaileysEventData) => void | Promise<void>): () => void;
14
14
  /**
15
15
  * starts buffering events, call flush() to release them
16
16
  * */
17
17
  buffer(): void;
18
18
  /** buffers all events till the promise completes */
19
- createBufferedFunction<A extends any[], T>(work: (...args: A) => Promise<T>): ((...args: A) => Promise<T>);
19
+ createBufferedFunction<A extends any[], T>(work: (...args: A) => Promise<T>): (...args: A) => Promise<T>;
20
20
  /**
21
21
  * flushes all buffered events
22
- * @param force if true, will flush all data regardless of any pending buffers
23
22
  * @returns returns true if the flush actually happened, otherwise false
24
23
  */
25
- flush(force?: boolean): boolean;
24
+ flush(): boolean;
26
25
  /** is there an ongoing buffer */
27
26
  isBuffering(): boolean;
28
27
  };
29
28
  /**
30
29
  * The event buffer logically consolidates different events into a single event
31
30
  * making the data processing more efficient.
32
- * @param ev the baileys event emitter
33
31
  */
34
- export declare const makeEventBuffer: (logger: Logger) => BaileysBufferableEventEmitter;
32
+ export declare const makeEventBuffer: (logger: ILogger) => BaileysBufferableEventEmitter;
35
33
  export {};