Echo-AI-official's picture
Upload 280 files
0e759d2 verified
import { configDotenv } from "dotenv";
import crypto from "crypto";
import { parse } from "tldts";
configDotenv();
const hashKey = Buffer.from(process.env.HASH_KEY || "", "utf-8");
const algorithm = "aes-256-ecb";
export function encryptAES(plaintext: string, key: Buffer): string {
const cipher = crypto.createCipheriv(algorithm, key, null);
const encrypted = Buffer.concat([
cipher.update(plaintext, "utf-8"),
cipher.final(),
]);
return encrypted.toString("base64");
}
export function decryptAES(ciphertext: string, key: Buffer): string {
const decipher = crypto.createDecipheriv(algorithm, key, null);
const decrypted = Buffer.concat([
decipher.update(Buffer.from(ciphertext, "base64")),
decipher.final(),
]);
return decrypted.toString("utf-8");
}
const urlBlocklist = [
"h8ngAFXUNLO3ZqQufJjGVA==",
"fEGiDm/TWDBkXUXejFVICg==",
"l6Mei7IGbEmTTFoSudUnqQ==",
"4OjallJzXRiZUAWDiC2Xww==",
"ReSvkSfx34TNEdecmmSDdQ==",
"X1E4WtdmXAv3SAX9xN925Q==",
"VTzBQfMtXZzM05mnNkWkjA==",
"m/q4Lb2Z8cxwU7/CoztOFg==",
"UbVnmRaeG+gKcyVDLAm0vg==",
"xNQhczYG22tTVc6lYE3qwg==",
"CQfGDydbg4l1swRCru6O6Q==",
"l86LQxm2NonTWMauXwEsPw==",
"6v4QDUcwjnID80G+uU+tgw==",
"pCF/6nrKZAxaYntzEGluZQ==",
"r0CRhAmQqSe7V2s3073T00sAh4WcS5779jwuGJ26ows==",
"aBOVqRFBM4UVg33usY10NdiF0HCnFH/ImtD0n+zIpc8==",
"QV436UZuQ6D0Dqrx9MwaGw==",
"OYVvrwILYbzA2mSSqOPPpw==",
"xW2i4C0Dzcnp+qu12u0SAw==",
"OLHba209l0dfl0MI4EnQonBITK9z8Qwgd/NsuaTkXmA=",
"X0VynmNjpL3PrYxpUIG7sFMBt8OlrmQWtxj8oXVu2QM=",
"ObdlM5NEkvBJ/sojRW5K/Q==",
"C8Th38X0SjsE1vL/OsD8bA==",
"PTbGg8PK/h0Seyw4HEpK4Q==",
"lZdQMknjHb7+4+sjF3qNTw==",
"LsgSq54q5oDysbva29JxnQ==",
"KZfBtpwjOpdSoqacRbz7og==",
"Indtl4yxJMHCKBGF4KABCQ==",
"e3HFXLVgxhaVoadYpwb2BA==",
"b+asgLayXQ5Jq+se+q56jA==",
"86ZDUI7vmp4MvNq3fvZrGQ==",
"sEGFoYZ6GEg4Zocd+TiyfQ==",
"6OOL72eXthgnJ1Hj4PfOQQ==",
"g/ME+Sh1CAFboKrwkVb+5Q==",
"Pw+xawUoX8xBYbX2yqqGWQ==",
"k6vBalxYFhAvkPsF19t9gQ==",
"b+asgLayXQ5Jq+se+q56jA==",
"KKttwRz4w+AMJrZcB828WQ==",
"vMdzZ33BXoyWVZnAPOBcrg==",
"l8GDVI8w/ueHnNzdN1ODuQ==",
"+yz9bnYYMnC0trJZGJwf6Q==",
"oTdhIjEjqdT2pEvyxD1Ssg==",
]
const allowedKeywords = [
"pulse",
"privacy",
"terms",
"policy",
"user-agreement",
"legal",
"help",
"policies",
"support",
"contact",
"about",
"careers",
"blog",
"press",
"conditions",
"tos",
"://library.tiktok.com",
"://ads.tiktok.com",
"://tiktok.com/business",
"://developers.facebook.com",
"://facebook.com/ads/library",
"://www.facebook.com/ads/library",
];
export function decryptedBlocklist(list: string[]): string[] {
return hashKey.length > 0
? list.map((ciphertext) => decryptAES(ciphertext, hashKey))
: [];
}
export function isUrlBlocked(url: string): boolean {
const lowerCaseUrl = url.trim().toLowerCase();
const blockedlist = decryptedBlocklist(urlBlocklist);
const decryptedUrl =
blockedlist.find((decrypted) => lowerCaseUrl === decrypted) ||
lowerCaseUrl;
// If the URL is empty or invalid, return false
let parsedUrl: any;
try {
parsedUrl = parse(decryptedUrl);
} catch {
console.log("Error parsing URL:", url);
return false;
}
const domain = parsedUrl.domain;
const publicSuffix = parsedUrl.publicSuffix;
if (!domain) {
return false;
}
// Check if URL contains any allowed keyword
if (
allowedKeywords.some((keyword) =>
lowerCaseUrl.includes(keyword.toLowerCase()),
)
) {
return false;
}
// Block exact matches
if (blockedlist.includes(domain)) {
return true;
}
// Block subdomains
if (blockedlist.some((blocked) => domain.endsWith(`.${blocked}`))) {
return true;
}
// Block different TLDs of the same base domain
const baseDomain = domain.split(".")[0]; // Extract the base domain (e.g., "facebook" from "facebook.com")
if (
publicSuffix &&
blockedlist.some(
(blocked) => blocked.startsWith(baseDomain + ".") && blocked !== domain,
)
) {
return true;
}
return false;
}