@n4tzz/n4lyx 2.7.2 → 2.7.4
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/lib/Utils/validate-connection.js +120 -200
- package/package.json +1 -1
|
@@ -1,229 +1,149 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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");
|
|
12
|
-
|
|
13
|
-
const getUserAgent = (config) => {
|
|
14
|
-
return {
|
|
15
|
-
appVersion: {
|
|
16
|
-
primary: config.version[0],
|
|
17
|
-
secondary: config.version[1],
|
|
18
|
-
tertiary: config.version[2],
|
|
19
|
-
},
|
|
20
|
-
platform: WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB,
|
|
21
|
-
releaseChannel: WAProto_1.proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
|
|
22
|
-
osVersion: '0.1',
|
|
23
|
-
device: 'Desktop',
|
|
24
|
-
osBuildNumber: '0.1',
|
|
25
|
-
localeLanguageIso6391: 'en',
|
|
26
|
-
mnc: '000',
|
|
27
|
-
mcc: '000',
|
|
28
|
-
localeCountryIso31661Alpha2: config.countryCode || 'US'
|
|
29
|
-
};
|
|
30
|
-
};
|
|
4
|
+
exports.useMultiFileAuthState = void 0;
|
|
31
5
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
6
|
+
const { Mutex } = require("async-mutex");
|
|
7
|
+
const { writeFile, readFile, unlink, stat, mkdir } = require("fs/promises");
|
|
8
|
+
const { join } = require("path");
|
|
9
|
+
const { proto } = require("../../WAProto");
|
|
10
|
+
const { initAuthCreds } = require("./auth-utils");
|
|
11
|
+
const { BufferJSON } = require("./generics");
|
|
36
12
|
|
|
37
|
-
const
|
|
38
|
-
let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
|
|
39
|
-
if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]] && config.browser[1] === 'Desktop') {
|
|
40
|
-
webSubPlatform = PLATFORM_MAP[config.browser[0]];
|
|
41
|
-
}
|
|
42
|
-
return { webSubPlatform };
|
|
43
|
-
};
|
|
13
|
+
const fileLocks = new Map();
|
|
44
14
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
payload.webInfo = getWebInfo(config);
|
|
52
|
-
return payload;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const generateLoginNode = (userJid, config) => {
|
|
56
|
-
const { user, device } = (0, WABinary_1.jidDecode)(userJid);
|
|
57
|
-
const payload = {
|
|
58
|
-
...getClientPayload(config),
|
|
59
|
-
passive: true,
|
|
60
|
-
pull: true,
|
|
61
|
-
username: +user,
|
|
62
|
-
device: device,
|
|
63
|
-
lidDbMigrated: false
|
|
64
|
-
};
|
|
65
|
-
return WAProto_1.proto.ClientPayload.fromObject(payload);
|
|
15
|
+
const getFileLock = (path) => {
|
|
16
|
+
if (!fileLocks.has(path)) {
|
|
17
|
+
fileLocks.set(path, new Mutex());
|
|
18
|
+
}
|
|
19
|
+
return fileLocks.get(path);
|
|
66
20
|
};
|
|
67
|
-
exports.generateLoginNode = generateLoginNode;
|
|
68
21
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.CHROME;
|
|
22
|
+
const fixFileName = (file) => {
|
|
23
|
+
return file?.replace(/\//g, '__')?.replace(/:/g, '-');
|
|
72
24
|
};
|
|
73
25
|
|
|
74
|
-
const
|
|
75
|
-
const appVersionBuf = (0, crypto_1.createHash)('md5')
|
|
76
|
-
.update(config.version.join('.'))
|
|
77
|
-
.digest();
|
|
78
|
-
|
|
79
|
-
const companion = {
|
|
80
|
-
os: config.browser[0],
|
|
81
|
-
platformType: getPlatformType(config.browser[1]),
|
|
82
|
-
requireFullSync: config.syncFullHistory,
|
|
83
|
-
historySyncConfig: {
|
|
84
|
-
storageQuotaMb: 10240,
|
|
85
|
-
inlineInitialPayloadInE2EeMsg: true,
|
|
86
|
-
recentSyncDaysLimit: undefined,
|
|
87
|
-
supportCallLogHistory: false,
|
|
88
|
-
supportBotUserAgentChatHistory: true,
|
|
89
|
-
supportCagReactionsAndPolls: true,
|
|
90
|
-
supportBizHostedMsg: true,
|
|
91
|
-
supportRecentSyncChunkMessageCountTuning: true,
|
|
92
|
-
supportHostedGroupMsg: true,
|
|
93
|
-
supportFbidBotChatHistory: true,
|
|
94
|
-
supportAddOnHistorySyncMigration: undefined,
|
|
95
|
-
supportMessageAssociation: true,
|
|
96
|
-
supportGroupHistory: false,
|
|
97
|
-
onDemandReady: undefined,
|
|
98
|
-
supportGuestChat: undefined
|
|
99
|
-
},
|
|
100
|
-
version: {
|
|
101
|
-
primary: 10,
|
|
102
|
-
secondary: 15,
|
|
103
|
-
tertiary: 7
|
|
104
|
-
}
|
|
105
|
-
};
|
|
26
|
+
const delay = (ms) => new Promise(res => setTimeout(res, ms));
|
|
106
27
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
pull: false,
|
|
113
|
-
devicePairingData: {
|
|
114
|
-
buildHash: appVersionBuf,
|
|
115
|
-
deviceProps: companionProto,
|
|
116
|
-
eRegid: (0, generics_1.encodeBigEndian)(registrationId),
|
|
117
|
-
eKeytype: Defaults_1.KEY_BUNDLE_TYPE,
|
|
118
|
-
eIdent: signedIdentityKey.public,
|
|
119
|
-
eSkeyId: (0, generics_1.encodeBigEndian)(signedPreKey.keyId, 3),
|
|
120
|
-
eSkeyVal: signedPreKey.keyPair.public,
|
|
121
|
-
eSkeySig: signedPreKey.signature,
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
return WAProto_1.proto.ClientPayload.fromObject(registerPayload);
|
|
28
|
+
const safeWrite = async (filePath, data) => {
|
|
29
|
+
const tmp = filePath + ".tmp";
|
|
30
|
+
await writeFile(tmp, JSON.stringify(data, BufferJSON.replacer));
|
|
31
|
+
await writeFile(filePath, await readFile(tmp));
|
|
32
|
+
await unlink(tmp).catch(() => { });
|
|
125
33
|
};
|
|
126
|
-
exports.generateRegistrationNode = generateRegistrationNode;
|
|
127
|
-
|
|
128
|
-
const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
|
|
129
|
-
const msgId = stanza.attrs.id;
|
|
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');
|
|
135
|
-
|
|
136
|
-
if (!deviceIdentityNode || !deviceNode) {
|
|
137
|
-
throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza });
|
|
138
|
-
}
|
|
139
34
|
|
|
140
|
-
|
|
141
|
-
const jid = deviceNode.attrs.jid;
|
|
142
|
-
const lid = deviceNode.attrs.lid;
|
|
35
|
+
const useMultiFileAuthState = async (folder) => {
|
|
143
36
|
|
|
144
|
-
const
|
|
37
|
+
const folderInfo = await stat(folder).catch(() => null);
|
|
145
38
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
hmacPrefix = Buffer.from([0x06, 0x05]);
|
|
39
|
+
if (folderInfo && !folderInfo.isDirectory()) {
|
|
40
|
+
throw new Error(`Path ${folder} is not a directory`);
|
|
149
41
|
}
|
|
150
42
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
throw new boom_1.Boom('Invalid account signature');
|
|
43
|
+
if (!folderInfo) {
|
|
44
|
+
await mkdir(folder, { recursive: true });
|
|
154
45
|
}
|
|
155
46
|
|
|
156
|
-
const
|
|
157
|
-
|
|
47
|
+
const writeData = async (data, file) => {
|
|
48
|
+
const filePath = join(folder, fixFileName(file));
|
|
49
|
+
const mutex = getFileLock(filePath);
|
|
50
|
+
|
|
51
|
+
return mutex.acquire().then(async (release) => {
|
|
52
|
+
try {
|
|
53
|
+
await safeWrite(filePath, data);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
await delay(100);
|
|
56
|
+
try {
|
|
57
|
+
await safeWrite(filePath, data);
|
|
58
|
+
} catch (_) { }
|
|
59
|
+
} finally {
|
|
60
|
+
release();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
};
|
|
158
64
|
|
|
159
|
-
const
|
|
65
|
+
const readData = async (file) => {
|
|
66
|
+
const filePath = join(folder, fixFileName(file));
|
|
67
|
+
const mutex = getFileLock(filePath);
|
|
68
|
+
|
|
69
|
+
return mutex.acquire().then(async (release) => {
|
|
70
|
+
try {
|
|
71
|
+
const data = await readFile(filePath, { encoding: 'utf-8' });
|
|
72
|
+
return JSON.parse(data, BufferJSON.reviver);
|
|
73
|
+
} catch (_) {
|
|
74
|
+
return null;
|
|
75
|
+
} finally {
|
|
76
|
+
release();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
};
|
|
160
80
|
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public]);
|
|
165
|
-
|
|
166
|
-
if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
|
167
|
-
throw new boom_1.Boom('Failed to verify account signature');
|
|
168
|
-
}
|
|
81
|
+
const removeData = async (file) => {
|
|
82
|
+
const filePath = join(folder, fixFileName(file));
|
|
83
|
+
const mutex = getFileLock(filePath);
|
|
169
84
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg);
|
|
177
|
-
|
|
178
|
-
const identity = (0, signal_1.createSignalIdentity)(jid, accountSignatureKey);
|
|
179
|
-
const accountEnc = (0, exports.encodeSignedDeviceIdentity)(account, false);
|
|
180
|
-
|
|
181
|
-
const reply = {
|
|
182
|
-
tag: 'iq',
|
|
183
|
-
attrs: {
|
|
184
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
185
|
-
type: 'result',
|
|
186
|
-
id: msgId,
|
|
187
|
-
},
|
|
188
|
-
content: [
|
|
189
|
-
{
|
|
190
|
-
tag: 'pair-device-sign',
|
|
191
|
-
attrs: {},
|
|
192
|
-
content: [
|
|
193
|
-
{
|
|
194
|
-
tag: 'device-identity',
|
|
195
|
-
attrs: { 'key-index': deviceIdentity.keyIndex.toString() },
|
|
196
|
-
content: accountEnc
|
|
197
|
-
}
|
|
198
|
-
]
|
|
85
|
+
return mutex.acquire().then(async (release) => {
|
|
86
|
+
try {
|
|
87
|
+
await unlink(filePath);
|
|
88
|
+
} catch (_) { }
|
|
89
|
+
finally {
|
|
90
|
+
release();
|
|
199
91
|
}
|
|
200
|
-
|
|
92
|
+
});
|
|
201
93
|
};
|
|
202
94
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
],
|
|
210
|
-
platform: platformNode?.attrs.name
|
|
211
|
-
};
|
|
95
|
+
let creds = await readData('creds.json');
|
|
96
|
+
|
|
97
|
+
if (!creds) {
|
|
98
|
+
creds = initAuthCreds();
|
|
99
|
+
await writeData(creds, 'creds.json');
|
|
100
|
+
}
|
|
212
101
|
|
|
213
102
|
return {
|
|
214
|
-
|
|
215
|
-
|
|
103
|
+
state: {
|
|
104
|
+
creds,
|
|
105
|
+
keys: {
|
|
106
|
+
get: async (type, ids) => {
|
|
107
|
+
const data = {};
|
|
108
|
+
|
|
109
|
+
await Promise.all(ids.map(async (id) => {
|
|
110
|
+
let value = await readData(`${type}-${id}.json`);
|
|
111
|
+
|
|
112
|
+
if (type === 'app-state-sync-key' && value) {
|
|
113
|
+
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
data[id] = value;
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
return data;
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
set: async (data) => {
|
|
123
|
+
const tasks = [];
|
|
124
|
+
|
|
125
|
+
for (const category in data) {
|
|
126
|
+
for (const id in data[category]) {
|
|
127
|
+
const value = data[category][id];
|
|
128
|
+
const file = `${category}-${id}.json`;
|
|
129
|
+
|
|
130
|
+
if (value) {
|
|
131
|
+
tasks.push(writeData(value, file));
|
|
132
|
+
} else {
|
|
133
|
+
tasks.push(removeData(file));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
await Promise.all(tasks);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
saveCreds: async () => {
|
|
144
|
+
await writeData(creds, 'creds.json');
|
|
145
|
+
}
|
|
216
146
|
};
|
|
217
147
|
};
|
|
218
|
-
exports.configureSuccessfulPairing = configureSuccessfulPairing;
|
|
219
148
|
|
|
220
|
-
|
|
221
|
-
account = { ...account };
|
|
222
|
-
if (!includeSignatureKey || !account.accountSignatureKey?.length) {
|
|
223
|
-
account.accountSignatureKey = null;
|
|
224
|
-
}
|
|
225
|
-
return WAProto_1.proto.ADVSignedDeviceIdentity
|
|
226
|
-
.encode(account)
|
|
227
|
-
.finish();
|
|
228
|
-
};
|
|
229
|
-
exports.encodeSignedDeviceIdentity = encodeSignedDeviceIdentity;
|
|
149
|
+
exports.useMultiFileAuthState = useMultiFileAuthState;
|