node-ainzfb-new 1.7.10-2-zGsq2er → 1.7.10-24ejweqr
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/StateCrypt.js +24 -14
- package/index.js +316 -42
- package/package.json +3 -3
- package/src/pinMessage.js +58 -0
- package/src/shareContact.js +46 -0
- package/src/shareLink.js +54 -0
- package/utils.js +23 -5
package/StateCrypt.js
CHANGED
@@ -1,22 +1,32 @@
|
|
1
|
-
/* eslint-disable linebreak-style */
|
2
1
|
const crypto = require('crypto');
|
3
2
|
const aes = require("aes-js");
|
4
3
|
|
5
4
|
function encryptState(data, key) {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
try {
|
6
|
+
const hashEngine = crypto.createHash("sha256");
|
7
|
+
const hashKey = hashEngine.update(key).digest();
|
8
|
+
const bytes = aes.utils.utf8.toBytes(data);
|
9
|
+
const aesCtr = new aes.ModeOfOperation.ctr(hashKey);
|
10
|
+
const encryptedData = aesCtr.encrypt(bytes);
|
11
|
+
return aes.utils.hex.fromBytes(encryptedData);
|
12
|
+
} catch (error) {
|
13
|
+
console.error("Error encrypting state:", error.message);
|
14
|
+
throw error;
|
15
|
+
}
|
12
16
|
}
|
13
17
|
|
14
18
|
function decryptState(data, key) {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
try {
|
20
|
+
const hashEngine = crypto.createHash("sha256");
|
21
|
+
const hashKey = hashEngine.update(key).digest();
|
22
|
+
const encryptedBytes = aes.utils.hex.toBytes(data);
|
23
|
+
const aesCtr = new aes.ModeOfOperation.ctr(hashKey);
|
24
|
+
const decryptedData = aesCtr.decrypt(encryptedBytes);
|
25
|
+
return aes.utils.utf8.fromBytes(decryptedData);
|
26
|
+
} catch (error) {
|
27
|
+
console.error("Error decrypting state:", error.message);
|
28
|
+
throw error;
|
29
|
+
}
|
21
30
|
}
|
22
|
-
|
31
|
+
|
32
|
+
module.exports = { encryptState, decryptState };
|
package/index.js
CHANGED
@@ -9,7 +9,7 @@ process.env.UV_THREADPOOL_SIZE = require('os').cpus().length;
|
|
9
9
|
global.isThread = new Array();
|
10
10
|
global.isUser = new Array();
|
11
11
|
global.startTime = Date.now();
|
12
|
-
global.getText =
|
12
|
+
global.getText = require('gettext.js')();
|
13
13
|
|
14
14
|
/!-[ Require All Package Need Use ]-!/
|
15
15
|
/*globalThis.Fca = new Object({
|
@@ -19,13 +19,11 @@ global.getText = require('gettext.js')();
|
|
19
19
|
var utils = require("./utils"),
|
20
20
|
cheerio = require("cheerio"),
|
21
21
|
log = require("npmlog"),
|
22
|
-
//{ getAccessToken } = require('./Extra/ExtraAddons'),
|
22
|
+
//{ getAccessToken } = require('./Extra/ExtraAddons'),
|
23
23
|
logger = require('./logger'),
|
24
24
|
fs = require('fs-extra'),
|
25
25
|
getText = require('gettext.js')(),
|
26
|
-
logger = require('./logger'),
|
27
26
|
Fetch = require('got'),
|
28
|
-
fs = require('fs-extra'),
|
29
27
|
StateCrypt = require('./StateCrypt'),
|
30
28
|
Client = require("@replit/database"),
|
31
29
|
languageFile = require('./Language/index.json'),
|
@@ -90,7 +88,7 @@ var checkVerified = null;
|
|
90
88
|
/!-[ Function setOptions ]-!/
|
91
89
|
|
92
90
|
function setOptions(globalOptions, options) {
|
93
|
-
Object.keys(options).map(function(key) {
|
91
|
+
Object.keys(options).map(function (key) {
|
94
92
|
switch (key) {
|
95
93
|
case 'pauseLog':
|
96
94
|
if (options.pauseLog) log.pause();
|
@@ -158,7 +156,7 @@ function setOptions(globalOptions, options) {
|
|
158
156
|
/!-[ Function BuildAPI ]-!/
|
159
157
|
|
160
158
|
async function buildAPI(globalOptions, html, jar) {
|
161
|
-
var maybeCookie = jar.getCookies("https://www.facebook.com").filter(function(val) { return val.cookieString().split("=")[0] === "c_user"; });
|
159
|
+
var maybeCookie = jar.getCookies("https://www.facebook.com").filter(function (val) { return val.cookieString().split("=")[0] === "c_user"; });
|
162
160
|
|
163
161
|
if (maybeCookie.length === 0) throw { error: Language.ErrAppState };
|
164
162
|
|
@@ -246,7 +244,7 @@ async function buildAPI(globalOptions, html, jar) {
|
|
246
244
|
}
|
247
245
|
|
248
246
|
function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
249
|
-
return function(res) {
|
247
|
+
return function (res) {
|
250
248
|
var html = res.body;
|
251
249
|
var $ = cheerio.load(html);
|
252
250
|
var arr = [];
|
@@ -254,7 +252,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
254
252
|
// This will be empty, but just to be sure we leave it
|
255
253
|
$("#login_form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
|
256
254
|
|
257
|
-
arr = arr.filter(function(v) {
|
255
|
+
arr = arr.filter(function (v) {
|
258
256
|
return v.val && v.val.length;
|
259
257
|
});
|
260
258
|
|
@@ -280,7 +278,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
280
278
|
//
|
281
279
|
// ---------- Very Hacky Part Starts -----------------
|
282
280
|
var willBeCookies = html.split("\"_js_");
|
283
|
-
willBeCookies.slice(1).map(function(val) {
|
281
|
+
willBeCookies.slice(1).map(function (val) {
|
284
282
|
var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
|
285
283
|
jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
|
286
284
|
});
|
@@ -290,7 +288,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
290
288
|
return utils
|
291
289
|
.post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
|
292
290
|
.then(utils.saveCookies(jar))
|
293
|
-
.then(function(res) {
|
291
|
+
.then(function (res) {
|
294
292
|
var headers = res.headers;
|
295
293
|
if (!headers.location) throw { error: Language.InvaildAccount };
|
296
294
|
|
@@ -302,21 +300,21 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
302
300
|
return utils
|
303
301
|
.get(headers.location, jar, null, loginOptions)
|
304
302
|
.then(utils.saveCookies(jar))
|
305
|
-
.then(function(res) {
|
303
|
+
.then(function (res) {
|
306
304
|
var html = res.body;
|
307
305
|
// Make the form in advance which will contain the fb_dtsg and nh
|
308
306
|
var $ = cheerio.load(html);
|
309
307
|
var arr = [];
|
310
308
|
$("form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
|
311
309
|
|
312
|
-
arr = arr.filter(function(v) {
|
310
|
+
arr = arr.filter(function (v) {
|
313
311
|
return v.val && v.val.length;
|
314
312
|
});
|
315
313
|
|
316
314
|
var form = utils.arrToForm(arr);
|
317
315
|
if (html.indexOf("checkpoint/?next") > -1) {
|
318
316
|
setTimeout(() => {
|
319
|
-
checkVerified = setInterval((_form) => {}, 5000, {
|
317
|
+
checkVerified = setInterval((_form) => { }, 5000, {
|
320
318
|
fb_dtsg: form.fb_dtsg,
|
321
319
|
jazoest: form.jazoest,
|
322
320
|
dpr: 1
|
@@ -329,7 +327,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
329
327
|
form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
|
330
328
|
var prResolve = null;
|
331
329
|
var prReject = null;
|
332
|
-
var rtPromise = new Promise(function(resolve, reject) {
|
330
|
+
var rtPromise = new Promise(function (resolve, reject) {
|
333
331
|
prResolve = resolve;
|
334
332
|
prReject = reject;
|
335
333
|
});
|
@@ -337,7 +335,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
337
335
|
utils
|
338
336
|
.post(nextURL, jar, form, loginOptions)
|
339
337
|
.then(utils.saveCookies(jar))
|
340
|
-
.then(function(res) {
|
338
|
+
.then(function (res) {
|
341
339
|
var $ = cheerio.load(res.body);
|
342
340
|
var error = $("#approvals_code").parent().attr("data-xui-error");
|
343
341
|
if (error) {
|
@@ -349,7 +347,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
349
347
|
};
|
350
348
|
}
|
351
349
|
})
|
352
|
-
.then(function() {
|
350
|
+
.then(function () {
|
353
351
|
// Use the same form (safe I hope)
|
354
352
|
delete form.no_fido;
|
355
353
|
delete form.approvals_code;
|
@@ -357,14 +355,14 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
357
355
|
|
358
356
|
return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
|
359
357
|
})
|
360
|
-
.then(function(res) {
|
358
|
+
.then(function (res) {
|
361
359
|
var headers = res.headers;
|
362
360
|
if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: Language.ApprovalsErr };
|
363
361
|
|
364
362
|
var appState = utils.getAppState(jar);
|
365
363
|
|
366
364
|
if (callback === prCallback) {
|
367
|
-
callback = function(err, api) {
|
365
|
+
callback = function (err, api) {
|
368
366
|
if (err) return prReject(err);
|
369
367
|
return prResolve(api);
|
370
368
|
};
|
@@ -374,7 +372,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
374
372
|
// and will then complete the login process
|
375
373
|
return loginHelper(appState, email, password, loginOptions, callback);
|
376
374
|
})
|
377
|
-
.catch(function(err) {
|
375
|
+
.catch(function (err) {
|
378
376
|
// Check if using Promise instead of callback
|
379
377
|
if (callback === prCallback) prReject(err);
|
380
378
|
else callback(err);
|
@@ -390,7 +388,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
390
388
|
clearInterval(checkVerified);
|
391
389
|
logger(Language.VerifiedCheck, "[ FCA-SUS ]");
|
392
390
|
if (callback === prCallback) {
|
393
|
-
callback = function(err, api) {
|
391
|
+
callback = function (err, api) {
|
394
392
|
if (err) return prReject(err);
|
395
393
|
return prResolve(api);
|
396
394
|
};
|
@@ -416,13 +414,13 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
416
414
|
return utils
|
417
415
|
.post(nextURL, jar, form, loginOptions)
|
418
416
|
.then(utils.saveCookies(jar))
|
419
|
-
.then(function() {
|
417
|
+
.then(function () {
|
420
418
|
// Use the same form (safe I hope)
|
421
419
|
form.name_action_selected = 'save_device';
|
422
420
|
|
423
421
|
return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
|
424
422
|
})
|
425
|
-
.then(function(res) {
|
423
|
+
.then(function (res) {
|
426
424
|
var headers = res.headers;
|
427
425
|
|
428
426
|
if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with review recent login." };
|
@@ -455,7 +453,7 @@ function makeid(length) {
|
|
455
453
|
|
456
454
|
|
457
455
|
// Helps the login
|
458
|
-
async function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
|
456
|
+
/*async function loginHelper(appState, email, password, globalOptions, callback, prCallback) {
|
459
457
|
var mainPromise = null;
|
460
458
|
var jar = utils.getJar();
|
461
459
|
|
@@ -532,7 +530,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
532
530
|
// });
|
533
531
|
|
534
532
|
logger(Language.OnProcess, "[ FCA-SUS ]");
|
535
|
-
var backup = async(data) => {
|
533
|
+
var backup = async (data) => {
|
536
534
|
if (fs.existsSync('./appstate.json')) {
|
537
535
|
try {
|
538
536
|
fs.writeFileSync('./appstate.json', data);
|
@@ -580,9 +578,9 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
580
578
|
{
|
581
579
|
if (process.env["REPL_ID"] == undefined) {
|
582
580
|
try {
|
583
|
-
|
584
|
-
|
585
|
-
|
581
|
+
var { body } = await Fetch('https://sampleapi.netlify.app/.netlify/functions/api/generate/key');
|
582
|
+
|
583
|
+
process.env['FBKEY'] = JSON.parse(body).response.key;
|
586
584
|
} catch (e) {
|
587
585
|
logger(Language.ErrGetPassWord, '[ FCA-SUS ]');
|
588
586
|
logger.Error();
|
@@ -611,7 +609,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
611
609
|
case "android":
|
612
610
|
{
|
613
611
|
try {
|
614
|
-
|
612
|
+
var { body } = await Fetch('https://sampleapi.netlify.app/.netlify/functions/api/generate/key');
|
615
613
|
process.env['FBKEY'] = JSON.parse(body).response.key;
|
616
614
|
} catch (e) {
|
617
615
|
logger(Language.ErrGetPassWord, '[ FCA-SUS ]');
|
@@ -632,7 +630,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
632
630
|
case true:
|
633
631
|
{
|
634
632
|
appState = JSON.parse(JSON.stringify(appState, null, "\t"));
|
635
|
-
|
633
|
+
//console.log(appState);
|
636
634
|
switch (utils.getType(appState)) {
|
637
635
|
case "Array":
|
638
636
|
{
|
@@ -729,9 +727,9 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
729
727
|
case "String":
|
730
728
|
{
|
731
729
|
logger(Language.EncryptStateOff, "[ FCA-SUS ]");
|
732
|
-
|
730
|
+
//console.log("hello")
|
733
731
|
try {
|
734
|
-
|
732
|
+
// appState = appState;
|
735
733
|
appState = StateCrypt.decryptState(appState, process.env['FBKEY']);
|
736
734
|
logger(Language.DecryptSuccess, '[ FCA-SUS ]');
|
737
735
|
} catch (e) {
|
@@ -827,7 +825,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
827
825
|
}
|
828
826
|
}
|
829
827
|
try {
|
830
|
-
appState.map(function(c) {
|
828
|
+
appState.map(function (c) {
|
831
829
|
var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
|
832
830
|
jar.setCookie(str, "http://" + c.domain);
|
833
831
|
});
|
@@ -951,7 +949,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
951
949
|
.get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
|
952
950
|
.then(utils.saveCookies(jar))
|
953
951
|
.then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
|
954
|
-
.then(function() {
|
952
|
+
.then(function () {
|
955
953
|
return utils.get('https://www.facebook.com/', jar, null, globalOptions).then(utils.saveCookies(jar));
|
956
954
|
});
|
957
955
|
}
|
@@ -962,15 +960,54 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
962
960
|
var _defaultFuncs = null;
|
963
961
|
var api = null;
|
964
962
|
|
963
|
+
let redirect = [1, "https://m.facebook.com/"], bypass_region_err = false;
|
964
|
+
|
965
|
+
function CheckAndFixErr(res) {
|
966
|
+
let reg_antierr = /This browser is not supported/gs; // =))))))
|
967
|
+
if (reg_antierr.test(res.body)) {
|
968
|
+
const Data = JSON.stringify(res.body);
|
969
|
+
const Dt_Check = Data.split('2Fhome.php&gfid=')[1];
|
970
|
+
if (Dt_Check == undefined) return res
|
971
|
+
const fid = Dt_Check.split("\\\\")[0];//fix sau
|
972
|
+
if (Dt_Check == undefined || Dt_Check == "") return res
|
973
|
+
const final_fid = fid.split(`\\`)[0];
|
974
|
+
if (final_fid == undefined || final_fid == '') return res;
|
975
|
+
const redirectlink = redirect[1] + "a/preferences.php?basic_site_devices=m_basic&uri=" + encodeURIComponent("https://m.facebook.com/home.php") + "&gfid=" + final_fid;
|
976
|
+
bypass_region_err = true;
|
977
|
+
return utils.get(redirectlink, jar, null, globalOptions).then(utils.saveCookies(jar));
|
978
|
+
}
|
979
|
+
else return res
|
980
|
+
}
|
981
|
+
|
982
|
+
function Redirect(res) {
|
983
|
+
var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
|
984
|
+
redirect = reg.exec(res.body);
|
985
|
+
if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
|
986
|
+
return res;
|
987
|
+
}
|
988
|
+
|
965
989
|
mainPromise = mainPromise
|
966
|
-
.then(function(res) {
|
990
|
+
.then(function (res) {
|
967
991
|
// Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
|
968
992
|
var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
|
969
993
|
var redirect = reg.exec(res.body);
|
970
994
|
if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
|
971
995
|
return res;
|
972
996
|
})
|
973
|
-
.then(
|
997
|
+
.then(res => Redirect(res))
|
998
|
+
.then(res => CheckAndFixErr(res))
|
999
|
+
.then(function (res) {
|
1000
|
+
let Regex_Via = /MPageLoadClientMetrics/gs; //default for normal account, can easily get region, without this u can't get region in some case but u can run normal
|
1001
|
+
if (!Regex_Via.test(res.body)) {
|
1002
|
+
//www.facebook.com
|
1003
|
+
globalOptions.userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1";
|
1004
|
+
return utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
|
1005
|
+
}
|
1006
|
+
else return res
|
1007
|
+
})
|
1008
|
+
.then(res => Redirect(res))
|
1009
|
+
.then(res => CheckAndFixErr(res))
|
1010
|
+
.then(async function (res) {
|
974
1011
|
var html = res.body;
|
975
1012
|
var stuff = await buildAPI(globalOptions, html, jar);
|
976
1013
|
ctx = stuff[0];
|
@@ -978,13 +1015,14 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
978
1015
|
api = stuff[2];
|
979
1016
|
return res;
|
980
1017
|
});
|
1018
|
+
|
981
1019
|
// given a pageID we log in as a page
|
982
1020
|
if (globalOptions.pageID) {
|
983
1021
|
mainPromise = mainPromise
|
984
|
-
.then(function() {
|
1022
|
+
.then(function () {
|
985
1023
|
return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
|
986
1024
|
})
|
987
|
-
.then(function(resData) {
|
1025
|
+
.then(function (resData) {
|
988
1026
|
var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
|
989
1027
|
url = url.substring(0, url.length - 1);
|
990
1028
|
return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
|
@@ -993,14 +1031,14 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
993
1031
|
|
994
1032
|
// At the end we call the callback or catch an exception
|
995
1033
|
mainPromise
|
996
|
-
.then(function() {
|
1034
|
+
.then(function () {
|
997
1035
|
logger(Language.DoneLogin, "[ FCA-SUS ]");
|
998
1036
|
logger(Language.AutoCheckUpdate, "[ FCA-SUS ]");
|
999
1037
|
//!---------- Auto Check, Update START -----------------!//
|
1000
1038
|
var Fetch = require('got');
|
1001
1039
|
var { readFileSync } = require('fs-extra');
|
1002
1040
|
const { execSync } = require('child_process');
|
1003
|
-
Fetch('https://raw.githubusercontent.com/amogusdevlol/node-ainzfb/main/package.json').then(async(res) => {
|
1041
|
+
Fetch('https://raw.githubusercontent.com/amogusdevlol/node-ainzfb/main/package.json').then(async (res) => {
|
1004
1042
|
const localbrand = JSON.parse(readFileSync('./node_modules/node-ainzfb-new/package.json')).version;
|
1005
1043
|
if (Number(localbrand.replace(/\./g, "")) < Number(JSON.parse(res.body.toString()).version.replace(/\./g, ""))) {
|
1006
1044
|
log.warn("[ FCA-SUS ] •", getText.gettext(Language.NewVersionFound, JSON.parse(readFileSync('./node_modules/node-ainzfb/package.json')).version, JSON.parse(res.body.toString()).version));
|
@@ -1040,13 +1078,249 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
1040
1078
|
callback(null, api);
|
1041
1079
|
}
|
1042
1080
|
});
|
1043
|
-
}).catch(function(e) {
|
1081
|
+
}).catch(function (e) {
|
1044
1082
|
log.error("login", e.error || e);
|
1045
1083
|
callback(e);
|
1046
1084
|
});
|
1047
1085
|
//!---------- Auto Check, Update END -----------------!//
|
1086
|
+
}*/
|
1087
|
+
|
1088
|
+
|
1089
|
+
async function loginHelper(
|
1090
|
+
appState,
|
1091
|
+
email,
|
1092
|
+
password,
|
1093
|
+
globalOptions,
|
1094
|
+
callback,
|
1095
|
+
prCallback
|
1096
|
+
) {
|
1097
|
+
var mainPromise = null;
|
1098
|
+
var jar = utils.getJar();
|
1099
|
+
|
1100
|
+
// If we're given an appState we loop through it and save each cookie
|
1101
|
+
// back into the jar.
|
1102
|
+
if (appState) {
|
1103
|
+
|
1104
|
+
|
1105
|
+
// Decrypt the appState if FBKEY is provided
|
1106
|
+
if (process.env['FBKEY']) {
|
1107
|
+
try {
|
1108
|
+
appState = JSON.parse(StateCrypt.decryptState(appState, process.env['FBKEY']));
|
1109
|
+
console.log("AppState decrypted successfully");
|
1110
|
+
} catch (e) {
|
1111
|
+
console.error("Failed to decrypt AppState:", e.message);
|
1112
|
+
return callback(new Error("Failed to decrypt AppState"));
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
if (!Array.isArray(appState)) {
|
1117
|
+
return callback(new Error("AppState must be an array"));
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
appState.map(function (c) {
|
1121
|
+
var str =
|
1122
|
+
c.key +
|
1123
|
+
'=' +
|
1124
|
+
c.value +
|
1125
|
+
'; expires=' +
|
1126
|
+
c.expires +
|
1127
|
+
'; domain=' +
|
1128
|
+
c.domain +
|
1129
|
+
'; path=' +
|
1130
|
+
c.path +
|
1131
|
+
';';
|
1132
|
+
jar.setCookie(str, 'http://' + c.domain);
|
1133
|
+
});
|
1134
|
+
|
1135
|
+
// Load the main page.
|
1136
|
+
mainPromise = utils
|
1137
|
+
.get('https://www.facebook.com/', jar, null, globalOptions, {
|
1138
|
+
noRef: true,
|
1139
|
+
})
|
1140
|
+
.then(utils.saveCookies(jar));
|
1141
|
+
} else {
|
1142
|
+
// Open the main page, then we login with the given credentials and finally
|
1143
|
+
// load the main page again (it'll give us some IDs that we need)
|
1144
|
+
mainPromise = utils
|
1145
|
+
.get('https://www.facebook.com/', null, null, globalOptions, {
|
1146
|
+
noRef: true,
|
1147
|
+
})
|
1148
|
+
.then(utils.saveCookies(jar))
|
1149
|
+
.then(
|
1150
|
+
makeLogin(jar, email, password, globalOptions, callback, prCallback)
|
1151
|
+
)
|
1152
|
+
.then(function () {
|
1153
|
+
return utils
|
1154
|
+
.get('https://www.facebook.com/', jar, null, globalOptions)
|
1155
|
+
.then(utils.saveCookies(jar));
|
1156
|
+
});
|
1157
|
+
}
|
1158
|
+
|
1159
|
+
var ctx = null;
|
1160
|
+
var _defaultFuncs = null;
|
1161
|
+
var api = null;
|
1162
|
+
|
1163
|
+
let redirect = [1, "https://m.facebook.com/"], bypass_region_err = false;
|
1164
|
+
|
1165
|
+
function CheckAndFixErr(res) {
|
1166
|
+
let reg_antierr = /This browser is not supported/gs;
|
1167
|
+
if (reg_antierr.test(res.body)) {
|
1168
|
+
const Data = JSON.stringify(res.body);
|
1169
|
+
const Dt_Check = Data.split('2Fhome.php&gfid=')[1];
|
1170
|
+
if (Dt_Check == undefined) return res
|
1171
|
+
const fid = Dt_Check.split("\\\\")[0];
|
1172
|
+
if (Dt_Check == undefined || Dt_Check == "") return res
|
1173
|
+
const final_fid = fid.split(`\\`)[0];
|
1174
|
+
if (final_fid == undefined || final_fid == '') return res;
|
1175
|
+
const redirectlink = redirect[1] + "a/preferences.php?basic_site_devices=m_basic&uri=" + encodeURIComponent("https://m.facebook.com/home.php") + "&gfid=" + final_fid;
|
1176
|
+
bypass_region_err = true;
|
1177
|
+
return utils.get(redirectlink, jar, null, globalOptions).then(utils.saveCookies(jar));
|
1178
|
+
}
|
1179
|
+
else return res
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
function Redirect(res) {
|
1183
|
+
var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
|
1184
|
+
redirect = reg.exec(res.body);
|
1185
|
+
if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
|
1186
|
+
return res;
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
mainPromise = mainPromise
|
1190
|
+
.then(function (res) {
|
1191
|
+
var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
|
1192
|
+
var redirect = reg.exec(res.body);
|
1193
|
+
if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
|
1194
|
+
return res;
|
1195
|
+
})
|
1196
|
+
.then(res => Redirect(res))
|
1197
|
+
.then(res => CheckAndFixErr(res))
|
1198
|
+
.then(function (res) {
|
1199
|
+
let Regex_Via = /MPageLoadClientMetrics/gs;
|
1200
|
+
if (!Regex_Via.test(res.body)) {
|
1201
|
+
globalOptions.userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1";
|
1202
|
+
return utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
|
1203
|
+
}
|
1204
|
+
else return res
|
1205
|
+
})
|
1206
|
+
.then(res => Redirect(res))
|
1207
|
+
.then(res => CheckAndFixErr(res))
|
1208
|
+
.then(async function (res) {
|
1209
|
+
var html = res.body;
|
1210
|
+
var stuff = await buildAPI(globalOptions, html, jar);
|
1211
|
+
ctx = stuff[0];
|
1212
|
+
_defaultFuncs = stuff[1];
|
1213
|
+
api = stuff[2];
|
1214
|
+
return res;
|
1215
|
+
});
|
1216
|
+
|
1217
|
+
if (globalOptions.pageID) {
|
1218
|
+
mainPromise = mainPromise
|
1219
|
+
.then(function () {
|
1220
|
+
return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
|
1221
|
+
})
|
1222
|
+
.then(function (resData) {
|
1223
|
+
var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
|
1224
|
+
url = url.substring(0, url.length - 1);
|
1225
|
+
return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
|
1226
|
+
});
|
1227
|
+
}
|
1228
|
+
|
1229
|
+
mainPromise
|
1230
|
+
.then(function () {
|
1231
|
+
// Encrypt and save the appState
|
1232
|
+
if (process.env['FBKEY']) {
|
1233
|
+
try {
|
1234
|
+
const currentAppState = jar.getCookies("https://www.facebook.com").concat(jar.getCookies("https://facebook.com")).concat(jar.getCookies("https://www.messenger.com"));
|
1235
|
+
const encryptedAppState = StateCrypt.encryptState(JSON.stringify(currentAppState), process.env['FBKEY']);
|
1236
|
+
// Save the encrypted appState (you might want to implement a save function)
|
1237
|
+
saveAppState(encryptedAppState, (err) => {
|
1238
|
+
if (err) {
|
1239
|
+
console.error("Failed to encrypt and save AppState:", err.message);
|
1240
|
+
} else {
|
1241
|
+
console.log("AppState encrypted and saved successfully");
|
1242
|
+
}
|
1243
|
+
callback(null, api);
|
1244
|
+
});
|
1245
|
+
console.log("AppState encrypted and saved successfully");
|
1246
|
+
} catch (e) {
|
1247
|
+
console.error("Failed to encrypt and save AppState:", e.message);
|
1248
|
+
}
|
1249
|
+
}
|
1250
|
+
//callback(null, api);
|
1251
|
+
})
|
1252
|
+
|
1253
|
+
// At the end we call the callback or catch an exception
|
1254
|
+
mainPromise
|
1255
|
+
.then(function () {
|
1256
|
+
logger(Language.DoneLogin, "[ FCA-SUS ]");
|
1257
|
+
logger(Language.AutoCheckUpdate, "[ FCA-SUS ]");
|
1258
|
+
//!---------- Auto Check, Update START -----------------!//
|
1259
|
+
var Fetch = require('got');
|
1260
|
+
var { readFileSync } = require('fs-extra');
|
1261
|
+
const { execSync } = require('child_process');
|
1262
|
+
Fetch('https://raw.githubusercontent.com/amogusdevlol/node-ainzfb/main/package.json').then(async (res) => {
|
1263
|
+
const localbrand = JSON.parse(readFileSync('./node_modules/node-ainzfb-new/package.json')).version;
|
1264
|
+
if (Number(localbrand.replace(/\./g, "")) < Number(JSON.parse(res.body.toString()).version.replace(/\./g, ""))) {
|
1265
|
+
log.warn("[ FCA-SUS ] •", getText.gettext(Language.NewVersionFound, JSON.parse(readFileSync('./node_modules/node-ainzfb/package.json')).version, JSON.parse(res.body.toString()).version));
|
1266
|
+
log.warn("[ FCA-SUS ] •", Language.AutoUpdate);
|
1267
|
+
try {
|
1268
|
+
execSync('npm install node-ainzfb-new@latest', { stdio: 'inherit' });
|
1269
|
+
logger(Language.UpdateSuccess, "[ FCA-SUS ]")
|
1270
|
+
logger(Language.RestartAfterUpdate, '[ FCA-SUS ]');
|
1271
|
+
await new Promise(resolve => setTimeout(resolve, 5 * 1000));
|
1272
|
+
console.clear();
|
1273
|
+
process.exit(1);
|
1274
|
+
} catch (err) {
|
1275
|
+
log.warn('Error Update: ' + err);
|
1276
|
+
logger(Language.UpdateFailed, "[ FCA-SUS ]");
|
1277
|
+
try {
|
1278
|
+
require.resolve('sus-support');
|
1279
|
+
} catch (e) {
|
1280
|
+
logger(Language.InstallSupportTool, "[ FCA-SUS ]");
|
1281
|
+
execSync('npm install git+https://github.com/amogusdevlol/sus-support.git', { stdio: 'inherit' });
|
1282
|
+
process.exit(1);
|
1283
|
+
}
|
1284
|
+
var fcasp = require('sus-support');
|
1285
|
+
try {
|
1286
|
+
fcasp.onError()
|
1287
|
+
} catch (e) {
|
1288
|
+
logger(Language.NotiAfterUseToolFail, "[ Fca - Helper ]")
|
1289
|
+
logger("rmdir ./node_modules then enter npm i && npm start", "[ Fca - Helper ]");
|
1290
|
+
process.exit(0);
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
}
|
1294
|
+
} else {
|
1295
|
+
logger(getText.gettext(Language.LocalVersion, localbrand), "[ FCA-SUS ]");
|
1296
|
+
logger(Language.WishMessage[Math.floor(Math.random() * Language.WishMessage.length)], "[ FCA-SUS ]");
|
1297
|
+
require('./Extra/ExtraUptimeRobot')()
|
1298
|
+
await new Promise(resolve => setTimeout(resolve, 5 * 1000));
|
1299
|
+
return callback(null, api);
|
1300
|
+
}
|
1301
|
+
});
|
1302
|
+
})
|
1303
|
+
.catch(function (e) {
|
1304
|
+
log.error("login", e.error || e);
|
1305
|
+
callback(e);
|
1306
|
+
});
|
1048
1307
|
}
|
1049
1308
|
|
1309
|
+
|
1310
|
+
function saveAppState(encryptedAppState, callback) {
|
1311
|
+
const appStatePath = './appstate.json';
|
1312
|
+
fs.writeFile(appStatePath, encryptedAppState, 'utf8', (err) => {
|
1313
|
+
if (err) {
|
1314
|
+
console.error("Error saving AppState:", err.message);
|
1315
|
+
callback(err);
|
1316
|
+
} else {
|
1317
|
+
console.log("AppState saved successfully to:", appStatePath);
|
1318
|
+
callback(null);
|
1319
|
+
}
|
1320
|
+
});
|
1321
|
+
}
|
1322
|
+
|
1323
|
+
|
1050
1324
|
function login(loginData, options, callback) {
|
1051
1325
|
if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
|
1052
1326
|
callback = options;
|
@@ -1077,11 +1351,11 @@ function login(loginData, options, callback) {
|
|
1077
1351
|
if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
|
1078
1352
|
var rejectFunc = null;
|
1079
1353
|
var resolveFunc = null;
|
1080
|
-
var returnPromise = new Promise(function(resolve, reject) {
|
1354
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
1081
1355
|
resolveFunc = resolve;
|
1082
1356
|
rejectFunc = reject;
|
1083
1357
|
});
|
1084
|
-
prCallback = function(error, api) {
|
1358
|
+
prCallback = function (error, api) {
|
1085
1359
|
if (error) return rejectFunc(error);
|
1086
1360
|
return resolveFunc(api);
|
1087
1361
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "node-ainzfb-new",
|
3
|
-
"version": "1.7.10-
|
3
|
+
"version": "1.7.10-24ejweqr",
|
4
4
|
"description": "A Facebook chat API that doesn't rely on XMPP. Will NOT be deprecated after April 30th 2015.",
|
5
5
|
"scripts": {
|
6
6
|
"test": "mocha",
|
@@ -35,12 +35,12 @@
|
|
35
35
|
"https-proxy-agent": "latest",
|
36
36
|
"is-hexcolor": "^1.0.0",
|
37
37
|
"lodash": "",
|
38
|
-
"mqtt": "^4.3.
|
38
|
+
"mqtt": "^4.3.8",
|
39
39
|
"node-superfetch": "^0.2.3",
|
40
40
|
"npmlog": "latest",
|
41
41
|
"path": "latest",
|
42
|
-
"pretty-ms": "latest",
|
43
42
|
"pm2": "^5.3.0",
|
43
|
+
"pretty-ms": "^7.0.1",
|
44
44
|
"request": "latest",
|
45
45
|
"semver": "latest",
|
46
46
|
"sus-support": "git+https://github.com/amogusdevlol/sus-support.git",
|
@@ -0,0 +1,58 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const { generateOfflineThreadingID, getCurrentTimestamp } = require('../utils');
|
4
|
+
|
5
|
+
function isCallable(func) {
|
6
|
+
try {
|
7
|
+
Reflect.apply(func, null, []);
|
8
|
+
return true;
|
9
|
+
} catch (error) {
|
10
|
+
return false;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
15
|
+
return function pinMessage(pinMode, messageID, threadID, callback) {
|
16
|
+
if (!ctx.mqttClient) {
|
17
|
+
throw new Error('Not connected to MQTT');
|
18
|
+
}
|
19
|
+
|
20
|
+
ctx.wsReqNumber += 1;
|
21
|
+
ctx.wsTaskNumber += 1;
|
22
|
+
|
23
|
+
const taskLabel = pinMode ? '430' : '431';
|
24
|
+
const queueNamePrefix = pinMode ? 'pin_msg_v2_' : 'unpin_msg_v2_';
|
25
|
+
|
26
|
+
const taskPayload = {
|
27
|
+
thread_key: threadID,
|
28
|
+
message_id: messageID,
|
29
|
+
timestamp_ms: getCurrentTimestamp(),
|
30
|
+
};
|
31
|
+
|
32
|
+
const task = {
|
33
|
+
failure_count: null,
|
34
|
+
label: taskLabel,
|
35
|
+
payload: JSON.stringify(taskPayload),
|
36
|
+
queue_name: `${queueNamePrefix}${threadID}`,
|
37
|
+
task_id: ctx.wsTaskNumber,
|
38
|
+
};
|
39
|
+
|
40
|
+
const content = {
|
41
|
+
app_id: '2220391788200892',
|
42
|
+
payload: JSON.stringify({
|
43
|
+
data_trace_id: null,
|
44
|
+
epoch_id: parseInt(generateOfflineThreadingID()),
|
45
|
+
tasks: [task],
|
46
|
+
version_id: '25095469420099952',
|
47
|
+
}),
|
48
|
+
request_id: ctx.wsReqNumber,
|
49
|
+
type: 3,
|
50
|
+
};
|
51
|
+
|
52
|
+
if (isCallable(callback)) {
|
53
|
+
// to be implemented
|
54
|
+
}
|
55
|
+
|
56
|
+
ctx.mqttClient.publish('/ls_req', JSON.stringify(content), { qos: 1, retain: false });
|
57
|
+
};
|
58
|
+
};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
|
6
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
7
|
+
return async function shareContact(text, senderID, threadID, mentionID, userID, leaverID, callback) {
|
8
|
+
var resolveFunc = function () { };
|
9
|
+
var rejectFunc = function () { };
|
10
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
11
|
+
resolveFunc = resolve;
|
12
|
+
rejectFunc = reject;
|
13
|
+
});
|
14
|
+
if (!callback) {
|
15
|
+
callback = function (err, data) {
|
16
|
+
if (err) return rejectFunc(err);
|
17
|
+
resolveFunc(data);
|
18
|
+
};
|
19
|
+
}
|
20
|
+
let count_req = 0;
|
21
|
+
var form = JSON.stringify({
|
22
|
+
"app_id": "2220391788200892",
|
23
|
+
"payload": JSON.stringify({
|
24
|
+
tasks: [{
|
25
|
+
label: '359',
|
26
|
+
payload: JSON.stringify({
|
27
|
+
"contact_id": senderID,
|
28
|
+
"sync_group": 1,
|
29
|
+
"text": text || "",
|
30
|
+
"thread_id": threadID
|
31
|
+
}),
|
32
|
+
queue_name: 'messenger_contact_sharing',
|
33
|
+
task_id: Math.random() * 1001 << 0,
|
34
|
+
failure_count: null,
|
35
|
+
}],
|
36
|
+
epoch_id: utils.generateOfflineThreadingID(),
|
37
|
+
version_id: '7214102258676893',
|
38
|
+
}),
|
39
|
+
"request_id": ++count_req,
|
40
|
+
"type": 3
|
41
|
+
});
|
42
|
+
ctx.mqttClient.publish('/ls_req', form);
|
43
|
+
|
44
|
+
return returnPromise;
|
45
|
+
};
|
46
|
+
};
|
package/src/shareLink.js
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
|
6
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
7
|
+
return async function shareLink(text, url, threadID, callback) {
|
8
|
+
var resolveFunc = function () { };
|
9
|
+
var rejectFunc = function () { };
|
10
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
11
|
+
resolveFunc = resolve;
|
12
|
+
rejectFunc = reject;
|
13
|
+
});
|
14
|
+
if (!callback) {
|
15
|
+
callback = function (err, data) {
|
16
|
+
if (err) return rejectFunc(err);
|
17
|
+
resolveFunc(data);
|
18
|
+
};
|
19
|
+
}
|
20
|
+
ctx.mqttClient.publish('/ls_req',
|
21
|
+
JSON.stringify({
|
22
|
+
"app_id": "2220391788200892",
|
23
|
+
"payload": JSON.stringify({
|
24
|
+
tasks: [{
|
25
|
+
label: 46,
|
26
|
+
payload: JSON.stringify({
|
27
|
+
"otid": utils.generateOfflineThreadingID(),
|
28
|
+
"source": 524289,
|
29
|
+
"sync_group": 1,
|
30
|
+
"send_type": 6,
|
31
|
+
"mark_thread_read": 0,
|
32
|
+
"url": url || "",
|
33
|
+
"text": text || "",
|
34
|
+
"thread_id": threadID,
|
35
|
+
"initiating_source": 0
|
36
|
+
}),
|
37
|
+
queue_name: threadID,
|
38
|
+
task_id: Math.random() * 1001 << 0,
|
39
|
+
failure_count: null,
|
40
|
+
}],
|
41
|
+
epoch_id: utils.generateOfflineThreadingID(),
|
42
|
+
version_id: '7191105584331330',
|
43
|
+
}),
|
44
|
+
"request_id": ++ctx.req_ID,
|
45
|
+
"type": 3
|
46
|
+
}),
|
47
|
+
{
|
48
|
+
qos: 1,
|
49
|
+
retain: false,
|
50
|
+
}
|
51
|
+
)
|
52
|
+
return returnPromise;
|
53
|
+
};
|
54
|
+
};
|
package/utils.js
CHANGED
@@ -150,6 +150,12 @@ function generateThreadingID(clientID) {
|
|
150
150
|
return "<" + k + ":" + l + "-" + m + "@mail.projektitan.com>";
|
151
151
|
}
|
152
152
|
|
153
|
+
function getCurrentTimestamp() {
|
154
|
+
const date = new Date();
|
155
|
+
const unixTime = date.getTime();
|
156
|
+
return unixTime;
|
157
|
+
}
|
158
|
+
|
153
159
|
function binaryToDecimal(data) {
|
154
160
|
var ret = "";
|
155
161
|
while (data !== "0") {
|
@@ -1320,8 +1326,8 @@ function decodeClientPayload(payload) {
|
|
1320
1326
|
}
|
1321
1327
|
|
1322
1328
|
|
1323
|
-
|
1324
1329
|
/*function getAppState(jar) {
|
1330
|
+
var StateCrypt = require('./StateCrypt');
|
1325
1331
|
try {
|
1326
1332
|
var appstate = jar.getCookies("https://www.facebook.com").concat(jar.getCookies("https://facebook.com")).concat(jar.getCookies("https://www.messenger.com"));
|
1327
1333
|
|
@@ -1350,11 +1356,22 @@ function getAppState(jar) {
|
|
1350
1356
|
var StateCrypt = require('./StateCrypt');
|
1351
1357
|
var logger = require('./logger');
|
1352
1358
|
logger('Encrypted Appstate Successfully!', '[ FCA-SUS ]');
|
1353
|
-
|
1359
|
+
|
1360
|
+
let processDuration = 0;
|
1361
|
+
if (process.env.startTime) {
|
1362
|
+
processDuration = Date.now() - parseInt(process.env.startTime);
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
if (isFinite(processDuration)) {
|
1366
|
+
logger(`Process Done: ${prettyMilliseconds(processDuration)}`, '[ FCA-SUS ]');
|
1367
|
+
} else {
|
1368
|
+
logger(`Process Done: Unable to calculate duration`, '[ FCA-SUS ]');
|
1369
|
+
}
|
1370
|
+
|
1354
1371
|
if (process.env['FBKEY']) {
|
1355
|
-
return StateCrypt.encryptState(JSON.stringify(appstate),process.env['FBKEY']);
|
1372
|
+
return StateCrypt.encryptState(JSON.stringify(appstate), process.env['FBKEY']);
|
1356
1373
|
}
|
1357
|
-
|
1374
|
+
else return appstate;
|
1358
1375
|
}
|
1359
1376
|
|
1360
1377
|
module.exports = {
|
@@ -1395,5 +1412,6 @@ module.exports = {
|
|
1395
1412
|
decodeClientPayload,
|
1396
1413
|
getAppState,
|
1397
1414
|
getAdminTextMessageType,
|
1398
|
-
setProxy
|
1415
|
+
setProxy,
|
1416
|
+
getCurrentTimestamp
|
1399
1417
|
};
|