@baileys-md/baileys 11.0.3 → 11.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.
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/WAProto/index.js +4182 -13516
- package/WASignalGroup/GroupProtocol.js +1697 -0
- package/WASignalGroup/ciphertext_message.js +16 -0
- package/WASignalGroup/group_cipher.js +120 -0
- package/WASignalGroup/group_session_builder.js +46 -0
- package/WASignalGroup/index.js +5 -0
- package/WASignalGroup/keyhelper.js +21 -0
- package/WASignalGroup/protobufs.js +3 -0
- package/WASignalGroup/queue_job.js +69 -0
- package/WASignalGroup/sender_chain_key.js +50 -0
- package/WASignalGroup/sender_key_distribution_message.js +78 -0
- package/WASignalGroup/sender_key_message.js +92 -0
- package/WASignalGroup/sender_key_name.js +70 -0
- package/WASignalGroup/sender_key_record.js +56 -0
- package/WASignalGroup/sender_key_state.js +129 -0
- package/{lib/Signal/Group/sender-message-key.js → WASignalGroup/sender_message_key.js} +16 -4
- package/lib/Defaults/baileys-version.json +3 -0
- package/lib/Defaults/index.js +71 -52
- package/lib/Defaults/{phonenumber-mcc.js → phonenumber-mcc.json} +1 -1
- package/lib/Signal/libsignal.js +61 -41
- package/lib/Socket/Client/abstract-socket-client.js +13 -0
- package/lib/Socket/Client/index.js +19 -3
- package/lib/Socket/Client/mobile-socket-client.js +65 -0
- package/lib/Socket/Client/web-socket-client.js +62 -0
- package/lib/Socket/business.js +42 -37
- package/lib/Socket/chats.js +187 -194
- package/lib/Socket/groups.js +90 -87
- package/lib/Socket/index.js +8 -7
- package/lib/Socket/messages-recv.js +335 -360
- package/lib/Socket/messages-send.js +279 -156
- package/lib/Socket/newsletter.js +213 -144
- package/lib/Socket/registration.js +166 -0
- package/lib/Socket/socket.js +161 -128
- package/lib/Socket/usync.js +26 -19
- package/lib/Store/index.js +8 -0
- package/lib/Store/make-cache-manager-store.js +83 -0
- package/lib/{Utils → Store}/make-in-memory-store.js +27 -19
- package/lib/Store/make-mongo-store.js +567 -0
- package/lib/{Utils → Store}/make-ordered-dictionary.js +5 -2
- package/lib/{Utils → Store}/object-repository.js +4 -1
- package/lib/Types/Auth.js +2 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.js +4 -8
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.js +5 -3
- package/lib/Types/LabelAssociation.js +5 -3
- package/lib/Types/Message.js +7 -7
- package/lib/Types/Newsletter.js +17 -30
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.js +2 -3
- package/lib/Types/State.js +2 -2
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.js +31 -15
- package/lib/Utils/auth-utils.js +47 -31
- package/lib/Utils/baileys-event-stream.js +22 -15
- package/lib/Utils/business.js +69 -66
- package/lib/Utils/chat-utils.js +195 -200
- package/lib/Utils/crypto.js +85 -70
- package/lib/Utils/decode-wa-message.js +51 -46
- package/lib/Utils/event-buffer.js +46 -36
- package/lib/Utils/generics.js +188 -116
- package/lib/Utils/history.js +46 -37
- package/lib/Utils/index.js +33 -19
- package/lib/Utils/link-preview.js +55 -14
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.js +26 -23
- package/lib/Utils/make-mutex.js +10 -7
- package/lib/Utils/messages-media.js +368 -239
- package/lib/Utils/messages.js +510 -278
- package/lib/Utils/noise-handler.js +31 -22
- package/lib/Utils/process-message.js +148 -144
- package/lib/Utils/signal.js +64 -71
- package/lib/Utils/use-multi-file-auth-state.js +32 -14
- package/lib/Utils/validate-connection.js +115 -72
- package/lib/WABinary/constants.js +20 -1281
- package/lib/WABinary/decode.js +52 -15
- package/lib/WABinary/encode.js +48 -14
- package/lib/WABinary/generic-utils.js +39 -31
- package/lib/WABinary/index.js +21 -6
- package/lib/WABinary/jid-utils.js +40 -23
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.js +5 -2
- package/lib/WAM/constants.js +2366 -2257
- package/lib/WAM/encode.js +21 -17
- package/lib/WAM/index.js +19 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +11 -8
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +14 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -9
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +13 -9
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +22 -20
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +6 -3
- package/lib/WAUSync/Protocols/index.js +20 -5
- package/lib/WAUSync/USyncQuery.js +32 -34
- package/lib/WAUSync/USyncUser.js +5 -2
- package/lib/WAUSync/index.js +19 -4
- package/lib/index.js +33 -11
- package/package.json +61 -21
- package/WAProto/GenerateStatics.sh +0 -3
- package/WAProto/WAProto.proto +0 -4633
- package/WAProto/fix-imports.js +0 -29
- package/lib/Defaults/baileys-version.js +0 -1
- package/lib/Signal/Group/ciphertext-message.js +0 -12
- package/lib/Signal/Group/group-session-builder.js +0 -30
- package/lib/Signal/Group/group_cipher.js +0 -94
- package/lib/Signal/Group/index.js +0 -12
- package/lib/Signal/Group/keyhelper.js +0 -19
- package/lib/Signal/Group/queue-job.js +0 -54
- package/lib/Signal/Group/sender-chain-key.js +0 -32
- package/lib/Signal/Group/sender-key-distribution-message.js +0 -63
- package/lib/Signal/Group/sender-key-message.js +0 -67
- package/lib/Signal/Group/sender-key-name.js +0 -48
- package/lib/Signal/Group/sender-key-record.js +0 -50
- package/lib/Signal/Group/sender-key-state.js +0 -96
- package/lib/Socket/Client/types.js +0 -11
- package/lib/Socket/Client/websocket.js +0 -50
- package/lib/Socket/communities.js +0 -351
- package/lib/Socket/mex.js +0 -42
package/lib/Utils/signal.js
CHANGED
|
@@ -1,105 +1,96 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
return chunks;
|
|
11
|
-
}
|
|
12
|
-
export const createSignalIdentity = (wid, accountSignatureKey) => {
|
|
1
|
+
"use strict";
|
|
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;
|
|
4
|
+
const Defaults_1 = require("../Defaults");
|
|
5
|
+
const WABinary_1 = require("../WABinary");
|
|
6
|
+
const crypto_1 = require("./crypto");
|
|
7
|
+
const generics_1 = require("./generics");
|
|
8
|
+
const createSignalIdentity = (wid, accountSignatureKey) => {
|
|
13
9
|
return {
|
|
14
10
|
identifier: { name: wid, deviceId: 0 },
|
|
15
|
-
identifierKey: generateSignalPubKey(accountSignatureKey)
|
|
11
|
+
identifierKey: (0, crypto_1.generateSignalPubKey)(accountSignatureKey)
|
|
16
12
|
};
|
|
17
13
|
};
|
|
18
|
-
|
|
14
|
+
exports.createSignalIdentity = createSignalIdentity;
|
|
15
|
+
const getPreKeys = async ({ get }, min, limit) => {
|
|
19
16
|
const idList = [];
|
|
20
17
|
for (let id = min; id < limit; id++) {
|
|
21
18
|
idList.push(id.toString());
|
|
22
19
|
}
|
|
23
20
|
return get('pre-key', idList);
|
|
24
21
|
};
|
|
25
|
-
|
|
22
|
+
exports.getPreKeys = getPreKeys;
|
|
23
|
+
const generateOrGetPreKeys = (creds, range) => {
|
|
26
24
|
const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId;
|
|
27
25
|
const remaining = range - avaliable;
|
|
28
26
|
const lastPreKeyId = creds.nextPreKeyId + remaining - 1;
|
|
29
27
|
const newPreKeys = {};
|
|
30
28
|
if (remaining > 0) {
|
|
31
29
|
for (let i = creds.nextPreKeyId; i <= lastPreKeyId; i++) {
|
|
32
|
-
newPreKeys[i] = Curve.generateKeyPair();
|
|
30
|
+
newPreKeys[i] = crypto_1.Curve.generateKeyPair();
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
return {
|
|
36
34
|
newPreKeys,
|
|
37
35
|
lastPreKeyId,
|
|
38
|
-
preKeysRange: [creds.firstUnuploadedPreKeyId, range]
|
|
36
|
+
preKeysRange: [creds.firstUnuploadedPreKeyId, range],
|
|
39
37
|
};
|
|
40
38
|
};
|
|
41
|
-
|
|
39
|
+
exports.generateOrGetPreKeys = generateOrGetPreKeys;
|
|
40
|
+
const xmppSignedPreKey = (key) => ({
|
|
42
41
|
tag: 'skey',
|
|
43
42
|
attrs: {},
|
|
44
43
|
content: [
|
|
45
|
-
{ tag: 'id', attrs: {}, content: encodeBigEndian(key.keyId, 3) },
|
|
44
|
+
{ tag: 'id', attrs: {}, content: (0, generics_1.encodeBigEndian)(key.keyId, 3) },
|
|
46
45
|
{ tag: 'value', attrs: {}, content: key.keyPair.public },
|
|
47
46
|
{ tag: 'signature', attrs: {}, content: key.signature }
|
|
48
47
|
]
|
|
49
48
|
});
|
|
50
|
-
|
|
49
|
+
exports.xmppSignedPreKey = xmppSignedPreKey;
|
|
50
|
+
const xmppPreKey = (pair, id) => ({
|
|
51
51
|
tag: 'key',
|
|
52
52
|
attrs: {},
|
|
53
53
|
content: [
|
|
54
|
-
{ tag: 'id', attrs: {}, content: encodeBigEndian(id, 3) },
|
|
54
|
+
{ tag: 'id', attrs: {}, content: (0, generics_1.encodeBigEndian)(id, 3) },
|
|
55
55
|
{ tag: 'value', attrs: {}, content: pair.public }
|
|
56
56
|
]
|
|
57
57
|
});
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const nodes = getBinaryNodeChildren(getBinaryNodeChild(node, 'list'), 'user');
|
|
58
|
+
exports.xmppPreKey = xmppPreKey;
|
|
59
|
+
const parseAndInjectE2ESessions = async (node, repository) => {
|
|
60
|
+
const extractKey = (key) => (key ? ({
|
|
61
|
+
keyId: (0, WABinary_1.getBinaryNodeChildUInt)(key, 'id', 3),
|
|
62
|
+
publicKey: (0, crypto_1.generateSignalPubKey)((0, WABinary_1.getBinaryNodeChildBuffer)(key, 'value')),
|
|
63
|
+
signature: (0, WABinary_1.getBinaryNodeChildBuffer)(key, 'signature'),
|
|
64
|
+
}) : undefined);
|
|
65
|
+
const nodes = (0, WABinary_1.getBinaryNodeChildren)((0, WABinary_1.getBinaryNodeChild)(node, 'list'), 'user');
|
|
67
66
|
for (const node of nodes) {
|
|
68
|
-
assertNodeErrorFree(node);
|
|
69
|
-
}
|
|
70
|
-
// Most of the work in repository.injectE2ESession is CPU intensive, not IO
|
|
71
|
-
// So Promise.all doesn't really help here,
|
|
72
|
-
// but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
|
|
73
|
-
// This way we chunk it in smaller parts and between those parts we can yield to the event loop
|
|
74
|
-
// It's rare case when you need to E2E sessions for so many users, but it's possible
|
|
75
|
-
const chunkSize = 100;
|
|
76
|
-
const chunks = chunk(nodes, chunkSize);
|
|
77
|
-
for (const nodesChunk of chunks) {
|
|
78
|
-
await Promise.all(nodesChunk.map(async (node) => {
|
|
79
|
-
const signedKey = getBinaryNodeChild(node, 'skey');
|
|
80
|
-
const key = getBinaryNodeChild(node, 'key');
|
|
81
|
-
const identity = getBinaryNodeChildBuffer(node, 'identity');
|
|
82
|
-
const jid = node.attrs.jid;
|
|
83
|
-
const registrationId = getBinaryNodeChildUInt(node, 'registration', 4);
|
|
84
|
-
await repository.injectE2ESession({
|
|
85
|
-
jid,
|
|
86
|
-
session: {
|
|
87
|
-
registrationId: registrationId,
|
|
88
|
-
identityKey: generateSignalPubKey(identity),
|
|
89
|
-
signedPreKey: extractKey(signedKey),
|
|
90
|
-
preKey: extractKey(key)
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
}));
|
|
67
|
+
(0, WABinary_1.assertNodeErrorFree)(node);
|
|
94
68
|
}
|
|
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
|
+
}));
|
|
95
85
|
};
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
exports.parseAndInjectE2ESessions = parseAndInjectE2ESessions;
|
|
87
|
+
const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
|
|
88
|
+
const { user: myUser, device: myDevice } = (0, WABinary_1.jidDecode)(myJid);
|
|
98
89
|
const extracted = [];
|
|
99
90
|
for (const userResult of result) {
|
|
100
91
|
const { devices, id } = userResult;
|
|
101
|
-
const { user } = jidDecode(id);
|
|
102
|
-
const deviceList = devices
|
|
92
|
+
const { user } = (0, WABinary_1.jidDecode)(id);
|
|
93
|
+
const deviceList = devices === null || devices === void 0 ? void 0 : devices.deviceList;
|
|
103
94
|
if (Array.isArray(deviceList)) {
|
|
104
95
|
for (const { id: device, keyIndex } of deviceList) {
|
|
105
96
|
if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
|
|
@@ -113,38 +104,40 @@ export const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
|
|
|
113
104
|
}
|
|
114
105
|
return extracted;
|
|
115
106
|
};
|
|
107
|
+
exports.extractDeviceJids = extractDeviceJids;
|
|
116
108
|
/**
|
|
117
109
|
* get the next N keys for upload or processing
|
|
118
110
|
* @param count number of pre-keys to get or generate
|
|
119
111
|
*/
|
|
120
|
-
|
|
121
|
-
const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(creds, count);
|
|
112
|
+
const getNextPreKeys = async ({ creds, keys }, count) => {
|
|
113
|
+
const { newPreKeys, lastPreKeyId, preKeysRange } = (0, exports.generateOrGetPreKeys)(creds, count);
|
|
122
114
|
const update = {
|
|
123
115
|
nextPreKeyId: Math.max(lastPreKeyId + 1, creds.nextPreKeyId),
|
|
124
116
|
firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId + 1)
|
|
125
117
|
};
|
|
126
118
|
await keys.set({ 'pre-key': newPreKeys });
|
|
127
|
-
const preKeys = await getPreKeys(keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]);
|
|
119
|
+
const preKeys = await (0, exports.getPreKeys)(keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]);
|
|
128
120
|
return { update, preKeys };
|
|
129
121
|
};
|
|
130
|
-
|
|
122
|
+
exports.getNextPreKeys = getNextPreKeys;
|
|
123
|
+
const getNextPreKeysNode = async (state, count) => {
|
|
131
124
|
const { creds } = state;
|
|
132
|
-
const { update, preKeys } = await getNextPreKeys(state, count);
|
|
125
|
+
const { update, preKeys } = await (0, exports.getNextPreKeys)(state, count);
|
|
133
126
|
const node = {
|
|
134
127
|
tag: 'iq',
|
|
135
128
|
attrs: {
|
|
136
129
|
xmlns: 'encrypt',
|
|
137
130
|
type: 'set',
|
|
138
|
-
to: S_WHATSAPP_NET
|
|
131
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
139
132
|
},
|
|
140
133
|
content: [
|
|
141
|
-
{ tag: 'registration', attrs: {}, content: encodeBigEndian(creds.registrationId) },
|
|
142
|
-
{ tag: 'type', attrs: {}, content: KEY_BUNDLE_TYPE },
|
|
134
|
+
{ tag: 'registration', attrs: {}, content: (0, generics_1.encodeBigEndian)(creds.registrationId) },
|
|
135
|
+
{ tag: 'type', attrs: {}, content: Defaults_1.KEY_BUNDLE_TYPE },
|
|
143
136
|
{ tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
|
|
144
|
-
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) },
|
|
145
|
-
xmppSignedPreKey(creds.signedPreKey)
|
|
137
|
+
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => (0, exports.xmppPreKey)(preKeys[+k], +k)) },
|
|
138
|
+
(0, exports.xmppSignedPreKey)(creds.signedPreKey)
|
|
146
139
|
]
|
|
147
140
|
};
|
|
148
141
|
return { update, node };
|
|
149
142
|
};
|
|
150
|
-
|
|
143
|
+
exports.getNextPreKeysNode = getNextPreKeysNode;
|
|
@@ -1,27 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function(mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : {
|
|
4
|
+
"default": mod
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8
|
+
value: true
|
|
9
|
+
});
|
|
10
|
+
exports.useMultiFileAuthState = void 0;
|
|
11
|
+
const fs = require("fs");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const WAProto_1 = require("../../WAProto");
|
|
14
|
+
const auth_utils_1 = require("./auth-utils");
|
|
15
|
+
const generics_1 = require("./generics");
|
|
16
|
+
/**
|
|
17
|
+
* stores the full authentication state in a single folder.
|
|
18
|
+
* Far more efficient than singlefileauthstate
|
|
19
|
+
*
|
|
20
|
+
* Again, I wouldn't endorse this for any production level use other than perhaps a bot.
|
|
21
|
+
* Would recommend writing an auth state for use with a proper SQL or No-SQL DB
|
|
22
|
+
* */
|
|
23
|
+
const useMultiFileAuthState = async (folder) => {
|
|
7
24
|
const writeData = async (data, file) => {
|
|
8
|
-
const filePath = await (0, join)(folder, fixFileName(file));
|
|
9
|
-
return (0, fs.writeFileSync)((0, join)(filePath), JSON.stringify(data, BufferJSON.replacer));
|
|
25
|
+
const filePath = await (0, path_1.join)(folder, fixFileName(file));
|
|
26
|
+
return (0, fs.writeFileSync)((0, path_1.join)(filePath), JSON.stringify(data, generics_1.BufferJSON.replacer));
|
|
10
27
|
};
|
|
11
28
|
const readData = async (file) => {
|
|
12
29
|
try {
|
|
13
|
-
const filePath = await (0, join)(folder, fixFileName(file));
|
|
30
|
+
const filePath = await (0, path_1.join)(folder, fixFileName(file));
|
|
14
31
|
const data = (0, fs.readFileSync)(filePath, {
|
|
15
32
|
encoding: 'utf-8'
|
|
16
33
|
});
|
|
17
|
-
return JSON.parse(data, BufferJSON.reviver);
|
|
34
|
+
return JSON.parse(data, generics_1.BufferJSON.reviver);
|
|
18
35
|
} catch (e) {
|
|
19
36
|
return null;
|
|
20
37
|
}
|
|
21
38
|
};
|
|
22
39
|
const removeData = async (file) => {
|
|
23
40
|
try {
|
|
24
|
-
const filePath = await (0, join)(folder, fixFileName(file));
|
|
41
|
+
const filePath = await (0, path_1.join)(folder, fixFileName(file));
|
|
25
42
|
(0, fs.unlinkSync)(filePath);
|
|
26
43
|
} catch (_a) {}
|
|
27
44
|
};
|
|
@@ -39,7 +56,7 @@ export const useMultiFileAuthState = async (folder) => {
|
|
|
39
56
|
var _a;
|
|
40
57
|
return (_a = file === null || file === void 0 ? void 0 : file.replace(/\//g, '__')) === null || _a === void 0 ? void 0 : _a.replace(/:/g, '-');
|
|
41
58
|
};
|
|
42
|
-
const creds = await readData('creds.json') || await (0, await initAuthCreds)();
|
|
59
|
+
const creds = await readData('creds.json') || await (0, await auth_utils_1.initAuthCreds)();
|
|
43
60
|
return {
|
|
44
61
|
state: {
|
|
45
62
|
creds,
|
|
@@ -49,7 +66,7 @@ export const useMultiFileAuthState = async (folder) => {
|
|
|
49
66
|
await Promise.all(ids.map(async (id) => {
|
|
50
67
|
let value = await readData(`${type}-${id}.json`);
|
|
51
68
|
if (type === 'app-state-sync-key' && value) {
|
|
52
|
-
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
|
69
|
+
value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value);
|
|
53
70
|
}
|
|
54
71
|
data[id] = value;
|
|
55
72
|
}));
|
|
@@ -72,4 +89,5 @@ export const useMultiFileAuthState = async (folder) => {
|
|
|
72
89
|
return writeData(creds, 'creds.json');
|
|
73
90
|
}
|
|
74
91
|
};
|
|
75
|
-
};
|
|
92
|
+
};
|
|
93
|
+
exports.useMultiFileAuthState = useMultiFileAuthState;
|
|
@@ -1,35 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.encodeSignedDeviceIdentity = exports.configureSuccessfulPairing = exports.generateRegistrationNode = exports.generateLoginNode = exports.generateMobileNode = void 0;
|
|
4
|
+
const boom_1 = require("@hapi/boom");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const WAProto_1 = require("../../WAProto");
|
|
7
|
+
const Defaults_1 = require("../Defaults");
|
|
8
|
+
const WABinary_1 = require("../WABinary");
|
|
9
|
+
const crypto_2 = require("./crypto");
|
|
10
|
+
const generics_1 = require("./generics");
|
|
11
|
+
const signal_1 = require("./signal");
|
|
9
12
|
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 } : {};
|
|
10
20
|
return {
|
|
11
21
|
appVersion: {
|
|
12
|
-
primary:
|
|
13
|
-
secondary:
|
|
14
|
-
tertiary:
|
|
22
|
+
primary: version[0],
|
|
23
|
+
secondary: version[1],
|
|
24
|
+
tertiary: version[2],
|
|
15
25
|
},
|
|
16
|
-
platform
|
|
17
|
-
releaseChannel: proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
platform,
|
|
27
|
+
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,
|
|
21
34
|
localeLanguageIso6391: 'en',
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
localeCountryIso31661Alpha2: config.countryCode
|
|
35
|
+
localeCountryIso31661Alpha2: config.countryCode,
|
|
36
|
+
...phoneId
|
|
25
37
|
};
|
|
26
38
|
};
|
|
27
39
|
const PLATFORM_MAP = {
|
|
28
|
-
'Mac OS': proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
|
|
29
|
-
Windows: proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
|
|
40
|
+
'Mac OS': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
|
|
41
|
+
'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
|
|
30
42
|
};
|
|
31
43
|
const getWebInfo = (config) => {
|
|
32
|
-
let webSubPlatform = proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
|
|
44
|
+
let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
|
|
33
45
|
if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
|
|
34
46
|
webSubPlatform = PLATFORM_MAP[config.browser[0]];
|
|
35
47
|
}
|
|
@@ -37,41 +49,64 @@ const getWebInfo = (config) => {
|
|
|
37
49
|
};
|
|
38
50
|
const getClientPayload = (config) => {
|
|
39
51
|
const payload = {
|
|
40
|
-
connectType: proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
|
|
41
|
-
connectReason: proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
42
|
-
userAgent: getUserAgent(config)
|
|
52
|
+
connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
|
|
53
|
+
connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
54
|
+
userAgent: getUserAgent(config),
|
|
43
55
|
};
|
|
44
|
-
|
|
56
|
+
if (!config.mobile) {
|
|
57
|
+
payload.webInfo = getWebInfo(config);
|
|
58
|
+
}
|
|
45
59
|
return payload;
|
|
46
60
|
};
|
|
47
|
-
|
|
48
|
-
|
|
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, // XMPP heartbeat setting (false: server actively pings) (true: client actively pings)
|
|
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;
|
|
82
|
+
const generateLoginNode = (userJid, config) => {
|
|
83
|
+
const { user, device } = (0, WABinary_1.jidDecode)(userJid);
|
|
49
84
|
const payload = {
|
|
50
85
|
...getClientPayload(config),
|
|
51
86
|
passive: false,
|
|
52
87
|
pull: true,
|
|
53
88
|
username: +user,
|
|
54
|
-
device: device
|
|
89
|
+
device: device,
|
|
55
90
|
};
|
|
56
|
-
return proto.ClientPayload.fromObject(payload);
|
|
91
|
+
return WAProto_1.proto.ClientPayload.fromObject(payload);
|
|
57
92
|
};
|
|
93
|
+
exports.generateLoginNode = generateLoginNode;
|
|
58
94
|
const getPlatformType = (platform) => {
|
|
59
95
|
const platformType = platform.toUpperCase();
|
|
60
|
-
return
|
|
61
|
-
proto.DeviceProps.PlatformType.DESKTOP);
|
|
96
|
+
return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.DESKTOP;
|
|
62
97
|
};
|
|
63
|
-
|
|
98
|
+
const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
|
|
64
99
|
// the app version needs to be md5 hashed
|
|
65
100
|
// and passed in
|
|
66
|
-
const appVersionBuf = createHash('md5')
|
|
101
|
+
const appVersionBuf = (0, crypto_1.createHash)('md5')
|
|
67
102
|
.update(config.version.join('.')) // join as string
|
|
68
103
|
.digest();
|
|
69
104
|
const companion = {
|
|
70
105
|
os: config.browser[0],
|
|
71
106
|
platformType: getPlatformType(config.browser[1]),
|
|
72
|
-
requireFullSync: config.syncFullHistory
|
|
107
|
+
requireFullSync: config.syncFullHistory,
|
|
73
108
|
};
|
|
74
|
-
const companionProto = proto.DeviceProps.encode(companion).finish();
|
|
109
|
+
const companionProto = WAProto_1.proto.DeviceProps.encode(companion).finish();
|
|
75
110
|
const registerPayload = {
|
|
76
111
|
...getClientPayload(config),
|
|
77
112
|
passive: false,
|
|
@@ -79,53 +114,54 @@ export const generateRegistrationNode = ({ registrationId, signedPreKey, signedI
|
|
|
79
114
|
devicePairingData: {
|
|
80
115
|
buildHash: appVersionBuf,
|
|
81
116
|
deviceProps: companionProto,
|
|
82
|
-
eRegid: encodeBigEndian(registrationId),
|
|
83
|
-
eKeytype: KEY_BUNDLE_TYPE,
|
|
117
|
+
eRegid: (0, generics_1.encodeBigEndian)(registrationId),
|
|
118
|
+
eKeytype: Defaults_1.KEY_BUNDLE_TYPE,
|
|
84
119
|
eIdent: signedIdentityKey.public,
|
|
85
|
-
eSkeyId: encodeBigEndian(signedPreKey.keyId, 3),
|
|
120
|
+
eSkeyId: (0, generics_1.encodeBigEndian)(signedPreKey.keyId, 3),
|
|
86
121
|
eSkeyVal: signedPreKey.keyPair.public,
|
|
87
|
-
eSkeySig: signedPreKey.signature
|
|
88
|
-
}
|
|
122
|
+
eSkeySig: signedPreKey.signature,
|
|
123
|
+
},
|
|
89
124
|
};
|
|
90
|
-
return proto.ClientPayload.fromObject(registerPayload);
|
|
125
|
+
return WAProto_1.proto.ClientPayload.fromObject(registerPayload);
|
|
91
126
|
};
|
|
92
|
-
|
|
127
|
+
exports.generateRegistrationNode = generateRegistrationNode;
|
|
128
|
+
const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
|
|
93
129
|
const msgId = stanza.attrs.id;
|
|
94
|
-
const pairSuccessNode = getBinaryNodeChild(stanza, 'pair-success');
|
|
95
|
-
const deviceIdentityNode = getBinaryNodeChild(pairSuccessNode, 'device-identity');
|
|
96
|
-
const platformNode = getBinaryNodeChild(pairSuccessNode, 'platform');
|
|
97
|
-
const deviceNode = getBinaryNodeChild(pairSuccessNode, 'device');
|
|
98
|
-
const businessNode = getBinaryNodeChild(pairSuccessNode, 'biz');
|
|
130
|
+
const pairSuccessNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-success');
|
|
131
|
+
const deviceIdentityNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'device-identity');
|
|
132
|
+
const platformNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'platform');
|
|
133
|
+
const deviceNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'device');
|
|
134
|
+
const businessNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'biz');
|
|
99
135
|
if (!deviceIdentityNode || !deviceNode) {
|
|
100
|
-
throw new Boom('Missing device-identity or device in pair success node', { data: stanza });
|
|
136
|
+
throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza });
|
|
101
137
|
}
|
|
102
|
-
const bizName = businessNode
|
|
138
|
+
const bizName = businessNode === null || businessNode === void 0 ? void 0 : businessNode.attrs.name;
|
|
103
139
|
const jid = deviceNode.attrs.jid;
|
|
104
|
-
const { details, hmac
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const advSign = hmacSign(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'));
|
|
140
|
+
const { details, hmac } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
|
|
141
|
+
// check HMAC matches
|
|
142
|
+
const advSign = (0, crypto_2.hmacSign)(details, Buffer.from(advSecretKey, 'base64'));
|
|
108
143
|
if (Buffer.compare(hmac, advSign) !== 0) {
|
|
109
|
-
throw new Boom('Invalid account signature');
|
|
144
|
+
throw new boom_1.Boom('Invalid account signature');
|
|
110
145
|
}
|
|
111
|
-
const account = proto.ADVSignedDeviceIdentity.decode(details);
|
|
146
|
+
const account = WAProto_1.proto.ADVSignedDeviceIdentity.decode(details);
|
|
112
147
|
const { accountSignatureKey, accountSignature, details: deviceDetails } = account;
|
|
148
|
+
// verify the device signature matches
|
|
113
149
|
const accountMsg = Buffer.concat([Buffer.from([6, 0]), deviceDetails, signedIdentityKey.public]);
|
|
114
|
-
if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
|
115
|
-
throw new Boom('Failed to verify account signature');
|
|
150
|
+
if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
|
151
|
+
throw new boom_1.Boom('Failed to verify account signature');
|
|
116
152
|
}
|
|
117
|
-
|
|
118
|
-
const deviceMsg = Buffer.concat([
|
|
119
|
-
account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg);
|
|
120
|
-
const identity = createSignalIdentity(jid, accountSignatureKey);
|
|
121
|
-
const accountEnc = encodeSignedDeviceIdentity(account, false);
|
|
122
|
-
const deviceIdentity = proto.ADVDeviceIdentity.decode(account.details);
|
|
153
|
+
// sign the details with our identity key
|
|
154
|
+
const deviceMsg = Buffer.concat([Buffer.from([6, 1]), deviceDetails, signedIdentityKey.public, accountSignatureKey]);
|
|
155
|
+
account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg);
|
|
156
|
+
const identity = (0, signal_1.createSignalIdentity)(jid, accountSignatureKey);
|
|
157
|
+
const accountEnc = (0, exports.encodeSignedDeviceIdentity)(account, false);
|
|
158
|
+
const deviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(account.details);
|
|
123
159
|
const reply = {
|
|
124
160
|
tag: 'iq',
|
|
125
161
|
attrs: {
|
|
126
|
-
to: S_WHATSAPP_NET,
|
|
162
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
127
163
|
type: 'result',
|
|
128
|
-
id: msgId
|
|
164
|
+
id: msgId,
|
|
129
165
|
},
|
|
130
166
|
content: [
|
|
131
167
|
{
|
|
@@ -144,21 +180,28 @@ export const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentit
|
|
|
144
180
|
const authUpdate = {
|
|
145
181
|
account,
|
|
146
182
|
me: { id: jid, name: bizName },
|
|
147
|
-
signalIdentities: [
|
|
148
|
-
|
|
183
|
+
signalIdentities: [
|
|
184
|
+
...(signalIdentities || []),
|
|
185
|
+
identity
|
|
186
|
+
],
|
|
187
|
+
platform: platformNode === null || platformNode === void 0 ? void 0 : platformNode.attrs.name
|
|
149
188
|
};
|
|
150
189
|
return {
|
|
151
190
|
creds: authUpdate,
|
|
152
191
|
reply
|
|
153
192
|
};
|
|
154
193
|
};
|
|
155
|
-
|
|
194
|
+
exports.configureSuccessfulPairing = configureSuccessfulPairing;
|
|
195
|
+
const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
|
|
196
|
+
var _a;
|
|
156
197
|
account = { ...account };
|
|
157
198
|
// set to null if we are not to include the signature key
|
|
158
199
|
// or if we are including the signature key but it is empty
|
|
159
|
-
if (!includeSignatureKey || !account.accountSignatureKey
|
|
200
|
+
if (!includeSignatureKey || !((_a = account.accountSignatureKey) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
160
201
|
account.accountSignatureKey = null;
|
|
161
202
|
}
|
|
162
|
-
return proto.ADVSignedDeviceIdentity
|
|
203
|
+
return WAProto_1.proto.ADVSignedDeviceIdentity
|
|
204
|
+
.encode(account)
|
|
205
|
+
.finish();
|
|
163
206
|
};
|
|
164
|
-
|
|
207
|
+
exports.encodeSignedDeviceIdentity = encodeSignedDeviceIdentity;
|