jake-chan 0.0.1-security → 6.1.2

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