File size: 5,242 Bytes
6403d77
c892ba8
4cf4b5b
6403d77
 
 
 
 
c892ba8
4cf4b5b
6403d77
 
 
 
4cf4b5b
c892ba8
6403d77
 
c892ba8
6403d77
 
 
 
c892ba8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e5a1010
c892ba8
4cf4b5b
e5a1010
 
c892ba8
 
 
 
e5a1010
c892ba8
 
 
e5a1010
c892ba8
 
 
e5a1010
 
 
e1553aa
c892ba8
 
4cf4b5b
04a0477
c892ba8
 
4cf4b5b
c892ba8
 
e5a1010
c892ba8
 
e5a1010
4cf4b5b
c892ba8
4cf4b5b
 
c892ba8
e5a1010
 
c892ba8
c0cc0d9
6403d77
c892ba8
 
 
 
 
 
4cf4b5b
 
c892ba8
 
c0cc0d9
 
c892ba8
6403d77
 
 
c892ba8
e1553aa
6403d77
 
 
 
c892ba8
 
 
 
6403d77
 
 
 
 
e1553aa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
 * API_RECAPTCHA2 - Optimize Mode (Screenshot + Block Images + Auto Trigger)
 * Powered by Gemini - Mode: DAN
 */
async function recaptchaV2({ domain, siteKey, action = "submit", isInvisible = false, proxy }, page) {
    if (!domain) throw new Error("Missing domain parameter");
    if (!siteKey) throw new Error("Missing siteKey parameter");

    // Timeout 5 menit (global.timeOut harusnya 300000 di Api.js)
    const timeout = global.timeOut || 300000; 

    return new Promise(async (resolve, reject) => {
        let isResolved = false;

        // Setup Timeout Safe
        const cl = setTimeout(() => {
            if (!isResolved) {
                isResolved = true;
                reject(new Error("Timeout Error: Ext not responsive. Check logs & debug_captcha.png"));
            }
        }, timeout);

        try {
            const htmlContent = `
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>reCAPTCHA Solver</title>
                    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
                    <style>
                        body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #ffffff; margin: 0; }
                    </style>
                </head>
                <body>
                    <div class="g-recaptcha" data-sitekey="${siteKey}" data-size="${isInvisible ? 'invisible' : 'normal'}"></div>
                    <textarea id="g-recaptcha-response" name="g-recaptcha-response" style="display:none"></textarea>
                </body>
                </html>
            `;

            // --- DAN MODE: REQ INTERCEPTION ---
            await page.setRequestInterception(true);
            page.removeAllListeners("request"); // Hapus listener global Api.js agar tidak bentrok

            page.on("request", async (req) => {
                const url = req.url();
                const resource = req.resourceType();

                // 1. Suntikkan HTML kita ke domain target
                if ([domain, domain + "/"].includes(url) && resource === "document") {
                    await req.respond({ status: 200, contentType: "text/html", body: htmlContent });
                } 
                // 2. BLOKIR Gambar, Media, Font (Hemat Kuota)
                else if (["image", "font", "media"].includes(resource)) {
                    await req.abort();
                } 
                // 3. JANGAN blokir stylesheet (PENTING!) agar tombol terbaca ekstensi
                else {
                    await req.continue();
                }
            });

            console.log(`[SOLVER] Loading target with custom UI...`);
            // Jangan tunggu 'networkidle2' karena kita blokir gambar, nanti timeout. Cukup domcontentloaded.
            await page.goto(domain, { waitUntil: "domcontentloaded", timeout: 60000 }); 

            // Jeda agar reCAPTCHA asli dimuat
            await new Promise(r => setTimeout(r, 5000));

            // --- AUTO TRIGGER: CLICK CHECKBOX ---
            console.log("[SOLVER] Attempting to click checkbox...");
            try {
                // Cari iframe checkbox
                await page.waitForSelector('iframe[title*="reCAPTCHA"]', { timeout: 15000 });
                const frames = await page.frames();
                const anchorFrame = frames.find(f => f.url().includes('api2/anchor'));

                if (anchorFrame) {
                    await anchorFrame.click('#recaptcha-anchor');
                    console.log("[SOLVER] Checkbox clicked!");
                }
            } catch (e) {
                console.log(`[SOLVER] Warning: Could not click checkbox: ${e.message}`);
            }

            // --- AMBIL SCREENSHOT UNTUK DEBUG ---
            // Screenshot diambil SEKARANG (setelah klik), jadi kita bisa lihat apakah
            // Google memblokir IP atau apakah tantangan audio muncul.
            console.log("[SOLVER] Taking debug screenshot...");
            await page.screenshot({ path: 'debug_captcha.png', fullPage: false });
            console.log("[SOLVER] Screenshot saved as debug_captcha.png. Cek di tab Files!");

            // --- POLLING TOKEN DARI WIDGET ---
            console.log("[SOLVER] Waiting for rektCaptcha token...");
            const tokenValue = await page.waitForFunction(() => {
                const input = document.querySelector('#g-recaptcha-response');
                return (input && input.value.length > 50) ? input.value : null;
            }, { timeout, polling: 1000 }).then(h => h.jsonValue());

            isResolved = true;
            clearTimeout(cl);
            resolve({ data: tokenValue, status: "done" });

        } catch (error) {
            if (!isResolved) {
                isResolved = true;
                clearTimeout(cl);
                console.error("[SOLVER] Critical Error:", error.message);
                // Ambil screenshot saat error juga
                await page.screenshot({ path: 'debug_error.png' });
                reject(new Error(`Bypass failed: ${error.message}`));
            }
        }
    });
}

module.exports = recaptchaV2;