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

Files changed (69) hide show
  1. package/.gitattributes +2 -0
  2. package/.travis.yml +6 -0
  3. package/CHANGELOG.md +2 -0
  4. package/DOCS.md +1738 -0
  5. package/LICENSE-MIT +21 -0
  6. package/README.md +219 -0
  7. package/index.js +541 -0
  8. package/package.json +73 -0
  9. package/replit.nix +5 -0
  10. package/src/Screenshot.js +83 -0
  11. package/src/addExternalModule.js +15 -0
  12. package/src/addUserToGroup.js +77 -0
  13. package/src/changeAdminStatus.js +47 -0
  14. package/src/changeArchivedStatus.js +41 -0
  15. package/src/changeAvt.js +85 -0
  16. package/src/changeBio.js +65 -0
  17. package/src/changeBlockedStatus.js +36 -0
  18. package/src/changeGroupImage.js +106 -0
  19. package/src/changeNickname.js +45 -0
  20. package/src/changeThreadColor.js +61 -0
  21. package/src/changeThreadEmoji.js +41 -0
  22. package/src/createNewGroup.js +70 -0
  23. package/src/createPoll.js +59 -0
  24. package/src/deleteMessage.js +44 -0
  25. package/src/deleteThread.js +42 -0
  26. package/src/forwardAttachment.js +47 -0
  27. package/src/getCurrentUserID.js +7 -0
  28. package/src/getEmojiUrl.js +27 -0
  29. package/src/getFriendsList.js +73 -0
  30. package/src/getThreadHistory.js +537 -0
  31. package/src/getThreadHistoryDeprecated.js +71 -0
  32. package/src/getThreadInfo.js +171 -0
  33. package/src/getThreadInfoDeprecated.js +56 -0
  34. package/src/getThreadList.js +213 -0
  35. package/src/getThreadListDeprecated.js +46 -0
  36. package/src/getThreadPictures.js +59 -0
  37. package/src/getUserID.js +61 -0
  38. package/src/getUserInfo.js +66 -0
  39. package/src/handleFriendRequest.js +46 -0
  40. package/src/handleMessageRequest.js +47 -0
  41. package/src/httpGet.js +49 -0
  42. package/src/httpPost.js +48 -0
  43. package/src/listenMqtt.js +701 -0
  44. package/src/logout.js +68 -0
  45. package/src/markAsDelivered.js +47 -0
  46. package/src/markAsRead.js +70 -0
  47. package/src/markAsReadAll.js +40 -0
  48. package/src/markAsSeen.js +48 -0
  49. package/src/muteThread.js +45 -0
  50. package/src/removeUserFromGroup.js +45 -0
  51. package/src/resolvePhotoUrl.js +36 -0
  52. package/src/searchForThread.js +42 -0
  53. package/src/sendMessage.js +328 -0
  54. package/src/sendTypingIndicator.js +70 -0
  55. package/src/setMessageReaction.js +109 -0
  56. package/src/setPostReaction.js +102 -0
  57. package/src/setTitle.js +70 -0
  58. package/src/shareContact.js +46 -0
  59. package/src/threadColors.js +41 -0
  60. package/src/unfriend.js +42 -0
  61. package/src/unsendMessage.js +39 -0
  62. package/test/data/shareAttach.js +146 -0
  63. package/test/data/something.mov +0 -0
  64. package/test/data/test.png +0 -0
  65. package/test/data/test.txt +7 -0
  66. package/test/example-config.json +18 -0
  67. package/test/test-page.js +140 -0
  68. package/test/test.js +385 -0
  69. package/utils.js +1196 -0
package/index.js ADDED
@@ -0,0 +1,541 @@
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 = 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
+
205
+ // HTTP
206
+ 'httpGet',
207
+ 'httpPost',
208
+
209
+ // Deprecated features
210
+ "getThreadListDeprecated",
211
+ 'getThreadHistoryDeprecated',
212
+ 'getThreadInfoDeprecated',
213
+ ];
214
+
215
+ var defaultFuncs = utils.makeDefaults(html, userID, ctx);
216
+ api.postFormData = function(url, body) {
217
+ return defaultFuncs.postFormData(url, ctx.jar, body);
218
+ };
219
+ // Load all api functions in a loop
220
+ apiFuncNames.map(v => api[v] = require('./src/' + v)(defaultFuncs, api, ctx));
221
+
222
+ return [ctx, defaultFuncs, api];
223
+ }
224
+
225
+ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
226
+ return function (res) {
227
+ var html = res.body;
228
+ var $ = cheerio.load(html);
229
+ var arr = [];
230
+
231
+ // This will be empty, but just to be sure we leave it
232
+ $("#login_form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
233
+
234
+ arr = arr.filter(function (v) {
235
+ return v.val && v.val.length;
236
+ });
237
+
238
+ var form = utils.arrToForm(arr);
239
+ form.lsd = utils.getFrom(html, "[\"LSD\",[],{\"token\":\"", "\"}");
240
+ form.lgndim = Buffer.from("{\"w\":1440,\"h\":900,\"aw\":1440,\"ah\":834,\"c\":24}").toString('base64');
241
+ form.email = email;
242
+ form.pass = password;
243
+ form.default_persistent = '0';
244
+ form.lgnrnd = utils.getFrom(html, "name=\"lgnrnd\" value=\"", "\"");
245
+ form.locale = 'en_US';
246
+ form.timezone = '240';
247
+ form.lgnjs = ~~(Date.now() / 1000);
248
+
249
+
250
+ // Getting cookies from the HTML page... (kill me now plz)
251
+ // we used to get a bunch of cookies in the headers of the response of the
252
+ // request, but FB changed and they now send those cookies inside the JS.
253
+ // They run the JS which then injects the cookies in the page.
254
+ // The "solution" is to parse through the html and find those cookies
255
+ // which happen to be conveniently indicated with a _js_ in front of their
256
+ // variable name.
257
+ //
258
+ // ---------- Very Hacky Part Starts -----------------
259
+ var willBeCookies = html.split("\"_js_");
260
+ willBeCookies.slice(1).map(function (val) {
261
+ var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
262
+ jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
263
+ });
264
+ // ---------- Very Hacky Part Ends -----------------
265
+
266
+ log.info("login", "Logging in...");
267
+ return utils
268
+ .post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
269
+ .then(utils.saveCookies(jar))
270
+ .then(function (res) {
271
+ var headers = res.headers;
272
+ if (!headers.location) throw { error: "Wrong username/password." };
273
+
274
+ // This means the account has login approvals turned on.
275
+ if (headers.location.indexOf('https://www.facebook.com/checkpoint/') > -1) {
276
+ log.info("login", "You have login approvals turned on.");
277
+ var nextURL = 'https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php';
278
+
279
+ return utils
280
+ .get(headers.location, jar, null, loginOptions)
281
+ .then(utils.saveCookies(jar))
282
+ .then(function (res) {
283
+ var html = res.body;
284
+ // Make the form in advance which will contain the fb_dtsg and nh
285
+ var $ = cheerio.load(html);
286
+ var arr = [];
287
+ $("form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
288
+
289
+ arr = arr.filter(function (v) {
290
+ return v.val && v.val.length;
291
+ });
292
+
293
+ var form = utils.arrToForm(arr);
294
+ if (html.indexOf("checkpoint/?next") > -1) {
295
+ setTimeout(() => {
296
+ checkVerified = setInterval((_form) => { }, 5000, {
297
+ fb_dtsg: form.fb_dtsg,
298
+ jazoest: form.jazoest,
299
+ dpr: 1
300
+ });
301
+ }, 2500);
302
+ throw {
303
+ error: 'login-approval',
304
+ continue: function submit2FA(code) {
305
+ form.approvals_code = code;
306
+ form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
307
+ var prResolve = null;
308
+ var prReject = null;
309
+ var rtPromise = new Promise(function (resolve, reject) {
310
+ prResolve = resolve;
311
+ prReject = reject;
312
+ });
313
+ if (typeof code == "string") {
314
+ utils
315
+ .post(nextURL, jar, form, loginOptions)
316
+ .then(utils.saveCookies(jar))
317
+ .then(function (res) {
318
+ var $ = cheerio.load(res.body);
319
+ var error = $("#approvals_code").parent().attr("data-xui-error");
320
+ if (error) {
321
+ throw {
322
+ error: 'login-approval',
323
+ errordesc: "Invalid 2FA code.",
324
+ lerror: error,
325
+ continue: submit2FA
326
+ };
327
+ }
328
+ })
329
+ .then(function () {
330
+ // Use the same form (safe I hope)
331
+ delete form.no_fido;
332
+ delete form.approvals_code;
333
+ form.name_action_selected = 'dont_save'; //'save_device';
334
+
335
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
336
+ })
337
+ .then(function (res) {
338
+ var headers = res.headers;
339
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with login approvals." };
340
+
341
+ var appState = utils.getAppState(jar);
342
+
343
+ if (callback === prCallback) {
344
+ callback = function (err, api) {
345
+ if (err) return prReject(err);
346
+ return prResolve(api);
347
+ };
348
+ }
349
+
350
+ // Simply call loginHelper because all it needs is the jar
351
+ // and will then complete the login process
352
+ return loginHelper(appState, email, password, loginOptions, callback);
353
+ })
354
+ .catch(function (err) {
355
+ // Check if using Promise instead of callback
356
+ if (callback === prCallback) prReject(err);
357
+ else callback(err);
358
+ });
359
+ }
360
+ else {
361
+ utils
362
+ .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" })
363
+ .then(utils.saveCookies(jar))
364
+ .then(res => {
365
+ try {
366
+ JSON.parse(res.body.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, ""));
367
+ }
368
+ catch (ex) {
369
+ clearInterval(checkVerified);
370
+ log.info("login", "Verified from browser. Logging in...");
371
+ if (callback === prCallback) {
372
+ callback = function (err, api) {
373
+ if (err) return prReject(err);
374
+ return prResolve(api);
375
+ };
376
+ }
377
+ return loginHelper(utils.getAppState(jar), email, password, loginOptions, callback);
378
+ }
379
+ })
380
+ .catch(ex => {
381
+ log.error("login", ex);
382
+ if (callback === prCallback) prReject(ex);
383
+ else callback(ex);
384
+ });
385
+ }
386
+ return rtPromise;
387
+ }
388
+ };
389
+ }
390
+ else {
391
+ 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." };
392
+
393
+ if (html.indexOf("Suspicious Login Attempt") > -1) form['submit[This was me]'] = "This was me";
394
+ else form['submit[This Is Okay]'] = "This Is Okay";
395
+
396
+ return utils
397
+ .post(nextURL, jar, form, loginOptions)
398
+ .then(utils.saveCookies(jar))
399
+ .then(function () {
400
+ // Use the same form (safe I hope)
401
+ form.name_action_selected = 'save_device';
402
+
403
+ return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
404
+ })
405
+ .then(function (res) {
406
+ var headers = res.headers;
407
+
408
+ if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with review recent login." };
409
+
410
+ var appState = utils.getAppState(jar);
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(e => callback(e));
417
+ }
418
+ });
419
+ }
420
+
421
+ return utils.get('https://www.facebook.com/', jar, null, loginOptions).then(utils.saveCookies(jar));
422
+ });
423
+ };
424
+ }
425
+
426
+ // Helps the login
427
+ function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
428
+ var mainPromise = null;
429
+ var jar = utils.getJar();
430
+
431
+ // If we're given an appState we loop through it and save each cookie
432
+ // back into the jar.
433
+ if (appState) {
434
+ appState.map(function (c) {
435
+ var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
436
+ jar.setCookie(str, "http://" + c.domain);
437
+ });
438
+
439
+ // Load the main page.
440
+ mainPromise = utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
441
+ }
442
+ else {
443
+ // Open the main page, then we login with the given credentials and finally
444
+ // load the main page again (it'll give us some IDs that we need)
445
+ mainPromise = utils
446
+ .get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
447
+ .then(utils.saveCookies(jar))
448
+ .then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
449
+ .then(function () {
450
+ return utils.get('https://www.facebook.com/', jar, null, globalOptions).then(utils.saveCookies(jar));
451
+ });
452
+ }
453
+
454
+ var ctx = null;
455
+ var _defaultFuncs = null;
456
+ var api = null;
457
+
458
+ mainPromise = mainPromise
459
+ .then(function (res) {
460
+ // Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
461
+ var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
462
+ var redirect = reg.exec(res.body);
463
+ if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
464
+ return res;
465
+ })
466
+ .then(function (res) {
467
+ var html = res.body;
468
+ var stuff = buildAPI(globalOptions, html, jar);
469
+ ctx = stuff[0];
470
+ _defaultFuncs = stuff[1];
471
+ api = stuff[2];
472
+ return res;
473
+ });
474
+
475
+ // given a pageID we log in as a page
476
+ if (globalOptions.pageID) {
477
+ mainPromise = mainPromise
478
+ .then(function () {
479
+ return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
480
+ })
481
+ .then(function (resData) {
482
+ var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
483
+ url = url.substring(0, url.length - 1);
484
+ return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
485
+ });
486
+ }
487
+
488
+ // At the end we call the callback or catch an exception
489
+ mainPromise
490
+ .then(function () {
491
+ log.info("login", 'Done logging in.');
492
+ return callback(null, api);
493
+ })
494
+ .catch(function (e) {
495
+ log.error("login", e.error || e);
496
+ callback(e);
497
+ });
498
+ }
499
+
500
+ function login(loginData, options, callback) {
501
+ if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
502
+ callback = options;
503
+ options = {};
504
+ }
505
+
506
+ var globalOptions = {
507
+ selfListen: false,
508
+ listenEvents: true,
509
+ listenTyping: false,
510
+ updatePresence: false,
511
+ forceLogin: false,
512
+ autoMarkDelivery: true,
513
+ autoMarkRead: false,
514
+ autoReconnect: true,
515
+ logRecordSize: defaultLogRecordSize,
516
+ online: true,
517
+ emitReady: false,
518
+ 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"
519
+ };
520
+
521
+ setOptions(globalOptions, options);
522
+
523
+ var prCallback = null;
524
+ if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
525
+ var rejectFunc = null;
526
+ var resolveFunc = null;
527
+ var returnPromise = new Promise(function (resolve, reject) {
528
+ resolveFunc = resolve;
529
+ rejectFunc = reject;
530
+ });
531
+ prCallback = function (error, api) {
532
+ if (error) return rejectFunc(error);
533
+ return resolveFunc(api);
534
+ };
535
+ callback = prCallback;
536
+ }
537
+ loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
538
+ return returnPromise;
539
+ }
540
+
541
+ module.exports = login;
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "fca-nino",
3
+ "version": "1.1.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
+ }
package/replit.nix ADDED
@@ -0,0 +1,5 @@
1
+ {pkgs}: {
2
+ deps = [
3
+ pkgs.unzipNLS
4
+ ];
5
+ }