12cf / index.js
Arrgcw6's picture
Update index.js
ca7264e verified
const express = require('express');
const cors = require('cors');
const { connect } = require("puppeteer-real-browser");
const app = express();
app.use(cors());
app.use(express.json());
const PORT = process.env.PORT || 7860;
const MAX_CONCURRENT_BROWSERS = 2; // Limit 2 Browser agar RAM aman
let activeBrowsers = 0;
async function createBrowser(proxy = null) {
const options = {
headless: false, // Wajib false
turnstile: true, // Auto-click turnstile bawaan library
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--disable-gpu',
'--window-size=1920,1080',
'--disable-blink-features=AutomationControlled'
],
executablePath: process.env.CHROME_PATH || "/usr/bin/google-chrome-stable",
customConfig: {},
connectOption: { defaultViewport: null }
};
if (proxy) {
options.args.push(`--proxy-server=${proxy.hostname}:${proxy.port}`);
}
const { browser, page } = await connect(options);
if (proxy && proxy.username && proxy.password) {
await page.authenticate({ username: proxy.username, password: proxy.password });
}
return { browser, page };
}
async function handleTurnstile(page, url, siteKey) {
return new Promise(async (resolve, reject) => {
// PERBAIKAN 1: Timeout diperpanjang jadi 120 detik (2 menit)
const timeout = setTimeout(() => {
reject(new Error("Timeout Turnstile (120s limit reached)"));
}, 120000);
try {
console.log(`[Turnstile] Preparing Injection for ${url}`);
// Template HTML minimalis untuk memancing Turnstile keluar
const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Turnstile Solver</title>
</head>
<body>
<div class="cf-turnstile" data-sitekey="${siteKey}" data-callback="turnstileCallback"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script>
console.log("Widget rendered...");
function turnstileCallback(token) {
console.log("Token received in browser!");
window.cf_token = token;
}
</script>
</body>
</html>`;
// Intercept request ke URL target dan ganti isinya dengan HTML di atas
await page.setRequestInterception(true);
page.once('request', request => {
request.respond({
status: 200,
contentType: 'text/html',
body: htmlContent
});
});
// Handle request lain (gambar/css) agar tidak error
page.on('request', req => {
if (req.isInterceptResolutionHandled()) return;
req.continue();
});
// Buka URL (ini akan memicu intercept di atas)
console.log(`[Turnstile] Navigating...`);
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60000 });
// Polling Token
const checkToken = setInterval(async () => {
try {
const token = await page.evaluate(() => window.cf_token);
if (token) {
clearInterval(checkToken);
clearTimeout(timeout);
console.log(`[Turnstile] Token found: ${token.substring(0, 15)}...`);
resolve({ token: token });
}
} catch (e) {}
}, 1000);
} catch (e) {
clearTimeout(timeout);
reject(e);
}
});
}
app.post('/bypass', async (req, res) => {
const { url, mode, siteKey, proxy } = req.body;
if (!url || !mode) return res.status(400).json({ status: "error", message: "Missing url or mode" });
if (activeBrowsers >= MAX_CONCURRENT_BROWSERS) {
return res.status(429).json({ status: "busy", message: "Server busy, try again in a few seconds" });
}
activeBrowsers++;
let browserInstance = null;
try {
console.log(`[REQ] Processing: ${url} | Mode: ${mode}`);
const { browser, page } = await createBrowser(proxy);
browserInstance = browser;
let result;
if (mode === 'turnstile') {
result = await handleTurnstile(page, url, siteKey);
} else {
throw new Error("Invalid mode (only turnstile supported in this version)");
}
console.log(`[SUCCESS] Operation completed.`);
res.json({ status: "success", ...result });
} catch (error) {
console.error(`[ERROR] ${error.message}`);
res.status(500).json({ status: "error", message: error.message });
} finally {
if (browserInstance) {
try { await browserInstance.close(); } catch {}
}
activeBrowsers--;
}
});
app.get('/', (req, res) => res.send("Turnstile Solver Ready (v3 - 120s Timeout)"));
app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));