shadowx-fca 2.2.0 → 2.3.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/README.md +3 -11
- package/index.js +41 -188
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
Here's a comprehensive README.md for your shadowx-fca package:
|
|
2
|
-
|
|
3
1
|
```markdown
|
|
4
2
|
# shadowx-fca
|
|
5
|
-
|
|
6
|
-
<div align="center">
|
|
7
|
-
<img src="https://img.shields.io/npm/v/shadowx-fca.svg?style=for-the-badge" alt="NPM Version">
|
|
8
|
-
<img src="https://img.shields.io/npm/dt/shadowx-fca.svg?style=for-the-badge" alt="NPM Downloads">
|
|
9
|
-
<img src="https://img.shields.io/github/license/mueidmursalinrifat/shadowx-fca.svg?style=for-the-badge" alt="License">
|
|
10
|
-
<img src="https://img.shields.io/badge/node-%3E%3D14.0.0-brightgreen.svg?style=for-the-badge" alt="Node Version">
|
|
11
|
-
</div>
|
|
3
|
+
#Mueid Mursalin Rifat
|
|
12
4
|
|
|
13
5
|
<p align="center">
|
|
14
6
|
<strong>Unofficial Facebook Chat API for Node.js with Auto-Update System</strong><br>
|
|
@@ -51,8 +43,8 @@ npm install shadowx-fca
|
|
|
51
43
|
|
|
52
44
|
Requirements
|
|
53
45
|
|
|
54
|
-
· Node.js >=
|
|
55
|
-
· npm >=
|
|
46
|
+
· Node.js >= 16.0.0
|
|
47
|
+
· npm >= 7.0.0
|
|
56
48
|
|
|
57
49
|
🚀 Quick Start
|
|
58
50
|
|
package/index.js
CHANGED
|
@@ -3,35 +3,11 @@
|
|
|
3
3
|
var utils = require("./utils");
|
|
4
4
|
var cheerio = require("cheerio");
|
|
5
5
|
var log = require("npmlog");
|
|
6
|
-
var { checkForFCAUpdate } = require("./checkUpdate");
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
6
|
|
|
10
7
|
log.maxRecordSize = 100;
|
|
11
8
|
var checkVerified = null;
|
|
12
|
-
|
|
13
9
|
const Boolean_Option = ['online', 'selfListen', 'listenEvents', 'updatePresence', 'forceLogin', 'autoMarkDelivery', 'autoMarkRead', 'listenTyping', 'autoReconnect', 'emitReady'];
|
|
14
|
-
|
|
15
10
|
global.ditconmemay = false;
|
|
16
|
-
global.stfcaUpdateChecked = false;
|
|
17
|
-
|
|
18
|
-
// Rotating user agents to avoid detection
|
|
19
|
-
const USER_AGENTS = [
|
|
20
|
-
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
21
|
-
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
|
|
22
|
-
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
|
|
23
|
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
24
|
-
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
function getRandomUserAgent() {
|
|
28
|
-
return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Delay function to avoid rate limiting
|
|
32
|
-
function delay(ms) {
|
|
33
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
34
|
-
}
|
|
35
11
|
|
|
36
12
|
function setOptions(globalOptions, options) {
|
|
37
13
|
Object.keys(options).map(function (key) {
|
|
@@ -62,7 +38,7 @@ function setOptions(globalOptions, options) {
|
|
|
62
38
|
break;
|
|
63
39
|
}
|
|
64
40
|
case 'userAgent': {
|
|
65
|
-
globalOptions.userAgent = options.userAgent ||
|
|
41
|
+
globalOptions.userAgent = (options.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36');
|
|
66
42
|
break;
|
|
67
43
|
}
|
|
68
44
|
case 'proxy': {
|
|
@@ -75,10 +51,6 @@ function setOptions(globalOptions, options) {
|
|
|
75
51
|
}
|
|
76
52
|
break;
|
|
77
53
|
}
|
|
78
|
-
case 'delayBetweenRequests': {
|
|
79
|
-
globalOptions.delayBetweenRequests = options.delayBetweenRequests || 1000;
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
54
|
default: {
|
|
83
55
|
log.warn("setOptions", "Unrecognized option given to setOptions: " + key);
|
|
84
56
|
break;
|
|
@@ -93,7 +65,6 @@ function setOptions(globalOptions, options) {
|
|
|
93
65
|
function buildAPI(globalOptions, html, jar) {
|
|
94
66
|
let fb_dtsg = null;
|
|
95
67
|
let irisSeqID = null;
|
|
96
|
-
|
|
97
68
|
function extractFromHTML() {
|
|
98
69
|
try {
|
|
99
70
|
const $ = cheerio.load(html);
|
|
@@ -141,43 +112,35 @@ function buildAPI(globalOptions, html, jar) {
|
|
|
141
112
|
}
|
|
142
113
|
} catch { }
|
|
143
114
|
if (fb_dtsg) {
|
|
144
|
-
log
|
|
115
|
+
console.log("Found fb_dtsg!");
|
|
145
116
|
}
|
|
146
117
|
} catch (e) {
|
|
147
|
-
log
|
|
118
|
+
console.log("Error finding fb_dtsg:", e);
|
|
148
119
|
}
|
|
149
120
|
}
|
|
150
|
-
|
|
151
121
|
extractFromHTML();
|
|
152
|
-
|
|
153
122
|
var userID;
|
|
154
123
|
var cookies = jar.getCookies("https://www.facebook.com");
|
|
155
124
|
var userCookie = cookies.find(cookie => cookie.cookieString().startsWith("c_user="));
|
|
156
125
|
var tiktikCookie = cookies.find(cookie => cookie.cookieString().startsWith("i_user="));
|
|
157
|
-
|
|
158
126
|
if (!userCookie && !tiktikCookie) {
|
|
159
|
-
log.error("Error! Your cookiestate is not valid!");
|
|
160
|
-
throw new Error("Invalid appState");
|
|
127
|
+
return log.error("Error! Your cookiestate is not valid!");
|
|
161
128
|
}
|
|
162
|
-
|
|
163
129
|
if (html.includes("/checkpoint/block/?next")) {
|
|
164
|
-
log.error('error', "Appstate is dead
|
|
165
|
-
throw new Error("AppState expired");
|
|
130
|
+
return log.error('error', "Appstate is dead rechange it!", 'error');
|
|
166
131
|
}
|
|
167
|
-
|
|
168
132
|
userID = (tiktikCookie || userCookie).cookieString().split("=")[1];
|
|
169
|
-
|
|
133
|
+
//logger.log(`${cra(`[ CONNECT ]`)} Logged in as ${userID}`, "DATABASE");
|
|
170
134
|
try { clearInterval(checkVerified); } catch (_) { }
|
|
171
|
-
|
|
172
135
|
const clientID = (Math.random() * 2147483648 | 0).toString(16);
|
|
173
136
|
let mqttEndpoint = `wss://edge-chat.facebook.com/chat?region=pnb&sid=${userID}`;
|
|
174
137
|
let region = "PNB";
|
|
175
138
|
|
|
176
139
|
try {
|
|
177
140
|
const endpointMatch = html.match(/"endpoint":"([^"]+)"/);
|
|
178
|
-
if (endpointMatch
|
|
179
|
-
|
|
180
|
-
|
|
141
|
+
if (endpointMatch.input.includes("601051028565049")) {
|
|
142
|
+
console.log(`login error.`);
|
|
143
|
+
ditconmemay = true;
|
|
181
144
|
}
|
|
182
145
|
if (endpointMatch) {
|
|
183
146
|
mqttEndpoint = endpointMatch[1].replace(/\\\//g, '/');
|
|
@@ -185,11 +148,9 @@ function buildAPI(globalOptions, html, jar) {
|
|
|
185
148
|
region = url.searchParams.get('region')?.toUpperCase() || "PNB";
|
|
186
149
|
}
|
|
187
150
|
} catch (e) {
|
|
188
|
-
log
|
|
151
|
+
console.log('Using default MQTT endpoint');
|
|
189
152
|
}
|
|
190
|
-
|
|
191
|
-
log.info('Building API...');
|
|
192
|
-
|
|
153
|
+
log.info('Logging in...');
|
|
193
154
|
var ctx = {
|
|
194
155
|
userID: userID,
|
|
195
156
|
jar: jar,
|
|
@@ -210,92 +171,19 @@ function buildAPI(globalOptions, html, jar) {
|
|
|
210
171
|
wsReqNumber: 0,
|
|
211
172
|
wsTaskNumber: 0,
|
|
212
173
|
reqCallbacks: {},
|
|
213
|
-
threadTypes: {}
|
|
174
|
+
threadTypes: {} // Store thread type (dm/group) for each thread
|
|
214
175
|
};
|
|
215
|
-
|
|
216
|
-
let config = { enableTypingIndicator: false, typingDuration: 4000 };
|
|
217
|
-
|
|
218
|
-
try {
|
|
219
|
-
const rootConfigPath = path.join(process.cwd(), 'config.json');
|
|
220
|
-
if (fs.existsSync(rootConfigPath)) {
|
|
221
|
-
const rootConfig = JSON.parse(fs.readFileSync(rootConfigPath, 'utf8'));
|
|
222
|
-
if (rootConfig && typeof rootConfig === 'object') {
|
|
223
|
-
if (typeof rootConfig.enableTypingIndicator !== 'undefined') config.enableTypingIndicator = rootConfig.enableTypingIndicator;
|
|
224
|
-
if (typeof rootConfig.typingDuration !== 'undefined') config.typingDuration = rootConfig.typingDuration;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const fcaConfigPath = path.join(__dirname, 'config.json');
|
|
229
|
-
if (fs.existsSync(fcaConfigPath)) {
|
|
230
|
-
const fcaConfig = JSON.parse(fs.readFileSync(fcaConfigPath, 'utf8'));
|
|
231
|
-
if (fcaConfig && typeof fcaConfig === 'object') {
|
|
232
|
-
if (typeof fcaConfig.enableTypingIndicator !== 'undefined') config.enableTypingIndicator = fcaConfig.enableTypingIndicator;
|
|
233
|
-
if (typeof fcaConfig.typingDuration !== 'undefined') config.typingDuration = fcaConfig.typingDuration;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (global.GoatBot && global.GoatBot.config) {
|
|
238
|
-
if (typeof global.GoatBot.config.enableTypingIndicator !== 'undefined') config.enableTypingIndicator = global.GoatBot.config.enableTypingIndicator;
|
|
239
|
-
if (typeof global.GoatBot.config.typingDuration !== 'undefined') config.typingDuration = global.GoatBot.config.typingDuration;
|
|
240
|
-
}
|
|
241
|
-
} catch (e) {
|
|
242
|
-
log.warn('Error loading config.json:', e.message);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const refreshFcaConfig = () => {
|
|
246
|
-
try {
|
|
247
|
-
const updatedConfig = { enableTypingIndicator: false, typingDuration: 4000 };
|
|
248
|
-
|
|
249
|
-
if (fs.existsSync(path.join(process.cwd(), 'config.json'))) {
|
|
250
|
-
const rootConfig = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'config.json'), 'utf8'));
|
|
251
|
-
if (rootConfig && typeof rootConfig === 'object') {
|
|
252
|
-
if (typeof rootConfig.enableTypingIndicator !== 'undefined') updatedConfig.enableTypingIndicator = rootConfig.enableTypingIndicator;
|
|
253
|
-
if (typeof rootConfig.typingDuration !== 'undefined') updatedConfig.typingDuration = rootConfig.typingDuration;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (fs.existsSync(path.join(__dirname, 'config.json'))) {
|
|
258
|
-
const fcaConfig = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json'), 'utf8'));
|
|
259
|
-
if (fcaConfig && typeof fcaConfig === 'object') {
|
|
260
|
-
if (typeof fcaConfig.enableTypingIndicator !== 'undefined') updatedConfig.enableTypingIndicator = fcaConfig.enableTypingIndicator;
|
|
261
|
-
if (typeof fcaConfig.typingDuration !== 'undefined') updatedConfig.typingDuration = fcaConfig.typingDuration;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (global.GoatBot && global.GoatBot.config) {
|
|
266
|
-
if (typeof global.GoatBot.config.enableTypingIndicator !== 'undefined') updatedConfig.enableTypingIndicator = global.GoatBot.config.enableTypingIndicator;
|
|
267
|
-
if (typeof global.GoatBot.config.typingDuration !== 'undefined') updatedConfig.typingDuration = global.GoatBot.config.typingDuration;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
ctx.config = updatedConfig;
|
|
271
|
-
config = updatedConfig;
|
|
272
|
-
} catch (e) {
|
|
273
|
-
log.warn('Failed to refresh fca config:', e.message);
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
refreshFcaConfig();
|
|
278
|
-
ctx.refreshFcaConfig = refreshFcaConfig;
|
|
279
|
-
if (global.GoatBot) {
|
|
280
|
-
global.GoatBot.refreshFcaConfig = refreshFcaConfig;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
ctx.config = config;
|
|
284
|
-
|
|
285
176
|
var api = {
|
|
286
177
|
setOptions: setOptions.bind(null, globalOptions),
|
|
287
178
|
getAppState: () => utils.getAppState(jar),
|
|
288
179
|
postFormData: (url, body) => utils.makeDefaults(html, userID, ctx).postFormData(url, ctx.jar, body)
|
|
289
180
|
};
|
|
290
|
-
|
|
291
181
|
var defaultFuncs = utils.makeDefaults(html, userID, ctx);
|
|
292
182
|
api.postFormData = function (url, body) {
|
|
293
183
|
return defaultFuncs.postFormData(url, ctx.jar, body);
|
|
294
184
|
};
|
|
295
|
-
|
|
296
185
|
api.getFreshDtsg = async function () {
|
|
297
186
|
try {
|
|
298
|
-
await delay(globalOptions.delayBetweenRequests || 1000);
|
|
299
187
|
const res = await defaultFuncs.get('https://www.facebook.com/', jar, null, globalOptions);
|
|
300
188
|
const $ = cheerio.load(res.body);
|
|
301
189
|
let newDtsg;
|
|
@@ -325,18 +213,12 @@ function buildAPI(globalOptions, html, jar) {
|
|
|
325
213
|
|
|
326
214
|
return newDtsg;
|
|
327
215
|
} catch (e) {
|
|
328
|
-
log
|
|
216
|
+
console.log("Error getting fresh dtsg:", e);
|
|
329
217
|
return null;
|
|
330
218
|
}
|
|
331
219
|
};
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const srcPath = path.join(__dirname, 'src');
|
|
335
|
-
if (fs.existsSync(srcPath)) {
|
|
336
|
-
fs.readdirSync(srcPath).filter(v => v.endsWith('.js')).forEach(v => {
|
|
337
|
-
api[v.replace('.js', '')] = require(`./src/${v}`)(utils.makeDefaults(html, userID, ctx), api, ctx);
|
|
338
|
-
});
|
|
339
|
-
}
|
|
220
|
+
//if (noMqttData) api.htmlData = noMqttData;
|
|
221
|
+
require('fs').readdirSync(__dirname + '/src/').filter(v => v.endsWith('.js')).forEach(v => { api[v.replace('.js', '')] = require(`./src/${v}`)(utils.makeDefaults(html, userID, ctx), api, ctx); });
|
|
340
222
|
|
|
341
223
|
// Store original sendMessage as the primary method
|
|
342
224
|
const originalSendMessage = api.sendMessage;
|
|
@@ -346,7 +228,8 @@ function buildAPI(globalOptions, html, jar) {
|
|
|
346
228
|
try {
|
|
347
229
|
return await originalSendMessage(msg, threadID, callback, replyToMessage, isSingleUser);
|
|
348
230
|
} catch (error) {
|
|
349
|
-
|
|
231
|
+
// If modern method fails, fallback to OldMessage
|
|
232
|
+
console.log('sendMessage failed, using OldMessage fallback:', error.message);
|
|
350
233
|
return api.OldMessage(msg, threadID, callback, replyToMessage, isSingleUser);
|
|
351
234
|
}
|
|
352
235
|
};
|
|
@@ -357,7 +240,6 @@ function buildAPI(globalOptions, html, jar) {
|
|
|
357
240
|
};
|
|
358
241
|
|
|
359
242
|
api.listen = api.listenMqtt;
|
|
360
|
-
|
|
361
243
|
return {
|
|
362
244
|
ctx,
|
|
363
245
|
defaultFuncs,
|
|
@@ -383,32 +265,23 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
|
383
265
|
form.locale = 'en_US';
|
|
384
266
|
form.timezone = '240';
|
|
385
267
|
form.lgnjs = Math.floor(Date.now() / 1000);
|
|
386
|
-
|
|
387
268
|
const willBeCookies = html.split("\"_js_");
|
|
388
269
|
willBeCookies.slice(1).forEach(val => {
|
|
389
270
|
const cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
|
|
390
271
|
jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
|
|
391
272
|
});
|
|
392
|
-
|
|
393
|
-
log.info("Logging in with email/password...");
|
|
394
|
-
await delay(2000); // Delay to avoid rate limiting
|
|
395
|
-
|
|
273
|
+
log.info("Logging in...");
|
|
396
274
|
const loginRes = await utils.post(
|
|
397
275
|
"https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110",
|
|
398
276
|
jar,
|
|
399
277
|
form,
|
|
400
278
|
loginOptions
|
|
401
279
|
);
|
|
402
|
-
|
|
403
280
|
await utils.saveCookies(jar)(loginRes);
|
|
404
281
|
const headers = loginRes.headers;
|
|
405
|
-
|
|
406
|
-
if (!headers.location) {
|
|
407
|
-
throw new Error("Wrong username/password or account locked.");
|
|
408
|
-
}
|
|
409
|
-
|
|
282
|
+
if (!headers.location) throw new Error("Wrong username/password.");
|
|
410
283
|
if (headers.location.includes('https://www.facebook.com/checkpoint/')) {
|
|
411
|
-
log.info("login", "
|
|
284
|
+
log.info("login", "You have login approvals turned on.");
|
|
412
285
|
const checkpointRes = await utils.get(headers.location, jar, null, loginOptions);
|
|
413
286
|
await utils.saveCookies(jar)(checkpointRes);
|
|
414
287
|
const checkpointHtml = checkpointRes.body;
|
|
@@ -417,7 +290,6 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
|
417
290
|
$("form input").each((i, v) => checkpointForm.push({ val: $(v).val(), name: $(v).attr("name") }));
|
|
418
291
|
checkpointForm = checkpointForm.filter(v => v.val && v.val.length);
|
|
419
292
|
const form = utils.arrToForm(checkpointForm);
|
|
420
|
-
|
|
421
293
|
if (checkpointHtml.includes("checkpoint/?next")) {
|
|
422
294
|
return new Promise((resolve, reject) => {
|
|
423
295
|
const submit2FA = async (code) => {
|
|
@@ -453,11 +325,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
|
453
325
|
};
|
|
454
326
|
});
|
|
455
327
|
}
|
|
456
|
-
|
|
457
|
-
if (!loginOptions.forceLogin) {
|
|
458
|
-
throw new Error("Couldn't login. Facebook might have blocked this account or requires verification.");
|
|
459
|
-
}
|
|
460
|
-
|
|
328
|
+
if (!loginOptions.forceLogin) throw new Error("Couldn't login. Facebook might have blocked this account.");
|
|
461
329
|
form['submit[This was me]'] = checkpointHtml.includes("Suspicious Login Attempt") ? "This was me" : "This Is Okay";
|
|
462
330
|
await utils.post("https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php", jar, form, loginOptions);
|
|
463
331
|
form.name_action_selected = 'save_device';
|
|
@@ -465,40 +333,39 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
|
465
333
|
const appState = utils.getAppState(jar);
|
|
466
334
|
return await loginHelper(appState, email, password, loginOptions, callback);
|
|
467
335
|
}
|
|
468
|
-
|
|
469
336
|
await utils.get('https://www.facebook.com/', jar, null, loginOptions);
|
|
470
337
|
return await utils.saveCookies(jar);
|
|
471
338
|
} catch (error) {
|
|
472
|
-
log.error("Login error:", error.message);
|
|
473
339
|
callback(error);
|
|
474
340
|
}
|
|
475
341
|
};
|
|
476
342
|
}
|
|
477
343
|
|
|
344
|
+
|
|
478
345
|
function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
|
|
479
346
|
let mainPromise = null;
|
|
480
347
|
const jar = utils.getJar();
|
|
481
|
-
|
|
482
348
|
if (appState) {
|
|
483
349
|
try {
|
|
484
|
-
|
|
485
|
-
appState = JSON.parse(appState);
|
|
486
|
-
}
|
|
350
|
+
appState = JSON.parse(appState);
|
|
487
351
|
} catch (e) {
|
|
488
|
-
|
|
352
|
+
try {
|
|
353
|
+
appState = appState;
|
|
354
|
+
} catch (e) {
|
|
355
|
+
return callback(new Error("Failed to parse appState"));
|
|
356
|
+
}
|
|
489
357
|
}
|
|
490
358
|
|
|
491
359
|
try {
|
|
492
360
|
appState.forEach(c => {
|
|
493
|
-
const str = `${c.key}=${c.value};
|
|
361
|
+
const str = `${c.key}=${c.value}; expires=${c.expires}; domain=${c.domain}; path=${c.path};`;
|
|
494
362
|
jar.setCookie(str, "http://" + c.domain);
|
|
495
363
|
});
|
|
496
364
|
|
|
497
365
|
mainPromise = utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true })
|
|
498
366
|
.then(utils.saveCookies(jar));
|
|
499
367
|
} catch (e) {
|
|
500
|
-
|
|
501
|
-
return callback(new Error("Failed to set appState cookies"));
|
|
368
|
+
process.exit(0);
|
|
502
369
|
}
|
|
503
370
|
} else {
|
|
504
371
|
mainPromise = utils
|
|
@@ -523,7 +390,7 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
|
|
|
523
390
|
.then(res => {
|
|
524
391
|
const mobileAgentRegex = /MPageLoadClientMetrics/gs;
|
|
525
392
|
if (!mobileAgentRegex.test(res.body)) {
|
|
526
|
-
globalOptions.userAgent =
|
|
393
|
+
globalOptions.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36";
|
|
527
394
|
return utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
|
|
528
395
|
}
|
|
529
396
|
return res;
|
|
@@ -553,20 +420,12 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
|
|
|
553
420
|
callback(null, api);
|
|
554
421
|
})
|
|
555
422
|
.catch(e => {
|
|
556
|
-
log.error("Login helper error:", e.message);
|
|
557
423
|
callback(e);
|
|
558
424
|
});
|
|
559
425
|
}
|
|
560
426
|
|
|
561
|
-
function login(loginData, options, callback) {
|
|
562
|
-
// Check for updates (non-blocking, only once per session)
|
|
563
|
-
if (!global.stfcaUpdateChecked) {
|
|
564
|
-
global.stfcaUpdateChecked = true;
|
|
565
|
-
checkForFCAUpdate().catch(err => {
|
|
566
|
-
// Silently ignore update check errors to not block login
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
427
|
|
|
428
|
+
function login(loginData, options, callback) {
|
|
570
429
|
if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
|
|
571
430
|
callback = options;
|
|
572
431
|
options = {};
|
|
@@ -584,8 +443,7 @@ function login(loginData, options, callback) {
|
|
|
584
443
|
logRecordSize: 100,
|
|
585
444
|
online: false,
|
|
586
445
|
emitReady: false,
|
|
587
|
-
|
|
588
|
-
userAgent: getRandomUserAgent()
|
|
446
|
+
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
589
447
|
};
|
|
590
448
|
|
|
591
449
|
var prCallback = null;
|
|
@@ -603,24 +461,19 @@ function login(loginData, options, callback) {
|
|
|
603
461
|
callback = prCallback;
|
|
604
462
|
}
|
|
605
463
|
|
|
606
|
-
|
|
607
|
-
if (loginData.appState) {
|
|
608
|
-
setOptions(globalOptions, options);
|
|
609
|
-
loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
|
|
610
|
-
} else if (loginData.email && loginData.password) {
|
|
464
|
+
if (loginData.email && loginData.password) {
|
|
611
465
|
setOptions(globalOptions, {
|
|
466
|
+
logLevel: "silent",
|
|
612
467
|
forceLogin: true,
|
|
613
|
-
userAgent:
|
|
614
|
-
delayBetweenRequests: 1500
|
|
468
|
+
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
615
469
|
});
|
|
616
|
-
loginHelper(
|
|
617
|
-
} else {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
else throw error;
|
|
470
|
+
loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
|
|
471
|
+
} else if (loginData.appState) {
|
|
472
|
+
setOptions(globalOptions, options);
|
|
473
|
+
return loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
|
|
621
474
|
}
|
|
622
|
-
|
|
623
475
|
return returnPromise;
|
|
624
476
|
}
|
|
625
477
|
|
|
478
|
+
|
|
626
479
|
module.exports = login;
|