alicezetion 1.8.2 → 1.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -1
  2. package/.cache/replit/nix/env.json +1 -1
  3. package/index.js +210 -375
  4. package/package.json +6 -3
  5. package/replit.nix +4 -4
  6. package/src/addExternalModule.js +17 -0
  7. package/src/addUserToGroup.js +113 -0
  8. package/src/changeAdminStatus.js +79 -0
  9. package/src/changeArchivedStatus.js +55 -0
  10. package/src/changeAvatar.js +93 -0
  11. package/src/changeBio.js +77 -0
  12. package/src/changeBlockedStatus.js +47 -0
  13. package/src/changeCover.js +73 -0
  14. package/src/changeGroupImage.js +132 -0
  15. package/src/changeName.js +79 -0
  16. package/src/changeNickname.js +59 -0
  17. package/src/changeThreadColor.js +65 -0
  18. package/src/changeThreadEmoji.js +55 -0
  19. package/{leiamnash → src}/chat.js +28 -3
  20. package/src/createNewGroup.js +86 -0
  21. package/src/createPoll.js +71 -0
  22. package/src/data/getThreadInfo.json +1 -0
  23. package/src/deleteMessage.js +56 -0
  24. package/src/deleteThread.js +56 -0
  25. package/src/forwardAttachment.js +60 -0
  26. package/src/getAccess.js +112 -0
  27. package/src/getAvatarUser.js +78 -0
  28. package/src/getCurrentUserID.js +7 -0
  29. package/src/getEmojiUrl.js +29 -0
  30. package/src/getFriendsList.js +83 -0
  31. package/src/getThreadHistory.js +666 -0
  32. package/{leiamnash → src}/getThreadInfo.js +70 -54
  33. package/src/getThreadList.js +237 -0
  34. package/src/getThreadPictures.js +79 -0
  35. package/src/getUserID.js +66 -0
  36. package/src/getUserInfo.js +163 -0
  37. package/src/handleFriendRequest.js +61 -0
  38. package/src/handleMessageRequest.js +65 -0
  39. package/src/httpGet.js +57 -0
  40. package/src/httpPost.js +57 -0
  41. package/src/httpPostFormData.js +63 -0
  42. package/{leiamnash → src}/listenMqtt.js +16 -6
  43. package/src/listenNotification.js +88 -0
  44. package/src/logout.js +275 -0
  45. package/src/markAsDelivered.js +58 -0
  46. package/src/markAsRead.js +80 -0
  47. package/src/markAsReadAll.js +50 -0
  48. package/src/markAsSeen.js +59 -0
  49. package/src/muteThread.js +52 -0
  50. package/src/react.js +117 -0
  51. package/{leiamnash → src}/refreshFb_dtsg.js +1 -1
  52. package/src/removeUserFromGroup.js +79 -0
  53. package/src/resolvePhotoUrl.js +45 -0
  54. package/src/searchForThread.js +53 -0
  55. package/src/searchStickers.js +52 -0
  56. package/src/seen.js +50 -0
  57. package/src/sendMessage.js +477 -0
  58. package/src/sendMessageMqtt.js +316 -0
  59. package/src/sendTypingIndicator.js +103 -0
  60. package/src/setMessageReaction.js +117 -0
  61. package/src/setPostReaction.js +109 -0
  62. package/src/setTitle.js +86 -0
  63. package/src/threadColors.js +131 -0
  64. package/src/unfriend.js +52 -0
  65. package/src/unsendMessage.js +49 -0
  66. package/utils.js +135 -176
  67. package/.cache/replit/modules.stamp +0 -1
  68. package/leiamnash/addExternalModule.js +0 -15
  69. package/leiamnash/addUserToGroup.js +0 -77
  70. package/leiamnash/changeAdminStatus.js +0 -47
  71. package/leiamnash/changeArchivedStatus.js +0 -41
  72. package/leiamnash/changeAvatar.js +0 -127
  73. package/leiamnash/changeBio.js +0 -64
  74. package/leiamnash/changeBlockedStatus.js +0 -36
  75. package/leiamnash/changeGroupImage.js +0 -105
  76. package/leiamnash/changeNickname.js +0 -43
  77. package/leiamnash/changeThreadColor.js +0 -61
  78. package/leiamnash/changeThreadEmoji.js +0 -41
  79. package/leiamnash/createNewGroup.js +0 -70
  80. package/leiamnash/createPoll.js +0 -59
  81. package/leiamnash/deleteMessage.js +0 -44
  82. package/leiamnash/deleteThread.js +0 -42
  83. package/leiamnash/forwardAttachment.js +0 -47
  84. package/leiamnash/forwardMessage.js +0 -0
  85. package/leiamnash/getCurrentUserID.js +0 -7
  86. package/leiamnash/getEmojiUrl.js +0 -27
  87. package/leiamnash/getFriendsList.js +0 -73
  88. package/leiamnash/getInfoVideo.js +0 -134
  89. package/leiamnash/getThreadHistory.js +0 -537
  90. package/leiamnash/getThreadHistoryDeprecated.js +0 -71
  91. package/leiamnash/getThreadInfoDeprecated.js +0 -56
  92. package/leiamnash/getThreadList.js +0 -213
  93. package/leiamnash/getThreadListDeprecated.js +0 -46
  94. package/leiamnash/getThreadPictures.js +0 -59
  95. package/leiamnash/getUserID.js +0 -61
  96. package/leiamnash/getUserInfo.js +0 -66
  97. package/leiamnash/handleFriendRequest.js +0 -46
  98. package/leiamnash/handleMessageRequest.js +0 -47
  99. package/leiamnash/httpGet.js +0 -47
  100. package/leiamnash/httpPost.js +0 -47
  101. package/leiamnash/logout.js +0 -68
  102. package/leiamnash/markAsDelivered.js +0 -47
  103. package/leiamnash/markAsRead.js +0 -70
  104. package/leiamnash/markAsReadAll.js +0 -40
  105. package/leiamnash/markAsSeen.js +0 -48
  106. package/leiamnash/muteThread.js +0 -45
  107. package/leiamnash/react.js +0 -109
  108. package/leiamnash/removeUserFromGroup.js +0 -45
  109. package/leiamnash/resolvePhotoUrl.js +0 -36
  110. package/leiamnash/searchForThread.js +0 -42
  111. package/leiamnash/seen.js +0 -40
  112. package/leiamnash/sendMessage.js +0 -315
  113. package/leiamnash/sendTypingIndicator.js +0 -70
  114. package/leiamnash/setMessageReaction.js +0 -103
  115. package/leiamnash/setPostReaction.js +0 -63
  116. package/leiamnash/setTitle.js +0 -70
  117. package/leiamnash/threadColors.js +0 -41
  118. package/leiamnash/unfriend.js +0 -42
  119. package/leiamnash/unsendMessage.js +0 -39
  120. /package/{leiamnash → src}/getMessage.js +0 -0
package/index.js CHANGED
@@ -1,20 +1,14 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("./utils");
4
- const cheerio = require("cheerio");
5
- const log = require("npmlog");
6
-
7
- let checkVerified = null;
8
-
9
- const defaultLogRecordSize = 100;
3
+ var utils = require("./utils");
4
+ var cheerio = require("cheerio");
5
+ var log = require('npmlog');
6
+ var defaultLogRecordSize = 100;
10
7
  log.maxRecordSize = defaultLogRecordSize;
11
8
 
12
9
  function setOptions(globalOptions, options) {
13
10
  Object.keys(options).map(function(key) {
14
11
  switch (key) {
15
- case 'pauseLog':
16
- if (options.pauseLog) log.pause();
17
- break;
18
12
  case 'online':
19
13
  globalOptions.online = Boolean(options.online);
20
14
  break;
@@ -29,6 +23,9 @@ function setOptions(globalOptions, options) {
29
23
  case 'selfListen':
30
24
  globalOptions.selfListen = Boolean(options.selfListen);
31
25
  break;
26
+ case 'selfListenEvent':
27
+ globalOptions.selfListenEvent = options.selfListenEvent;
28
+ break;
32
29
  case 'listenEvents':
33
30
  globalOptions.listenEvents = Boolean(options.listenEvents);
34
31
  break;
@@ -65,9 +62,6 @@ function setOptions(globalOptions, options) {
65
62
  case 'autoReconnect':
66
63
  globalOptions.autoReconnect = Boolean(options.autoReconnect);
67
64
  break;
68
- case 'emitReady':
69
- globalOptions.emitReady = Boolean(options.emitReady);
70
- break;
71
65
  default:
72
66
  log.warn("setOptions", "Unrecognized option given to setOptions: " + key);
73
67
  break;
@@ -75,67 +69,63 @@ function setOptions(globalOptions, options) {
75
69
  });
76
70
  }
77
71
 
78
- function buildAPI(globalOptions, html, jar) {
79
- const maybeCookie = jar.getCookies("https://www.facebook.com").filter(function(val) {
80
- return val.cookieString().split("=")[0] === "c_user";
81
- });
82
-
83
- const objCookie = jar.getCookies("https://www.facebook.com").reduce(function(obj, val) {
84
- obj[val.cookieString().split("=")[0]] = val.cookieString().split("=")[1];
85
- return obj;
72
+ function buildAPI(globalOptions, html, token, jar) {
73
+ var { c_user, i_user } = jar.getCookies('https://www.facebook.com').reduce(function(form, val) {
74
+ var [name, value] = val.cookieString().split('=');
75
+ form[name] = value;
76
+ return form;
86
77
  }, {});
87
78
 
88
- if (maybeCookie.length === 0) {
89
- throw { error: "please check your facebook account and get new alicestate" };
90
- }
91
- if (html.indexOf("/checkpoint/block/?next") > -1) {
92
- throw { error: "your facebook account has been ended please check it and get new alicestate"}
79
+ if (!i_user && !c_user) {
80
+ throw { error: "" };
93
81
  }
94
- const userID = maybeCookie[0].cookieString().split("=")[1].toString();
95
- const i_userID = objCookie.i_user || null;
96
- try {
97
- clearInterval(checkVerified);
98
- } catch (_) { }
99
82
 
100
- const clientID = (Math.random() * 2147483648 | 0).toString(16);
83
+ if (html.indexOf("/checkpoint/block/?next") > -1) return;
101
84
 
85
+ var userID = i_user || c_user;
86
+ var clientID = (Math.random() * 2147483648 | 0).toString(16);
87
+ var api = {
88
+ setOptions: setOptions.bind(null, globalOptions),
89
+ getAppState: function getAppState() {
90
+ return utils.getAppState(jar);
91
+ }
92
+ }
102
93
 
103
- const oldFBMQTTMatch = html.match(/irisSeqID:"(.+?)",appID:219994525426954,endpoint:"(.+?)"/);
94
+ let oldFBMQTTMatch = html.match(/irisSeqID:"(.+?)",appID:219994525426954,endpoint:"(.+?)"/);
104
95
  let mqttEndpoint = null;
105
96
  let region = null;
106
97
  let irisSeqID = null;
107
- let noMqttData = null;
108
98
 
99
+ if (token == 'NONE') return;
109
100
  if (oldFBMQTTMatch) {
110
101
  irisSeqID = oldFBMQTTMatch[1];
111
102
  mqttEndpoint = oldFBMQTTMatch[2];
112
103
  region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
113
104
  } else {
114
- const newFBMQTTMatch = html.match(/{"app_id":"219994525426954","endpoint":"(.+?)","iris_seq_id":"(.+?)"}/);
105
+ let newFBMQTTMatch = html.match(/{"app_id":"219994525426954","endpoint":"(.+?)","iris_seq_id":"(.+?)"}/);
115
106
  if (newFBMQTTMatch) {
116
107
  irisSeqID = newFBMQTTMatch[2];
117
108
  mqttEndpoint = newFBMQTTMatch[1].replace(/\\\//g, "/");
118
109
  region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
119
110
  } else {
120
- const legacyFBMQTTMatch = html.match(/(\["MqttWebConfig",\[\],{fbid:")(.+?)(",appID:219994525426954,endpoint:")(.+?)(",pollingEndpoint:")(.+?)(3790])/);
111
+ let legacyFBMQTTMatch = html.match(/(\["MqttWebConfig",\[\],{fbid:")(.+?)(",appID:219994525426954,endpoint:")(.+?)(",pollingEndpoint:")(.+?)(3790])/);
121
112
  if (legacyFBMQTTMatch) {
122
113
  mqttEndpoint = legacyFBMQTTMatch[4];
123
114
  region = new URL(mqttEndpoint).searchParams.get("region").toUpperCase();
115
+ return;
124
116
  } else {
125
- noMqttData = html;
117
+ api.htmlData = html;
126
118
  }
127
119
  }
128
120
  }
129
-
130
- // All data available to api functions
131
- const ctx = {
132
- userID: userID,
133
- i_userID: i_userID,
134
- jar: jar,
135
- clientID: clientID,
136
- globalOptions: globalOptions,
121
+
122
+ var ctx = {
123
+ userID,
124
+ jar,
125
+ clientID,
126
+ globalOptions,
137
127
  loggedIn: true,
138
- access_token: 'NONE',
128
+ access_token: token,
139
129
  clientMutationId: 0,
140
130
  mqttClient: undefined,
141
131
  lastSeqId: irisSeqID,
@@ -145,99 +135,24 @@ function buildAPI(globalOptions, html, jar) {
145
135
  firstListen: true
146
136
  };
147
137
 
148
- const api = {
149
- setOptions: setOptions.bind(null, globalOptions),
150
- getAppState: function getAppState() {
151
- const appState = utils.getAppState(jar);
152
- // filter duplicate
153
- return appState.filter((item, index, self) => self.findIndex((t) => { return t.key === item.key }) === index);
154
- }
155
- };
156
-
157
- if (noMqttData) {
158
- api["htmlData"] = noMqttData;
159
- }
138
+ var http = utils.makeDefaults(html, userID, ctx);
160
139
 
161
- const apiFuncNames = [
162
- 'addExternalModule',
163
- 'addUserToGroup',
164
- 'changeAdminStatus',
165
- 'changeArchivedStatus',
166
- 'changeAvatar',
167
- 'changeBio',
168
- 'changeBlockedStatus',
169
- 'changeGroupImage',
170
- 'changeNickname',
171
- 'changeThreadColor',
172
- 'changeThreadEmoji',
173
- 'chat',
174
- 'createNewGroup',
175
- 'createPoll',
176
- 'deleteMessage',
177
- 'deleteThread',
178
- 'forwardAttachment',
179
- 'getCurrentUserID',
180
- 'getEmojiUrl',
181
- 'getFriendsList',
182
- 'getMessage',
183
- 'getThreadHistory',
184
- 'getThreadInfo',
185
- 'getThreadList',
186
- 'getThreadPictures',
187
- 'getUserID',
188
- 'getUserInfo',
189
- 'handleMessageRequest',
190
- 'listenMqtt',
191
- 'logout',
192
- 'markAsDelivered',
193
- 'markAsRead',
194
- 'markAsReadAll',
195
- 'markAsSeen',
196
- 'muteThread',
197
- 'react',
198
- 'refreshFb_dtsg',
199
- 'removeUserFromGroup',
200
- 'resolvePhotoUrl',
201
- 'searchForThread',
202
- 'seen',
203
- 'sendMessage',
204
- 'sendTypingIndicator',
205
- 'setMessageReaction',
206
- 'setPostReaction',
207
- 'setTitle',
208
- 'threadColors',
209
- 'unsendMessage',
210
- 'unfriend',
211
-
212
- // HTTP
213
- 'httpGet',
214
- 'httpPost',
215
- 'httpPostFormData',
216
-
217
- 'uploadAttachment'
218
- ];
219
-
220
- const defaultFuncs = utils.makeDefaults(html, i_userID || userID, ctx);
221
-
222
- // Load all api functions in a loop
223
- apiFuncNames.map(function(v) {
224
- api[v] = require('./leiamnash/' + v)(defaultFuncs, api, ctx);
225
- });
226
-
227
- //Removing original `listen` that uses pull.
228
- //Map it to listenMqtt instead for backward compatibly.
140
+ require('node:fs')
141
+ .readdirSync(__dirname + '/src/')
142
+ .filter((v) => v.endsWith('.js'))
143
+ .map(function(v) {
144
+ api[v.replace('.js', '')] = require('./src/' + v)(http, api, ctx);
145
+ });
229
146
  api.listen = api.listenMqtt;
230
147
 
231
- return [ctx, defaultFuncs, api];
148
+ return [ctx, http, api];
232
149
  }
233
150
 
234
151
  function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
235
152
  return function(res) {
236
- const html = res.body;
237
- const $ = cheerio.load(html);
238
- let arr = [];
239
-
240
- // This will be empty, but just to be sure we leave it
153
+ var html = res.body;
154
+ var $ = cheerio.load(html);
155
+ var arr = [];
241
156
  $("#login_form input").map(function(i, v) {
242
157
  arr.push({ val: $(v).val(), name: $(v).attr("name") });
243
158
  });
@@ -246,7 +161,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
246
161
  return v.val && v.val.length;
247
162
  });
248
163
 
249
- const form = utils.arrToForm(arr);
164
+ var form = utils.arrToForm(arr);
250
165
  form.lsd = utils.getFrom(html, "[\"LSD\",[],{\"token\":\"", "\"}");
251
166
  form.lgndim = Buffer.from("{\"w\":1440,\"h\":900,\"aw\":1440,\"ah\":834,\"c\":24}").toString('base64');
252
167
  form.email = email;
@@ -257,269 +172,194 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
257
172
  form.timezone = '240';
258
173
  form.lgnjs = ~~(Date.now() / 1000);
259
174
 
260
-
261
- // Getting cookies from the HTML page... (kill me now plz)
262
- // we used to get a bunch of cookies in the headers of the response of the
263
- // request, but FB changed and they now send those cookies inside the JS.
264
- // They run the JS which then injects the cookies in the page.
265
- // The "solution" is to parse through the html and find those cookies
266
- // which happen to be conveniently indicated with a _js_ in front of their
267
- // variable name.
268
- //
269
- // ---------- Very Hacky Part Starts -----------------
270
- const willBeCookies = html.split("\"_js_");
175
+ var willBeCookies = html.split("\"_js_");
271
176
  willBeCookies.slice(1).map(function(val) {
272
- const cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
177
+ var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
273
178
  jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
274
179
  });
275
- // ---------- Very Hacky Part Ends -----------------
276
-
277
180
  return utils
278
181
  .post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
279
182
  .then(utils.saveCookies(jar))
280
183
  .then(function(res) {
281
- const headers = res.headers;
282
- if (!headers.location) {
283
- throw { error: "Wrong username/password." };
284
- }
285
-
286
- // This means the account has login approvals turned on.
287
- if (headers.location.indexOf('https://www.facebook.com/checkpoint/') > -1) {
288
- log.info("login", "You have login approvals turned on.");
289
- const nextURL = 'https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php';
290
-
184
+ var headers = res.headers;
185
+ if (!headers.location)
186
+ throw { error: "Wrong username/password." };
187
+
188
+ if (headers.location.includes('.com/checkpoint/')) {
189
+ if (callback == prCallback)
190
+ throw { error: 'Promise is not supported for login code verification' };
191
+ var Referer = headers.location;
291
192
  return utils
292
- .get(headers.location, jar, null, loginOptions)
193
+ .get(Referer, jar, null, loginOptions)
293
194
  .then(utils.saveCookies(jar))
294
195
  .then(function(res) {
295
- const html = res.body;
296
- // Make the form in advance which will contain the fb_dtsg and nh
297
- const $ = cheerio.load(html);
298
- let arr = [];
196
+ var html = res.body;
197
+ var $ = cheerio.load(html);
198
+ var arr = [];
299
199
  $("form input").map(function(i, v) {
300
- arr.push({ val: $(v).val(), name: $(v).attr("name") });
200
+ arr.push({ val: $(v).val(), name: $(v).attr("name") });
301
201
  });
302
-
303
202
  arr = arr.filter(function(v) {
304
203
  return v.val && v.val.length;
305
204
  });
205
+ var form = utils.arrToForm(arr);
206
+ if (html.includes('.com/checkpoint/?next')) {
207
+ function submit2FA(code) {
208
+ var cb;
209
+ var rtPromise = new Promise(function(resolve) {
210
+ cb = function(err, api) {
211
+ resolve(callback(err, api));
212
+ }
213
+ });
306
214
 
307
- const form = utils.arrToForm(arr);
308
- if (html.indexOf("checkpoint/?next") > -1) {
309
- setTimeout(() => {
310
- checkVerified = setInterval((_form) => {
311
- /* utils
312
- .post("https://www.facebook.com/login/approvals/approved_machine_check/", jar, form, loginOptions, null, {
313
- "Referer": "https://www.facebook.com/checkpoint/?next"
215
+ form.approvals_code = code;
216
+ form['submit[Continue]'] = $("#checkpointSubmitButton").html();
217
+ if (typeof code == 'string') {
218
+ utils
219
+ .post(Referer, jar, form, loginOptions, null, { Referer })
220
+ .then(utils.saveCookies(jar))
221
+ .then(function(res) {
222
+ var html = res.body;
223
+ var $ = cheerio.load(html);
224
+ var error = $("#approvals_code").parent().attr("data-xui-error");
225
+ if (error)
226
+ throw {
227
+ error: 'submit2FA',
228
+ errordesc: "Invalid 2FA code.",
229
+ lerror: error,
230
+ continue: submit2FA
231
+ }
232
+ })
233
+ .then(function() {
234
+ delete form.no_fido;
235
+ delete form.approvals_code;
236
+ form.name_action_selected = 'save_device';
237
+
238
+ return utils
239
+ .post(Referer, jar, form, loginOptions, null, { Referer })
240
+ .then(utils.saveCookies(jar));
314
241
  })
242
+ .then(function(res) {
243
+ var { headers, body: html } = res;
244
+ if (!headers.location && html.indexOf('Review Recent Login') > -1)
245
+ throw { error: "Something went wrong with login approvals." }
246
+ var appState = utils.getAppState(jar);
247
+ return loginHelper(appState, email, password, loginOptions, cb);
248
+ }).catch(function(err) {});
249
+ }
250
+ else {
251
+ utils
252
+ .post(Referer, jar, form, loginOptions, null, { Referer })
315
253
  .then(utils.saveCookies(jar))
316
- .then(res => {
254
+ .then(function(res) {
317
255
  try {
318
- JSON.parse(res.body.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*()/, ""));
319
- } catch (ex) {
320
- clearInterval(checkVerified);
321
- log.info("login", "Verified from browser. Logging in...");
322
- return loginHelper(utils.getAppState(jar), email, password, loginOptions, callback);
256
+ var maybeObject = res.body.split(';').pop();
257
+ JSON.parse(maybeObject);
258
+ } catch (_) {
259
+ var appState = utils.getAppState(jar);
260
+ return loginHelper(appState, email, password, loginOptions, cb);
323
261
  }
324
262
  })
325
- .catch(ex => {
326
- log.error("login", ex);
327
- }); */
328
- }, 5000, {
329
- fb_dtsg: form.fb_dtsg,
330
- jazoest: form.jazoest,
331
- dpr: 1
332
- });
333
- }, 2500);
334
- throw {
335
- error: 'login-approval',
336
- continue: function submit2FA(code) {
337
- form.approvals_code = code;
338
- form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
339
- let prResolve = null;
340
- let prReject = null;
341
- const rtPromise = new Promise(function(resolve, reject) {
342
- prResolve = resolve;
343
- prReject = reject;
344
- });
345
- if (typeof code == "string") {
346
- utils
347
- .post(nextURL, jar, form, loginOptions)
348
- .then(utils.saveCookies(jar))
349
- .then(function(res) {
350
- const $ = cheerio.load(res.body);
351
- const error = $("#approvals_code").parent().attr("data-xui-error");
352
- if (error) {
353
- throw {
354
- error: 'login-approval',
355
- errordesc: "Invalid 2FA code.",
356
- lerror: error,
357
- continue: submit2FA
358
- };
359
- }
360
- })
361
- .then(function() {
362
- // Use the same form (safe I hope)
363
- delete form.no_fido;
364
- delete form.approvals_code;
365
- form.name_action_selected = 'dont_save'; //'save_device';
366
-
367
- return utils
368
- .post(nextURL, jar, form, loginOptions)
369
- .then(utils.saveCookies(jar));
370
- })
371
- .then(function(res) {
372
- const headers = res.headers;
373
- if (!headers.location && res.body.indexOf('Review Recent Login') > -1) {
374
- throw { error: "Something went wrong with login approvals." };
375
- }
376
-
377
- const appState = utils.getAppState(jar);
378
-
379
- if (callback === prCallback) {
380
- callback = function(err, api) {
381
- if (err) {
382
- return prReject(err);
383
- }
384
- return prResolve(api);
385
- };
386
- }
387
-
388
- // Simply call loginHelper because all it needs is the jar
389
- // and will then complete the login process
390
- return loginHelper(appState, email, password, loginOptions, callback);
391
- })
392
- .catch(function(err) {
393
- // Check if using Promise instead of callback
394
- if (callback === prCallback) {
395
- prReject(err);
396
- } else {
397
- callback(err);
398
- }
399
- });
400
- } else {
401
- utils
402
- .post("https://www.facebook.com/checkpoint/?next=https%3A%2F%2Fwww.facebook.com%2Fhome.php", jar, form, loginOptions, null, {
403
- "Referer": "https://www.facebook.com/checkpoint/?next"
404
- })
405
- .then(utils.saveCookies(jar))
406
- .then(res => {
407
- try {
408
- JSON.parse(res.body.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, ""));
409
- } catch (ex) {
410
- clearInterval(checkVerified);
411
-
412
- if (callback === prCallback) {
413
- callback = function(err, api) {
414
- if (err) {
415
- return prReject(err);
416
- }
417
- return prResolve(api);
418
- };
419
- }
420
- return loginHelper(utils.getAppState(jar), email, password, loginOptions, callback);
421
- }
422
- })
423
- .catch(ex => {
424
- log.error("login", ex);
425
- if (callback === prCallback) {
426
- prReject(ex);
427
- } else {
428
- callback(ex);
429
- }
430
- });
431
- }
432
- return rtPromise;
263
+ .catch(function(err) {});
433
264
  }
434
- };
435
- } else {
436
- if (!loginOptions.forceLogin) {
437
- throw { error: "Couldn't login. Facebook might have blocked this account. Please login with a browser or enable the option 'forceLogin' and try again." };
265
+
266
+ return rtPromise;
267
+ }
268
+ throw {
269
+ error: 'submit2FA',
270
+ continue: submit2FA
438
271
  }
439
- if (html.indexOf("Suspicious Login Attempt") > -1) {
272
+ }
273
+ else {
274
+ if (!loginOptions.forceLogin)
275
+ throw { error: "" };
276
+ if (html.indexOf("Suspicious Login Attempt") > -1)
440
277
  form['submit[This was me]'] = "This was me";
441
- } else {
278
+ else
442
279
  form['submit[This Is Okay]'] = "This Is Okay";
443
- }
444
280
 
445
- return utils
446
- .post(nextURL, jar, form, loginOptions)
447
- .then(utils.saveCookies(jar))
448
- .then(function() {
449
- // Use the same form (safe I hope)
450
- form.name_action_selected = 'save_device';
451
-
452
- return utils
453
- .post(nextURL, jar, form, loginOptions)
454
- .then(utils.saveCookies(jar));
455
- })
456
- .then(function(res) {
457
- const headers = res.headers;
458
-
459
- if (!headers.location && res.body.indexOf('Review Recent Login') > -1) {
460
- throw { error: "Something went wrong with review recent login." };
281
+ function submitNot2FA() {
282
+ var cb;
283
+ var rtPromise = new Promise(function(resolve) {
284
+ cb = function(err, api) {
285
+ resolve(callback(err, api));
461
286
  }
462
-
463
- const 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(function(e) {
470
- callback(e);
471
287
  });
288
+
289
+ utils
290
+ .post(Referer, jar, form, loginOptions)
291
+ .then(utils.saveCookies(jar))
292
+ .then(function() {
293
+
294
+ form.name_action_selected = 'save_device';
295
+ return utils
296
+ .post(Referer, jar, form, loginOptions)
297
+ .then(utils.saveCookies(jar));
298
+ })
299
+ .then(function(res) {
300
+ var headers = res.headers;
301
+ if (!headers.location && res.body.includes('Review Recent Login'))
302
+ throw { error: "Something went wrong with review recent login." };
303
+ var appState = utils.getAppState(jar);
304
+
305
+ return loginHelper(appState, email, password, loginOptions, cb);
306
+ })
307
+ .catch(function(e) {
308
+ return cb(e);
309
+ });
310
+ return rtPromise;
311
+ }
312
+ throw {
313
+ error: 'submitNot2FA',
314
+ continue: submitNot2FA()
315
+ }
472
316
  }
473
317
  });
474
318
  }
475
319
 
320
+ setOptions(loginOptions, {
321
+ 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"
322
+ });
476
323
  return utils
477
- .get('https://www.facebook.com/', jar, null, loginOptions)
324
+ .get('https://www.facebook.com/', jar, null, loginOptions, null, { noRef: true })
478
325
  .then(utils.saveCookies(jar));
479
326
  });
480
- };
327
+ }
481
328
  }
482
329
 
483
- // Helps the login
484
330
  function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
485
- let mainPromise = null;
486
- const jar = utils.getJar();
487
-
488
- // If we're given an appState we loop through it and save each cookie
489
- // back into the jar.
490
- if (appState) {
331
+ var mainPromise = null;
332
+ var jar = utils.getJar();
333
+ if (appState) {
334
+ setOptions(globalOptions, {
335
+ 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"
336
+ });
491
337
  appState.map(function(c) {
492
- const str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
338
+ var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
493
339
  jar.setCookie(str, "http://" + c.domain);
494
340
  });
495
341
 
496
- // Load the main page.
497
342
  mainPromise = utils
498
- .get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true })
343
+ .get('https://www.facebook.com/', jar, null, globalOptions, null, { noRef: true })
499
344
  .then(utils.saveCookies(jar));
500
345
  } else {
501
- // Open the main page, then we login with the given credentials and finally
502
- // load the main page again (it'll give us some IDs that we need)
346
+ setOptions(globalOptions, {
347
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
348
+ });
503
349
  mainPromise = utils
504
- .get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
350
+ .get("https://www.facebook.com/", null, null, globalOptions, null, { noRef: true })
505
351
  .then(utils.saveCookies(jar))
506
- .then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
507
- .then(function() {
508
- return utils
509
- .get('https://www.facebook.com/', jar, null, globalOptions)
510
- .then(utils.saveCookies(jar));
511
- });
352
+ .then(makeLogin(jar, email, password, globalOptions, callback, prCallback));
512
353
  }
513
354
 
514
- let ctx = null;
515
- let _defaultFuncs = null;
516
- let api = null;
355
+ var ctx = null;
356
+ var _defaultFuncs = null;
357
+ var api = null;
517
358
 
518
359
  mainPromise = mainPromise
519
360
  .then(function(res) {
520
- // Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
521
- const reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
522
- const redirect = reg.exec(res.body);
361
+ var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
362
+ var redirect = reg.exec(res.body);
523
363
  if (redirect && redirect[1]) {
524
364
  return utils
525
365
  .get(redirect[1], jar, null, globalOptions)
@@ -527,16 +367,16 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
527
367
  }
528
368
  return res;
529
369
  })
370
+ .then(utils.createAccess_token(jar, globalOptions))
530
371
  .then(function(res) {
531
- const html = res.body;
532
- const stuff = buildAPI(globalOptions, html, jar);
372
+ var [html, token] = res;
373
+ var stuff = buildAPI(globalOptions, html.body, token, jar);
533
374
  ctx = stuff[0];
534
375
  _defaultFuncs = stuff[1];
535
376
  api = stuff[2];
536
377
  return res;
537
378
  });
538
-
539
- // given a pageID we log in as a page
379
+
540
380
  if (globalOptions.pageID) {
541
381
  mainPromise = mainPromise
542
382
  .then(function() {
@@ -544,7 +384,7 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
544
384
  .get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
545
385
  })
546
386
  .then(function(resData) {
547
- let url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
387
+ var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
548
388
  url = url.substring(0, url.length - 1);
549
389
 
550
390
  return utils
@@ -552,58 +392,53 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
552
392
  });
553
393
  }
554
394
 
555
- // At the end we call the callback or catch an exception
556
395
  mainPromise
557
396
  .then(function() {
558
- return callback(null, api);
397
+ return callback(null, api);
559
398
  })
560
399
  .catch(function(e) {
561
- log.error("login", e.error || e);
562
- callback(e);
400
+ return callback(e);
563
401
  });
564
402
  }
565
403
 
566
404
  function alice(loginData, options, callback) {
567
- if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
405
+ var prCallback;
406
+ var returnPromise = new Promise(function(resolve, reject) {
407
+ prCallback = (error, api) => api ? resolve(api) : reject(error);
408
+ });
409
+
410
+ if (typeof options == 'function') {
568
411
  callback = options;
569
412
  options = {};
570
413
  }
414
+ if (typeof callback == 'function') prCallback = null;
415
+ else callback = prCallback;
416
+ if (options == undefined) options = {};
571
417
 
572
- const globalOptions = {
418
+ var globalOptions = {
573
419
  selfListen: false,
574
420
  selfListenEvent: false,
575
- listenEvents: false,
421
+ listenEvents: true,
576
422
  listenTyping: false,
577
- updatePresence: false,
423
+ updatePresence: true,
578
424
  forceLogin: false,
579
425
  autoMarkDelivery: true,
580
- autoMarkRead: false,
426
+ autoMarkRead: true,
581
427
  autoReconnect: true,
582
428
  logRecordSize: defaultLogRecordSize,
583
429
  online: true,
584
- emitReady: false,
585
- 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"
430
+ emitReady: false
586
431
  };
587
-
588
432
  setOptions(globalOptions, options);
589
433
 
590
- let prCallback = null;
591
- if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
592
- let rejectFunc = null;
593
- let resolveFunc = null;
594
- var returnPromise = new Promise(function(resolve, reject) {
595
- resolveFunc = resolve;
596
- rejectFunc = reject;
434
+ if (parseInt(process.versions.node) < 14) {
435
+ return callback({
436
+ error: 'nodeDeprecated',
437
+ lerror: 'node version must be 14.x or higher, recommended version: 16.7.0'
597
438
  });
598
- prCallback = function(error, api) {
599
- if (error) {
600
- return rejectFunc(error);
601
- }
602
- return resolveFunc(api);
603
- };
604
- callback = prCallback;
605
439
  }
606
440
  loginHelper(loginData.appState, loginData.email, loginData.password, globalOptions, callback, prCallback);
441
+
607
442
  return returnPromise;
608
443
  }
609
444