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.
- package/WAProto/AICommon.js +27981 -0
- package/WAProto/AICommon.proto +713 -0
- package/WAProto/Ephemeral.js +295 -0
- package/WAProto/Ephemeral.proto +7 -0
- package/WAProto/GenerateStatics.sh +4 -0
- package/WAProto/WAProto.proto +4775 -0
- package/WAProto/cuki.js +7 -0
- package/WAProto/index.js +56886 -17506
- package/lib/Defaults/baileys-version.json +2 -2
- package/lib/Defaults/index.js +117 -102
- package/lib/Socket/Client/index.js +2 -3
- package/lib/Socket/Client/{web-socket-client.js → websocket.js} +54 -5
- package/lib/Socket/chats.js +97 -90
- package/lib/Socket/groups.js +20 -5
- package/lib/Socket/index.js +2 -2
- package/lib/Socket/messages-recv.js +9 -65
- package/lib/Socket/messages-send.js +612 -286
- package/lib/Socket/newsletter.js +68 -41
- package/lib/Socket/{dugong.js → setup.js} +5 -13
- package/lib/Socket/socket.js +58 -32
- package/lib/Store/index.js +1 -3
- package/lib/Store/make-in-memory-store.js +26 -14
- package/lib/Store/make-ordered-dictionary.js +2 -2
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Message.js +0 -2
- package/lib/Types/Newsletter.js +3 -17
- package/lib/Types/index.js +2 -2
- package/lib/Utils/auth-utils.js +6 -13
- package/lib/Utils/business.js +2 -2
- package/lib/Utils/chat-utils.js +36 -35
- package/lib/Utils/crypto.js +71 -29
- package/lib/Utils/decode-wa-message.js +65 -56
- package/lib/Utils/event-buffer.js +11 -7
- package/lib/Utils/generics.js +73 -23
- package/lib/Utils/history.js +4 -6
- package/lib/Utils/link-preview.js +34 -1
- package/lib/Utils/lt-hash.js +6 -6
- package/lib/Utils/messages-media.js +479 -161
- package/lib/Utils/messages.js +391 -77
- package/lib/Utils/noise-handler.js +19 -23
- package/lib/Utils/signal.js +47 -36
- package/lib/Utils/use-multi-file-auth-state.js +51 -6
- package/lib/Utils/validate-connection.js +94 -66
- package/lib/WABinary/constants.js +1276 -13
- package/lib/WABinary/decode.js +26 -13
- package/lib/WABinary/encode.js +39 -17
- package/lib/WABinary/generic-utils.js +2 -85
- package/lib/WABinary/jid-utils.js +12 -5
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
- package/lib/index.js +18 -5
- package/package.json +100 -105
- package/engine-requirements.js +0 -10
- package/lib/Defaults/index.d.ts +0 -53
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -9
- package/lib/Signal/Group/group-session-builder.d.ts +0 -14
- package/lib/Signal/Group/group_cipher.d.ts +0 -17
- package/lib/Signal/Group/index.d.ts +0 -11
- package/lib/Signal/Group/keyhelper.d.ts +0 -10
- package/lib/Signal/Group/queue-job.d.ts +0 -1
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -13
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -16
- package/lib/Signal/Group/sender-key-message.d.ts +0 -18
- package/lib/Signal/Group/sender-key-name.d.ts +0 -17
- package/lib/Signal/Group/sender-key-record.d.ts +0 -30
- package/lib/Signal/Group/sender-key-state.d.ts +0 -38
- package/lib/Signal/Group/sender-message-key.d.ts +0 -11
- package/lib/Signal/libsignal.d.ts +0 -3
- package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
- package/lib/Socket/Client/index.d.ts +0 -3
- package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/Client/web-socket-client.d.ts +0 -12
- package/lib/Socket/business.d.ts +0 -171
- package/lib/Socket/chats.d.ts +0 -80
- package/lib/Socket/dugong.d.ts +0 -219
- package/lib/Socket/groups.d.ts +0 -115
- package/lib/Socket/index.d.ts +0 -173
- package/lib/Socket/messages-recv.d.ts +0 -161
- package/lib/Socket/messages-send.d.ts +0 -149
- package/lib/Socket/newsletter.d.ts +0 -134
- package/lib/Socket/registration.d.ts +0 -267
- package/lib/Socket/registration.js +0 -166
- package/lib/Socket/socket.d.ts +0 -43
- package/lib/Socket/socket.js.bak +0 -630
- package/lib/Socket/usync.d.ts +0 -36
- package/lib/Store/index.d.ts +0 -3
- package/lib/Store/make-cache-manager-store.d.ts +0 -13
- package/lib/Store/make-cache-manager-store.js +0 -83
- package/lib/Store/make-in-memory-store.d.ts +0 -118
- package/lib/Store/make-ordered-dictionary.d.ts +0 -13
- package/lib/Store/object-repository.d.ts +0 -10
- package/lib/Types/Auth.d.ts +0 -110
- package/lib/Types/Call.d.ts +0 -13
- package/lib/Types/Chat.d.ts +0 -102
- package/lib/Types/Contact.d.ts +0 -19
- package/lib/Types/Events.d.ts +0 -157
- package/lib/Types/GroupMetadata.d.ts +0 -55
- package/lib/Types/Label.d.ts +0 -35
- package/lib/Types/LabelAssociation.d.ts +0 -29
- package/lib/Types/Message.d.ts +0 -273
- package/lib/Types/Newsletter.d.ts +0 -92
- package/lib/Types/Product.d.ts +0 -78
- package/lib/Types/Signal.d.ts +0 -57
- package/lib/Types/Socket.d.ts +0 -111
- package/lib/Types/State.d.ts +0 -27
- package/lib/Types/USync.d.ts +0 -25
- package/lib/Types/index.d.ts +0 -57
- package/lib/Utils/auth-utils.d.ts +0 -18
- package/lib/Utils/baileys-event-stream.d.ts +0 -16
- package/lib/Utils/business.d.ts +0 -22
- package/lib/Utils/chat-utils.d.ts +0 -71
- package/lib/Utils/crypto.d.ts +0 -41
- package/lib/Utils/decode-wa-message.d.ts +0 -19
- package/lib/Utils/event-buffer.d.ts +0 -35
- package/lib/Utils/generics.d.ts +0 -92
- package/lib/Utils/history.d.ts +0 -15
- package/lib/Utils/index.d.ts +0 -17
- package/lib/Utils/link-preview.d.ts +0 -21
- package/lib/Utils/logger.d.ts +0 -4
- package/lib/Utils/lt-hash.d.ts +0 -12
- package/lib/Utils/make-mutex.d.ts +0 -7
- package/lib/Utils/messages-media.d.ts +0 -116
- package/lib/Utils/messages.d.ts +0 -77
- package/lib/Utils/noise-handler.d.ts +0 -21
- package/lib/Utils/process-message.d.ts +0 -41
- package/lib/Utils/signal.d.ts +0 -32
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
- package/lib/Utils/validate-connection.d.ts +0 -11
- package/lib/WABinary/constants.d.ts +0 -27
- package/lib/WABinary/decode.d.ts +0 -7
- package/lib/WABinary/encode.d.ts +0 -3
- package/lib/WABinary/generic-utils.d.ts +0 -16
- package/lib/WABinary/index.d.ts +0 -5
- package/lib/WABinary/jid-utils.d.ts +0 -31
- package/lib/WABinary/types.d.ts +0 -18
- package/lib/WAM/BinaryInfo.d.ts +0 -17
- package/lib/WAM/constants.d.ts +0 -38
- package/lib/WAM/encode.d.ts +0 -3
- package/lib/WAM/index.d.ts +0 -3
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -9
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -22
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -12
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -25
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -8
- package/lib/WAUSync/Protocols/index.d.ts +0 -4
- package/lib/WAUSync/USyncQuery.d.ts +0 -28
- package/lib/WAUSync/USyncUser.d.ts +0 -12
- package/lib/WAUSync/index.d.ts +0 -3
- package/lib/index.d.ts +0 -12
- package/lib/index.js.bak +0 -48
- /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,
|
|
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 =
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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);
|
package/lib/Utils/signal.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getNextPreKeysNode =
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
for
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
|
23
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
manufacturer,
|
|
32
|
-
device,
|
|
33
|
-
osBuildNumber: osVersion,
|
|
26
|
+
osVersion: '0.1',
|
|
27
|
+
device: 'Desktop',
|
|
28
|
+
osBuildNumber: '0.1',
|
|
34
29
|
localeLanguageIso6391: 'en',
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
57
|
-
payload.webInfo = getWebInfo(config);
|
|
58
|
-
}
|
|
55
|
+
payload.webInfo = getWebInfo(config);
|
|
59
56
|
return payload;
|
|
60
57
|
};
|
|
61
|
-
|
|
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.
|
|
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('.'))
|
|
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
|
-
|
|
143
|
+
|
|
144
|
+
const bizName = businessNode?.attrs.name;
|
|
137
145
|
const jid = deviceNode.attrs.jid;
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
const
|
|
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
|
-
|
|
147
|
-
const
|
|
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
|
-
|
|
152
|
-
const deviceMsg = Buffer.concat([
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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;
|