@ubedsockets/baileys 1.6.6 → 1.6.7

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 (87) hide show
  1. package/WAProto/GenerateStatics.sh +4 -3
  2. package/WAProto/WAProto.proto +511 -1215
  3. package/WAProto/index.js +131318 -59331
  4. package/lib/Defaults/index.js +92 -76
  5. package/lib/Signal/Group/ciphertext-message.js +5 -2
  6. package/lib/Signal/Group/group-session-builder.js +41 -7
  7. package/lib/Signal/Group/group_cipher.js +51 -37
  8. package/lib/Signal/Group/index.js +57 -12
  9. package/lib/Signal/Group/keyhelper.js +44 -7
  10. package/lib/Signal/Group/sender-chain-key.js +15 -7
  11. package/lib/Signal/Group/sender-key-distribution-message.js +11 -8
  12. package/lib/Signal/Group/sender-key-message.js +12 -9
  13. package/lib/Signal/Group/sender-key-name.js +5 -2
  14. package/lib/Signal/Group/sender-key-record.js +21 -9
  15. package/lib/Signal/Group/sender-key-state.js +42 -27
  16. package/lib/Signal/Group/sender-message-key.js +7 -4
  17. package/lib/Signal/libsignal.js +90 -347
  18. package/lib/Socket/Client/index.js +18 -3
  19. package/lib/Socket/Client/types.js +6 -4
  20. package/lib/Socket/Client/websocket.js +78 -21
  21. package/lib/Socket/business.js +43 -162
  22. package/lib/Socket/chats.js +249 -571
  23. package/lib/Socket/groups.js +99 -114
  24. package/lib/Socket/index.js +9 -11
  25. package/lib/Socket/messages-recv.js +559 -1277
  26. package/lib/Socket/messages-send.js +669 -674
  27. package/lib/Socket/newsletter.js +286 -149
  28. package/lib/Socket/socket.js +235 -548
  29. package/lib/Types/Auth.js +2 -2
  30. package/lib/Types/Call.js +2 -2
  31. package/lib/Types/Chat.js +4 -8
  32. package/lib/Types/Contact.js +2 -2
  33. package/lib/Types/Events.js +2 -2
  34. package/lib/Types/GroupMetadata.js +2 -2
  35. package/lib/Types/Label.js +5 -3
  36. package/lib/Types/LabelAssociation.js +5 -3
  37. package/lib/Types/Message.js +7 -11
  38. package/lib/Types/Product.js +2 -2
  39. package/lib/Types/Signal.js +2 -2
  40. package/lib/Types/Socket.js +2 -3
  41. package/lib/Types/State.js +2 -56
  42. package/lib/Types/USync.js +2 -2
  43. package/lib/Types/index.js +31 -15
  44. package/lib/Utils/auth-utils.js +136 -239
  45. package/lib/Utils/business.js +69 -66
  46. package/lib/Utils/chat-utils.js +238 -380
  47. package/lib/Utils/crypto.js +127 -56
  48. package/lib/Utils/decode-wa-message.js +63 -173
  49. package/lib/Utils/event-buffer.js +70 -174
  50. package/lib/Utils/generics.js +207 -159
  51. package/lib/Utils/history.js +53 -93
  52. package/lib/Utils/index.js +33 -22
  53. package/lib/Utils/link-preview.js +58 -17
  54. package/lib/Utils/logger.js +7 -3
  55. package/lib/Utils/lt-hash.js +46 -3
  56. package/lib/Utils/make-mutex.js +34 -24
  57. package/lib/Utils/messages-media.js +744 -483
  58. package/lib/Utils/messages.js +621 -411
  59. package/lib/Utils/noise-handler.js +99 -149
  60. package/lib/Utils/process-message.js +150 -459
  61. package/lib/Utils/signal.js +73 -112
  62. package/lib/Utils/use-multi-file-auth-state.js +27 -23
  63. package/lib/Utils/validate-connection.js +104 -74
  64. package/lib/WABinary/constants.js +11 -9
  65. package/lib/WABinary/decode.js +52 -49
  66. package/lib/WABinary/encode.js +49 -19
  67. package/lib/WABinary/generic-utils.js +43 -46
  68. package/lib/WABinary/index.js +21 -6
  69. package/lib/WABinary/jid-utils.js +45 -72
  70. package/lib/WABinary/types.js +2 -2
  71. package/lib/WAM/BinaryInfo.js +5 -2
  72. package/lib/WAM/constants.js +11958 -19461
  73. package/lib/WAM/encode.js +22 -17
  74. package/lib/WAM/index.js +19 -4
  75. package/lib/WAUSync/Protocols/USyncContactProtocol.js +13 -33
  76. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
  77. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +11 -8
  78. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
  79. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
  80. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +8 -13
  81. package/lib/WAUSync/Protocols/index.js +20 -6
  82. package/lib/WAUSync/USyncQuery.js +35 -44
  83. package/lib/WAUSync/USyncUser.js +5 -10
  84. package/lib/WAUSync/index.js +19 -4
  85. package/lib/index.js +70 -11
  86. package/package.json +60 -100
  87. package/engine-requirements.js +0 -10
@@ -1,131 +1,75 @@
1
- import { Boom } from '@hapi/boom';
2
- import { proto } from '../../WAProto/index.js';
3
- import { NOISE_MODE, WA_CERT_DETAILS } from '../Defaults/index.js';
4
- import { decodeBinaryNode } from '../WABinary/index.js';
5
- import { aesDecryptGCM, aesEncryptGCM, Curve, hkdf, sha256 } from './crypto.js';
6
- const IV_LENGTH = 12;
7
- const EMPTY_BUFFER = Buffer.alloc(0);
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeNoiseHandler = void 0;
4
+
5
+ const boom_1 = require("@hapi/boom");
6
+ const WAProto_1 = require("../../WAProto");
7
+ const Defaults_1 = require("../Defaults");
8
+ const WABinary_1 = require("../WABinary");
9
+ const crypto_1 = require("./crypto");
8
10
  const generateIV = (counter) => {
9
- const iv = new ArrayBuffer(IV_LENGTH);
11
+ const iv = new ArrayBuffer(12);
10
12
  new DataView(iv).setUint32(8, counter);
11
13
  return new Uint8Array(iv);
12
14
  };
13
- class TransportState {
14
- constructor(encKey, decKey) {
15
- this.encKey = encKey;
16
- this.decKey = decKey;
17
- this.readCounter = 0;
18
- this.writeCounter = 0;
19
- this.iv = new Uint8Array(IV_LENGTH);
20
- }
21
- encrypt(plaintext) {
22
- const c = this.writeCounter++;
23
- this.iv[8] = (c >>> 24) & 0xff;
24
- this.iv[9] = (c >>> 16) & 0xff;
25
- this.iv[10] = (c >>> 8) & 0xff;
26
- this.iv[11] = c & 0xff;
27
- return aesEncryptGCM(plaintext, this.encKey, this.iv, EMPTY_BUFFER);
28
- }
29
- decrypt(ciphertext) {
30
- const c = this.readCounter++;
31
- this.iv[8] = (c >>> 24) & 0xff;
32
- this.iv[9] = (c >>> 16) & 0xff;
33
- this.iv[10] = (c >>> 8) & 0xff;
34
- this.iv[11] = c & 0xff;
35
- return aesDecryptGCM(ciphertext, this.decKey, this.iv, EMPTY_BUFFER);
36
- }
37
- }
38
- export const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
15
+ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
39
16
  logger = logger.child({ class: 'ns' });
40
- const data = Buffer.from(NOISE_MODE);
41
- let hash = data.byteLength === 32 ? data : sha256(data);
42
- let salt = hash;
43
- let encKey = hash;
44
- let decKey = hash;
45
- let counter = 0;
46
- let sentIntro = false;
47
- let inBytes = Buffer.alloc(0);
48
- let transport = null;
49
- let isWaitingForTransport = false;
50
- let pendingOnFrame = null;
51
- let introHeader;
52
- if (routingInfo) {
53
- introHeader = Buffer.alloc(7 + routingInfo.byteLength + NOISE_HEADER.length);
54
- introHeader.write('ED', 0, 'utf8');
55
- introHeader.writeUint8(0, 2);
56
- introHeader.writeUint8(1, 3);
57
- introHeader.writeUint8(routingInfo.byteLength >> 16, 4);
58
- introHeader.writeUint16BE(routingInfo.byteLength & 65535, 5);
59
- introHeader.set(routingInfo, 7);
60
- introHeader.set(NOISE_HEADER, 7 + routingInfo.byteLength);
61
- }
62
- else {
63
- introHeader = Buffer.from(NOISE_HEADER);
64
- }
65
17
  const authenticate = (data) => {
66
- if (!transport) {
67
- hash = sha256(Buffer.concat([hash, data]));
18
+ if (!isFinished) {
19
+ hash = (0, crypto_1.sha256)(Buffer.concat([hash, data]));
68
20
  }
69
21
  };
70
22
  const encrypt = (plaintext) => {
71
- if (transport) {
72
- return transport.encrypt(plaintext);
73
- }
74
- const result = aesEncryptGCM(plaintext, encKey, generateIV(counter++), hash);
23
+ const result = (0, crypto_1.aesEncryptGCM)(plaintext, encKey, generateIV(writeCounter), hash);
24
+ writeCounter += 1;
75
25
  authenticate(result);
76
26
  return result;
77
27
  };
78
28
  const decrypt = (ciphertext) => {
79
- if (transport) {
80
- return transport.decrypt(ciphertext);
29
+ // before the handshake is finished, we use the same counter
30
+ // after handshake, the counters are different
31
+ const iv = generateIV(isFinished ? readCounter : writeCounter);
32
+ const result = (0, crypto_1.aesDecryptGCM)(ciphertext, decKey, iv, hash);
33
+ if (isFinished) {
34
+ readCounter += 1;
35
+ }
36
+ else {
37
+ writeCounter += 1;
81
38
  }
82
- const result = aesDecryptGCM(ciphertext, decKey, generateIV(counter++), hash);
83
39
  authenticate(ciphertext);
84
40
  return result;
85
41
  };
86
- const localHKDF = (data) => {
87
- const key = hkdf(Buffer.from(data), 64, { salt, info: '' });
88
- return [key.subarray(0, 32), key.subarray(32)];
42
+ const localHKDF = async (data) => {
43
+ const key = await (0, crypto_1.hkdf)(Buffer.from(data), 64, { salt, info: '' });
44
+ return [key.slice(0, 32), key.slice(32)];
89
45
  };
90
- const mixIntoKey = (data) => {
91
- const [write, read] = localHKDF(data);
46
+ const mixIntoKey = async (data) => {
47
+ const [write, read] = await localHKDF(data);
92
48
  salt = write;
93
49
  encKey = read;
94
50
  decKey = read;
95
- counter = 0;
51
+ readCounter = 0;
52
+ writeCounter = 0;
96
53
  };
97
54
  const finishInit = async () => {
98
- isWaitingForTransport = true;
99
- const [write, read] = localHKDF(new Uint8Array(0));
100
- transport = new TransportState(write, read);
101
- isWaitingForTransport = false;
102
- logger.trace('Noise handler transitioned to Transport state');
103
- if (pendingOnFrame) {
104
- logger.trace({ length: inBytes.length }, 'Flushing buffered frames after transport ready');
105
- await processData(pendingOnFrame);
106
- pendingOnFrame = null;
107
- }
108
- };
109
- const processData = async (onFrame) => {
110
- let size;
111
- while (true) {
112
- if (inBytes.length < 3)
113
- return;
114
- size = (inBytes[0] << 16) | (inBytes[1] << 8) | inBytes[2];
115
- if (inBytes.length < size + 3)
116
- return;
117
- let frame = inBytes.subarray(3, size + 3);
118
- inBytes = inBytes.subarray(size + 3);
119
- if (transport) {
120
- const result = transport.decrypt(frame);
121
- frame = await decodeBinaryNode(result);
122
- }
123
- if (logger.level === 'trace') {
124
- logger.trace({ msg: frame?.attrs?.id }, 'recv frame');
125
- }
126
- onFrame(frame);
127
- }
55
+ const [write, read] = await localHKDF(new Uint8Array(0));
56
+ encKey = write;
57
+ decKey = read;
58
+ hash = Buffer.from([]);
59
+ readCounter = 0;
60
+ writeCounter = 0;
61
+ isFinished = true;
128
62
  };
63
+ const data = Buffer.from(Defaults_1.NOISE_MODE);
64
+ let hash = data.byteLength === 32 ? data : (0, crypto_1.sha256)(data);
65
+ let salt = hash;
66
+ let encKey = hash;
67
+ let decKey = hash;
68
+ let readCounter = 0;
69
+ let writeCounter = 0;
70
+ let isFinished = false;
71
+ let sentIntro = false;
72
+ let inBytes = Buffer.alloc(0);
129
73
  authenticate(NOISE_HEADER);
130
74
  authenticate(publicKey);
131
75
  return {
@@ -134,68 +78,74 @@ export const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publi
134
78
  authenticate,
135
79
  mixIntoKey,
136
80
  finishInit,
137
- processHandshake: ({ serverHello }, noiseKey) => {
81
+ processHandshake: async ({ serverHello }, noiseKey) => {
138
82
  authenticate(serverHello.ephemeral);
139
- mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral));
83
+ await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral));
140
84
  const decStaticContent = decrypt(serverHello.static);
141
- mixIntoKey(Curve.sharedKey(privateKey, decStaticContent));
85
+ await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
142
86
  const certDecoded = decrypt(serverHello.payload);
143
- const { intermediate: certIntermediate, leaf } = proto.CertChain.decode(certDecoded);
144
- // leaf
145
- if (!leaf?.details || !leaf?.signature) {
146
- throw new Boom('invalid noise leaf certificate', { statusCode: 400 });
147
- }
148
- if (!certIntermediate?.details || !certIntermediate?.signature) {
149
- throw new Boom('invalid noise intermediate certificate', { statusCode: 400 });
150
- }
151
- const details = proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
152
- const { issuerSerial } = details;
153
- const verify = Curve.verify(details.key, leaf.details, leaf.signature);
154
- const verifyIntermediate = Curve.verify(WA_CERT_DETAILS.PUBLIC_KEY, certIntermediate.details, certIntermediate.signature);
155
- if (!verify) {
156
- throw new Boom('noise certificate signature invalid', { statusCode: 400 });
157
- }
158
- if (!verifyIntermediate) {
159
- throw new Boom('noise intermediate certificate signature invalid', { statusCode: 400 });
160
- }
161
- if (issuerSerial !== WA_CERT_DETAILS.SERIAL) {
162
- throw new Boom('certification match failed', { statusCode: 400 });
87
+ const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
88
+ const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
89
+ if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
90
+ throw new boom_1.Boom('certification match failed', { statusCode: 400 }); // 🅥🅨🅩🅔🅝
163
91
  }
164
92
  const keyEnc = encrypt(noiseKey.public);
165
- mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
93
+ await mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
166
94
  return keyEnc;
167
95
  },
168
96
  encodeFrame: (data) => {
169
- if (transport) {
170
- data = transport.encrypt(data);
97
+ if (isFinished) {
98
+ data = encrypt(data);
99
+ }
100
+ let header;
101
+ if (routingInfo) {
102
+ header = Buffer.alloc(7);
103
+ header.write('ED', 0, 'utf8');
104
+ header.writeUint8(0, 2);
105
+ header.writeUint8(1, 3);
106
+ header.writeUint8(routingInfo.byteLength >> 16, 4);
107
+ header.writeUint16BE(routingInfo.byteLength & 65535, 5);
108
+ header = Buffer.concat([header, routingInfo, NOISE_HEADER]);
109
+ }
110
+ else {
111
+ header = Buffer.from(NOISE_HEADER);
171
112
  }
172
- const dataLen = data.byteLength;
173
- const introSize = sentIntro ? 0 : introHeader.length;
174
- const frame = Buffer.allocUnsafe(introSize + 3 + dataLen);
113
+ const introSize = sentIntro ? 0 : header.length;
114
+ const frame = Buffer.alloc(introSize + 3 + data.byteLength);
175
115
  if (!sentIntro) {
176
- frame.set(introHeader);
116
+ frame.set(header);
177
117
  sentIntro = true;
178
118
  }
179
- frame[introSize] = (dataLen >>> 16) & 0xff;
180
- frame[introSize + 1] = (dataLen >>> 8) & 0xff;
181
- frame[introSize + 2] = dataLen & 0xff;
119
+ frame.writeUInt8(data.byteLength >> 16, introSize);
120
+ frame.writeUInt16BE(65535 & data.byteLength, introSize + 1);
182
121
  frame.set(data, introSize + 3);
183
122
  return frame;
184
123
  },
185
124
  decodeFrame: async (newData, onFrame) => {
186
- if (isWaitingForTransport) {
187
- inBytes = Buffer.concat([inBytes, newData]);
188
- pendingOnFrame = onFrame;
189
- return;
190
- }
191
- if (inBytes.length === 0) {
192
- inBytes = Buffer.from(newData);
193
- }
194
- else {
195
- inBytes = Buffer.concat([inBytes, newData]);
125
+ var _a;
126
+ // the binary protocol uses its own framing mechanism
127
+ // on top of the WS frames
128
+ // so we get this data and separate out the frames
129
+ const getBytesSize = () => {
130
+ if (inBytes.length >= 3) {
131
+ return (inBytes.readUInt8() << 16) | inBytes.readUInt16BE(1);
132
+ }
133
+ };
134
+ inBytes = Buffer.concat([inBytes, newData]);
135
+ logger.trace(`recv ${newData.length} bytes, total recv ${inBytes.length} bytes`);
136
+ let size = getBytesSize();
137
+ while (size && inBytes.length >= size + 3) {
138
+ let frame = inBytes.slice(3, size + 3);
139
+ inBytes = inBytes.slice(size + 3);
140
+ if (isFinished) {
141
+ const result = decrypt(frame);
142
+ frame = await (0, WABinary_1.decodeBinaryNode)(result);
143
+ }
144
+ logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
145
+ onFrame(frame);
146
+ size = getBytesSize();
196
147
  }
197
- await processData(onFrame);
198
148
  }
199
149
  };
200
150
  };
201
- //# sourceMappingURL=noise-handler.js.map
151
+ exports.makeNoiseHandler = makeNoiseHandler;