fca-luxury 1.0.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-luxury might be problematic. Click here for more details.

Files changed (66) hide show
  1. package/DOCS.md +1686 -0
  2. package/README.md +220 -0
  3. package/index.js +544 -0
  4. package/package.json +73 -0
  5. package/src/Screenshot.js +83 -0
  6. package/src/addExternalModule.js +15 -0
  7. package/src/addUserToGroup.js +77 -0
  8. package/src/changeAdminStatus.js +47 -0
  9. package/src/changeArchivedStatus.js +41 -0
  10. package/src/changeAvt.js +85 -0
  11. package/src/changeBio.js +65 -0
  12. package/src/changeBlockedStatus.js +36 -0
  13. package/src/changeGroupImage.js +106 -0
  14. package/src/changeNickname.js +45 -0
  15. package/src/changeThreadColor.js +61 -0
  16. package/src/changeThreadEmoji.js +41 -0
  17. package/src/createNewGroup.js +70 -0
  18. package/src/createPoll.js +59 -0
  19. package/src/deleteMessage.js +44 -0
  20. package/src/deleteThread.js +42 -0
  21. package/src/editMessage.js +55 -0
  22. package/src/forwardAttachment.js +47 -0
  23. package/src/getCurrentUserID.js +7 -0
  24. package/src/getEmojiUrl.js +27 -0
  25. package/src/getFriendsList.js +73 -0
  26. package/src/getThreadHistory.js +537 -0
  27. package/src/getThreadHistoryDeprecated.js +71 -0
  28. package/src/getThreadInfo.js +171 -0
  29. package/src/getThreadInfoDeprecated.js +56 -0
  30. package/src/getThreadList.js +213 -0
  31. package/src/getThreadListDeprecated.js +46 -0
  32. package/src/getThreadPictures.js +59 -0
  33. package/src/getUserID.js +61 -0
  34. package/src/getUserInfo.js +66 -0
  35. package/src/handleFriendRequest.js +46 -0
  36. package/src/handleMessageRequest.js +47 -0
  37. package/src/httpGet.js +49 -0
  38. package/src/httpPost.js +48 -0
  39. package/src/listenMqtt.js +701 -0
  40. package/src/logout.js +68 -0
  41. package/src/markAsDelivered.js +47 -0
  42. package/src/markAsRead.js +70 -0
  43. package/src/markAsReadAll.js +40 -0
  44. package/src/markAsSeen.js +48 -0
  45. package/src/muteThread.js +45 -0
  46. package/src/removeUserFromGroup.js +45 -0
  47. package/src/resolvePhotoUrl.js +36 -0
  48. package/src/searchForThread.js +42 -0
  49. package/src/sendMessage.js +328 -0
  50. package/src/sendTypingIndicator.js +70 -0
  51. package/src/setMessageReaction.js +109 -0
  52. package/src/setPostReaction.js +102 -0
  53. package/src/setTitle.js +70 -0
  54. package/src/shareContact.js +46 -0
  55. package/src/shareLink.js +55 -0
  56. package/src/threadColors.js +41 -0
  57. package/src/unfriend.js +42 -0
  58. package/src/unsendMessage.js +39 -0
  59. package/test/data/shareAttach.js +146 -0
  60. package/test/data/something.mov +0 -0
  61. package/test/data/test.png +0 -0
  62. package/test/data/test.txt +7 -0
  63. package/test/example-config.json +18 -0
  64. package/test/test-page.js +140 -0
  65. package/test/test.js +385 -0
  66. package/utils.js +1196 -0
package/index.js ADDED
@@ -0,0 +1,544 @@
1
+ "use strict";
2
+
3
+ var utils = require("./utils");
4
+ var cheerio = require("cheerio");
5
+ var log = require("npmlog");
6
+
7
+ var checkVerified = null;
8
+
9
+ var defaultLogRecordSize = 100;
10
+ log.maxRecordSize = defaultLogRecordSize;
11
+
12
+ function setOptions(globalOptions, options) {
13
+ Object.keys(options).map(function (key) {
14
+ switch (key) {
15
+ case 'pauseLog':
16
+ if (options.pauseLog) log.pause();
17
+ break;
18
+ case 'online':
19
+ globalOptions.online = Boolean(options.online);
20
+ break;
21
+ case 'logLevel':
22
+ log.level = options.logLevel;
23
+ globalOptions.logLevel = options.logLevel;
24
+ break;
25
+ case 'logRecordSize':
26
+ log.maxRecordSize = options.logRecordSize;
27
+ globalOptions.logRecordSize = options.logRecordSize;
28
+ break;
29
+ case 'selfListen':
30
+ globalOptions.selfListen = Boolean(options.selfListen);
31
+ break;
32
+ case 'listenEvents':
33
+ globalOptions.listenEvents = Boolean(options.listenEvents);
34
+ break;
35
+ case 'pageID':
36
+ globalOptions.pageID = options.pageID.toString();
37
+ break;
38
+ case 'updatePresence':
39
+ globalOptions.updatePresence = Boolean(options.updatePresence);
40
+ break;
41
+ case 'forceLogin':
42
+ globalOptions.forceLogin = Boolean(options.forceLogin);
43
+ break;
44
+ case 'userAgent':
45
+ globalOptions.userAgent = options.userAgent;
46
+ break;
47
+ case 'autoMarkDelivery':
48
+ globalOptions.autoMarkDelivery = Boolean(options.autoMarkDelivery);
49
+ break;
50
+ case 'autoMarkRead':
51
+ globalOptions.autoMarkRead = Boolean(options.autoMarkRead);
52
+ break;
53
+ case 'listenTyping':
54
+ globalOptions.listenTyping = Boolean(options.listenTyping);
55
+ break;
56
+ case 'proxy':
57
+ if (typeof options.proxy != "string") {
58
+ delete globalOptions.proxy;
59
+ utils.setProxy();
60
+ }
61
+ else {
62
+ globalOptions.proxy = options.proxy;
63
+ utils.setProxy(globalOptions.proxy);
64
+ }
65
+ break;
66
+ case 'autoReconnect':
67
+ globalOptions.autoReconnect = Boolean(options.autoReconnect);
68
+ break;
69
+ case 'emitReady':
70
+ globalOptions.emitReady = Boolean(options.emitReady);
71
+ break;
72
+ default:
73
+ log.warn("setOptions", "Unrecognized option given to setOptions: " + key);
74
+ break;
75
+ }
76
+ });
77
+ }
78
+
79
+ function buildAPI(globalOptions, html, jar) {
80
+ var maybeCookie = jar.getCookies("https://www.facebook.com").filter(function (val) {
81
+ return val.cookieString().split("=")[0] === "c_user";
82
+ });
83
+
84
+ if (maybeCookie.length === 0) throw { error: "Error retrieving userID. This can be caused by a lot of things, including getting blocked by Facebook for logging in from an unknown location. Try logging in with a browser to verify." };
85
+
86
+ if (html.indexOf("/checkpoint/block/?next") > -1) log.warn("login", "Checkpoint detected. Please log in with a browser to verify.");
87
+
88
+ var userID = Object.values(jar._jar.store.idx['facebook.com']['/']).map($=>$.toString()).join(';').match(/i_user=([^;]+);/)?.[1]||maybeCookie[0].cookieString().split("=")[1].toString();
89
+ log.info("login", `Logged in as ${userID}`);
90
+
91
+ try {
92
+ clearInterval(checkVerified);
93
+ }
94
+ catch (_) { }
95
+
96
+ var clientID = (Math.random() * 2147483648 | 0).toString(16);
97
+
98
+ let oldFBMQTTMatch = html.match(/irisSeqID:"(.+?)",appID:219994525426954,endpoint:"(.+?)"/);
99
+ let mqttEndpoint = null;
100
+ let region = null;
101
+ let irisSeqID = null;
102
+ var noMqttData = null;
103
+
104
+ if (oldFBMQTTMatch) {
105
+ irisSeqID = oldFBMQTTMatch[1];
106
+ mqttEndpoint = oldFBMQTTMatch[2];
107
+ region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
108
+ log.info("login", `Got this account's message region: ${region}`);
109
+ }
110
+ else {
111
+ let newFBMQTTMatch = html.match(/{"app_id":"219994525426954","endpoint":"(.+?)","iris_seq_id":"(.+?)"}/);
112
+ if (newFBMQTTMatch) {
113
+ irisSeqID = newFBMQTTMatch[2];
114
+ mqttEndpoint = newFBMQTTMatch[1].replace(/\\\//g, "/");
115
+ region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
116
+ log.info("login", `Got this account's message region: ${region}`);
117
+ }
118
+ else {
119
+ let legacyFBMQTTMatch = html.match(/(\["MqttWebConfig",\[\],{fbid:")(.+?)(",appID:219994525426954,endpoint:")(.+?)(",pollingEndpoint:")(.+?)(3790])/);
120
+ if (legacyFBMQTTMatch) {
121
+ mqttEndpoint = legacyFBMQTTMatch[4];
122
+ region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
123
+ log.warn("login", `Cannot get sequence ID with new RegExp. Fallback to old RegExp (without seqID)...`);
124
+ log.info("login", `Got this account's message region: ${region}`);
125
+ log.info("login", `[Unused] Polling endpoint: ${legacyFBMQTTMatch[6]}`);
126
+ }
127
+ else {
128
+ log.warn("login", "Cannot get MQTT region & sequence ID.");
129
+ noMqttData = html;
130
+ }
131
+ }
132
+ }
133
+
134
+ // All data available to api functions
135
+ var ctx = {
136
+ userID: userID,
137
+ jar: jar,
138
+ clientID: clientID,
139
+ globalOptions: globalOptions,
140
+ loggedIn: true,
141
+ access_token: 'NONE',
142
+ clientMutationId: 0,
143
+ mqttClient: undefined,
144
+ lastSeqId: irisSeqID,
145
+ syncToken: undefined,
146
+ mqttEndpoint,
147
+ region,
148
+ firstListen: true
149
+ };
150
+
151
+ var api = {
152
+ setOptions: setOptions.bind(null, globalOptions),
153
+ getAppState: function getAppState() {
154
+ return utils.getAppState(jar);
155
+ }
156
+ };
157
+
158
+ if (noMqttData) api["htmlData"] = noMqttData;
159
+
160
+ const apiFuncNames = [
161
+ 'addExternalModule',
162
+ 'addUserToGroup',
163
+ 'changeAdminStatus',
164
+ 'changeArchivedStatus',
165
+ 'changeBio',
166
+ 'changeBlockedStatus',
167
+ 'changeGroupImage',
168
+ 'changeNickname',
169
+ 'changeThreadColor',
170
+ 'changeThreadEmoji',
171
+ 'createNewGroup',
172
+ 'createPoll',
173
+ 'deleteMessage',
174
+ 'deleteThread',
175
+ 'forwardAttachment',
176
+ 'getCurrentUserID',
177
+ 'getEmojiUrl',
178
+ 'getFriendsList',
179
+ 'getThreadHistory',
180
+ 'getThreadInfo',
181
+ 'getThreadList',
182
+ 'getThreadPictures',
183
+ 'getUserID',
184
+ 'getUserInfo',
185
+ 'handleMessageRequest',
186
+ 'listenMqtt',
187
+ 'logout',
188
+ 'markAsDelivered',
189
+ 'markAsRead',
190
+ 'markAsReadAll',
191
+ 'markAsSeen',
192
+ 'muteThread',
193
+ 'removeUserFromGroup',
194
+ 'resolvePhotoUrl',
195
+ 'searchForThread',
196
+ 'sendMessage',
197
+ 'sendTypingIndicator',
198
+ 'setMessageReaction',
199
+ 'setTitle',
200
+ 'threadColors',
201
+ 'unsendMessage',
202
+ 'unfriend',
203
+ 'shareContact',
204
+ 'editMessage',
205
+ 'shareLink',
206
+ 'shareContact',
207
+
208
+ // HTTP
209
+ 'httpGet',
210
+ 'httpPost',
211
+
212
+ // Deprecated features
213
+ "getThreadListDeprecated",
214
+ 'getThreadHistoryDeprecated',
215
+ 'getThreadInfoDeprecated',
216
+ ];
217
+
218
+ var defaultFuncs = utils.makeDefaults(html, userID, ctx);
219
+ api.postFormData = function(url, body) {
220
+ return defaultFuncs.postFormData(url, ctx.jar, body);
221
+ };
222
+ // Load all api functions in a loop
223
+ apiFuncNames.map(v => api[v] = require('./src/' + v)(defaultFuncs, api, ctx));
224
+
225
+ return [ctx, defaultFuncs, api];
226
+ }
227
+
228
+ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
229
+ return function (res) {
230
+ var html = res.body;
231
+ var $ = cheerio.load(html);
232
+ var arr = [];
233
+
234
+ // This will be empty, but just to be sure we leave it
235
+ $("#login_form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
236
+
237
+ arr = arr.filter(function (v) {
238
+ return v.val && v.val.length;
239
+ });
240
+
241
+ var form = utils.arrToForm(arr);
242
+ form.lsd = utils.getFrom(html, "[\"LSD\",[],{\"token\":\"", "\"}");
243
+ form.lgndim = Buffer.from("{\"w\":1440,\"h\":900,\"aw\":1440,\"ah\":834,\"c\":24}").toString('base64');
244
+ form.email = email;
245
+ form.pass = password;
246
+ form.default_persistent = '0';
247
+ form.lgnrnd = utils.getFrom(html, "name=\"lgnrnd\" value=\"", "\"");
248
+ form.locale = 'en_US';
249
+ form.timezone = '240';
250
+ form.lgnjs = ~~(Date.now() / 1000);
251
+
252
+
253
+ // Getting cookies from the HTML page... (kill me now plz)
254
+ // we used to get a bunch of cookies in the headers of the response of the
255
+ // request, but FB changed and they now send those cookies inside the JS.
256
+ // They run the JS which then injects the cookies in the page.
257
+ // The "solution" is to parse through the html and find those cookies
258
+ // which happen to be conveniently indicated with a _js_ in front of their
259
+ // variable name.
260
+ //
261
+ // ---------- Very Hacky Part Starts -----------------
262
+ var willBeCookies = html.split("\"_js_");
263
+ willBeCookies.slice(1).map(function (val) {
264
+ var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
265
+ jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
266
+ });
267
+ // ---------- Very Hacky Part Ends -----------------
268
+
269
+ log.info("login", "Logging in...");
270
+ return utils
271
+ .post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
272
+ .then(utils.saveCookies(jar))
273
+ .then(function (res) {
274
+ var headers = res.headers;
275
+ if (!headers.location) throw { error: "Wrong username/password." };
276
+
277
+ // This means the account has login approvals turned on.
278
+ if (headers.location.indexOf('https://www.facebook.com/checkpoint/') > -1) {
279
+ log.info("login", "You have login approvals turned on.");
280
+ var nextURL = 'https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php';
281
+
282
+ return utils
283
+ .get(headers.location, jar, null, loginOptions)
284
+ .then(utils.saveCookies(jar))
285
+ .then(function (res) {
286
+ var html = res.body;
287
+ // Make the form in advance which will contain the fb_dtsg and nh
288
+ var $ = cheerio.load(html);
289
+ var arr = [];
290
+ $("form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
291
+
292
+ arr = arr.filter(function (v) {
293
+ return v.val && v.val.length;
294
+ });
295
+
296
+ var form = utils.arrToForm(arr);
297
+ if (html.indexOf("checkpoint/?next") > -1) {
298
+ setTimeout(() => {
299
+ checkVerified = setInterval((_form) => { }, 5000, {
300
+ fb_dtsg: form.fb_dtsg,
301
+ jazoest: form.jazoest,
302
+ dpr: 1
303
+ });
304
+ }, 2500);
305
+ throw {
306
+ error: 'login-approval',
307
+ continue: function submit2FA(code) {
308
+ form.approvals_code = code;
309
+ form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
310
+ var prResolve = null;
311
+ var prReject = null;
312
+ var rtPromise = new Promise(function (resolve, reject) {
313
+ prResolve = resolve;
314
+ prReject = reject;
315
+ });
316
+ if (typeof code == "string") {
317
+ utils
318
+ .post(nextURL, jar, form, loginOptions)
319
+ .then(utils.saveCookies(jar))
320
+ .then(function (res) {
321
+ var $ = cheerio.load(res.body);
322
+ var error = $("#approvals_code").parent().attr("data-xui-error");
323
+ if (error) {
324
+ throw {
325
+ error: 'login-approval',
326
+ errordesc: "Invalid 2FA code.",
327
+ lerror: error,
328
+ continue: submit2FA
329
+ };
330
+ }
331
+ })
332
+ .then(function () {
333
+ // Use the same form (safe I hope)
334
+ delete form.no_fido;
335
+ delete form.approvals_code;
336
+ form.name_action_selected = 'dont_save'; //'save_device';
337
+
338
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
339
+ })
340
+ .then(function (res) {
341
+ var headers = res.headers;
342
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with login approvals." };
343
+
344
+ var appState = utils.getAppState(jar);
345
+
346
+ if (callback === prCallback) {
347
+ callback = function (err, api) {
348
+ if (err) return prReject(err);
349
+ return prResolve(api);
350
+ };
351
+ }
352
+
353
+ // Simply call loginHelper because all it needs is the jar
354
+ // and will then complete the login process
355
+ return loginHelper(appState, email, password, loginOptions, callback);
356
+ })
357
+ .catch(function (err) {
358
+ // Check if using Promise instead of callback
359
+ if (callback === prCallback) prReject(err);
360
+ else callback(err);
361
+ });
362
+ }
363
+ else {
364
+ utils
365
+ .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" })
366
+ .then(utils.saveCookies(jar))
367
+ .then(res => {
368
+ try {
369
+ JSON.parse(res.body.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, ""));
370
+ }
371
+ catch (ex) {
372
+ clearInterval(checkVerified);
373
+ log.info("login", "Verified from browser. Logging in...");
374
+ if (callback === prCallback) {
375
+ callback = function (err, api) {
376
+ if (err) return prReject(err);
377
+ return prResolve(api);
378
+ };
379
+ }
380
+ return loginHelper(utils.getAppState(jar), email, password, loginOptions, callback);
381
+ }
382
+ })
383
+ .catch(ex => {
384
+ log.error("login", ex);
385
+ if (callback === prCallback) prReject(ex);
386
+ else callback(ex);
387
+ });
388
+ }
389
+ return rtPromise;
390
+ }
391
+ };
392
+ }
393
+ else {
394
+ 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." };
395
+
396
+ if (html.indexOf("Suspicious Login Attempt") > -1) form['submit[This was me]'] = "This was me";
397
+ else form['submit[This Is Okay]'] = "This Is Okay";
398
+
399
+ return utils
400
+ .post(nextURL, jar, form, loginOptions)
401
+ .then(utils.saveCookies(jar))
402
+ .then(function () {
403
+ // Use the same form (safe I hope)
404
+ form.name_action_selected = 'save_device';
405
+
406
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
407
+ })
408
+ .then(function (res) {
409
+ var headers = res.headers;
410
+
411
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with review recent login." };
412
+
413
+ var appState = utils.getAppState(jar);
414
+
415
+ // Simply call loginHelper because all it needs is the jar
416
+ // and will then complete the login process
417
+ return loginHelper(appState, email, password, loginOptions, callback);
418
+ })
419
+ .catch(e => callback(e));
420
+ }
421
+ });
422
+ }
423
+
424
+ return utils.get('https://www.facebook.com/', jar, null, loginOptions).then(utils.saveCookies(jar));
425
+ });
426
+ };
427
+ }
428
+
429
+ // Helps the login
430
+ function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
431
+ var mainPromise = null;
432
+ var jar = utils.getJar();
433
+
434
+ // If we're given an appState we loop through it and save each cookie
435
+ // back into the jar.
436
+ if (appState) {
437
+ appState.map(function (c) {
438
+ var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
439
+ jar.setCookie(str, "http://" + c.domain);
440
+ });
441
+
442
+ // Load the main page.
443
+ mainPromise = utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
444
+ }
445
+ else {
446
+ // Open the main page, then we login with the given credentials and finally
447
+ // load the main page again (it'll give us some IDs that we need)
448
+ mainPromise = utils
449
+ .get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
450
+ .then(utils.saveCookies(jar))
451
+ .then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
452
+ .then(function () {
453
+ return utils.get('https://www.facebook.com/', jar, null, globalOptions).then(utils.saveCookies(jar));
454
+ });
455
+ }
456
+
457
+ var ctx = null;
458
+ var _defaultFuncs = null;
459
+ var api = null;
460
+
461
+ mainPromise = mainPromise
462
+ .then(function (res) {
463
+ // Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
464
+ var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
465
+ var redirect = reg.exec(res.body);
466
+ if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
467
+ return res;
468
+ })
469
+ .then(function (res) {
470
+ var html = res.body;
471
+ var stuff = buildAPI(globalOptions, html, jar);
472
+ ctx = stuff[0];
473
+ _defaultFuncs = stuff[1];
474
+ api = stuff[2];
475
+ return res;
476
+ });
477
+
478
+ // given a pageID we log in as a page
479
+ if (globalOptions.pageID) {
480
+ mainPromise = mainPromise
481
+ .then(function () {
482
+ return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
483
+ })
484
+ .then(function (resData) {
485
+ var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
486
+ url = url.substring(0, url.length - 1);
487
+ return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
488
+ });
489
+ }
490
+
491
+ // At the end we call the callback or catch an exception
492
+ mainPromise
493
+ .then(function () {
494
+ log.info("login", 'Done logging in.');
495
+ return callback(null, api);
496
+ })
497
+ .catch(function (e) {
498
+ log.error("login", e.error || e);
499
+ callback(e);
500
+ });
501
+ }
502
+
503
+ function login(loginData, options, callback) {
504
+ if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
505
+ callback = options;
506
+ options = {};
507
+ }
508
+
509
+ var globalOptions = {
510
+ selfListen: false,
511
+ listenEvents: true,
512
+ listenTyping: false,
513
+ updatePresence: false,
514
+ forceLogin: false,
515
+ autoMarkDelivery: true,
516
+ autoMarkRead: false,
517
+ autoReconnect: true,
518
+ logRecordSize: defaultLogRecordSize,
519
+ online: true,
520
+ emitReady: false,
521
+ 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"
522
+ };
523
+
524
+ setOptions(globalOptions, options);
525
+
526
+ var prCallback = null;
527
+ if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
528
+ var rejectFunc = null;
529
+ var resolveFunc = null;
530
+ var returnPromise = new Promise(function (resolve, reject) {
531
+ resolveFunc = resolve;
532
+ rejectFunc = reject;
533
+ });
534
+ prCallback = function (error, api) {
535
+ if (error) return rejectFunc(error);
536
+ return resolveFunc(api);
537
+ };
538
+ callback = prCallback;
539
+ }
540
+ loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
541
+ return returnPromise;
542
+ }
543
+
544
+ module.exports = login;
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "fca-luxury",
3
+ "version": "1.0.0",
4
+ "description": "A Facebook chat API that doesn't rely on XMPP. Will NOT be deprecated after April 30th 2015.",
5
+ "scripts": {
6
+ "test": "mocha",
7
+ "lint": "eslint **.js",
8
+ "prettier": "prettier utils.js src/* --write"
9
+ },
10
+ "keywords": [
11
+ "facebook",
12
+ "chat",
13
+ "api",
14
+ "fca"
15
+ ],
16
+ "author": "Avery, David, Maude, Benjamin, UIRI, MiraiTeam",
17
+ "license": "MIT",
18
+ "dependencies": {
19
+ "bluebird": "^2.11.0",
20
+ "cheerio": "^1.0.0-rc.10",
21
+ "https-proxy-agent": "^4.0.0",
22
+ "mqtt": "^4.2.8",
23
+ "npmlog": "^1.2.0",
24
+ "request": "^2.53.0",
25
+ "websocket-stream": "^5.5.0"
26
+ },
27
+ "engines": {
28
+ "node": ">=10.x"
29
+ },
30
+ "devDependencies": {
31
+ "eslint": "^7.5.0",
32
+ "mocha": "^7.0.1",
33
+ "prettier": "^1.11.1"
34
+ },
35
+ "eslintConfig": {
36
+ "env": {
37
+ "es6": true,
38
+ "es2017": true,
39
+ "node": true
40
+ },
41
+ "extends": "eslint:recommended",
42
+ "parserOptions": {
43
+ "sourceType": "module"
44
+ },
45
+ "rules": {
46
+ "linebreak-style": [
47
+ "error",
48
+ "unix"
49
+ ],
50
+ "semi": [
51
+ "error",
52
+ "always"
53
+ ],
54
+ "no-unused-vars": [
55
+ 1,
56
+ {
57
+ "argsIgnorePattern": "^_",
58
+ "varsIgnorePattern": "^_"
59
+ }
60
+ ],
61
+ "no-empty": [
62
+ "error",
63
+ {
64
+ "allowEmptyCatch": true
65
+ }
66
+ ]
67
+ }
68
+ },
69
+ "main": "index.js",
70
+ "directories": {
71
+ "test": "test"
72
+ }
73
+ }
@@ -0,0 +1,83 @@
1
+ /* eslint-disable linebreak-style */
2
+ "use strict";
3
+
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ var Coookie = JSON.parse(JSON.stringify(ctx.jar.getCookies("https://www.facebook.com").concat(ctx.jar.getCookies("https://facebook.com")).concat(ctx.jar.getCookies("https://www.messenger.com"))));
7
+ for (let i of Coookie) {
8
+ i.name = i.key;
9
+ i.domain = 'www.facebook.com';
10
+ delete i.key;
11
+ }
12
+ return function(Link, callback) {
13
+ var logger = require('../logger');
14
+ if (process.platform != 'win32') return logger.Error('Not Supported Platform');
15
+ else try {
16
+ let i = require('puppeteer');
17
+ }
18
+ catch (e) {
19
+ var { execSync } = require('child_process');
20
+ execSync('npm i puppeteer', { stdio: 'inherit' });
21
+ }
22
+ const Screenshot = require('../Extra/ExtraScreenShot');
23
+ var resolveFunc = function () { };
24
+ var rejectFunc = function () { };
25
+ var returnPromise = new Promise(function (resolve, reject) {
26
+ resolveFunc = resolve;
27
+ rejectFunc = reject;
28
+ });
29
+
30
+ if (!callback) {
31
+ callback = function (err, data) {
32
+ if (err) return rejectFunc(err);
33
+ resolveFunc(data);
34
+ };
35
+ }
36
+ if (Link.includes('facebook.com') || Link.includes('Facebook.com') || Link.includes('fb')) {
37
+ let LinkSplit = Link.split('/');
38
+ if (LinkSplit.indexOf("https:") == 0) {
39
+ if (Link.includes('messages')) {
40
+ Screenshot.buffer(Link, {
41
+ cookies: Coookie
42
+ }).then(data => {
43
+ callback(null,data);
44
+ });
45
+ }
46
+ else if (!isNaN(LinkSplit[3]) && !Link.split('=')[1] && !isNaN(Link.split('=')[1])) {
47
+ api.sendMessage('Invaild link, format link: facebook.com/Lazic.Kanzu',global.Fca.Data.event.threadID,global.Fca.Data.event.messageID);
48
+ callback('Error Link', null);
49
+ }
50
+ else if (!isNaN(Link.split('=')[1]) && Link.split('=')[1]) {
51
+ let Format = `https://www.facebook.com/profile.php?id=${Link.split('=')[1]}`;
52
+ Screenshot.buffer(Format, {
53
+ cookies: Coookie
54
+ }).then(data => {
55
+ callback(null,data);
56
+ });
57
+ }
58
+ else {
59
+ let Format = `https://www.facebook.com/${LinkSplit[3]}`;
60
+ Screenshot.buffer(Format, {
61
+ cookies: Coookie
62
+ }).then(data => {
63
+ callback(null,data);
64
+ });
65
+ }
66
+ }
67
+ else {
68
+ let Form = `https://www.facebook.com/${LinkSplit[1]}`;
69
+ Screenshot.buffer(Form, {
70
+ cookies: Coookie
71
+ }).then(data => {
72
+ callback(null,data);
73
+ });
74
+ }
75
+ }
76
+ else {
77
+ Screenshot.buffer(Link).then(data => {
78
+ callback(null,data);
79
+ });
80
+ }
81
+ return returnPromise;
82
+ };
83
+ };