fca-rqzax-remake 0.0.1-security → 5.0.2

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