node-ainzfb-new 1.7.10-tDs19uqa → 1.7.11
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 +203 -154
- package/package.json +4 -4
- 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,14 +19,13 @@ 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'),
|
28
|
+
{ execSync } = require('child_process'),
|
30
29
|
Client = require("@replit/database"),
|
31
30
|
languageFile = require('./Language/index.json'),
|
32
31
|
ObjFastConfig = {
|
@@ -90,7 +89,7 @@ var checkVerified = null;
|
|
90
89
|
/!-[ Function setOptions ]-!/
|
91
90
|
|
92
91
|
function setOptions(globalOptions, options) {
|
93
|
-
Object.keys(options).map(function(key) {
|
92
|
+
Object.keys(options).map(function (key) {
|
94
93
|
switch (key) {
|
95
94
|
case 'pauseLog':
|
96
95
|
if (options.pauseLog) log.pause();
|
@@ -158,7 +157,7 @@ function setOptions(globalOptions, options) {
|
|
158
157
|
/!-[ Function BuildAPI ]-!/
|
159
158
|
|
160
159
|
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"; });
|
160
|
+
var maybeCookie = jar.getCookies("https://www.facebook.com").filter(function (val) { return val.cookieString().split("=")[0] === "c_user"; });
|
162
161
|
|
163
162
|
if (maybeCookie.length === 0) throw { error: Language.ErrAppState };
|
164
163
|
|
@@ -222,7 +221,7 @@ async function buildAPI(globalOptions, html, jar) {
|
|
222
221
|
syncToken: undefined,
|
223
222
|
mqttEndpoint,
|
224
223
|
region,
|
225
|
-
firstListen: true
|
224
|
+
firstListen: true,
|
226
225
|
wsReqNumber: 0,
|
227
226
|
wsTaskNumber: 0
|
228
227
|
};
|
@@ -246,7 +245,7 @@ async function buildAPI(globalOptions, html, jar) {
|
|
246
245
|
}
|
247
246
|
|
248
247
|
function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
249
|
-
return function(res) {
|
248
|
+
return function (res) {
|
250
249
|
var html = res.body;
|
251
250
|
var $ = cheerio.load(html);
|
252
251
|
var arr = [];
|
@@ -254,7 +253,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
254
253
|
// This will be empty, but just to be sure we leave it
|
255
254
|
$("#login_form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
|
256
255
|
|
257
|
-
arr = arr.filter(function(v) {
|
256
|
+
arr = arr.filter(function (v) {
|
258
257
|
return v.val && v.val.length;
|
259
258
|
});
|
260
259
|
|
@@ -280,7 +279,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
280
279
|
//
|
281
280
|
// ---------- Very Hacky Part Starts -----------------
|
282
281
|
var willBeCookies = html.split("\"_js_");
|
283
|
-
willBeCookies.slice(1).map(function(val) {
|
282
|
+
willBeCookies.slice(1).map(function (val) {
|
284
283
|
var cookieData = JSON.parse("[\"" + utils.getFrom(val, "", "]") + "]");
|
285
284
|
jar.setCookie(utils.formatCookie(cookieData, "facebook"), "https://www.facebook.com");
|
286
285
|
});
|
@@ -290,7 +289,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
290
289
|
return utils
|
291
290
|
.post("https://www.facebook.com/login/device-based/regular/login/?login_attempt=1&lwv=110", jar, form, loginOptions)
|
292
291
|
.then(utils.saveCookies(jar))
|
293
|
-
.then(function(res) {
|
292
|
+
.then(function (res) {
|
294
293
|
var headers = res.headers;
|
295
294
|
if (!headers.location) throw { error: Language.InvaildAccount };
|
296
295
|
|
@@ -302,21 +301,21 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
302
301
|
return utils
|
303
302
|
.get(headers.location, jar, null, loginOptions)
|
304
303
|
.then(utils.saveCookies(jar))
|
305
|
-
.then(function(res) {
|
304
|
+
.then(function (res) {
|
306
305
|
var html = res.body;
|
307
306
|
// Make the form in advance which will contain the fb_dtsg and nh
|
308
307
|
var $ = cheerio.load(html);
|
309
308
|
var arr = [];
|
310
309
|
$("form input").map((i, v) => arr.push({ val: $(v).val(), name: $(v).attr("name") }));
|
311
310
|
|
312
|
-
arr = arr.filter(function(v) {
|
311
|
+
arr = arr.filter(function (v) {
|
313
312
|
return v.val && v.val.length;
|
314
313
|
});
|
315
314
|
|
316
315
|
var form = utils.arrToForm(arr);
|
317
316
|
if (html.indexOf("checkpoint/?next") > -1) {
|
318
317
|
setTimeout(() => {
|
319
|
-
checkVerified = setInterval((_form) => {}, 5000, {
|
318
|
+
checkVerified = setInterval((_form) => { }, 5000, {
|
320
319
|
fb_dtsg: form.fb_dtsg,
|
321
320
|
jazoest: form.jazoest,
|
322
321
|
dpr: 1
|
@@ -329,7 +328,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
329
328
|
form['submit[Continue]'] = $("#checkpointSubmitButton").html(); //'Continue';
|
330
329
|
var prResolve = null;
|
331
330
|
var prReject = null;
|
332
|
-
var rtPromise = new Promise(function(resolve, reject) {
|
331
|
+
var rtPromise = new Promise(function (resolve, reject) {
|
333
332
|
prResolve = resolve;
|
334
333
|
prReject = reject;
|
335
334
|
});
|
@@ -337,7 +336,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
337
336
|
utils
|
338
337
|
.post(nextURL, jar, form, loginOptions)
|
339
338
|
.then(utils.saveCookies(jar))
|
340
|
-
.then(function(res) {
|
339
|
+
.then(function (res) {
|
341
340
|
var $ = cheerio.load(res.body);
|
342
341
|
var error = $("#approvals_code").parent().attr("data-xui-error");
|
343
342
|
if (error) {
|
@@ -349,7 +348,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
349
348
|
};
|
350
349
|
}
|
351
350
|
})
|
352
|
-
.then(function() {
|
351
|
+
.then(function () {
|
353
352
|
// Use the same form (safe I hope)
|
354
353
|
delete form.no_fido;
|
355
354
|
delete form.approvals_code;
|
@@ -357,14 +356,14 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
357
356
|
|
358
357
|
return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
|
359
358
|
})
|
360
|
-
.then(function(res) {
|
359
|
+
.then(function (res) {
|
361
360
|
var headers = res.headers;
|
362
361
|
if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: Language.ApprovalsErr };
|
363
362
|
|
364
363
|
var appState = utils.getAppState(jar);
|
365
364
|
|
366
365
|
if (callback === prCallback) {
|
367
|
-
callback = function(err, api) {
|
366
|
+
callback = function (err, api) {
|
368
367
|
if (err) return prReject(err);
|
369
368
|
return prResolve(api);
|
370
369
|
};
|
@@ -374,7 +373,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
374
373
|
// and will then complete the login process
|
375
374
|
return loginHelper(appState, email, password, loginOptions, callback);
|
376
375
|
})
|
377
|
-
.catch(function(err) {
|
376
|
+
.catch(function (err) {
|
378
377
|
// Check if using Promise instead of callback
|
379
378
|
if (callback === prCallback) prReject(err);
|
380
379
|
else callback(err);
|
@@ -390,7 +389,7 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
390
389
|
clearInterval(checkVerified);
|
391
390
|
logger(Language.VerifiedCheck, "[ FCA-SUS ]");
|
392
391
|
if (callback === prCallback) {
|
393
|
-
callback = function(err, api) {
|
392
|
+
callback = function (err, api) {
|
394
393
|
if (err) return prReject(err);
|
395
394
|
return prResolve(api);
|
396
395
|
};
|
@@ -416,13 +415,13 @@ function makeLogin(jar, email, password, loginOptions, callback, prCallback) {
|
|
416
415
|
return utils
|
417
416
|
.post(nextURL, jar, form, loginOptions)
|
418
417
|
.then(utils.saveCookies(jar))
|
419
|
-
.then(function() {
|
418
|
+
.then(function () {
|
420
419
|
// Use the same form (safe I hope)
|
421
420
|
form.name_action_selected = 'save_device';
|
422
421
|
|
423
422
|
return utils.post(nextURL, jar, form, loginOptions).then(utils.saveCookies(jar));
|
424
423
|
})
|
425
|
-
.then(function(res) {
|
424
|
+
.then(function (res) {
|
426
425
|
var headers = res.headers;
|
427
426
|
|
428
427
|
if (!headers.location && res.body.indexOf('Review Recent Login') > -1) throw { error: "Something went wrong with review recent login." };
|
@@ -459,80 +458,74 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
459
458
|
var mainPromise = null;
|
460
459
|
var jar = utils.getJar();
|
461
460
|
|
461
|
+
const envPath = process.cwd() + '/.env';
|
462
|
+
|
463
|
+
const loadDotenv = async () => {
|
464
|
+
try {
|
465
|
+
// Check if dotenv is already installed
|
466
|
+
let dotenv;
|
467
|
+
try {
|
468
|
+
dotenv = require('dotenv');
|
469
|
+
} catch (err) {
|
470
|
+
if (err.code === 'MODULE_NOT_FOUND') {
|
471
|
+
console.log('.env file does not exist. Installing dotenv...');
|
472
|
+
execSync('npm install dotenv'); // Install dotenv if missing
|
473
|
+
dotenv = require('dotenv'); // Require dotenv after installation
|
474
|
+
} else {
|
475
|
+
throw err; // Re-throw other errors
|
476
|
+
}
|
477
|
+
}
|
478
|
+
|
479
|
+
// Load the .env file if it exists
|
480
|
+
if (fs.existsSync(envPath)) {
|
481
|
+
dotenv.config({ path: envPath });
|
482
|
+
}
|
483
|
+
} catch (error) {
|
484
|
+
//console.error('Error loading dotenv or installing:', error);
|
485
|
+
}
|
486
|
+
};
|
487
|
+
|
488
|
+
await loadDotenv(); // Ensure dotenv is loaded before proceeding
|
489
|
+
|
490
|
+
const setEnvVariable = (key, value) => {
|
491
|
+
try {
|
492
|
+
if (process.env[key]) {
|
493
|
+
return true; // Variable already exists, no need to set it
|
494
|
+
}
|
495
|
+
|
496
|
+
let envContent = '';
|
497
|
+
if (fs.existsSync(envPath)) {
|
498
|
+
envContent = fs.readFileSync(envPath, 'utf8');
|
499
|
+
|
500
|
+
const envLines = envContent.split('\n');
|
501
|
+
for (const line of envLines) {
|
502
|
+
if (line.startsWith(`${key}=`)) {
|
503
|
+
process.env[key] = line.split('=')[1];
|
504
|
+
return true;
|
505
|
+
}
|
506
|
+
}
|
507
|
+
|
508
|
+
envContent += `\n${key}=${value}`;
|
509
|
+
} else {
|
510
|
+
envContent = `${key}=${value}`;
|
511
|
+
}
|
512
|
+
|
513
|
+
fs.writeFileSync(envPath, envContent);
|
514
|
+
process.env[key] = value;
|
515
|
+
|
516
|
+
return true;
|
517
|
+
} catch (error) {
|
518
|
+
console.error('Error setting environment variable:', error);
|
519
|
+
return false;
|
520
|
+
}
|
521
|
+
};
|
522
|
+
|
462
523
|
// If we're given an appState we loop through it and save each cookie
|
463
524
|
// back into the jar.
|
464
525
|
try {
|
465
526
|
if (appState) {
|
466
|
-
//const readline = require("readline");
|
467
|
-
//const chalk = require("chalk");
|
468
|
-
//const figlet = require("figlet");
|
469
|
-
//const os = require("os");
|
470
|
-
//const { execSync } = require('child_process');
|
471
|
-
// let rl = readline.createInterface({
|
472
|
-
// input: process.stdin,
|
473
|
-
// output: process.stdout,
|
474
|
-
// prompt: chalk.hex('#00CCCC').bold('[FCA-SUS] • ')
|
475
|
-
// });
|
476
|
-
// let type = {
|
477
|
-
// 1: {
|
478
|
-
// "name": "Tạo Mật Khẩu Cho Appstate",
|
479
|
-
// onRun: async function() {
|
480
|
-
// try {
|
481
|
-
// rl.question("Hãy Nhập Mật Khẩu Bạn Muốn Đặt Cho Appstate !", (answer) => {
|
482
|
-
// console.log("Được Rồi Mật Khẩu Của Bạn Là: " + answer + ", Bạn Hãy Nhớ Kĩ Nhé !");
|
483
|
-
// process.env["FBKEY"] = answer;
|
484
|
-
// fs.writeFile('../.env', `FBKEY=${answer}`, function (err) {
|
485
|
-
// if (err) {
|
486
|
-
// submiterr(err)
|
487
|
-
// logger("Tạo File ENV Thất Bại !", "[ FCA-SUS ]")
|
488
|
-
// rl.pause();
|
489
|
-
// }
|
490
|
-
// else logger("Tạo Thành Công File ENV !","[ FCA-SUS ]")
|
491
|
-
// rl.pause();
|
492
|
-
// });
|
493
|
-
// })
|
494
|
-
// }
|
495
|
-
// catch (e) {
|
496
|
-
// console.log(e);
|
497
|
-
// logger("Đã Có Lỗi Khi Đang Try Tạo Ra Câu Hỏi =))", "[ FCA-SUS ]");
|
498
|
-
// rl.pause();
|
499
|
-
// }
|
500
|
-
// }
|
501
|
-
// },
|
502
|
-
// 2: {
|
503
|
-
// "name": "Tiếp Tục Chạy Fca Mà Không Cần Mã Hóa AppState",
|
504
|
-
// onRun: async function () {
|
505
|
-
// rl.pause();
|
506
|
-
// }
|
507
|
-
// },
|
508
|
-
// 3: {
|
509
|
-
// "name": "Đổi Mật Khẩu AppState (Comming Soon..)",
|
510
|
-
// onRun: async function () {
|
511
|
-
// console.log(chalk.red.bold("Đã bảo là comming soon rồi mà >:v"));
|
512
|
-
// }
|
513
|
-
// }
|
514
|
-
// }
|
515
|
-
// const localbrand = JSON.parse(readFileSync('./package.json')).name;
|
516
|
-
// const localbrand2 = JSON.parse(readFileSync('./node_modules/fca-sus/package.json')).version;
|
517
|
-
// var axios = require('axios');
|
518
|
-
// axios.get('https://raw.githubusercontent.com/amogusdevlol/fca-sus/main/package.json').then(async (res) => {
|
519
|
-
// if (localbrand.toUpperCase() == 'HORIZON') {
|
520
|
-
// console.group(chalk.bold.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'))
|
521
|
-
// console.log(chalk.bold.hex('#00FFCC')("[</>]") + chalk.bold.yellow(' => ') + "Hệ Điều Hành: " + chalk.bold.red(os.type()));
|
522
|
-
// console.log(chalk.bold.hex('#00FFCC')("[</>]") + chalk.bold.yellow(' => ') + "Thông Tin Máy: " + chalk.bold.red(os.version()));
|
523
|
-
// console.log(chalk.bold.hex('#00FFCC')("[</>]") + chalk.bold.yellow(' => ') + "Phiên Bản Hiện Tại: " + chalk.bold.red(localbrand2));
|
524
|
-
// console.log(chalk.bold.hex('#00FFCC')("[</>]") + chalk.bold.yellow(' => ') + "Phiên Bản Mới Nhất: " + chalk.bold.red(res.data.version));
|
525
|
-
// console.groupEnd();
|
526
|
-
// }
|
527
|
-
// else {
|
528
|
-
// console.clear();
|
529
|
-
// console.log(figlet.textSync('TeamHorizon', {font: 'ANSI Shadow',horizontalLayout: 'default',verticalLayout: 'default',width: 0,whitespaceBreak: true }))
|
530
|
-
// console.log(chalk.hex('#9966CC')(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`));
|
531
|
-
// }
|
532
|
-
// });
|
533
|
-
|
534
527
|
logger(Language.OnProcess, "[ FCA-SUS ]");
|
535
|
-
var backup = async(data) => {
|
528
|
+
var backup = async (data) => {
|
536
529
|
if (fs.existsSync('./appstate.json')) {
|
537
530
|
try {
|
538
531
|
fs.writeFileSync('./appstate.json', data);
|
@@ -563,76 +556,93 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
563
556
|
} else return logger.Error();
|
564
557
|
}
|
565
558
|
|
559
|
+
|
566
560
|
switch (process.platform) {
|
567
|
-
case "win32":
|
568
|
-
{
|
561
|
+
case "win32": {
|
562
|
+
try {
|
563
|
+
// Only fetch new key if one doesn't exist
|
564
|
+
if (!process.env['FBKEY']) {
|
565
|
+
const { body } = await Fetch('https://sampleapi.netlify.app/.netlify/functions/api/generate/key');
|
566
|
+
const key = JSON.parse(body).response.key;
|
567
|
+
if (!setEnvVariable('FBKEY', key)) {
|
568
|
+
throw new Error('Failed to set environment variable');
|
569
|
+
}
|
570
|
+
}
|
571
|
+
} catch (e) {
|
572
|
+
logger(Language.ErrGetPassWord);
|
573
|
+
logger.Error();
|
574
|
+
process.exit(1);
|
575
|
+
}
|
576
|
+
break;
|
577
|
+
}
|
578
|
+
case "linux": {
|
579
|
+
if (process.env["REPL_ID"] == undefined) {
|
569
580
|
try {
|
570
|
-
|
571
|
-
process.env['FBKEY']
|
581
|
+
// Only fetch new key if one doesn't exist
|
582
|
+
if (!process.env['FBKEY']) {
|
583
|
+
const { body } = await Fetch('https://sampleapi.netlify.app/.netlify/functions/api/generate/key');
|
584
|
+
const key = JSON.parse(body).response.key;
|
585
|
+
if (!setEnvVariable('FBKEY', key)) {
|
586
|
+
throw new Error('Failed to set environment variable');
|
587
|
+
}
|
588
|
+
}
|
572
589
|
} catch (e) {
|
573
|
-
logger(Language.ErrGetPassWord);
|
590
|
+
logger(Language.ErrGetPassWord, '[ FCA-SUS ]');
|
574
591
|
logger.Error();
|
575
592
|
process.exit(1);
|
576
593
|
}
|
577
|
-
}
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
process.env['FBKEY'] = JSON.parse(body).response.key;
|
586
|
-
} catch (e) {
|
587
|
-
logger(Language.ErrGetPassWord, '[ FCA-SUS ]');
|
588
|
-
logger.Error();
|
589
|
-
process.exit(1);
|
590
|
-
}
|
591
|
-
} else {
|
592
|
-
try {
|
593
|
-
const client = new Client();
|
594
|
-
let key = await client.get("FBKEY");
|
594
|
+
} else {
|
595
|
+
try {
|
596
|
+
const client = new Client();
|
597
|
+
// Check process.env first
|
598
|
+
let key = process.env['FBKEY'];
|
599
|
+
if (!key) {
|
600
|
+
// Then check client storage
|
601
|
+
key = await client.get("FBKEY");
|
595
602
|
if (!key) {
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
603
|
+
key = makeid(49);
|
604
|
+
await client.set("FBKEY", key);
|
605
|
+
}
|
606
|
+
if (!setEnvVariable('FBKEY', key)) {
|
607
|
+
throw new Error('Failed to set environment variable');
|
601
608
|
}
|
602
|
-
} catch (e) {
|
603
|
-
logger(Language.ErrGenerateKey, '[ FCA-SUS ]');
|
604
|
-
logger(e, '[ FCA-SUS ]');
|
605
|
-
logger.Error();
|
606
|
-
process.exit(0)
|
607
609
|
}
|
610
|
+
} catch (e) {
|
611
|
+
logger(Language.ErrGenerateKey, '[ FCA-SUS ]');
|
612
|
+
logger(e, '[ FCA-SUS ]');
|
613
|
+
logger.Error();
|
614
|
+
process.exit(0);
|
608
615
|
}
|
609
616
|
}
|
610
617
|
break;
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
618
|
+
}
|
619
|
+
case "android": {
|
620
|
+
try {
|
621
|
+
// Only fetch new key if one doesn't exist
|
622
|
+
if (!process.env['FBKEY']) {
|
623
|
+
const { body } = await Fetch('https://sampleapi.netlify.app/.netlify/functions/api/generate/key');
|
624
|
+
const key = JSON.parse(body).response.key;
|
625
|
+
if (!setEnvVariable('FBKEY', key)) {
|
626
|
+
throw new Error('Failed to set environment variable');
|
627
|
+
}
|
619
628
|
}
|
629
|
+
} catch (e) {
|
630
|
+
logger(Language.ErrGetPassWord, '[ FCA-SUS ]');
|
631
|
+
return logger.Error();
|
620
632
|
}
|
621
633
|
break;
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
634
|
+
}
|
635
|
+
default: {
|
636
|
+
logger(Language.UnsupportedDevice, '[ FCA-SUS ]');
|
637
|
+
logger.Error();
|
638
|
+
process.exit(0);
|
639
|
+
}
|
628
640
|
}
|
629
|
-
|
630
641
|
try {
|
631
642
|
switch (require("../../FastConfigFca.json").EncryptFeature) {
|
632
643
|
case true:
|
633
644
|
{
|
634
645
|
appState = JSON.parse(JSON.stringify(appState, null, "\t"));
|
635
|
-
//console.log(appState);
|
636
646
|
switch (utils.getType(appState)) {
|
637
647
|
case "Array":
|
638
648
|
{
|
@@ -729,9 +739,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
729
739
|
case "String":
|
730
740
|
{
|
731
741
|
logger(Language.EncryptStateOff, "[ FCA-SUS ]");
|
732
|
-
//console.log("hello")
|
733
742
|
try {
|
734
|
-
// appState = appState;
|
735
743
|
appState = StateCrypt.decryptState(appState, process.env['FBKEY']);
|
736
744
|
logger(Language.DecryptSuccess, '[ FCA-SUS ]');
|
737
745
|
} catch (e) {
|
@@ -827,7 +835,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
827
835
|
}
|
828
836
|
}
|
829
837
|
try {
|
830
|
-
appState.map(function(c) {
|
838
|
+
appState.map(function (c) {
|
831
839
|
var str = c.key + "=" + c.value + "; expires=" + c.expires + "; domain=" + c.domain + "; path=" + c.path + ";";
|
832
840
|
jar.setCookie(str, "http://" + c.domain);
|
833
841
|
});
|
@@ -951,7 +959,7 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
951
959
|
.get("https://www.facebook.com/", null, null, globalOptions, { noRef: true })
|
952
960
|
.then(utils.saveCookies(jar))
|
953
961
|
.then(makeLogin(jar, email, password, globalOptions, callback, prCallback))
|
954
|
-
.then(function() {
|
962
|
+
.then(function () {
|
955
963
|
return utils.get('https://www.facebook.com/', jar, null, globalOptions).then(utils.saveCookies(jar));
|
956
964
|
});
|
957
965
|
}
|
@@ -962,15 +970,54 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
962
970
|
var _defaultFuncs = null;
|
963
971
|
var api = null;
|
964
972
|
|
973
|
+
let redirect = [1, "https://m.facebook.com/"], bypass_region_err = false;
|
974
|
+
|
975
|
+
function CheckAndFixErr(res) {
|
976
|
+
let reg_antierr = /This browser is not supported/gs; // =))))))
|
977
|
+
if (reg_antierr.test(res.body)) {
|
978
|
+
const Data = JSON.stringify(res.body);
|
979
|
+
const Dt_Check = Data.split('2Fhome.php&gfid=')[1];
|
980
|
+
if (Dt_Check == undefined) return res
|
981
|
+
const fid = Dt_Check.split("\\\\")[0];//fix sau
|
982
|
+
if (Dt_Check == undefined || Dt_Check == "") return res
|
983
|
+
const final_fid = fid.split(`\\`)[0];
|
984
|
+
if (final_fid == undefined || final_fid == '') return res;
|
985
|
+
const redirectlink = redirect[1] + "a/preferences.php?basic_site_devices=m_basic&uri=" + encodeURIComponent("https://m.facebook.com/home.php") + "&gfid=" + final_fid;
|
986
|
+
bypass_region_err = true;
|
987
|
+
return utils.get(redirectlink, jar, null, globalOptions).then(utils.saveCookies(jar));
|
988
|
+
}
|
989
|
+
else return res
|
990
|
+
}
|
991
|
+
|
992
|
+
function Redirect(res) {
|
993
|
+
var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
|
994
|
+
redirect = reg.exec(res.body);
|
995
|
+
if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
|
996
|
+
return res;
|
997
|
+
}
|
998
|
+
|
965
999
|
mainPromise = mainPromise
|
966
|
-
.then(function(res) {
|
1000
|
+
.then(function (res) {
|
967
1001
|
// Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
|
968
1002
|
var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
|
969
1003
|
var redirect = reg.exec(res.body);
|
970
1004
|
if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
|
971
1005
|
return res;
|
972
1006
|
})
|
973
|
-
.then(
|
1007
|
+
.then(res => Redirect(res))
|
1008
|
+
.then(res => CheckAndFixErr(res))
|
1009
|
+
.then(function (res) {
|
1010
|
+
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
|
1011
|
+
if (!Regex_Via.test(res.body)) {
|
1012
|
+
//www.facebook.com
|
1013
|
+
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";
|
1014
|
+
return utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
|
1015
|
+
}
|
1016
|
+
else return res
|
1017
|
+
})
|
1018
|
+
.then(res => Redirect(res))
|
1019
|
+
.then(res => CheckAndFixErr(res))
|
1020
|
+
.then(async function (res) {
|
974
1021
|
var html = res.body;
|
975
1022
|
var stuff = await buildAPI(globalOptions, html, jar);
|
976
1023
|
ctx = stuff[0];
|
@@ -978,13 +1025,14 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
978
1025
|
api = stuff[2];
|
979
1026
|
return res;
|
980
1027
|
});
|
1028
|
+
|
981
1029
|
// given a pageID we log in as a page
|
982
1030
|
if (globalOptions.pageID) {
|
983
1031
|
mainPromise = mainPromise
|
984
|
-
.then(function() {
|
1032
|
+
.then(function () {
|
985
1033
|
return utils.get('https://www.facebook.com/' + ctx.globalOptions.pageID + '/messages/?section=messages&subsection=inbox', ctx.jar, null, globalOptions);
|
986
1034
|
})
|
987
|
-
.then(function(resData) {
|
1035
|
+
.then(function (resData) {
|
988
1036
|
var url = utils.getFrom(resData.body, 'window.location.replace("https:\\/\\/www.facebook.com\\', '");').split('\\').join('');
|
989
1037
|
url = url.substring(0, url.length - 1);
|
990
1038
|
return utils.get('https://www.facebook.com' + url, ctx.jar, null, globalOptions);
|
@@ -993,14 +1041,14 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
993
1041
|
|
994
1042
|
// At the end we call the callback or catch an exception
|
995
1043
|
mainPromise
|
996
|
-
.then(function() {
|
1044
|
+
.then(function () {
|
997
1045
|
logger(Language.DoneLogin, "[ FCA-SUS ]");
|
998
1046
|
logger(Language.AutoCheckUpdate, "[ FCA-SUS ]");
|
999
1047
|
//!---------- Auto Check, Update START -----------------!//
|
1000
1048
|
var Fetch = require('got');
|
1001
1049
|
var { readFileSync } = require('fs-extra');
|
1002
1050
|
const { execSync } = require('child_process');
|
1003
|
-
Fetch('https://raw.githubusercontent.com/amogusdevlol/node-ainzfb/main/package.json').then(async(res) => {
|
1051
|
+
Fetch('https://raw.githubusercontent.com/amogusdevlol/node-ainzfb/main/package.json').then(async (res) => {
|
1004
1052
|
const localbrand = JSON.parse(readFileSync('./node_modules/node-ainzfb-new/package.json')).version;
|
1005
1053
|
if (Number(localbrand.replace(/\./g, "")) < Number(JSON.parse(res.body.toString()).version.replace(/\./g, ""))) {
|
1006
1054
|
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 +1088,14 @@ async function loginHelper(appState, email, password, globalOptions, callback, p
|
|
1040
1088
|
callback(null, api);
|
1041
1089
|
}
|
1042
1090
|
});
|
1043
|
-
}).catch(function(e) {
|
1091
|
+
}).catch(function (e) {
|
1044
1092
|
log.error("login", e.error || e);
|
1045
1093
|
callback(e);
|
1046
1094
|
});
|
1047
1095
|
//!---------- Auto Check, Update END -----------------!//
|
1048
1096
|
}
|
1049
1097
|
|
1098
|
+
|
1050
1099
|
function login(loginData, options, callback) {
|
1051
1100
|
if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
|
1052
1101
|
callback = options;
|
@@ -1077,11 +1126,11 @@ function login(loginData, options, callback) {
|
|
1077
1126
|
if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
|
1078
1127
|
var rejectFunc = null;
|
1079
1128
|
var resolveFunc = null;
|
1080
|
-
var returnPromise = new Promise(function(resolve, reject) {
|
1129
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
1081
1130
|
resolveFunc = resolve;
|
1082
1131
|
rejectFunc = reject;
|
1083
1132
|
});
|
1084
|
-
prCallback = function(error, api) {
|
1133
|
+
prCallback = function (error, api) {
|
1085
1134
|
if (error) return rejectFunc(error);
|
1086
1135
|
return resolveFunc(api);
|
1087
1136
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "node-ainzfb-new",
|
3
|
-
"version": "1.7.
|
3
|
+
"version": "1.7.11",
|
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",
|
@@ -28,19 +28,19 @@
|
|
28
28
|
"better-sqlite3": "^7.6.2",
|
29
29
|
"bluebird": "^2.11.0",
|
30
30
|
"chalk": "^4.1.2",
|
31
|
-
"cheerio": "
|
31
|
+
"cheerio": "^0.20.0",
|
32
32
|
"crypto": "^1.0.1",
|
33
33
|
"gettext.js": "^1.1.1",
|
34
34
|
"got": "^11.8.3",
|
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
|
};
|