@n4tzz/n4lyx 2.7.3 → 2.7.5
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/Defaults/index.js +1 -1
- package/lib/Utils/validate-connection.js +120 -190
- package/package.json +1 -1
package/lib/Defaults/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const WAProto_1 = require("../../WAProto");
|
|
|
8
8
|
const libsignal_1 = require("../Signal/libsignal");
|
|
9
9
|
const browser_utils_1 = require("../Utils/browser-utils");
|
|
10
10
|
const logger_1 = __importDefault(require("../Utils/logger"));
|
|
11
|
-
exports.version = [2,
|
|
11
|
+
exports.version = [2, 2413, 51];
|
|
12
12
|
exports.UNAUTHORIZED_CODES = [401, 403, 419];
|
|
13
13
|
exports.DEFAULT_ORIGIN = 'https://web.whatsapp.com';
|
|
14
14
|
exports.CALL_VIDEO_PREFIX = 'https://call.whatsapp.com/video/';
|
|
@@ -1,219 +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");
|
|
12
|
+
|
|
13
|
+
const fileLocks = new Map();
|
|
36
14
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
webSubPlatform = PLATFORM_MAP[config.browser[0]];
|
|
15
|
+
const getFileLock = (path) => {
|
|
16
|
+
if (!fileLocks.has(path)) {
|
|
17
|
+
fileLocks.set(path, new Mutex());
|
|
41
18
|
}
|
|
42
|
-
return
|
|
19
|
+
return fileLocks.get(path);
|
|
43
20
|
};
|
|
44
21
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
|
|
48
|
-
connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
49
|
-
userAgent: getUserAgent(config),
|
|
50
|
-
};
|
|
51
|
-
payload.webInfo = getWebInfo(config);
|
|
52
|
-
return payload;
|
|
22
|
+
const fixFileName = (file) => {
|
|
23
|
+
return file?.replace(/\//g, '__')?.replace(/:/g, '-');
|
|
53
24
|
};
|
|
54
25
|
|
|
55
|
-
|
|
56
|
-
const generateLoginNode = (userJid, config) => {
|
|
57
|
-
const { user, device } = (0, WABinary_1.jidDecode)(userJid);
|
|
58
|
-
const payload = {
|
|
59
|
-
...getClientPayload(config),
|
|
60
|
-
passive: true,
|
|
61
|
-
pull: true,
|
|
62
|
-
username: +user,
|
|
63
|
-
device: device,
|
|
64
|
-
};
|
|
65
|
-
return WAProto_1.proto.ClientPayload.fromObject(payload);
|
|
66
|
-
};
|
|
67
|
-
exports.generateLoginNode = generateLoginNode;
|
|
26
|
+
const delay = (ms) => new Promise(res => setTimeout(res, ms));
|
|
68
27
|
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
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(() => { });
|
|
72
33
|
};
|
|
73
34
|
|
|
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
|
-
},
|
|
97
|
-
};
|
|
35
|
+
const useMultiFileAuthState = async (folder) => {
|
|
98
36
|
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
const registerPayload = {
|
|
102
|
-
...getClientPayload(config),
|
|
103
|
-
passive: false,
|
|
104
|
-
pull: false,
|
|
105
|
-
devicePairingData: {
|
|
106
|
-
buildHash: appVersionBuf,
|
|
107
|
-
deviceProps: companionProto,
|
|
108
|
-
eRegid: (0, generics_1.encodeBigEndian)(registrationId),
|
|
109
|
-
eKeytype: Defaults_1.KEY_BUNDLE_TYPE,
|
|
110
|
-
eIdent: signedIdentityKey.public,
|
|
111
|
-
eSkeyId: (0, generics_1.encodeBigEndian)(signedPreKey.keyId, 3),
|
|
112
|
-
eSkeyVal: signedPreKey.keyPair.public,
|
|
113
|
-
eSkeySig: signedPreKey.signature,
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
return WAProto_1.proto.ClientPayload.fromObject(registerPayload);
|
|
117
|
-
};
|
|
118
|
-
exports.generateRegistrationNode = generateRegistrationNode;
|
|
119
|
-
|
|
120
|
-
const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
|
|
121
|
-
const msgId = stanza.attrs.id;
|
|
122
|
-
const pairSuccessNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-success');
|
|
123
|
-
const deviceIdentityNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'device-identity');
|
|
124
|
-
const platformNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'platform');
|
|
125
|
-
const deviceNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'device');
|
|
126
|
-
const businessNode = (0, WABinary_1.getBinaryNodeChild)(pairSuccessNode, 'biz');
|
|
127
|
-
|
|
128
|
-
if (!deviceIdentityNode || !deviceNode) {
|
|
129
|
-
throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza });
|
|
130
|
-
}
|
|
37
|
+
const folderInfo = await stat(folder).catch(() => null);
|
|
131
38
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
39
|
+
if (folderInfo && !folderInfo.isDirectory()) {
|
|
40
|
+
throw new Error(`Path ${folder} is not a directory`);
|
|
41
|
+
}
|
|
135
42
|
|
|
136
|
-
|
|
43
|
+
if (!folderInfo) {
|
|
44
|
+
await mkdir(folder, { recursive: true });
|
|
45
|
+
}
|
|
137
46
|
|
|
138
|
-
const
|
|
139
|
-
|
|
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
|
+
};
|
|
140
64
|
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
+
};
|
|
145
80
|
|
|
146
|
-
const
|
|
147
|
-
|
|
81
|
+
const removeData = async (file) => {
|
|
82
|
+
const filePath = join(folder, fixFileName(file));
|
|
83
|
+
const mutex = getFileLock(filePath);
|
|
148
84
|
|
|
149
|
-
|
|
85
|
+
return mutex.acquire().then(async (release) => {
|
|
86
|
+
try {
|
|
87
|
+
await unlink(filePath);
|
|
88
|
+
} catch (_) { }
|
|
89
|
+
finally {
|
|
90
|
+
release();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
};
|
|
150
94
|
|
|
151
|
-
|
|
152
|
-
? Buffer.from([0x06, 0x05])
|
|
153
|
-
: Buffer.from([0x06, 0x00]);
|
|
154
|
-
const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public]);
|
|
95
|
+
let creds = await readData('creds.json');
|
|
155
96
|
|
|
156
|
-
if (!
|
|
157
|
-
|
|
97
|
+
if (!creds) {
|
|
98
|
+
creds = initAuthCreds();
|
|
99
|
+
await writeData(creds, 'creds.json');
|
|
158
100
|
}
|
|
159
101
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
102
|
+
return {
|
|
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
|
+
}
|
|
187
136
|
}
|
|
188
|
-
]
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
};
|
|
192
137
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
...(signalIdentities || []),
|
|
198
|
-
identity
|
|
199
|
-
],
|
|
200
|
-
platform: platformNode?.attrs.name
|
|
201
|
-
};
|
|
138
|
+
await Promise.all(tasks);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
202
142
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
143
|
+
saveCreds: async () => {
|
|
144
|
+
await writeData(creds, 'creds.json');
|
|
145
|
+
}
|
|
206
146
|
};
|
|
207
147
|
};
|
|
208
|
-
exports.configureSuccessfulPairing = configureSuccessfulPairing;
|
|
209
148
|
|
|
210
|
-
|
|
211
|
-
account = { ...account };
|
|
212
|
-
if (!includeSignatureKey || !account.accountSignatureKey?.length) {
|
|
213
|
-
account.accountSignatureKey = null;
|
|
214
|
-
}
|
|
215
|
-
return WAProto_1.proto.ADVSignedDeviceIdentity
|
|
216
|
-
.encode(account)
|
|
217
|
-
.finish();
|
|
218
|
-
};
|
|
219
|
-
exports.encodeSignedDeviceIdentity = encodeSignedDeviceIdentity;
|
|
149
|
+
exports.useMultiFileAuthState = useMultiFileAuthState;
|