jake-chan 0.0.1-security → 5.3.7

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

Potentially problematic release.


This version of jake-chan might be problematic. Click here for more details.

Files changed (88) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -0
  2. package/.cache/replit/modules.stamp +0 -0
  3. package/.cache/replit/nix/env.json +1 -0
  4. package/.config/configstore/update-notifier-npm.json +4 -0
  5. package/CHANGELOG.md +2 -0
  6. package/DOCS.md +1738 -0
  7. package/LICENSE-MIT +21 -0
  8. package/README.md +106 -3
  9. package/StateCrypt.js +28 -0
  10. package/broadcast.js +35 -0
  11. package/index.js +701 -0
  12. package/languages/languages.json +182 -0
  13. package/lib/getInfoNew.js +34 -0
  14. package/lib/getToken.js +44 -0
  15. package/logger.js +19 -0
  16. package/package.json +82 -4
  17. package/src/K2IMG.js +8 -0
  18. package/src/ReportV1.js +55 -0
  19. package/src/Screenshot.js +77 -0
  20. package/src/T2S.js +8 -0
  21. package/src/addExternalModule.js +16 -0
  22. package/src/addUserToGroup.js +79 -0
  23. package/src/changeAdminStatus.js +79 -0
  24. package/src/changeArchivedStatus.js +41 -0
  25. package/src/changeAvatar.js +127 -0
  26. package/src/changeAvt.js +85 -0
  27. package/src/changeBio.js +65 -0
  28. package/src/changeBlockedStatus.js +36 -0
  29. package/src/changeGroupImage.js +106 -0
  30. package/src/changeNickname.js +45 -0
  31. package/src/changeThreadColor.js +62 -0
  32. package/src/changeThreadEmoji.js +42 -0
  33. package/src/createNewGroup.js +70 -0
  34. package/src/createPoll.js +60 -0
  35. package/src/deleteMessage.js +45 -0
  36. package/src/deleteThread.js +43 -0
  37. package/src/desktop.ini +2 -0
  38. package/src/forwardAttachment.js +48 -0
  39. package/src/getAccessToken.js +32 -0
  40. package/src/getCurrentUserID.js +7 -0
  41. package/src/getEmojiUrl.js +27 -0
  42. package/src/getFriendsList.js +73 -0
  43. package/src/getMessage.js +80 -0
  44. package/src/getThreadHistory.js +537 -0
  45. package/src/getThreadHistoryDeprecated.js +93 -0
  46. package/src/getThreadInfo.js +346 -0
  47. package/src/getThreadInfoDeprecated.js +80 -0
  48. package/src/getThreadList.js +213 -0
  49. package/src/getThreadListDeprecated.js +75 -0
  50. package/src/getThreadMain.js +219 -0
  51. package/src/getThreadPictures.js +59 -0
  52. package/src/getUID.js +59 -0
  53. package/src/getUserID.js +62 -0
  54. package/src/getUserInfo.js +129 -0
  55. package/src/getUserInfoMain.js +65 -0
  56. package/src/getUserInfoV2.js +35 -0
  57. package/src/getUserInfoV3.js +63 -0
  58. package/src/getUserInfoV4.js +55 -0
  59. package/src/getUserInfoV5.js +61 -0
  60. package/src/handleFriendRequest.js +46 -0
  61. package/src/handleMessageRequest.js +49 -0
  62. package/src/httpGet.js +49 -0
  63. package/src/httpPost.js +48 -0
  64. package/src/httpPostFormData.js +41 -0
  65. package/src/listenMqtt.js +725 -0
  66. package/src/logout.js +68 -0
  67. package/src/markAsDelivered.js +48 -0
  68. package/src/markAsRead.js +70 -0
  69. package/src/markAsReadAll.js +43 -0
  70. package/src/markAsSeen.js +51 -0
  71. package/src/muteThread.js +47 -0
  72. package/src/removeUserFromGroup.js +49 -0
  73. package/src/resolvePhotoUrl.js +37 -0
  74. package/src/searchForThread.js +43 -0
  75. package/src/sendMessage.js +334 -0
  76. package/src/sendTypingIndicator.js +80 -0
  77. package/src/setMessageReaction.js +109 -0
  78. package/src/setPostReaction.js +102 -0
  79. package/src/setTitle.js +74 -0
  80. package/src/threadColors.js +39 -0
  81. package/src/unfriend.js +43 -0
  82. package/src/unsendMessage.js +40 -0
  83. package/test/data/shareAttach.js +146 -0
  84. package/test/data/test.txt +7 -0
  85. package/test/example-config.json +18 -0
  86. package/test/test-page.js +140 -0
  87. package/test/test.js +387 -0
  88. package/utils.js +2476 -0
package/index.js ADDED
@@ -0,0 +1,701 @@
1
+ 'use strict';
2
+
3
+ /!-[ Max Cpu Speed ]-!/
4
+
5
+ process.env.UV_THREADPOOL_SIZE = require('os').cpus().length;
6
+
7
+ var utils = require("./utils");
8
+ var cheerio = require("cheerio");
9
+ var log = require("npmlog");
10
+ var logger = require('./logger');
11
+ var fs = require("fs-extra");
12
+ var axios = require('axios')
13
+ if (!fs.existsSync("./Jake_Config.json")) {
14
+ log.warn("warn", "FcaConfig File Not Found Proceeding to Create New")
15
+ global.fca = new Object ({
16
+ data: new Object ({
17
+ languages: "english",
18
+ mainName: "[ FCA - JAKE ]",
19
+ mainColor: "#00FFFF",
20
+ autoRestartMinutes: 0,
21
+ encryptSt: true,
22
+ uptime: true
23
+ })
24
+ })
25
+ fs.writeFileSync("./Jake_Config.json", JSON.stringify(global.fca.data, null, "\t"))
26
+ return process.exit(1)
27
+ }
28
+ try {
29
+ var langfile = JSON.parse(fs.readFileSync(__dirname + "/languages/languages.json", 'utf-8'));
30
+ var lang
31
+ switch (require("../../Jake_Config.json").languages) {
32
+ case "vietnam": lang = langfile.vi.index;
33
+ break;
34
+ case "tagalog": lang = langfile.vi.index;
35
+ break;
36
+ case "cebuano": lang = langfile.vi.index;
37
+ break;
38
+ case "english": lang = langfile.en.index;
39
+ break;
40
+ case "thailand": lang = langfile.th.index;
41
+ break;
42
+ case "japan": lang = langfile.jp.index;
43
+ break;
44
+ default: {
45
+ log.warn("warn", "Currently Only Support 4 Kinds of Language VI, EN, TH, JP & TL, Self Fix By Find And Delete File Jake_Config.json")
46
+ process.exit(0)
47
+ }
48
+ }
49
+ } catch(e) {
50
+ console.log(e)
51
+ log.warn("warn", "No matching language found")
52
+ process.exit(0)
53
+ }
54
+ global.fca = new Object({
55
+ ObjFcaConfig: require("../../Jake_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://api-choru.edu-choru.repl.co/uptime?link=${UrlRepl}`)
67
+ logger(global.fca.languages.uptime + UrlRepl, '[ FCA - JAKE ]');
68
+ }
69
+ catch {
70
+ logger(global.fca.languages.erroUptime, '[ FCA - JAKE ]');
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
+ logger(`${global.fca.languages.loginSu}${userID}`, "[ FCA - Jake ]");
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
+ logger(`${global.fca.languages.region}${region}`, "[ FCA - JAKE ]");
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
+ logger(`${global.fca.languages.region}${region}`, "[ FCA - JAKE ]");
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
+ logger(`${global.fca.languages.region}${region}`, "[ FCA - JAKE ]");
187
+ logger("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
+ 'changeAvatar',
223
+ 'changeAvt',
224
+ 'changeBio',
225
+ 'changeBlockedStatus',
226
+ 'changeGroupImage',
227
+ 'changeNickname',
228
+ 'changeThreadColor',
229
+ 'changeThreadEmoji',
230
+ 'createNewGroup',
231
+ 'createPoll',
232
+ 'deleteMessage',
233
+ 'deleteThread',
234
+ 'forwardAttachment',
235
+ 'getAccessToken',
236
+ 'getCurrentUserID',
237
+ 'getEmojiUrl',
238
+ 'getFriendsList',
239
+ 'getMessage',
240
+ 'getThreadHistory',
241
+ 'getThreadInfo',
242
+ 'getThreadList',
243
+ 'getThreadMain',
244
+ 'getThreadPictures',
245
+ 'getUID',
246
+ 'getUserID',
247
+ 'getUserInfo',
248
+ 'getUserInfoMain',
249
+ 'getUserInfoV2',
250
+ 'getUserInfoV3',
251
+ 'getUserInfoV4',
252
+ 'getUserInfoV5',
253
+ 'handleFriendRequest',
254
+ 'handleMessageRequest',
255
+ 'listenMqtt',
256
+ 'logout',
257
+ 'markAsDelivered',
258
+ 'markAsRead',
259
+ 'markAsReadAll',
260
+ 'markAsSeen',
261
+ 'muteThread',
262
+ 'removeUserFromGroup',
263
+ 'resolvePhotoUrl',
264
+ 'ReportV1',
265
+ 'Screenshot',
266
+ 'searchForThread',
267
+ 'sendMessage',
268
+ 'sendTypingIndicator',
269
+ 'setMessageReaction',
270
+ 'setTitle',
271
+ 'threadColors',
272
+ 'unsendMessage',
273
+ 'unfriend',
274
+ 'setPostReaction',
275
+ // HTTP
276
+ 'httpGet',
277
+ 'httpPost',
278
+ 'httpPostFormData',
279
+ // Deprecated features
280
+ "getThreadListDeprecated",
281
+ 'getThreadHistoryDeprecated',
282
+ 'getThreadInfoDeprecated'
283
+ ];
284
+ var defaultFuncs = utils.makeDefaults(html, userID, ctx);
285
+
286
+ // Load all api functions in a loop
287
+ apiFuncNames.map(v => api[v] = require('./src/' + v)(defaultFuncs, api, ctx));
288
+
289
+ return [ctx, defaultFuncs, api];
290
+ }
291
+ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
292
+ return function(res) {
293
+ var html = res.body;
294
+ var $ = cheerio.load(html);
295
+ var arr = [];
296
+
297
+ // This will be empty, but just to be sure we leave it
298
+ $("#login_form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
299
+
300
+ arr = arr.filter(function(v) {
301
+ return v.val && v.val.length;
302
+ });
303
+ var form = utils.arrToForm(arr);
304
+ form.lsd = utils.getFrom(html, "[\"LSD\",[],{\"token\":\"", "\"}");
305
+ form.lgndim = Buffer.from("{\"w\":1440,\"h\":900,\"aw\":1440,\"ah\":834,\"c\":24}").toString('base64');
306
+ form.email = email;
307
+ form.pass = password;
308
+ form.default_persistent = '0';
309
+ form.lgnrnd = utils.getFrom(html, "name=\"lgnrnd\" value=\"", "\"");
310
+ form.locale = 'en_US';
311
+ form.timezone = '240';
312
+ form.lgnjs = ~~(Date.now() / 1000);
313
+ // Getting cookies from the HTML page... (kill me now plz)
314
+ // we used to get a bunch of cookies in the headers of the response of the
315
+ // request, but FB changed and they now send those cookies inside the JS.
316
+ // They run the JS which then injects the cookies in the page.
317
+ // The "solution" is to parse through the html and find those cookies
318
+ // which happen to be conveniently indicated with a _js_ in front of their
319
+ // variable name.
320
+ //
321
+ // ---------- Very Hacky Part Starts -----------------
322
+ var willBeCookies = html.split("\"_js_");
323
+ willBeCookies.slice(1).map(function(val) {
324
+ var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
325
+ jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
326
+ });
327
+ // ---------- Very Hacky Part Ends -----------------
328
+ logger(global.fca.languages.login, "[ FCA - Jake ]");
329
+ return utils
330
+ .post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
331
+ .then(utils.saveCookies(jar))
332
+ .then(function(res) {
333
+ var headers = res.headers;
334
+ if (!headers.location) throw { error: global.fca.languages.loginError };
335
+
336
+ // This means the account has login approvals turned on.
337
+ if (headers.location.indexOf('https://www.facebook.com/checkpoint/') > -1) {
338
+ logger(global.fca.languages.errorFa, "[ FCA - JAKE ]");
339
+ var nextURL = 'https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php';
340
+
341
+ return utils
342
+ .get(headers.location, jar, null, loginOptions)
343
+ .then(utils.saveCookies(jar))
344
+ .then(function(res) {
345
+ var html = res.body;
346
+ // Make the form in advance which will contain the fb_dtsg and nh
347
+ var $ = cheerio.load(html);
348
+ var arr = [];
349
+ $("form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
350
+
351
+ arr = arr.filter(function(v) {
352
+ return v.val && v.val.length;
353
+ });
354
+
355
+ var form = utils.arrToForm(arr);
356
+ if (html.indexOf("checkpoint/?next") > -1) {
357
+ setTimeout(() => {
358
+ checkVerified = setInterval((_form) => {}, 5000, {
359
+ fb_dtsg: form.fb_dtsg,
360
+ jazoest: form.jazoest,
361
+ dpr: 1
362
+ });
363
+ }, 2500);
364
+ throw {
365
+ error: 'login-approval',
366
+ continue: function submit2FA(code) {
367
+ form.approvals_code = code;
368
+ form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
369
+ var prResolve = null;
370
+ var prReject = null;
371
+ var rtPromise = new Promise(function(resolve, reject) {
372
+ prResolve = resolve;
373
+ prReject = reject;
374
+ });
375
+ if (typeof code == "string") {
376
+ utils
377
+ .post(nextURL, jar, form, loginOptions)
378
+ .then(utils.saveCookies(jar))
379
+ .then(function(res) {
380
+ var $ = cheerio.load(res.body);
381
+ var error = $("#approvals_code").parent().attr("data-xui-error");
382
+ if (error) {
383
+ throw {
384
+ error: 'login-approval',
385
+ errordesc: "Invalid 2FA code.",
386
+ lerror: error,
387
+ continue: submit2FA
388
+ };
389
+ }
390
+ })
391
+ .then(function() {
392
+ // Use the same form (safe I hope)
393
+ delete form.no_fido;
394
+ delete form.approvals_code;
395
+ form.name_action_selected = 'dont_save'; //'save_device';
396
+
397
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
398
+ })
399
+ .then(function(res) {
400
+ var headers = res.headers;
401
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with login approvals." };
402
+
403
+ var appState = utils.getAppState(jar);
404
+
405
+ if (callback === prCallback) {
406
+ callback = function(err, api) {
407
+ if (err) return prReject(err);
408
+ return prResolve(api);
409
+ };
410
+ }
411
+
412
+ // Simply call loginHelper because all it needs is the jar
413
+ // and will then complete the login process
414
+ return loginHelper(appState, email, password, loginOptions, callback);
415
+ })
416
+ .catch(function(err) {
417
+ // Check if using Promise instead of callback
418
+ if (callback === prCallback) prReject(err);
419
+ else callback(err);
420
+ });
421
+ } else {
422
+ utils
423
+ .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" })
424
+ .then(utils.saveCookies(jar))
425
+ .then(res => {
426
+ try {
427
+ JSON.parse(res.body.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, ""));
428
+ } catch (ex) {
429
+ clearInterval(checkVerified);
430
+ logger(global.fca.languages.okweb, "[ FCA - Jake ]");
431
+ if (callback === prCallback) {
432
+ callback = function(err, api) {
433
+ if (err) return prReject(err);
434
+ return prResolve(api);
435
+ };
436
+ }
437
+ return loginHelper(utils.getAppState(jar), email, password, loginOptions, callback);
438
+ }
439
+ })
440
+ .catch(ex => {
441
+ log.error("login", ex);
442
+ if (callback === prCallback) prReject(ex);
443
+ else callback(ex);
444
+ });
445
+ }
446
+ return rtPromise;
447
+ }
448
+ };
449
+ } else {
450
+ 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." };
451
+
452
+ if (html.indexOf("Suspicious Login Attempt") > -1) form['submit[This was me]'] = "This was me";
453
+ else form['submit[This Is Okay]'] = "This Is Okay";
454
+
455
+ return utils
456
+ .post(nextURL, jar, form, loginOptions)
457
+ .then(utils.saveCookies(jar))
458
+ .then(function() {
459
+ // Use the same form (safe I hope)
460
+ form.name_action_selected = 'save_device';
461
+
462
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
463
+ })
464
+ .then(function(res) {
465
+ var headers = res.headers;
466
+
467
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with review recent login." };
468
+
469
+ var appState = utils.getAppState(jar);
470
+
471
+ // Simply call loginHelper because all it needs is the jar
472
+ // and will then complete the login process
473
+ return loginHelper(appState, email, password, loginOptions, callback);
474
+ })
475
+ .catch(e => callback(e));
476
+ }
477
+ });
478
+ }
479
+
480
+ return utils.get('https://www.facebook.com/', jar, null, loginOptions).then(utils.saveCookies(jar));
481
+ });
482
+ };
483
+ }
484
+ function makeid(length) {
485
+ var result = '';
486
+ var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
487
+ var charactersLength = characters.length;
488
+ for ( var i = 0; i < length; i++ ) {
489
+ result += characters.charAt(Math.floor(Math.random() *
490
+ charactersLength));
491
+ }
492
+ return result;
493
+ }
494
+ // Helps the login
495
+ function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
496
+ var mainPromise = null;
497
+ var jar = utils.getJar();
498
+
499
+ // If we're given an appState we loop through it and save each cookie
500
+ // back into the jar.
501
+ try {
502
+ if (appState) {
503
+ if (global.fca.ObjFcaConfig['encryptSt']) {
504
+ try {
505
+ if (fs.existsSync('./../.env')) {
506
+ require('dotenv').config({ path: './../.env' });
507
+ }
508
+ else {
509
+ fs.writeFileSync('./../.env', ``);
510
+ require('dotenv').config({ path: './../.env' });
511
+ }
512
+ }
513
+ catch (e) {
514
+ console.log(e);
515
+ process.exit(1);
516
+ }
517
+ if (!process.env['FBKEY']) {
518
+ try {
519
+ var ans = makeid(49)
520
+ process.env["FBKEY"] = ans;
521
+ fs.writeFile('./../.env', `FBKEY=${ans}`, function (err) {
522
+ if (err) {
523
+ logger(global.fca.languages.errorEnv, "[ FCA - JAKE ]");
524
+ }
525
+ else logger(global.fca.languages.env,"[ FCA - JAKE ]")
526
+ });
527
+ }
528
+ catch (e) {
529
+ console.log(e);
530
+ logger(global.fca.languages.errorPassRandom, "[ FCA - JAKE ]");
531
+ }
532
+ }
533
+
534
+ if (process.env['FBKEY']) {
535
+ try {
536
+ appState = JSON.stringify(appState);
537
+ if (appState.includes('[')) {
538
+ logger(global.fca.languages.appstateDec, '[ FCA - JAKE ]');
539
+ } else {
540
+ try {
541
+ appState = JSON.parse(appState);
542
+ var StateCrypt = require('./StateCrypt');
543
+ appState = StateCrypt.decryptState(appState, process.env['FBKEY']);
544
+ logger(global.fca.languages.appstate, '[ FCA - JAKE ]');
545
+ }
546
+ catch (e) {
547
+ logger(global.fca.languages.appstateError, '[ FCA-JAKE ]');
548
+ }
549
+ }
550
+ }
551
+ catch (e) {
552
+ console.log(e);
553
+ }
554
+ }
555
+ try {
556
+ appState = JSON.parse(appState);
557
+ }
558
+ catch (e) {
559
+ try {
560
+ appState = appState;
561
+ }
562
+ catch (e) {
563
+ return logger(global.fca.languages.appstateError, '[ FCA-JAKE ]')
564
+ }
565
+ }
566
+ }
567
+ try {
568
+ appState.map(function(c) {
569
+ var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
570
+ jar.setCookie(str, "http://" + c.domain);
571
+ });
572
+
573
+ // Load the main page.
574
+ mainPromise = utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
575
+ } catch (e) {
576
+ return logger(global.fca.languages.appstateError, '[ FCA - JAKE ]')
577
+ }
578
+ } else {
579
+ // Open the main page, then we login with the given credentials and finally
580
+ // load the main page again (it'll give us some IDs that we need)
581
+ mainPromise = utils
582
+ .get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
583
+ .then(utils.saveCookies(jar))
584
+ .then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
585
+ .then(function() {
586
+ return utils.get('https://www.facebook.com/', jar, null, globalOptions).then(utils.saveCookies(jar));
587
+ });
588
+ }
589
+ } catch (e) {
590
+ console.log(e);
591
+ }
592
+ var ctx = null;
593
+ var _defaultFuncs = null;
594
+ var api = null;
595
+
596
+ mainPromise = mainPromise
597
+ .then(function(res) {
598
+ // Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
599
+ var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
600
+ var redirect = reg.exec(res.body);
601
+ if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
602
+ return res;
603
+ })
604
+ .then(function(res) {
605
+ var html = res.body;
606
+ var stuff = buildAPI(globalOptions, html, jar);
607
+ ctx = stuff[0];
608
+ _defaultFuncs = stuff[1];
609
+ api = stuff[2];
610
+ return res;
611
+ });
612
+
613
+ // given a pageID we log in as a page
614
+ if (globalOptions.pageID) {
615
+ mainPromise = mainPromise
616
+ .then(function() {
617
+ return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
618
+ })
619
+ .then(function(resData) {
620
+ var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
621
+ url = url.substring(0, url.length - 1);
622
+ return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
623
+ });
624
+ }
625
+ // At the end we call the callback or catch an exception
626
+ mainPromise
627
+ .then(function() {
628
+ logger(global.fca.languages.oklogin, "[ FCA - JAKE ]");
629
+ //!---------- Auto Check, Update START -----------------!//
630
+ var axios = require('axios');
631
+ var { readFileSync } = require('fs-extra');
632
+ const { execSync } = require('child_process');
633
+ axios.get('https://raw.githubusercontent.com/JakeAsunto/fca-temp/main/package.json').then(async (res) => {
634
+ const localbrand = JSON.parse(readFileSync('./node_modules/jake-chan/package.json')).version;
635
+ if (localbrand != res.data.version) {
636
+ log.warn("UPDATE > ",`${global.fca.languages.newVersion}${JSON.parse(readFileSync('./node_modules/jake-chan/package.json')).version} => ${res.data.version}`);
637
+ log.warn("UPDATE > ",`${global.fca.languages.autoUpdate}`);
638
+ try {
639
+ execSync('npm install jake-chan@latest', { stdio: 'inherit' });
640
+ logger(global.fca.languages.okUpdate,"UPDATE")
641
+ logger(global.fca.languages.restart, '[ FCA - JAKE ]');
642
+ await new Promise(resolve => setTimeout(resolve,5*1000));
643
+ console.clear();process.exit(1);
644
+ }
645
+ catch (err) {
646
+ log.warn(global.fca.languages.errorUpdate + err);
647
+ }
648
+ }
649
+ else {
650
+ logger(`${global.fca.languages.checkVersion}` + localbrand + ' !', "[ FCA - JAKE ]");
651
+ logger(global.fca.languages.chucAdmin, "[ FCA - JAKE ]");
652
+ await new Promise(resolve => setTimeout(resolve, 3*1000));
653
+ callback(null, api);
654
+ }
655
+ });
656
+ }).catch(function(e) {
657
+ log.error("login", e.error || e);
658
+ callback(e);
659
+ });
660
+ //!---------- Auto Check, Update END -----------------!//
661
+ }
662
+ function login(loginData, options, callback) {
663
+ if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
664
+ callback = options;
665
+ options = {};
666
+ }
667
+ var globalOptions = {
668
+ selfListen: false,
669
+ listenEvents: true,
670
+ listenTyping: false,
671
+ updatePresence: false,
672
+ forceLogin: false,
673
+ autoMarkDelivery: false,
674
+ autoMarkRead: false,
675
+ autoReconnect: true,
676
+ logRecordSize: defaultLogRecordSize,
677
+ online: true,
678
+ emitReady: false,
679
+ 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"
680
+ };
681
+ //! bằng 1 cách nào đó tắt online sẽ đánh lừa được facebook :v
682
+ //! phải có that có this chứ :v
683
+ setOptions(globalOptions, options);
684
+ var prCallback = null;
685
+ if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
686
+ var rejectFunc = null;
687
+ var resolveFunc = null;
688
+ var returnPromise = new Promise(function(resolve, reject) {
689
+ resolveFunc = resolve;
690
+ rejectFunc = reject;
691
+ });
692
+ prCallback = function(error, api) {
693
+ if (error) return rejectFunc(error);
694
+ return resolveFunc(api);
695
+ };
696
+ callback = prCallback;
697
+ }
698
+ loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
699
+ return returnPromise;
700
+ }
701
+ module.exports = login;