cuki-bailx 1.2.5 → 2.0.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 (154) hide show
  1. package/WAProto/AICommon.js +27981 -0
  2. package/WAProto/AICommon.proto +713 -0
  3. package/WAProto/Ephemeral.js +295 -0
  4. package/WAProto/Ephemeral.proto +7 -0
  5. package/WAProto/GenerateStatics.sh +4 -0
  6. package/WAProto/WAProto.proto +4775 -0
  7. package/WAProto/cuki.js +7 -0
  8. package/WAProto/index.js +56886 -17506
  9. package/lib/Defaults/baileys-version.json +2 -2
  10. package/lib/Defaults/index.js +117 -102
  11. package/lib/Socket/Client/index.js +2 -3
  12. package/lib/Socket/Client/{web-socket-client.js → websocket.js} +54 -5
  13. package/lib/Socket/chats.js +97 -90
  14. package/lib/Socket/groups.js +20 -5
  15. package/lib/Socket/index.js +2 -2
  16. package/lib/Socket/messages-recv.js +9 -65
  17. package/lib/Socket/messages-send.js +612 -286
  18. package/lib/Socket/newsletter.js +68 -41
  19. package/lib/Socket/{dugong.js → setup.js} +5 -13
  20. package/lib/Socket/socket.js +58 -32
  21. package/lib/Store/index.js +1 -3
  22. package/lib/Store/make-in-memory-store.js +26 -14
  23. package/lib/Store/make-ordered-dictionary.js +2 -2
  24. package/lib/Types/Label.js +1 -1
  25. package/lib/Types/LabelAssociation.js +1 -1
  26. package/lib/Types/Message.js +0 -2
  27. package/lib/Types/Newsletter.js +3 -17
  28. package/lib/Types/index.js +2 -2
  29. package/lib/Utils/auth-utils.js +6 -13
  30. package/lib/Utils/business.js +2 -2
  31. package/lib/Utils/chat-utils.js +36 -35
  32. package/lib/Utils/crypto.js +71 -29
  33. package/lib/Utils/decode-wa-message.js +65 -56
  34. package/lib/Utils/event-buffer.js +11 -7
  35. package/lib/Utils/generics.js +73 -23
  36. package/lib/Utils/history.js +4 -6
  37. package/lib/Utils/link-preview.js +34 -1
  38. package/lib/Utils/lt-hash.js +6 -6
  39. package/lib/Utils/messages-media.js +479 -161
  40. package/lib/Utils/messages.js +391 -77
  41. package/lib/Utils/noise-handler.js +19 -23
  42. package/lib/Utils/signal.js +47 -36
  43. package/lib/Utils/use-multi-file-auth-state.js +51 -6
  44. package/lib/Utils/validate-connection.js +94 -66
  45. package/lib/WABinary/constants.js +1276 -13
  46. package/lib/WABinary/decode.js +26 -13
  47. package/lib/WABinary/encode.js +39 -17
  48. package/lib/WABinary/generic-utils.js +2 -85
  49. package/lib/WABinary/jid-utils.js +12 -5
  50. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  51. package/lib/index.js +18 -5
  52. package/package.json +100 -105
  53. package/engine-requirements.js +0 -10
  54. package/lib/Defaults/index.d.ts +0 -53
  55. package/lib/Defaults/phonenumber-mcc.json +0 -223
  56. package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
  57. package/lib/Signal/Group/group-session-builder.d.ts +0 -14
  58. package/lib/Signal/Group/group_cipher.d.ts +0 -17
  59. package/lib/Signal/Group/index.d.ts +0 -11
  60. package/lib/Signal/Group/keyhelper.d.ts +0 -10
  61. package/lib/Signal/Group/queue-job.d.ts +0 -1
  62. package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
  63. package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
  64. package/lib/Signal/Group/sender-key-message.d.ts +0 -18
  65. package/lib/Signal/Group/sender-key-name.d.ts +0 -17
  66. package/lib/Signal/Group/sender-key-record.d.ts +0 -30
  67. package/lib/Signal/Group/sender-key-state.d.ts +0 -38
  68. package/lib/Signal/Group/sender-message-key.d.ts +0 -11
  69. package/lib/Signal/libsignal.d.ts +0 -3
  70. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
  71. package/lib/Socket/Client/index.d.ts +0 -3
  72. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  73. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  74. package/lib/Socket/Client/web-socket-client.d.ts +0 -12
  75. package/lib/Socket/business.d.ts +0 -171
  76. package/lib/Socket/chats.d.ts +0 -80
  77. package/lib/Socket/dugong.d.ts +0 -219
  78. package/lib/Socket/groups.d.ts +0 -115
  79. package/lib/Socket/index.d.ts +0 -173
  80. package/lib/Socket/messages-recv.d.ts +0 -161
  81. package/lib/Socket/messages-send.d.ts +0 -149
  82. package/lib/Socket/newsletter.d.ts +0 -134
  83. package/lib/Socket/registration.d.ts +0 -267
  84. package/lib/Socket/registration.js +0 -166
  85. package/lib/Socket/socket.d.ts +0 -43
  86. package/lib/Socket/socket.js.bak +0 -630
  87. package/lib/Socket/usync.d.ts +0 -36
  88. package/lib/Store/index.d.ts +0 -3
  89. package/lib/Store/make-cache-manager-store.d.ts +0 -13
  90. package/lib/Store/make-cache-manager-store.js +0 -83
  91. package/lib/Store/make-in-memory-store.d.ts +0 -118
  92. package/lib/Store/make-ordered-dictionary.d.ts +0 -13
  93. package/lib/Store/object-repository.d.ts +0 -10
  94. package/lib/Types/Auth.d.ts +0 -110
  95. package/lib/Types/Call.d.ts +0 -13
  96. package/lib/Types/Chat.d.ts +0 -102
  97. package/lib/Types/Contact.d.ts +0 -19
  98. package/lib/Types/Events.d.ts +0 -157
  99. package/lib/Types/GroupMetadata.d.ts +0 -55
  100. package/lib/Types/Label.d.ts +0 -35
  101. package/lib/Types/LabelAssociation.d.ts +0 -29
  102. package/lib/Types/Message.d.ts +0 -273
  103. package/lib/Types/Newsletter.d.ts +0 -92
  104. package/lib/Types/Product.d.ts +0 -78
  105. package/lib/Types/Signal.d.ts +0 -57
  106. package/lib/Types/Socket.d.ts +0 -111
  107. package/lib/Types/State.d.ts +0 -27
  108. package/lib/Types/USync.d.ts +0 -25
  109. package/lib/Types/index.d.ts +0 -57
  110. package/lib/Utils/auth-utils.d.ts +0 -18
  111. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  112. package/lib/Utils/business.d.ts +0 -22
  113. package/lib/Utils/chat-utils.d.ts +0 -71
  114. package/lib/Utils/crypto.d.ts +0 -41
  115. package/lib/Utils/decode-wa-message.d.ts +0 -19
  116. package/lib/Utils/event-buffer.d.ts +0 -35
  117. package/lib/Utils/generics.d.ts +0 -92
  118. package/lib/Utils/history.d.ts +0 -15
  119. package/lib/Utils/index.d.ts +0 -17
  120. package/lib/Utils/link-preview.d.ts +0 -21
  121. package/lib/Utils/logger.d.ts +0 -4
  122. package/lib/Utils/lt-hash.d.ts +0 -12
  123. package/lib/Utils/make-mutex.d.ts +0 -7
  124. package/lib/Utils/messages-media.d.ts +0 -116
  125. package/lib/Utils/messages.d.ts +0 -77
  126. package/lib/Utils/noise-handler.d.ts +0 -21
  127. package/lib/Utils/process-message.d.ts +0 -41
  128. package/lib/Utils/signal.d.ts +0 -32
  129. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
  130. package/lib/Utils/validate-connection.d.ts +0 -11
  131. package/lib/WABinary/constants.d.ts +0 -27
  132. package/lib/WABinary/decode.d.ts +0 -7
  133. package/lib/WABinary/encode.d.ts +0 -3
  134. package/lib/WABinary/generic-utils.d.ts +0 -16
  135. package/lib/WABinary/index.d.ts +0 -5
  136. package/lib/WABinary/jid-utils.d.ts +0 -31
  137. package/lib/WABinary/types.d.ts +0 -18
  138. package/lib/WAM/BinaryInfo.d.ts +0 -17
  139. package/lib/WAM/constants.d.ts +0 -38
  140. package/lib/WAM/encode.d.ts +0 -3
  141. package/lib/WAM/index.d.ts +0 -3
  142. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
  143. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
  144. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
  145. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
  146. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
  147. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
  148. package/lib/WAUSync/Protocols/index.d.ts +0 -4
  149. package/lib/WAUSync/USyncQuery.d.ts +0 -28
  150. package/lib/WAUSync/USyncUser.d.ts +0 -12
  151. package/lib/WAUSync/index.d.ts +0 -3
  152. package/lib/index.d.ts +0 -12
  153. package/lib/index.js.bak +0 -48
  154. /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeNoiseHandler = void 0;
4
+ // Kazumarii Baileys
4
5
  const boom_1 = require("@hapi/boom");
5
6
  const WAProto_1 = require("../../WAProto");
6
7
  const Defaults_1 = require("../Defaults");
@@ -11,7 +12,7 @@ const generateIV = (counter) => {
11
12
  new DataView(iv).setUint32(8, counter);
12
13
  return new Uint8Array(iv);
13
14
  };
14
- const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, mobile, logger, routingInfo }) => {
15
+ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey }, NOISE_HEADER, logger, routingInfo }) => {
15
16
  logger = logger.child({ class: 'ns' });
16
17
  const authenticate = (data) => {
17
18
  if (!isFinished) {
@@ -38,20 +39,20 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
38
39
  authenticate(ciphertext);
39
40
  return result;
40
41
  };
41
- const localHKDF = (data) => {
42
- const key = (0, crypto_1.hkdf)(Buffer.from(data), 64, { salt, info: '' });
42
+ const localHKDF = async (data) => {
43
+ const key = await (0, crypto_1.hkdf)(Buffer.from(data), 64, { salt, info: '' });
43
44
  return [key.slice(0, 32), key.slice(32)];
44
45
  };
45
- const mixIntoKey = (data) => {
46
- const [write, read] = localHKDF(data);
46
+ const mixIntoKey = async (data) => {
47
+ const [write, read] = await localHKDF(data);
47
48
  salt = write;
48
49
  encKey = read;
49
50
  decKey = read;
50
51
  readCounter = 0;
51
52
  writeCounter = 0;
52
53
  };
53
- const finishInit = () => {
54
- const [write, read] = localHKDF(new Uint8Array(0));
54
+ const finishInit = async () => {
55
+ const [write, read] = await localHKDF(new Uint8Array(0));
55
56
  encKey = write;
56
57
  decKey = read;
57
58
  hash = Buffer.from([]);
@@ -60,7 +61,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
60
61
  isFinished = true;
61
62
  };
62
63
  const data = Buffer.from(Defaults_1.NOISE_MODE);
63
- let hash = Buffer.from(data.byteLength === 32 ? data : (0, crypto_1.sha256)(data));
64
+ let hash = data.byteLength === 32 ? data : (0, crypto_1.sha256)(data);
64
65
  let salt = hash;
65
66
  let encKey = hash;
66
67
  let decKey = hash;
@@ -77,24 +78,19 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
77
78
  authenticate,
78
79
  mixIntoKey,
79
80
  finishInit,
80
- processHandshake: ({ serverHello }, noiseKey) => {
81
+ processHandshake: async ({ serverHello }, noiseKey) => {
81
82
  authenticate(serverHello.ephemeral);
82
- mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral));
83
+ await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral));
83
84
  const decStaticContent = decrypt(serverHello.static);
84
- mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
85
+ await mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
85
86
  const certDecoded = decrypt(serverHello.payload);
86
- if (mobile) {
87
- WAProto_1.proto.CertChain.NoiseCertificate.decode(certDecoded);
88
- }
89
- else {
90
- const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
91
- const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
92
- if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
93
- throw new boom_1.Boom('certification match failed', { statusCode: 400 });
94
- }
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 });
95
91
  }
96
92
  const keyEnc = encrypt(noiseKey.public);
97
- mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
93
+ await mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
98
94
  return keyEnc;
99
95
  },
100
96
  encodeFrame: (data) => {
@@ -125,7 +121,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
125
121
  frame.set(data, introSize + 3);
126
122
  return frame;
127
123
  },
128
- decodeFrame: (newData, onFrame) => {
124
+ decodeFrame: async (newData, onFrame) => {
129
125
  var _a;
130
126
  // the binary protocol uses its own framing mechanism
131
127
  // on top of the WS frames
@@ -143,7 +139,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
143
139
  inBytes = inBytes.slice(size + 3);
144
140
  if (isFinished) {
145
141
  const result = decrypt(frame);
146
- frame = (0, WABinary_1.decodeBinaryNode)(result);
142
+ frame = await (0, WABinary_1.decodeBinaryNode)(result);
147
143
  }
148
144
  logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
149
145
  onFrame(frame);
@@ -1,6 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNextPreKeysNode = exports.getNextPreKeys = exports.extractDeviceJids = exports.parseAndInjectE2ESessions = exports.xmppPreKey = exports.xmppSignedPreKey = exports.generateOrGetPreKeys = exports.getPreKeys = exports.createSignalIdentity = void 0;
3
+ exports.getNextPreKeysNode =
4
+ exports.getNextPreKeys =
5
+ exports.extractDeviceJids =
6
+ exports.parseAndInjectE2ESessions =
7
+ exports.xmppPreKey =
8
+ exports.xmppSignedPreKey =
9
+ exports.generateOrGetPreKeys =
10
+ exports.getPreKeys =
11
+ exports.createSignalIdentity = void 0;
12
+
13
+ const lodash_1 = require("lodash");
4
14
  const Defaults_1 = require("../Defaults");
5
15
  const WABinary_1 = require("../WABinary");
6
16
  const crypto_1 = require("./crypto");
@@ -66,46 +76,47 @@ const parseAndInjectE2ESessions = async (node, repository) => {
66
76
  for (const node of nodes) {
67
77
  (0, WABinary_1.assertNodeErrorFree)(node);
68
78
  }
69
- await Promise.all(nodes.map(async (node) => {
70
- const signedKey = (0, WABinary_1.getBinaryNodeChild)(node, 'skey');
71
- const key = (0, WABinary_1.getBinaryNodeChild)(node, 'key');
72
- const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(node, 'identity');
73
- const jid = node.attrs.jid;
74
- const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(node, 'registration', 4);
75
- await repository.injectE2ESession({
76
- jid,
77
- session: {
78
- registrationId: registrationId,
79
- identityKey: (0, crypto_1.generateSignalPubKey)(identity),
80
- signedPreKey: extractKey(signedKey),
81
- preKey: extractKey(key)
82
- }
83
- });
84
- }));
79
+ // Most of the work in repository.injectE2ESession is CPU intensive, not IO
80
+ // So Promise.all doesn't really help here,
81
+ // but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
82
+ // This way we chunk it in smaller parts and between those parts we can yield to the event loop
83
+ // It's rare case when you need to E2E sessions for so many users, but it's possible
84
+ const chunkSize = 100;
85
+ const chunks = (0, lodash_1.chunk)(nodes, chunkSize);
86
+ for (const nodesChunk of chunks) {
87
+ await Promise.all(nodesChunk.map(async (node) => {
88
+ const signedKey = (0, WABinary_1.getBinaryNodeChild)(node, 'skey');
89
+ const key = (0, WABinary_1.getBinaryNodeChild)(node, 'key');
90
+ const identity = (0, WABinary_1.getBinaryNodeChildBuffer)(node, 'identity');
91
+ const jid = node.attrs.jid;
92
+ const registrationId = (0, WABinary_1.getBinaryNodeChildUInt)(node, 'registration', 4);
93
+ await repository.injectE2ESession({
94
+ jid,
95
+ session: {
96
+ registrationId: registrationId,
97
+ identityKey: (0, crypto_1.generateSignalPubKey)(identity),
98
+ signedPreKey: extractKey(signedKey),
99
+ preKey: extractKey(key)
100
+ }
101
+ });
102
+ }));
103
+ }
85
104
  };
86
105
  exports.parseAndInjectE2ESessions = parseAndInjectE2ESessions;
87
106
  const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
88
- var _a;
89
107
  const { user: myUser, device: myDevice } = (0, WABinary_1.jidDecode)(myJid);
90
108
  const extracted = [];
91
- for (const node of result.content) {
92
- const list = (_a = (0, WABinary_1.getBinaryNodeChild)(node, 'list')) === null || _a === void 0 ? void 0 : _a.content;
93
- if (list && Array.isArray(list)) {
94
- for (const item of list) {
95
- const { user } = (0, WABinary_1.jidDecode)(item.attrs.jid);
96
- const devicesNode = (0, WABinary_1.getBinaryNodeChild)(item, 'devices');
97
- const deviceListNode = (0, WABinary_1.getBinaryNodeChild)(devicesNode, 'device-list');
98
- if (Array.isArray(deviceListNode === null || deviceListNode === void 0 ? void 0 : deviceListNode.content)) {
99
- for (const { tag, attrs } of deviceListNode.content) {
100
- const device = +attrs.id;
101
- if (tag === 'device' && // ensure the "device" tag
102
- (!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
103
- (myUser !== user || myDevice !== device) && // either different user or if me user, not this device
104
- (device === 0 || !!attrs['key-index']) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
105
- ) {
106
- extracted.push({ user, device });
107
- }
108
- }
109
+ for (const userResult of result) {
110
+ const { devices, id } = userResult;
111
+ const { user } = (0, WABinary_1.jidDecode)(id);
112
+ const deviceList = devices === null || devices === void 0 ? void 0 : devices.deviceList;
113
+ if (Array.isArray(deviceList)) {
114
+ for (const { id: device, keyIndex } of deviceList) {
115
+ if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
116
+ (myUser !== user || myDevice !== device) && // either different user or if me user, not this device
117
+ (device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
118
+ ) {
119
+ extracted.push({ user, device });
109
120
  }
110
121
  }
111
122
  }
@@ -1,11 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMultiFileAuthState = void 0;
4
+ const async_mutex_1 = require("async-mutex");
4
5
  const promises_1 = require("fs/promises");
5
6
  const path_1 = require("path");
6
7
  const WAProto_1 = require("../../WAProto");
7
8
  const auth_utils_1 = require("./auth-utils");
8
9
  const generics_1 = require("./generics");
10
+ // We need to lock files due to the fact that we are using async functions to read and write files
11
+ // https://github.com/WhiskeySockets/Baileys/issues/794
12
+ // https://github.com/nodejs/node/issues/26338
13
+ // Use a Map to store mutexes for each file path
14
+ const fileLocks = new Map();
15
+ // Get or create a mutex for a specific file path
16
+ const getFileLock = (path) => {
17
+ let mutex = fileLocks.get(path);
18
+ if (!mutex) {
19
+ mutex = new async_mutex_1.Mutex();
20
+ fileLocks.set(path, mutex);
21
+ }
22
+ return mutex;
23
+ };
9
24
  /**
10
25
  * stores the full authentication state in a single folder.
11
26
  * Far more efficient than singlefileauthstate
@@ -14,13 +29,32 @@ const generics_1 = require("./generics");
14
29
  * Would recommend writing an auth state for use with a proper SQL or No-SQL DB
15
30
  * */
16
31
  const useMultiFileAuthState = async (folder) => {
17
- const writeData = (data, file) => {
18
- return (0, promises_1.writeFile)((0, path_1.join)(folder, fixFileName(file)), JSON.stringify(data, generics_1.BufferJSON.replacer));
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ const writeData = async (data, file) => {
34
+ const filePath = (0, path_1.join)(folder, fixFileName(file));
35
+ const mutex = getFileLock(filePath);
36
+ return mutex.acquire().then(async (release) => {
37
+ try {
38
+ await (0, promises_1.writeFile)(filePath, JSON.stringify(data, generics_1.BufferJSON.replacer));
39
+ }
40
+ finally {
41
+ release();
42
+ }
43
+ });
19
44
  };
20
45
  const readData = async (file) => {
21
46
  try {
22
- const data = await (0, promises_1.readFile)((0, path_1.join)(folder, fixFileName(file)), { encoding: 'utf-8' });
23
- return JSON.parse(data, generics_1.BufferJSON.reviver);
47
+ const filePath = (0, path_1.join)(folder, fixFileName(file));
48
+ const mutex = getFileLock(filePath);
49
+ return await mutex.acquire().then(async (release) => {
50
+ try {
51
+ const data = await (0, promises_1.readFile)(filePath, { encoding: 'utf-8' });
52
+ return JSON.parse(data, generics_1.BufferJSON.reviver);
53
+ }
54
+ finally {
55
+ release();
56
+ }
57
+ });
24
58
  }
25
59
  catch (error) {
26
60
  return null;
@@ -28,7 +62,18 @@ const useMultiFileAuthState = async (folder) => {
28
62
  };
29
63
  const removeData = async (file) => {
30
64
  try {
31
- await (0, promises_1.unlink)((0, path_1.join)(folder, fixFileName(file)));
65
+ const filePath = (0, path_1.join)(folder, fixFileName(file));
66
+ const mutex = getFileLock(filePath);
67
+ return mutex.acquire().then(async (release) => {
68
+ try {
69
+ await (0, promises_1.unlink)(filePath);
70
+ }
71
+ catch (_a) {
72
+ }
73
+ finally {
74
+ release();
75
+ }
76
+ });
32
77
  }
33
78
  catch (_a) {
34
79
  }
@@ -72,7 +117,7 @@ const useMultiFileAuthState = async (folder) => {
72
117
  }
73
118
  }
74
119
  },
75
- saveCreds: () => {
120
+ saveCreds: async () => {
76
121
  return writeData(creds, 'creds.json');
77
122
  }
78
123
  };
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.encodeSignedDeviceIdentity = exports.configureSuccessfulPairing = exports.generateRegistrationNode = exports.generateLoginNode = exports.generateMobileNode = void 0;
3
+ exports.encodeSignedDeviceIdentity =
4
+ exports.configureSuccessfulPairing =
5
+ exports.generateRegistrationNode =
6
+ exports.generateLoginNode = void 0;
7
+ // Kazumarii Baileys
4
8
  const boom_1 = require("@hapi/boom");
5
9
  const crypto_1 = require("crypto");
6
10
  const WAProto_1 = require("../../WAProto");
@@ -8,107 +12,108 @@ const Defaults_1 = require("../Defaults");
8
12
  const WABinary_1 = require("../WABinary");
9
13
  const crypto_2 = require("./crypto");
10
14
  const generics_1 = require("./generics");
11
- const signal_1 = require("./signal");
15
+ const signal_1 = require("./signal");
16
+
12
17
  const getUserAgent = (config) => {
13
- var _a, _b;
14
- const osVersion = config.mobile ? '15.3.1' : '0.1';
15
- const version = config.mobile ? [2, 24, 6] : config.version;
16
- const device = config.mobile ? 'iPhone_7' : 'Desktop';
17
- const manufacturer = config.mobile ? 'Apple' : '';
18
- const platform = config.mobile ? WAProto_1.proto.ClientPayload.UserAgent.Platform.IOS : WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB;
19
- const phoneId = config.mobile ? { phoneId: config.auth.creds.phoneId } : {};
20
18
  return {
21
19
  appVersion: {
22
- primary: version[0],
23
- secondary: version[1],
24
- tertiary: version[2],
20
+ primary: config.version[0],
21
+ secondary: config.version[1],
22
+ tertiary: config.version[2],
25
23
  },
26
- platform,
24
+ platform: WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB,
27
25
  releaseChannel: WAProto_1.proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
28
- mcc: ((_a = config.auth.creds.registration) === null || _a === void 0 ? void 0 : _a.phoneNumberMobileCountryCode) || '000',
29
- mnc: ((_b = config.auth.creds.registration) === null || _b === void 0 ? void 0 : _b.phoneNumberMobileNetworkCode) || '000',
30
- osVersion: osVersion,
31
- manufacturer,
32
- device,
33
- osBuildNumber: osVersion,
26
+ osVersion: '0.1',
27
+ device: 'Desktop',
28
+ osBuildNumber: '0.1',
34
29
  localeLanguageIso6391: 'en',
35
- localeCountryIso31661Alpha2: 'US',
36
- ...phoneId
30
+ mnc: '000',
31
+ mcc: '000',
32
+ localeCountryIso31661Alpha2: config.countryCode || 'US'
37
33
  };
38
34
  };
35
+
39
36
  const PLATFORM_MAP = {
40
37
  'Mac OS': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
41
38
  'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
42
39
  };
40
+
43
41
  const getWebInfo = (config) => {
44
42
  let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
45
- if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
43
+ if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]] && config.browser[1] === 'Desktop') {
46
44
  webSubPlatform = PLATFORM_MAP[config.browser[0]];
47
45
  }
48
46
  return { webSubPlatform };
49
47
  };
48
+
50
49
  const getClientPayload = (config) => {
51
50
  const payload = {
52
51
  connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
53
52
  connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
54
53
  userAgent: getUserAgent(config),
55
54
  };
56
- if (!config.mobile) {
57
- payload.webInfo = getWebInfo(config);
58
- }
55
+ payload.webInfo = getWebInfo(config);
59
56
  return payload;
60
57
  };
61
- const generateMobileNode = (config) => {
62
- if (!config.auth.creds) {
63
- throw new boom_1.Boom('No registration data found', { data: config });
64
- }
65
- const payload = {
66
- ...getClientPayload(config),
67
- sessionId: Math.floor(Math.random() * 999999999 + 1),
68
- shortConnect: true,
69
- connectAttemptCount: 0,
70
- device: 0,
71
- dnsSource: {
72
- appCached: false,
73
- dnsMethod: WAProto_1.proto.ClientPayload.DNSSource.DNSResolutionMethod.SYSTEM,
74
- },
75
- passive: false,
76
- pushName: 'test',
77
- username: Number(`${config.auth.creds.registration.phoneNumberCountryCode}${config.auth.creds.registration.phoneNumberNationalNumber}`),
78
- };
79
- return WAProto_1.proto.ClientPayload.fromObject(payload);
80
- };
81
- exports.generateMobileNode = generateMobileNode;
58
+
82
59
  const generateLoginNode = (userJid, config) => {
83
60
  const { user, device } = (0, WABinary_1.jidDecode)(userJid);
84
61
  const payload = {
85
62
  ...getClientPayload(config),
86
63
  passive: true,
64
+ pull: true,
87
65
  username: +user,
88
66
  device: device,
67
+ lidDbMigrated: false
89
68
  };
90
69
  return WAProto_1.proto.ClientPayload.fromObject(payload);
91
70
  };
92
71
  exports.generateLoginNode = generateLoginNode;
72
+
93
73
  const getPlatformType = (platform) => {
94
74
  const platformType = platform.toUpperCase();
95
- return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.DESKTOP;
75
+ return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.CHROME;
96
76
  };
77
+
97
78
  const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
98
- // the app version needs to be md5 hashed
99
- // and passed in
100
79
  const appVersionBuf = (0, crypto_1.createHash)('md5')
101
- .update(config.version.join('.')) // join as string
80
+ .update(config.version.join('.'))
102
81
  .digest();
82
+
103
83
  const companion = {
104
84
  os: config.browser[0],
105
85
  platformType: getPlatformType(config.browser[1]),
106
86
  requireFullSync: config.syncFullHistory,
87
+ historySyncConfig: {
88
+ storageQuotaMb: 10240,
89
+ inlineInitialPayloadInE2EeMsg: true,
90
+ recentSyncDaysLimit: undefined,
91
+ supportCallLogHistory: false,
92
+ supportBotUserAgentChatHistory: true,
93
+ supportCagReactionsAndPolls: true,
94
+ supportBizHostedMsg: true,
95
+ supportRecentSyncChunkMessageCountTuning: true,
96
+ supportHostedGroupMsg: true,
97
+ supportFbidBotChatHistory: true,
98
+ supportAddOnHistorySyncMigration: undefined,
99
+ supportMessageAssociation: true,
100
+ supportGroupHistory: false,
101
+ onDemandReady: undefined,
102
+ supportGuestChat: undefined
103
+ },
104
+ version: {
105
+ primary: 10,
106
+ secondary: 15,
107
+ tertiary: 7
108
+ }
107
109
  };
110
+
108
111
  const companionProto = WAProto_1.proto.DeviceProps.encode(companion).finish();
112
+
109
113
  const registerPayload = {
110
114
  ...getClientPayload(config),
111
115
  passive: false,
116
+ pull: false,
112
117
  devicePairingData: {
113
118
  buildHash: appVersionBuf,
114
119
  deviceProps: companionProto,
@@ -123,6 +128,7 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
123
128
  return WAProto_1.proto.ClientPayload.fromObject(registerPayload);
124
129
  };
125
130
  exports.generateRegistrationNode = generateRegistrationNode;
131
+
126
132
  const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
127
133
  const msgId = stanza.attrs.id;
128
134
  const pairSuccessNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-success');
@@ -130,30 +136,52 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
130
136
  const platformNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'platform');
131
137
  const deviceNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'device');
132
138
  const businessNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'biz');
139
+
133
140
  if (!deviceIdentityNode || !deviceNode) {
134
141
  throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza });
135
142
  }
136
- const bizName = businessNode === null || businessNode === void 0 ? void 0 : businessNode.attrs.name;
143
+
144
+ const bizName = businessNode?.attrs.name;
137
145
  const jid = deviceNode.attrs.jid;
138
- const { details, hmac } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
139
- // check HMAC matches
140
- const advSign = (0, crypto_2.hmacSign)(details, Buffer.from(advSecretKey, 'base64'));
146
+ const lid = deviceNode.attrs.lid;
147
+
148
+ const { details, hmac, accountType } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
149
+
150
+ let hmacPrefix = Buffer.from([]);
151
+ if (accountType !== undefined && accountType === WAProto_1.proto.ADVEncryptionType.HOSTED) {
152
+ hmacPrefix = Buffer.from([0x06, 0x05]);
153
+ }
154
+
155
+ const advSign = (0, crypto_2.hmacSign)(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'));
141
156
  if (Buffer.compare(hmac, advSign) !== 0) {
142
157
  throw new boom_1.Boom('Invalid account signature');
143
158
  }
159
+
144
160
  const account = WAProto_1.proto.ADVSignedDeviceIdentity.decode(details);
145
161
  const { accountSignatureKey, accountSignature, details: deviceDetails } = account;
146
- // verify the device signature matches
147
- const accountMsg = Buffer.concat([Buffer.from([6, 0]), deviceDetails, signedIdentityKey.public]);
162
+
163
+ const deviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(deviceDetails);
164
+
165
+ const accountSignaturePrefix = deviceIdentity.deviceType === WAProto_1.proto.ADVEncryptionType.HOSTED
166
+ ? Buffer.from([0x06, 0x05])
167
+ : Buffer.from([0x06, 0x00]);
168
+ const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public]);
169
+
148
170
  if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
149
171
  throw new boom_1.Boom('Failed to verify account signature');
150
172
  }
151
- // sign the details with our identity key
152
- const deviceMsg = Buffer.concat([Buffer.from([6, 1]), deviceDetails, signedIdentityKey.public, accountSignatureKey]);
173
+
174
+ const deviceMsg = Buffer.concat([
175
+ Buffer.from([0x06, 0x01]),
176
+ deviceDetails,
177
+ signedIdentityKey.public,
178
+ accountSignatureKey
179
+ ]);
153
180
  account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg);
181
+
154
182
  const identity = (0, signal_1.createSignalIdentity)(jid, accountSignatureKey);
155
183
  const accountEnc = (0, exports.encodeSignedDeviceIdentity)(account, false);
156
- const deviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(account.details);
184
+
157
185
  const reply = {
158
186
  tag: 'iq',
159
187
  attrs: {
@@ -175,31 +203,31 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
175
203
  }
176
204
  ]
177
205
  };
206
+
178
207
  const authUpdate = {
179
208
  account,
180
- me: { id: jid, name: bizName },
209
+ me: { id: jid, name: bizName, lid },
181
210
  signalIdentities: [
182
211
  ...(signalIdentities || []),
183
212
  identity
184
213
  ],
185
- platform: platformNode === null || platformNode === void 0 ? void 0 : platformNode.attrs.name
214
+ platform: platformNode?.attrs.name
186
215
  };
216
+
187
217
  return {
188
218
  creds: authUpdate,
189
219
  reply
190
220
  };
191
221
  };
192
222
  exports.configureSuccessfulPairing = configureSuccessfulPairing;
223
+
193
224
  const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
194
- var _a;
195
225
  account = { ...account };
196
- // set to null if we are not to include the signature key
197
- // or if we are including the signature key but it is empty
198
- if (!includeSignatureKey || !((_a = account.accountSignatureKey) === null || _a === void 0 ? void 0 : _a.length)) {
226
+ if (!includeSignatureKey || !account.accountSignatureKey?.length) {
199
227
  account.accountSignatureKey = null;
200
228
  }
201
229
  return WAProto_1.proto.ADVSignedDeviceIdentity
202
230
  .encode(account)
203
231
  .finish();
204
232
  };
205
- exports.encodeSignedDeviceIdentity = encodeSignedDeviceIdentity;
233
+ exports.encodeSignedDeviceIdentity = encodeSignedDeviceIdentity;