@pontalabs/baileys 1.0.11 → 1.1.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 (119) hide show
  1. package/README.md +96 -85
  2. package/lib/Defaults/connection.js +39 -0
  3. package/lib/Defaults/constants.js +50 -0
  4. package/lib/Defaults/history.js +13 -0
  5. package/lib/Defaults/index.js +36 -151
  6. package/lib/Defaults/media.js +43 -0
  7. package/lib/Defaults/phonenumber-mcc.json +221 -221
  8. package/lib/Defaults/prefix.js +12 -0
  9. package/lib/Defaults/vialeys-version.json +7 -0
  10. package/lib/Signal/Group/ciphertext-message.js +10 -15
  11. package/lib/Signal/Group/group-session-builder.js +34 -60
  12. package/lib/Signal/Group/group_cipher.js +69 -76
  13. package/lib/Signal/Group/index.js +41 -60
  14. package/lib/Signal/Group/keyhelper.js +12 -57
  15. package/lib/Signal/Group/sender-chain-key.js +20 -33
  16. package/lib/Signal/Group/sender-key-distribution-message.js +43 -48
  17. package/lib/Signal/Group/sender-key-message.js +58 -53
  18. package/lib/Signal/Group/sender-key-name.js +21 -31
  19. package/lib/Signal/Group/sender-key-record.js +21 -34
  20. package/lib/Signal/Group/sender-key-state.js +59 -106
  21. package/lib/Signal/Group/sender-message-key.js +16 -21
  22. package/lib/Signal/libsignal.js +282 -203
  23. package/lib/Signal/lid-mapping.js +164 -184
  24. package/lib/Socket/Client/index.js +31 -22
  25. package/lib/Socket/Client/types.js +9 -15
  26. package/lib/Socket/Client/websocket.js +42 -37
  27. package/lib/Socket/business.js +212 -336
  28. package/lib/Socket/chats.js +696 -940
  29. package/lib/Socket/community.js +454 -369
  30. package/lib/Socket/groups.js +278 -280
  31. package/lib/Socket/index.js +9 -21
  32. package/lib/Socket/messages-recv.js +1027 -1570
  33. package/lib/Socket/messages-send.js +1180 -1136
  34. package/lib/Socket/mex.js +59 -0
  35. package/lib/Socket/newsletter.js +193 -251
  36. package/lib/Socket/socket.js +758 -898
  37. package/lib/Store/index.js +35 -24
  38. package/lib/Store/make-cache-manager-store.js +53 -66
  39. package/lib/Store/make-in-memory-store.js +319 -325
  40. package/lib/Store/make-ordered-dictionary.js +49 -57
  41. package/lib/Store/object-repository.js +10 -15
  42. package/lib/Types/Auth.js +2 -3
  43. package/lib/Types/Bussines.js +2 -3
  44. package/lib/Types/Call.js +2 -3
  45. package/lib/Types/Chat.js +10 -9
  46. package/lib/Types/Contact.js +2 -3
  47. package/lib/Types/Events.js +2 -3
  48. package/lib/Types/GroupMetadata.js +2 -3
  49. package/lib/Types/Label.js +6 -12
  50. package/lib/Types/LabelAssociation.js +4 -13
  51. package/lib/Types/Message.js +10 -18
  52. package/lib/Types/MexUpdates.js +15 -18
  53. package/lib/Types/Newsletter.js +26 -34
  54. package/lib/Types/Product.js +2 -3
  55. package/lib/Types/Signal.js +2 -3
  56. package/lib/Types/Socket.js +2 -3
  57. package/lib/Types/State.js +8 -13
  58. package/lib/Types/USync.js +2 -3
  59. package/lib/Types/index.js +49 -40
  60. package/lib/Utils/auth-utils.js +190 -495
  61. package/lib/Utils/browser-utils.js +29 -0
  62. package/lib/Utils/business.js +177 -199
  63. package/lib/Utils/chat-utils.js +711 -624
  64. package/lib/Utils/crypto.js +116 -161
  65. package/lib/Utils/decode-wa-message.js +225 -321
  66. package/lib/Utils/event-buffer.js +363 -405
  67. package/lib/Utils/generics.js +318 -472
  68. package/lib/Utils/history.js +72 -76
  69. package/lib/Utils/index.js +49 -41
  70. package/lib/Utils/link-preview.js +59 -103
  71. package/lib/Utils/logger.js +4 -7
  72. package/lib/Utils/lt-hash.js +29 -42
  73. package/lib/Utils/make-mutex.js +26 -42
  74. package/lib/Utils/message-retry-manager.js +134 -160
  75. package/lib/Utils/messages-media.js +665 -731
  76. package/lib/Utils/messages.js +518 -1
  77. package/lib/Utils/noise-handler.js +127 -125
  78. package/lib/Utils/pre-key-manager.js +86 -0
  79. package/lib/Utils/process-message.js +739 -351
  80. package/lib/Utils/signal.js +146 -129
  81. package/lib/Utils/use-multi-file-auth-state.js +68 -135
  82. package/lib/Utils/validate-connection.js +183 -142
  83. package/lib/Utils/vialeys-event-stream.js +41 -0
  84. package/lib/WABinary/constants.js +1281 -1289
  85. package/lib/WABinary/decode.js +145 -200
  86. package/lib/WABinary/encode.js +149 -202
  87. package/lib/WABinary/generic-utils.js +79 -97
  88. package/lib/WABinary/index.js +36 -25
  89. package/lib/WABinary/jid-utils.js +91 -123
  90. package/lib/WABinary/types.js +2 -3
  91. package/lib/WAM/BinaryInfo.js +8 -13
  92. package/lib/WAM/constants.js +16584 -11464
  93. package/lib/WAM/encode.js +117 -133
  94. package/lib/WAM/index.js +34 -23
  95. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +62 -69
  96. package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -25
  97. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +32 -44
  98. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +13 -23
  99. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +24 -38
  100. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +17 -31
  101. package/lib/WAUSync/Protocols/index.js +37 -26
  102. package/lib/WAUSync/USyncQuery.js +66 -66
  103. package/lib/WAUSync/USyncUser.js +13 -18
  104. package/lib/WAUSync/index.js +34 -23
  105. package/lib/index.js +95 -28
  106. package/package.json +2 -1
  107. package/lib/Defaults/baileys-version.json +0 -3
  108. package/lib/Signal/Group/queue-job.d.ts +0 -1
  109. package/lib/Signal/Group/queue-job.js +0 -57
  110. package/lib/Socket/usync.d.ts +0 -37
  111. package/lib/Socket/usync.js +0 -83
  112. package/lib/Utils/baileys-event-stream.d.ts +0 -18
  113. package/lib/Utils/baileys-event-stream.js +0 -70
  114. package/lib/Utils/signal-housekeeping.d.ts +0 -19
  115. package/lib/Utils/signal-housekeeping.js +0 -73
  116. package/lib/Utils/use-mongo-file-auth-state.d.ts +0 -6
  117. package/lib/Utils/use-mongo-file-auth-state.js +0 -84
  118. package/lib/Utils/use-single-file-auth-state.d.ts +0 -13
  119. package/lib/Utils/use-single-file-auth-state.js +0 -80
@@ -1,155 +1,157 @@
1
- "use strict"
2
-
3
- Object.defineProperty(exports, "__esModule", { value: true })
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")
10
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const { Boom: Boom } = require("@hapi/boom");
4
+ const { proto: proto } = require("../../WAProto");
5
+ const {
6
+ NOISE_MODE: NOISE_MODE,
7
+ WA_CERT_DETAILS: WA_CERT_DETAILS,
8
+ } = require("../Defaults/constants");
9
+ const { decodeBinaryNode: decodeBinaryNode } = require("../WABinary");
10
+ const {
11
+ aesDecryptGCM: aesDecryptGCM,
12
+ aesEncryptGCM: aesEncryptGCM,
13
+ Curve: Curve,
14
+ hkdf: hkdf,
15
+ sha256: sha256,
16
+ } = require("./crypto");
11
17
  const generateIV = (counter) => {
12
- const iv = new ArrayBuffer(12)
13
- new DataView(iv).setUint32(8, counter)
14
- return new Uint8Array(iv)
15
- }
16
-
17
- const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
18
- logger = logger.child({ class: 'ns' })
18
+ const iv = new ArrayBuffer(12);
19
+ new DataView(iv).setUint32(8, counter);
20
+ return new Uint8Array(iv);
21
+ };
22
+ const makeNoiseHandler = ({
23
+ keyPair: { private: privateKey, public: publicKey },
24
+ NOISE_HEADER: NOISE_HEADER,
25
+ logger: logger,
26
+ routingInfo: routingInfo,
27
+ }) => {
28
+ logger = logger.child({ class: "ns" });
19
29
  const authenticate = (data) => {
20
30
  if (!isFinished) {
21
- hash = crypto_1.sha256(Buffer.concat([hash, data]))
31
+ hash = sha256(Buffer.concat([hash, data]));
22
32
  }
23
- }
33
+ };
24
34
  const encrypt = (plaintext) => {
25
- const result = crypto_1.aesEncryptGCM(plaintext, encKey, generateIV(writeCounter), hash)
26
- writeCounter += 1
27
- authenticate(result)
28
- return result
29
- }
35
+ const result = aesEncryptGCM(plaintext, encKey, generateIV(writeCounter), hash);
36
+ writeCounter += 1;
37
+ authenticate(result);
38
+ return result;
39
+ };
30
40
  const decrypt = (ciphertext) => {
31
- // before the handshake is finished, we use the same counter
32
- // after handshake, the counters are different
33
- const iv = generateIV(isFinished ? readCounter : writeCounter)
34
- const result = crypto_1.aesDecryptGCM(ciphertext, decKey, iv, hash)
41
+ const iv = generateIV(isFinished ? readCounter : writeCounter);
42
+ const result = aesDecryptGCM(ciphertext, decKey, iv, hash);
35
43
  if (isFinished) {
36
- readCounter += 1
44
+ readCounter += 1;
45
+ } else {
46
+ writeCounter += 1;
37
47
  }
38
- else {
39
- writeCounter += 1
40
- }
41
- authenticate(ciphertext)
42
- return result
43
- }
48
+ authenticate(ciphertext);
49
+ return result;
50
+ };
44
51
  const localHKDF = async (data) => {
45
- const key = await crypto_1.hkdf(Buffer.from(data), 64, { salt, info: '' })
46
- return [key.slice(0, 32), key.slice(32)]
47
- }
52
+ const key = await hkdf(Buffer.from(data), 64, { salt: salt, info: "" });
53
+ return [key.slice(0, 32), key.slice(32)];
54
+ };
48
55
  const mixIntoKey = async (data) => {
49
- const [write, read] = await localHKDF(data)
50
- salt = write
51
- encKey = read
52
- decKey = read
53
- readCounter = 0
54
- writeCounter = 0
55
- }
56
+ const [write, read] = await localHKDF(data);
57
+ salt = write;
58
+ encKey = read;
59
+ decKey = read;
60
+ readCounter = 0;
61
+ writeCounter = 0;
62
+ };
56
63
  const finishInit = async () => {
57
- const [write, read] = await localHKDF(new Uint8Array(0))
58
- encKey = write
59
- decKey = read
60
- hash = Buffer.from([])
61
- readCounter = 0
62
- writeCounter = 0
63
- isFinished = true
64
- }
65
- const data = Buffer.from(Defaults_1.NOISE_MODE)
66
- let hash = data.byteLength === 32 ? data : crypto_1.sha256(data)
67
- let salt = hash
68
- let encKey = hash
69
- let decKey = hash
70
- let readCounter = 0
71
- let writeCounter = 0
72
- let isFinished = false
73
- let sentIntro = false
74
- let inBytes = Buffer.alloc(0)
75
- authenticate(NOISE_HEADER)
76
- authenticate(publicKey)
64
+ const [write, read] = await localHKDF(new Uint8Array(0));
65
+ encKey = write;
66
+ decKey = read;
67
+ hash = Buffer.from([]);
68
+ readCounter = 0;
69
+ writeCounter = 0;
70
+ isFinished = true;
71
+ };
72
+ const data = Buffer.from(NOISE_MODE);
73
+ let hash = data.byteLength === 32 ? data : sha256(data);
74
+ let salt = hash;
75
+ let encKey = hash;
76
+ let decKey = hash;
77
+ let readCounter = 0;
78
+ let writeCounter = 0;
79
+ let isFinished = false;
80
+ let sentIntro = false;
81
+ let inBytes = Buffer.alloc(0);
82
+ authenticate(NOISE_HEADER);
83
+ authenticate(publicKey);
77
84
  return {
78
- encrypt,
79
- decrypt,
80
- authenticate,
81
- mixIntoKey,
82
- finishInit,
83
- processHandshake: async ({ serverHello }, noiseKey) => {
84
- authenticate(serverHello.ephemeral)
85
- await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral))
86
- const decStaticContent = decrypt(serverHello.static)
87
- await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent))
88
- const certDecoded = decrypt(serverHello.payload)
89
- const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded)
90
- const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details)
91
- if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
92
- throw new boom_1.Boom('certification match failed', { statusCode: 400 })
85
+ encrypt: encrypt,
86
+ decrypt: decrypt,
87
+ authenticate: authenticate,
88
+ mixIntoKey: mixIntoKey,
89
+ finishInit: finishInit,
90
+ processHandshake: async ({ serverHello: serverHello }, noiseKey) => {
91
+ authenticate(serverHello.ephemeral);
92
+ await mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral));
93
+ const decStaticContent = decrypt(serverHello.static);
94
+ await mixIntoKey(Curve.sharedKey(privateKey, decStaticContent));
95
+ const certDecoded = decrypt(serverHello.payload);
96
+ const { intermediate: certIntermediate } = proto.CertChain.decode(certDecoded);
97
+ const { issuerSerial: issuerSerial } = proto.CertChain.NoiseCertificate.Details.decode(
98
+ certIntermediate.details
99
+ );
100
+ if (issuerSerial !== WA_CERT_DETAILS.SERIAL) {
101
+ throw new Boom("certification match failed", { statusCode: 400 });
93
102
  }
94
- const keyEnc = encrypt(noiseKey.public)
95
- await mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral))
96
- return keyEnc
103
+ const keyEnc = encrypt(noiseKey.public);
104
+ await mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
105
+ return keyEnc;
97
106
  },
98
107
  encodeFrame: (data) => {
99
108
  if (isFinished) {
100
- data = encrypt(data)
109
+ data = encrypt(data);
101
110
  }
102
- let header
111
+ let header;
103
112
  if (routingInfo) {
104
- header = Buffer.alloc(7)
105
- header.write('ED', 0, 'utf8')
106
- header.writeUint8(0, 2)
107
- header.writeUint8(1, 3)
108
- header.writeUint8(routingInfo.byteLength >> 16, 4)
109
- header.writeUint16BE(routingInfo.byteLength & 65535, 5)
110
- header = Buffer.concat([header, routingInfo, NOISE_HEADER])
111
- }
112
- else {
113
- header = Buffer.from(NOISE_HEADER)
113
+ header = Buffer.alloc(7);
114
+ header.write("ED", 0, "utf8");
115
+ header.writeUint8(0, 2);
116
+ header.writeUint8(1, 3);
117
+ header.writeUint8(routingInfo.byteLength >> 16, 4);
118
+ header.writeUint16BE(routingInfo.byteLength & 65535, 5);
119
+ header = Buffer.concat([header, routingInfo, NOISE_HEADER]);
120
+ } else {
121
+ header = Buffer.from(NOISE_HEADER);
114
122
  }
115
- const introSize = sentIntro ? 0 : header.length
116
- const frame = Buffer.alloc(introSize + 3 + data.byteLength)
123
+ const introSize = sentIntro ? 0 : header.length;
124
+ const frame = Buffer.alloc(introSize + 3 + data.byteLength);
117
125
  if (!sentIntro) {
118
- frame.set(header)
119
- sentIntro = true
126
+ frame.set(header);
127
+ sentIntro = true;
120
128
  }
121
- frame.writeUInt8(data.byteLength >> 16, introSize)
122
- frame.writeUInt16BE(65535 & data.byteLength, introSize + 1)
123
- frame.set(data, introSize + 3)
124
- return frame
129
+ frame.writeUInt8(data.byteLength >> 16, introSize);
130
+ frame.writeUInt16BE(65535 & data.byteLength, introSize + 1);
131
+ frame.set(data, introSize + 3);
132
+ return frame;
125
133
  },
126
134
  decodeFrame: async (newData, onFrame) => {
127
- // the binary protocol uses its own framing mechanism
128
- // on top of the WS frames
129
- // so we get this data and separate out the frames
130
135
  const getBytesSize = () => {
131
136
  if (inBytes.length >= 3) {
132
- return (inBytes.readUInt8() << 16) | inBytes.readUInt16BE(1)
137
+ return (inBytes.readUInt8() << 16) | inBytes.readUInt16BE(1);
133
138
  }
134
- }
135
- inBytes = Buffer.concat([inBytes, newData])
136
- logger.trace(`recv ${newData.length} bytes, total recv ${inBytes.length} bytes`)
137
- let size = getBytesSize()
139
+ };
140
+ inBytes = Buffer.concat([inBytes, newData]);
141
+ logger.trace(`recv ${newData.length} bytes, total recv ${inBytes.length} bytes`);
142
+ let size = getBytesSize();
138
143
  while (size && inBytes.length >= size + 3) {
139
- let frame = inBytes.slice(3, size + 3)
140
- inBytes = inBytes.slice(size + 3)
144
+ let frame = inBytes.slice(3, size + 3);
145
+ inBytes = inBytes.slice(size + 3);
141
146
  if (isFinished) {
142
- const result = decrypt(frame)
143
- frame = await WABinary_1.decodeBinaryNode(result)
147
+ const result = decrypt(frame);
148
+ frame = await decodeBinaryNode(result);
144
149
  }
145
- logger.trace({ msg: frame?.attrs?.id }, 'recv frame')
146
- onFrame(frame)
147
- size = getBytesSize()
150
+ logger.trace({ msg: frame?.attrs?.id }, "recv frame");
151
+ onFrame(frame);
152
+ size = getBytesSize();
148
153
  }
149
- }
150
- }
151
- }
152
-
153
- module.exports = {
154
- makeNoiseHandler
155
- }
154
+ },
155
+ };
156
+ };
157
+ module.exports = { makeNoiseHandler: makeNoiseHandler };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const { default: PQueue } = require("p-queue");
4
+ class PreKeyManager {
5
+ constructor(store, logger) {
6
+ this.store = store;
7
+ this.logger = logger;
8
+ this.queues = new Map();
9
+ }
10
+ getQueue(keyType) {
11
+ if (!this.queues.has(keyType)) {
12
+ this.queues.set(keyType, new PQueue({ concurrency: 1 }));
13
+ }
14
+ return this.queues.get(keyType);
15
+ }
16
+ async processOperations(data, keyType, transactionCache, mutations, isInTransaction) {
17
+ const keyData = data[keyType];
18
+ if (!keyData) return;
19
+ return this.getQueue(keyType).add(async () => {
20
+ transactionCache[keyType] = transactionCache[keyType] || {};
21
+ mutations[keyType] = mutations[keyType] || {};
22
+ const deletions = [];
23
+ const updates = {};
24
+ for (const keyId in keyData) {
25
+ if (keyData[keyId] === null) {
26
+ deletions.push(keyId);
27
+ } else {
28
+ updates[keyId] = keyData[keyId];
29
+ }
30
+ }
31
+ if (Object.keys(updates).length > 0) {
32
+ Object.assign(transactionCache[keyType], updates);
33
+ Object.assign(mutations[keyType], updates);
34
+ }
35
+ if (deletions.length > 0) {
36
+ await this.processDeletions(
37
+ keyType,
38
+ deletions,
39
+ transactionCache,
40
+ mutations,
41
+ isInTransaction
42
+ );
43
+ }
44
+ });
45
+ }
46
+ async processDeletions(keyType, ids, transactionCache, mutations, isInTransaction) {
47
+ if (isInTransaction) {
48
+ for (const keyId of ids) {
49
+ if (transactionCache[keyType]?.[keyId]) {
50
+ transactionCache[keyType][keyId] = null;
51
+ mutations[keyType][keyId] = null;
52
+ } else {
53
+ this.logger.warn(
54
+ `Skipping deletion of non-existent ${keyType} in transaction: ${keyId}`
55
+ );
56
+ }
57
+ }
58
+ } else {
59
+ const existingKeys = await this.store.get(keyType, ids);
60
+ for (const keyId of ids) {
61
+ if (existingKeys[keyId]) {
62
+ transactionCache[keyType][keyId] = null;
63
+ mutations[keyType][keyId] = null;
64
+ } else {
65
+ this.logger.warn(`Skipping deletion of non-existent ${keyType}: ${keyId}`);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ async validateDeletions(data, keyType) {
71
+ const keyData = data[keyType];
72
+ if (!keyData) return;
73
+ return this.getQueue(keyType).add(async () => {
74
+ const deletionIds = Object.keys(keyData).filter((id) => keyData[id] === null);
75
+ if (deletionIds.length === 0) return;
76
+ const existingKeys = await this.store.get(keyType, deletionIds);
77
+ for (const keyId of deletionIds) {
78
+ if (!existingKeys[keyId]) {
79
+ this.logger.warn(`Skipping deletion of non-existent ${keyType}: ${keyId}`);
80
+ delete data[keyType][keyId];
81
+ }
82
+ }
83
+ });
84
+ }
85
+ }
86
+ module.exports = { PreKeyManager: PreKeyManager };