/** * API.js - Integrated with rektCaptcha Auto-Config & Docker Path * Powered by Forget */ const express = require('express'); const { connect } = require("puppeteer-real-browser"); const fs = require('fs'); const path = require('path'); const app = express(); const port = process.env.PORT || 7860; global.browserLimit = 100; global.timeOut = 300000; // Path Ekstensi dari Docker (Absolute Path) const EXTENSION_PATH = '/A/extensions/rek'; // Cache Configuration const CACHE_DIR = path.join(__dirname, "cache"); const CACHE_AUTOSAVE = process.env.CACHE_AUTOSAVE === "true"; const CACHE_TTL = 5 * 60 * 1000; if (!fs.existsSync(CACHE_DIR)) fs.mkdirSync(CACHE_DIR, { recursive: true }); function writeCache(type, taskId, value) { const dir = path.join(CACHE_DIR, type); if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); const file = path.join(dir, `${taskId}.json`); const data = { timestamp: Date.now(), ...value }; fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8'); } app.use(express.json()); app.use(express.urlencoded({ extended: true })); const tasks = {}; // Root Route app.get("/", (req, res) => { res.json({ message: "Solver API Running with rektCaptcha Auto-Config", version: "7.5.0-DAN", extension: fs.existsSync(EXTENSION_PATH) ? "Loaded" : "Not Found", uptime: `${Math.floor(process.uptime())}s` }); }); app.post('/solve', async (req, res) => { const { type, domain, siteKey, taskId, action, proxy, isInvisible } = req.body; if (taskId) { const task = tasks[taskId]; if (!task) return res.status(404).json({ status: "error", message: "Task not found" }); return res.json(task.status === "pending" ? { status: "processing" } : task); } const newTaskId = Date.now().toString(36); tasks[newTaskId] = { status: "pending" }; console.log(`[NEW] ${newTaskId} | Type: ${type} | Domain: ${domain}`); (async () => { let browserInstance; try { const ctx = await init_browser(proxy); browserInstance = ctx.browser; const page = ctx.page; let result; switch (type) { case "turnstile": result = await turnstile({ domain, siteKey, action, proxy }, page); break; case "recaptcha2": result = await recaptchaV2({ domain, siteKey, action, isInvisible, proxy }, page); break; case "recaptcha3": result = await recaptchaV3({ domain, siteKey, action, proxy }, page); break; case "interstitial": result = await interstitial({ domain, proxy }, page); break; default: throw new Error("Invalid type"); } tasks[newTaskId] = { status: "done", ...result }; if (CACHE_AUTOSAVE) writeCache(type, newTaskId, tasks[newTaskId]); console.log(`[DONE] ${newTaskId}`); } catch (err) { tasks[newTaskId] = { status: "error", message: err.message }; console.error(`[FAILED] ${newTaskId}:`, err.message); } finally { if (browserInstance) await browserInstance.close(); } })(); res.json({ taskId: newTaskId, status: "pending" }); }); /** * Optimized init_browser with rektCaptcha Dynamic ID Detection & Config Injection */ async function init_browser(proxyData = null) { const connectOptions = { headless: false, // Wajib false agar ekstensi berjalan turnstile: true, connectOption: { defaultViewport: null, protocolTimeout: 600000, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', `--disable-extensions-except=${EXTENSION_PATH}`, `--load-extension=${EXTENSION_PATH}` ] }, disableXvfb: false, }; if (proxyData && proxyData.server) { connectOptions.connectOption.args.push(`--proxy-server=${proxyData.server}`); } const { browser } = await connect(connectOptions); const [page] = await browser.pages(); // --- DAN MODE: AUTO-CONFIG REKTCAPTCHA --- try { const targets = await browser.targets(); const extTarget = targets.find(t => t.url().includes('chrome-extension://')); if (extTarget) { const extId = extTarget.url().split('/')[2]; console.log(`[RECT] ID Detected: ${extId}`); const extBackground = await browser.newPage(); // Akses manifest untuk masuk ke konteks ID ekstensi tersebut await extBackground.goto(`chrome-extension://${extId}/manifest.json`, { waitUntil: 'networkidle2' }); await extBackground.evaluate(() => { const config = { "auto_open": true, "auto_solve": true, "image_click_delay": 0, "solve_delay": 0, "solve_method": "audio" }; if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.local) { chrome.storage.local.set(config); } }); await extBackground.close(); console.log(`[RECT] Config Forced: Auto-Solve ON, Delay 0`); } } catch (e) { console.log(`[RECT] Config Injection Bypass: ${e.message}`); } // Handle Proxy Auth if (proxyData && proxyData.auth) { const [username, password] = proxyData.auth.split(':'); await page.authenticate({ username, password }); } // Intercept: Stylesheet JANGAN diblokir agar widget terbaca await page.setRequestInterception(true); page.on('request', (req) => { const resource = req.resourceType(); if (["image", "font", "media"].includes(resource)) req.abort(); else req.continue(); }); console.log(`[SYSTEM] Browser initialized with rektCaptcha`); return { browser, page }; } // Load Modules const turnstile = require('./Api/turnstile'); const interstitial = require('./Api/interstitial'); const recaptchaV2 = require('./Api/recaptcha2'); const recaptchaV3 = require('./Api/recaptcha3'); app.listen(port, () => { console.log(`Server running on port ${port}`); });