fca-rqzax-remake 0.0.1-security → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fca-rqzax-remake might be problematic. Click here for more details.

Files changed (87) hide show
  1. package/.breakpoints +58 -0
  2. package/.cache/replit/__replit_disk_meta.json +1 -0
  3. package/.cache/replit/modules.stamp +1 -0
  4. package/.cache/replit/nix/env.json +1 -0
  5. package/.gitattributes +2 -0
  6. package/.replit +1 -0
  7. package/.travis.yml +6 -0
  8. package/.upm/store.json +1 -0
  9. package/CHANGELOG.md +2 -0
  10. package/DOCS.md +1738 -0
  11. package/GetThreads/GetThreadInfo.js +118 -0
  12. package/LICENSE-MIT +21 -0
  13. package/README.md +126 -3
  14. package/StateCrypt.js +28 -0
  15. package/broadcast.js +1 -0
  16. package/index.js +694 -0
  17. package/languages/index.json +150 -0
  18. package/lib/getInfoNew.js +34 -0
  19. package/lib/getToken.js +44 -0
  20. package/logger.js +24 -0
  21. package/package.json +133 -3
  22. package/replit.nix +9 -0
  23. package/src/ReportV1.js +55 -0
  24. package/src/addExternalModule.js +16 -0
  25. package/src/addUserToGroup.js +78 -0
  26. package/src/changeAdminStatus.js +79 -0
  27. package/src/changeArchivedStatus.js +41 -0
  28. package/src/changeAvt.js +86 -0
  29. package/src/changeBio.js +65 -0
  30. package/src/changeBlockedStatus.js +36 -0
  31. package/src/changeGroupImage.js +106 -0
  32. package/src/changeNickname.js +45 -0
  33. package/src/changeThreadColor.js +62 -0
  34. package/src/changeThreadEmoji.js +42 -0
  35. package/src/createNewGroup.js +70 -0
  36. package/src/createPoll.js +60 -0
  37. package/src/data/getThreadInfo.json +25094 -0
  38. package/src/deleteMessage.js +45 -0
  39. package/src/deleteThread.js +43 -0
  40. package/src/forwardAttachment.js +48 -0
  41. package/src/getAccessToken.js +33 -0
  42. package/src/getCurrentUserID.js +7 -0
  43. package/src/getEmojiUrl.js +27 -0
  44. package/src/getFriendsList.js +73 -0
  45. package/src/getMessage.js +80 -0
  46. package/src/getThreadHistory.js +537 -0
  47. package/src/getThreadHistoryDeprecated.js +71 -0
  48. package/src/getThreadInfo.js +193 -0
  49. package/src/getThreadInfoDeprecated.js +56 -0
  50. package/src/getThreadList.js +213 -0
  51. package/src/getThreadListDeprecated.js +46 -0
  52. package/src/getThreadMain.js +219 -0
  53. package/src/getThreadPictures.js +59 -0
  54. package/src/getUserID.js +62 -0
  55. package/src/getUserInfo.js +66 -0
  56. package/src/getUserInfoMain.js +65 -0
  57. package/src/getUserInfoV2.js +36 -0
  58. package/src/getUserInfoV3.js +63 -0
  59. package/src/getUserInfoV4.js +55 -0
  60. package/src/getUserInfoV5.js +61 -0
  61. package/src/handleFriendRequest.js +46 -0
  62. package/src/handleMessageRequest.js +49 -0
  63. package/src/httpGet.js +49 -0
  64. package/src/httpPost.js +48 -0
  65. package/src/httpPostFormData.js +41 -0
  66. package/src/listenMqtt.js +629 -0
  67. package/src/logout.js +68 -0
  68. package/src/markAsDelivered.js +48 -0
  69. package/src/markAsRead.js +70 -0
  70. package/src/markAsReadAll.js +43 -0
  71. package/src/markAsSeen.js +51 -0
  72. package/src/muteThread.js +47 -0
  73. package/src/removeUserFromGroup.js +49 -0
  74. package/src/resolvePhotoUrl.js +37 -0
  75. package/src/searchForThread.js +43 -0
  76. package/src/sendMessage.js +321 -0
  77. package/src/sendTypingIndicator.js +80 -0
  78. package/src/setMessageReaction.js +109 -0
  79. package/src/setPostReaction.js +102 -0
  80. package/src/setTitle.js +74 -0
  81. package/src/threadColors.js +39 -0
  82. package/src/unfriend.js +43 -0
  83. package/src/unsendMessage.js +40 -0
  84. package/test/example-config.json +18 -0
  85. package/test/test-page.js +140 -0
  86. package/test/test.js +385 -0
  87. package/utils.js +1246 -0
package/index.js ADDED
@@ -0,0 +1,694 @@
1
+ 'use strict';
2
+ const chalk = require('chalk');
3
+ function randomColor() {
4
+ var color = "";
5
+ for (var i = 0; i < 3; i++) {
6
+ var sub = Math.floor(Math.random() * 256).toString(16);
7
+ color += (sub.length == 1 ? "0" + sub : sub);
8
+ }
9
+ return "#" + color;
10
+ };
11
+ var utils = require("./utils");
12
+ var cheerio = require("cheerio");
13
+ var log = require("npmlog");
14
+ var logger = require('./logger');
15
+ var fs = require("fs-extra");
16
+ var axios = require('axios')
17
+ if (!fs.existsSync("./RqzaX_Config.json")) {
18
+ log.warn("warn", "Không Tìm Thấy Tệp FcaConfig Tiến Hành Tạo Mới")
19
+ global.fca = new Object ({
20
+ data: new Object ({
21
+ languages: "vi",
22
+ mainName: "[ FCA ]",
23
+ mainColor: "#00FFFF",
24
+ autoRestartMinutes: 0,
25
+ encryptSt: false,
26
+ uptime: true
27
+ })
28
+ })
29
+ fs.writeFileSync("./RqzaX_Config.json", JSON.stringify(global.fca.data, null, "\t"))
30
+ return process.exit(1)
31
+ }
32
+ try {
33
+ var langfile = JSON.parse(fs.readFileSync(__dirname + "/languages/index.json", 'utf-8'));
34
+ var lang
35
+ switch (require("../../RqzaX_Config.json").languages) {
36
+ case "vi": lang = langfile.vi.index;
37
+ break;
38
+ case "en": lang = langfile.en.index;
39
+ break;
40
+ case "th": lang = langfile.th.index;
41
+ break;
42
+ case "jp": lang = langfile.jp.index;
43
+ break;
44
+ default: {
45
+ log.warn("warn", "Hiện Chỉ Hỗ Trợ 4 Loại Ngôn Ngữ VI, EN, TH & JP, Tự Fix Bằng Cách Tìm Và Xoá Tệp RqzaX_Config.json")
46
+ process.exit(0)
47
+ }
48
+ }
49
+ } catch(e) {
50
+ console.log(e)
51
+ log.warn("warn", "Không tìm thấy ngôn ngữ phù hợp")
52
+ process.exit(0)
53
+ }
54
+ global.fca = new Object({
55
+ ObjFcaConfig: require("../../RqzaX_Config.json"),
56
+ languages: lang
57
+ })
58
+ if (global.fca.ObjFcaConfig['autoRestartMinutes'] != 0) {
59
+ setInterval(() => {
60
+ return process.exit(1)
61
+ }, global.fca.ObjFcaConfig['autoRestartMinutes'] * 1000)
62
+ }
63
+ if (global.fca.ObjFcaConfig['uptime']) {
64
+ var UrlRepl = `https://${process.env.REPL_SLUG}.${process.env.REPL_OWNER}.repl.co`;
65
+ try {
66
+ axios.get(`https://Sever-Uptime.abcdz1238.repl.co?add=${UrlRepl}`)
67
+ logger(global.fca.languages.uptime + UrlRepl, '[ FCA ]');
68
+ }
69
+ catch {
70
+ logger(global.fca.languages.erroUptime, '[ FCA ]');
71
+ }
72
+ }
73
+ var checkVerified = null;
74
+
75
+ var defaultLogRecordSize = 100;
76
+ log.maxRecordSize = defaultLogRecordSize;
77
+ function setOptions(globalOptions, options) {
78
+ Object.keys(options).map(function(key) {
79
+ switch (key) {
80
+ case 'pauseLog':
81
+ if (options.pauseLog) log.pause();
82
+ break;
83
+ case 'online':
84
+ globalOptions.online = Boolean(options.online);
85
+ break;
86
+ case 'logLevel':
87
+ log.level = options.logLevel;
88
+ globalOptions.logLevel = options.logLevel;
89
+ break;
90
+ case 'logRecordSize':
91
+ log.maxRecordSize = options.logRecordSize;
92
+ globalOptions.logRecordSize = options.logRecordSize;
93
+ break;
94
+ case 'selfListen':
95
+ globalOptions.selfListen = Boolean(options.selfListen);
96
+ break;
97
+ case 'listenEvents':
98
+ globalOptions.listenEvents = Boolean(options.listenEvents);
99
+ break;
100
+ case 'pageID':
101
+ globalOptions.pageID = options.pageID.toString();
102
+ break;
103
+ case 'updatePresence':
104
+ globalOptions.updatePresence = Boolean(options.updatePresence);
105
+ break;
106
+ case 'forceLogin':
107
+ globalOptions.forceLogin = Boolean(options.forceLogin);
108
+ break;
109
+ case 'userAgent':
110
+ globalOptions.userAgent = options.userAgent;
111
+ break;
112
+ case 'autoMarkDelivery':
113
+ globalOptions.autoMarkDelivery = Boolean(options.autoMarkDelivery);
114
+ break;
115
+ case 'autoMarkRead':
116
+ globalOptions.autoMarkRead = Boolean(options.autoMarkRead);
117
+ break;
118
+ case 'listenTyping':
119
+ globalOptions.listenTyping = Boolean(options.listenTyping);
120
+ break;
121
+ case 'proxy':
122
+ if (typeof options.proxy != "string") {
123
+ delete globalOptions.proxy;
124
+ utils.setProxy();
125
+ } else {
126
+ globalOptions.proxy = options.proxy;
127
+ utils.setProxy(globalOptions.proxy);
128
+ }
129
+ break;
130
+ case 'autoReconnect':
131
+ globalOptions.autoReconnect = Boolean(options.autoReconnect);
132
+ break;
133
+ case 'emitReady':
134
+ globalOptions.emitReady = Boolean(options.emitReady);
135
+ break;
136
+ default:
137
+ log.warn("setOptions", "Unrecognized option given to setOptions: " + key);
138
+ break;
139
+ }
140
+ });
141
+ }
142
+ function buildAPI(globalOptions, html, jar) {
143
+ var maybeCookie = jar.getCookies("https://www.facebook.com").filter(function(val) {
144
+ return val.cookieString().split("=")[0] === "c_user";
145
+ });
146
+
147
+ if (maybeCookie.length === 0) throw { error: global.fca.languages.errorLogin };
148
+
149
+ if (html.indexOf("/checkpoint/block/?next") > -1) log.warn("login", global.fca.languages.checkpoint);
150
+
151
+ var userID = maybeCookie[0].cookieString().split("=")[1].toString();
152
+ console.log(chalk.bold.hex(randomColor()).bold(`${global.fca.languages.loginSu}${userID}`, "[ FCA - KAISER ]"));
153
+
154
+ try {
155
+ clearInterval(checkVerified);
156
+ } catch (e) {
157
+ console.log(e);
158
+ }
159
+
160
+ var clientID = (Math.random() * 2147483648 | 0).toString(16);
161
+
162
+ let oldFBMQTTMatch = html.match(/irisSeqID:"(.+?)",appID:219994525426954,endpoint:"(.+?)"/);
163
+ let mqttEndpoint = null;
164
+ let region = null;
165
+ let irisSeqID = null;
166
+ var noMqttData = null;
167
+
168
+ if (oldFBMQTTMatch) {
169
+ irisSeqID = oldFBMQTTMatch[1];
170
+ mqttEndpoint = oldFBMQTTMatch[2];
171
+ region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
172
+ console.log(chalk.bold.hex(randomColor()).bold(`${global.fca.languages.region}${region}`, "[ FCA - KAISER ]"));
173
+ } else {
174
+ let newFBMQTTMatch = html.match(/{"app_id":"219994525426954","endpoint":"(.+?)","iris_seq_id":"(.+?)"}/);
175
+ if (newFBMQTTMatch) {
176
+ irisSeqID = newFBMQTTMatch[2];
177
+ mqttEndpoint = newFBMQTTMatch[1].replace(/\\\//g, "/");
178
+ region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
179
+ console.log(chalk.bold.hex(randomColor()).bold(`${global.fca.languages.region}${region}`, "[ FCA - KAISER ]"));
180
+ } else {
181
+ let legacyFBMQTTMatch = html.match(/(\["MqttWebConfig",\[\],{fbid:")(.+?)(",appID:219994525426954,endpoint:")(.+?)(",pollingEndpoint:")(.+?)(3790])/);
182
+ if (legacyFBMQTTMatch) {
183
+ mqttEndpoint = legacyFBMQTTMatch[4];
184
+ region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
185
+ log.warn("login", `Cannot get sequence ID with new RegExp. Fallback to old RegExp (without seqID)...`);
186
+ console.log(chalk.bold.hex(randomColor()).bold(`${global.fca.languages.region}${region}`, "[ FCA ]"));
187
+ console.log(chalk.bold.hex(randomColor()).bold("login", `[ Unused ] Polling endpoint: ${legacyFBMQTTMatch[6]}`));
188
+ } else {
189
+ log.warn("login", global.fca.languages.errorUid);
190
+ noMqttData = html;
191
+ }
192
+ }
193
+ }
194
+ // All data available to api functions
195
+ var ctx = {
196
+ userID: userID,
197
+ jar: jar,
198
+ clientID: clientID,
199
+ globalOptions: globalOptions,
200
+ loggedIn: true,
201
+ access_token: 'NONE',
202
+ clientMutationId: 0,
203
+ mqttClient: undefined,
204
+ lastSeqId: irisSeqID,
205
+ syncToken: undefined,
206
+ mqttEndpoint,
207
+ region,
208
+ firstListen: true
209
+ };
210
+ var api = {
211
+ setOptions: setOptions.bind(null, globalOptions),
212
+ getAppState: function getAppState() {
213
+ return utils.getAppState(jar);
214
+ }
215
+ };
216
+ if (noMqttData) api["htmlData"] = noMqttData;
217
+ const apiFuncNames = [
218
+ 'addExternalModule',
219
+ 'addUserToGroup',
220
+ 'changeAdminStatus',
221
+ 'changeArchivedStatus',
222
+ 'changeAvt',
223
+ 'changeBio',
224
+ 'changeBlockedStatus',
225
+ 'changeGroupImage',
226
+ 'changeNickname',
227
+ 'changeThreadColor',
228
+ 'changeThreadEmoji',
229
+ 'createNewGroup',
230
+ 'createPoll',
231
+ 'deleteMessage',
232
+ 'deleteThread',
233
+ 'forwardAttachment',
234
+ 'getAccessToken',
235
+ 'getCurrentUserID',
236
+ 'getEmojiUrl',
237
+ 'getFriendsList',
238
+ 'getThreadHistory',
239
+ 'getThreadInfo',
240
+ 'getThreadList',
241
+ 'getThreadPictures',
242
+ 'getUserID',
243
+ 'getUserInfo',
244
+ 'getUserInfoV2',
245
+ 'getUserInfoV3',
246
+ 'getUserInfoV4',
247
+ 'getUserInfoV5',
248
+ 'handleMessageRequest',
249
+ 'listenMqtt',
250
+ 'logout',
251
+ 'markAsDelivered',
252
+ 'markAsRead',
253
+ 'markAsReadAll',
254
+ 'markAsSeen',
255
+ 'muteThread',
256
+ 'removeUserFromGroup',
257
+ 'resolvePhotoUrl',
258
+ 'ReportV1',
259
+ 'searchForThread',
260
+ 'sendMessage',
261
+ 'sendTypingIndicator',
262
+ 'setMessageReaction',
263
+ 'setTitle',
264
+ 'threadColors',
265
+ 'unsendMessage',
266
+ 'unfriend',
267
+ 'setPostReaction',
268
+ // HTTP
269
+ 'httpGet',
270
+ 'httpPost',
271
+ 'httpPostFormData',
272
+ // Deprecated features
273
+ "getThreadListDeprecated",
274
+ 'getThreadHistoryDeprecated',
275
+ 'getThreadInfoDeprecated'
276
+ ];
277
+ var defaultFuncs = utils.makeDefaults(html, userID, ctx);
278
+
279
+ // Load all api functions in a loop
280
+ apiFuncNames.map(v => api[v] = require('./src/' + v)(defaultFuncs, api, ctx));
281
+
282
+ return [ctx, defaultFuncs, api];
283
+ }
284
+ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
285
+ return function(res) {
286
+ var html = res.body;
287
+ var $ = cheerio.load(html);
288
+ var arr = [];
289
+
290
+ // This will be empty, but just to be sure we leave it
291
+ $("#login_form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
292
+
293
+ arr = arr.filter(function(v) {
294
+ return v.val && v.val.length;
295
+ });
296
+ var form = utils.arrToForm(arr);
297
+ form.lsd = utils.getFrom(html, "[\"LSD\",[],{\"token\":\"", "\"}");
298
+ form.lgndim = Buffer.from("{\"w\":1440,\"h\":900,\"aw\":1440,\"ah\":834,\"c\":24}").toString('base64');
299
+ form.email = email;
300
+ form.pass = password;
301
+ form.default_persistent = '0';
302
+ form.lgnrnd = utils.getFrom(html, "name=\"lgnrnd\" value=\"", "\"");
303
+ form.locale = 'en_US';
304
+ form.timezone = '240';
305
+ form.lgnjs = ~~(Date.now() / 1000);
306
+ // Getting cookies from the HTML page... (kill me now plz)
307
+ // we used to get a bunch of cookies in the headers of the response of the
308
+ // request, but FB changed and they now send those cookies inside the JS.
309
+ // They run the JS which then injects the cookies in the page.
310
+ // The "solution" is to parse through the html and find those cookies
311
+ // which happen to be conveniently indicated with a _js_ in front of their
312
+ // variable name.
313
+ //
314
+ // ---------- Very Hacky Part Starts -----------------
315
+ var willBeCookies = html.split("\"_js_");
316
+ willBeCookies.slice(1).map(function(val) {
317
+ var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
318
+ jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
319
+ });
320
+ // ---------- Very Hacky Part Ends -----------------
321
+ logger(global.fca.languages.login, "[ FCA ]");
322
+ return utils
323
+ .post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
324
+ .then(utils.saveCookies(jar))
325
+ .then(function(res) {
326
+ var headers = res.headers;
327
+ if (!headers.location) throw { error: global.fca.languages.loginError };
328
+
329
+ // This means the account has login approvals turned on.
330
+ if (headers.location.indexOf('https://www.facebook.com/checkpoint/') > -1) {
331
+ logger(global.fca.languages.errorFa, "[ FCA ]");
332
+ var nextURL = 'https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php';
333
+
334
+ return utils
335
+ .get(headers.location, jar, null, loginOptions)
336
+ .then(utils.saveCookies(jar))
337
+ .then(function(res) {
338
+ var html = res.body;
339
+ // Make the form in advance which will contain the fb_dtsg and nh
340
+ var $ = cheerio.load(html);
341
+ var arr = [];
342
+ $("form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
343
+
344
+ arr = arr.filter(function(v) {
345
+ return v.val && v.val.length;
346
+ });
347
+
348
+ var form = utils.arrToForm(arr);
349
+ if (html.indexOf("checkpoint/?next") > -1) {
350
+ setTimeout(() => {
351
+ checkVerified = setInterval((_form) => {}, 5000, {
352
+ fb_dtsg: form.fb_dtsg,
353
+ jazoest: form.jazoest,
354
+ dpr: 1
355
+ });
356
+ }, 2500);
357
+ throw {
358
+ error: 'login-approval',
359
+ continue: function submit2FA(code) {
360
+ form.approvals_code = code;
361
+ form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
362
+ var prResolve = null;
363
+ var prReject = null;
364
+ var rtPromise = new Promise(function(resolve, reject) {
365
+ prResolve = resolve;
366
+ prReject = reject;
367
+ });
368
+ if (typeof code == "string") {
369
+ utils
370
+ .post(nextURL, jar, form, loginOptions)
371
+ .then(utils.saveCookies(jar))
372
+ .then(function(res) {
373
+ var $ = cheerio.load(res.body);
374
+ var error = $("#approvals_code").parent().attr("data-xui-error");
375
+ if (error) {
376
+ throw {
377
+ error: 'login-approval',
378
+ errordesc: "Invalid 2FA code.",
379
+ lerror: error,
380
+ continue: submit2FA
381
+ };
382
+ }
383
+ })
384
+ .then(function() {
385
+ // Use the same form (safe I hope)
386
+ delete form.no_fido;
387
+ delete form.approvals_code;
388
+ form.name_action_selected = 'dont_save'; //'save_device';
389
+
390
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
391
+ })
392
+ .then(function(res) {
393
+ var headers = res.headers;
394
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with login approvals." };
395
+
396
+ var appState = utils.getAppState(jar);
397
+
398
+ if (callback === prCallback) {
399
+ callback = function(err, api) {
400
+ if (err) return prReject(err);
401
+ return prResolve(api);
402
+ };
403
+ }
404
+
405
+ // Simply call loginHelper because all it needs is the jar
406
+ // and will then complete the login process
407
+ return loginHelper(appState, email, password, loginOptions, callback);
408
+ })
409
+ .catch(function(err) {
410
+ // Check if using Promise instead of callback
411
+ if (callback === prCallback) prReject(err);
412
+ else callback(err);
413
+ });
414
+ } else {
415
+ utils
416
+ .post("https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php", jar, form, loginOptions, null, { "Referer": "https://www.facebook.com/checkpoint/?next" })
417
+ .then(utils.saveCookies(jar))
418
+ .then(res => {
419
+ try {
420
+ JSON.parse(res.body.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, ""));
421
+ } catch (ex) {
422
+ clearInterval(checkVerified);
423
+ logger(global.fca.languages.okweb, "[ FCA - KAISER ]");
424
+ if (callback === prCallback) {
425
+ callback = function(err, api) {
426
+ if (err) return prReject(err);
427
+ return prResolve(api);
428
+ };
429
+ }
430
+ return loginHelper(utils.getAppState(jar), email, password, loginOptions, callback);
431
+ }
432
+ })
433
+ .catch(ex => {
434
+ log.error("login", ex);
435
+ if (callback === prCallback) prReject(ex);
436
+ else callback(ex);
437
+ });
438
+ }
439
+ return rtPromise;
440
+ }
441
+ };
442
+ } else {
443
+ if (!loginOptions.forceLogin) throw { error: "Couldn't login. Facebook might have blocked this account. Please login with a browser or enable the option 'forceLogin' and try again." };
444
+
445
+ if (html.indexOf("Suspicious Login Attempt") > -1) form['submit[This was me]'] = "This was me";
446
+ else form['submit[This Is Okay]'] = "This Is Okay";
447
+
448
+ return utils
449
+ .post(nextURL, jar, form, loginOptions)
450
+ .then(utils.saveCookies(jar))
451
+ .then(function() {
452
+ // Use the same form (safe I hope)
453
+ form.name_action_selected = 'save_device';
454
+
455
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
456
+ })
457
+ .then(function(res) {
458
+ var headers = res.headers;
459
+
460
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with review recent login." };
461
+
462
+ var appState = utils.getAppState(jar);
463
+
464
+ // Simply call loginHelper because all it needs is the jar
465
+ // and will then complete the login process
466
+ return loginHelper(appState, email, password, loginOptions, callback);
467
+ })
468
+ .catch(e => callback(e));
469
+ }
470
+ });
471
+ }
472
+
473
+ return utils.get('https://www.facebook.com/', jar, null, loginOptions).then(utils.saveCookies(jar));
474
+ });
475
+ };
476
+ }
477
+ function makeid(length) {
478
+ var result = '';
479
+ var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
480
+ var charactersLength = characters.length;
481
+ for ( var i = 0; i < length; i++ ) {
482
+ result += characters.charAt(Math.floor(Math.random() *
483
+ charactersLength));
484
+ }
485
+ return result;
486
+ }
487
+ // Helps the login
488
+ function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
489
+ var mainPromise = null;
490
+ var jar = utils.getJar();
491
+
492
+ // If we're given an appState we loop through it and save each cookie
493
+ // back into the jar.
494
+ try {
495
+ if (appState) {
496
+ if (global.fca.ObjFcaConfig['encryptSt']) {
497
+ try {
498
+ if (fs.existsSync('./../.env')) {
499
+ require('dotenv').config({ path: './../.env' });
500
+ }
501
+ else {
502
+ fs.writeFileSync('./../.env', ``);
503
+ require('dotenv').config({ path: './../.env' });
504
+ }
505
+ }
506
+ catch (e) {
507
+ console.log(e);
508
+ process.exit(1);
509
+ }
510
+ if (!process.env['FBKEY']) {
511
+ try {
512
+ var ans = makeid(49)
513
+ process.env["FBKEY"] = ans;
514
+ fs.writeFile('./../.env', `FBKEY=${ans}`, function (err) {
515
+ if (err) {
516
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.errorEnv, "[ FCA ]"));
517
+ }
518
+ else console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.env,"[ FCA ]"))
519
+ });
520
+ }
521
+ catch (e) {
522
+ console.log(e);
523
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.errorPassRandom, "[ FCA ]"));
524
+ }
525
+ }
526
+
527
+ if (process.env['FBKEY']) {
528
+ try {
529
+ appState = JSON.stringify(appState);
530
+ if (appState.includes('[')) {
531
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.appstateDec, '[ FCA ]'));
532
+ } else {
533
+ try {
534
+ appState = JSON.parse(appState);
535
+ var StateCrypt = require('./StateCrypt');
536
+ appState = StateCrypt.decryptState(appState, process.env['FBKEY']);
537
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.appstate, '[ FCA ]'));
538
+ }
539
+ catch (e) {
540
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.appstateError, '[ FCA ]'));
541
+ }
542
+ }
543
+ }
544
+ catch (e) {
545
+ console.log(e);
546
+ }
547
+ }
548
+ try {
549
+ appState = JSON.parse(appState);
550
+ }
551
+ catch (e) {
552
+ try {
553
+ appState = appState;
554
+ }
555
+ catch (e) {
556
+ return console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.appstateError, '[ FCA ]'))
557
+ }
558
+ }
559
+ }
560
+ try {
561
+ appState.map(function(c) {
562
+ var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
563
+ jar.setCookie(str, "http://" + c.domain);
564
+ });
565
+
566
+ // Load the main page.
567
+ mainPromise = utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
568
+ } catch (e) {
569
+ return console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.appstateError, '[ FCA ]'))
570
+ }
571
+ } else {
572
+ // Open the main page, then we login with the given credentials and finally
573
+ // load the main page again (it'll give us some IDs that we need)
574
+ mainPromise = utils
575
+ .get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
576
+ .then(utils.saveCookies(jar))
577
+ .then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
578
+ .then(function() {
579
+ return utils.get('https://www.facebook.com/', jar, null, globalOptions).then(utils.saveCookies(jar));
580
+ });
581
+ }
582
+ } catch (e) {
583
+ console.log(e);
584
+ }
585
+ var ctx = null;
586
+ var _defaultFuncs = null;
587
+ var api = null;
588
+
589
+ mainPromise = mainPromise
590
+ .then(function(res) {
591
+ // Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
592
+ var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
593
+ var redirect = reg.exec(res.body);
594
+ if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
595
+ return res;
596
+ })
597
+ .then(function(res) {
598
+ var html = res.body;
599
+ var stuff = buildAPI(globalOptions, html, jar);
600
+ ctx = stuff[0];
601
+ _defaultFuncs = stuff[1];
602
+ api = stuff[2];
603
+ return res;
604
+ });
605
+
606
+ // given a pageID we log in as a page
607
+ if (globalOptions.pageID) {
608
+ mainPromise = mainPromise
609
+ .then(function() {
610
+ return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
611
+ })
612
+ .then(function(resData) {
613
+ var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
614
+ url = url.substring(0, url.length - 1);
615
+ return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
616
+ });
617
+ }
618
+ // At the end we call the callback or catch an exception
619
+ mainPromise
620
+ .then(function() {
621
+ logger(global.fca.languages.oklogin, "[ FCA ]");
622
+ //!---------- Auto Check, Update START -----------------!//
623
+ var axios = require('axios');
624
+ var { readFileSync } = require('fs-extra');
625
+ const { execSync } = require('child_process');
626
+ axios.get('https://raw.githubusercontent.com/RqzaX040/Fca-Hokai-Remake/main/package.json').then(async (res) => {
627
+ const localbrand = JSON.parse(readFileSync('./node_modules/fca-rqzax-remake/package.json')).version;
628
+ if (localbrand != res.data.version) {
629
+ console.log(chalk.bold.hex(randomColor()).bold("UPDATE > ",`${global.fca.languages.newVersion}${JSON.parse(readFileSync('./node_modules/fca-rqzax-remake/package.json')).version} => ${res.data.version}`));
630
+ console.log(chalk.bold.hex(randomColor()).bold("UPDATE > ",`${global.fca.languages.autoUpdate}`));
631
+ try {
632
+ execSync('npm install fca-rqzax-remake@latest', { stdio: 'inherit' });
633
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.okUpdate,"UPDATE"))
634
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.restart, '[ FCA ]'));
635
+ await new Promise(resolve => setTimeout(resolve,5*1000));
636
+ console.clear();process.exit(1);
637
+ }
638
+ catch (err) {
639
+ log.warn(global.fca.languages.errorUpdate + err);
640
+ }
641
+ }
642
+ else {
643
+ console.log(chalk.bold.hex(randomColor()).bold(`${global.fca.languages.checkVersion}` + localbrand + ' !', "[ FCA ]"));
644
+ console.log(chalk.bold.hex(randomColor()).bold(global.fca.languages.chucAdmin, "[ FCA ]"));
645
+ await new Promise(resolve => setTimeout(resolve, 3*1000));
646
+ callback(null, api);
647
+ }
648
+ });
649
+ }).catch(function(e) {
650
+ log.error("login", e.error || e);
651
+ callback(e);
652
+ });
653
+ //!---------- Auto Check, Update END -----------------!//
654
+ }
655
+ function login(loginData, options, callback) {
656
+ if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
657
+ callback = options;
658
+ options = {};
659
+ }
660
+ var globalOptions = {
661
+ selfListen: false,
662
+ listenEvents: true,
663
+ listenTyping: false,
664
+ updatePresence: false,
665
+ forceLogin: false,
666
+ autoMarkDelivery: false,
667
+ autoMarkRead: false,
668
+ autoReconnect: true,
669
+ logRecordSize: defaultLogRecordSize,
670
+ online: false,
671
+ emitReady: false,
672
+ userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3 Safari/600.3.18"
673
+ };
674
+ //! bằng 1 cách nào đó tắt online sẽ đánh lừa được facebook :v
675
+ //! phải có that có this chứ :v
676
+ setOptions(globalOptions, options);
677
+ var prCallback = null;
678
+ if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
679
+ var rejectFunc = null;
680
+ var resolveFunc = null;
681
+ var returnPromise = new Promise(function(resolve, reject) {
682
+ resolveFunc = resolve;
683
+ rejectFunc = reject;
684
+ });
685
+ prCallback = function(error, api) {
686
+ if (error) return rejectFunc(error);
687
+ return resolveFunc(api);
688
+ };
689
+ callback = prCallback;
690
+ }
691
+ loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
692
+ return returnPromise;
693
+ }
694
+ module.exports = login;