Forgets commited on
Commit
fc5dfdb
·
verified ·
1 Parent(s): 9adc7c6

Update Api/recaptcha2.js

Browse files
Files changed (1) hide show
  1. Api/recaptcha2.js +185 -42
Api/recaptcha2.js CHANGED
@@ -1,12 +1,11 @@
1
  /**
2
- * API_RECAPTCHA2 - Fixed for Hugging Face
3
  */
4
  async function recaptchaV2({ domain, siteKey, action = "submit", isInvisible = false, proxy }, page) {
5
  if (!domain) throw new Error("Missing domain parameter");
6
  if (!siteKey) throw new Error("Missing siteKey parameter");
7
 
8
- // Gunakan timeout yang lebih manusiawi untuk reCAPTCHA (minimal 2-3 menit)
9
- const timeout = 300000;
10
 
11
  return new Promise(async (resolve, reject) => {
12
  let isResolved = false;
@@ -14,72 +13,216 @@ async function recaptchaV2({ domain, siteKey, action = "submit", isInvisible = f
14
  const cl = setTimeout(() => {
15
  if (!isResolved) {
16
  isResolved = true;
17
- reject(new Error("Timeout Error: Google reCAPTCHA took too long"));
18
  }
19
  }, timeout);
20
 
21
  try {
22
- // Setup Interception yang BENAR
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  await page.setRequestInterception(true);
24
  page.removeAllListeners("request");
25
-
26
  page.on("request", async (req) => {
27
- const type = req.resourceType();
28
- // JANGAN blokir image dan stylesheet untuk reCAPTCHA v2!
29
- if (["font", "media"].includes(type)) {
 
30
  await req.abort();
31
  } else {
32
  await req.continue();
33
  }
34
  });
35
 
36
- // Navigasi ke domain target
37
- await page.goto(domain, { waitUntil: "networkidle2", timeout });
38
-
39
- // Injeksi script untuk menangkap token secara otomatis
40
- await page.evaluate((sKey, isInv) => {
41
- const div = document.createElement('div');
42
- div.id = 'solver-container';
43
- div.innerHTML = `<div class="g-recaptcha" data-sitekey="${sKey}" data-callback="onSolved" data-size="${isInv ? 'invisible' : 'normal'}"></div>`;
44
- document.body.appendChild(div);
45
-
46
- window.onSolved = (token) => {
47
- window.captchaToken = token;
48
- console.log("CAPTCHA_SOLVED");
49
- };
50
 
51
- // Load Script Google secara dinamis
52
- const script = document.createElement('script');
53
- script.src = "https://www.google.com/recaptcha/api.js";
54
- script.async = true;
55
- script.defer = true;
56
- document.head.appendChild(script);
57
- }, siteKey, isInvisible);
 
58
 
59
- logMsg("info", "Memulai proses solve...");
60
-
61
- // Tunggu sampai token muncul di window.captchaToken
62
- const tokenValue = await page.waitForFunction(() => {
63
- return window.captchaToken;
64
- }, { timeout, polling: 500 }).then(h => h.jsonValue());
65
 
66
  isResolved = true;
67
  clearTimeout(cl);
68
 
69
- if (tokenValue) {
70
- resolve({ data: tokenValue, status: "done" });
71
  } else {
72
- reject(new Error("Token empty"));
73
  }
74
-
75
  } catch (error) {
76
  if (!isResolved) {
77
  isResolved = true;
78
  clearTimeout(cl);
79
- reject(new Error(`Solver Failed: ${error.message}`));
 
 
 
 
 
 
 
 
 
 
80
  }
81
  }
82
  });
83
  }
84
 
85
- module.exports = recaptchaV2;
 
1
  /**
2
+ * API_RECAPTCHA2
3
  */
4
  async function recaptchaV2({ domain, siteKey, action = "submit", isInvisible = false, proxy }, page) {
5
  if (!domain) throw new Error("Missing domain parameter");
6
  if (!siteKey) throw new Error("Missing siteKey parameter");
7
 
8
+ const timeout = global.timeOut;
 
9
 
10
  return new Promise(async (resolve, reject) => {
11
  let isResolved = false;
 
13
  const cl = setTimeout(() => {
14
  if (!isResolved) {
15
  isResolved = true;
16
+ reject(new Error("Timeout Error"));
17
  }
18
  }, timeout);
19
 
20
  try {
21
+ if (proxy?.username && proxy?.password) {
22
+ await page.authenticate({
23
+ username: proxy.username,
24
+ password: proxy.password,
25
+ });
26
+ }
27
+
28
+ const htmlContent = `
29
+ <!DOCTYPE html>
30
+ <html lang="en">
31
+ <head>
32
+ <meta charset="UTF-8">
33
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
34
+ <title>reCAPTCHA v2 Solver</title>
35
+ <style>
36
+ body {
37
+ font-family: Arial, sans-serif;
38
+ margin: 0;
39
+ padding: 20px;
40
+ background: #f5f5f5;
41
+ display: flex;
42
+ justify-content: center;
43
+ align-items: center;
44
+ min-height: 100vh;
45
+ }
46
+ .container {
47
+ background: white;
48
+ padding: 30px;
49
+ border-radius: 10px;
50
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
51
+ text-align: center;
52
+ }
53
+ .status {
54
+ margin-top: 20px;
55
+ padding: 10px;
56
+ border-radius: 5px;
57
+ background: #f8f9fa;
58
+ }
59
+ button {
60
+ background: #007bff;
61
+ color: white;
62
+ border: none;
63
+ padding: 10px 20px;
64
+ border-radius: 5px;
65
+ cursor: pointer;
66
+ margin: 10px;
67
+ }
68
+ button:hover { background: #0056b3; }
69
+ </style>
70
+ </head>
71
+ <body>
72
+ <div class="container">
73
+ <h2>reCAPTCHA v2 Solver</h2>
74
+ <p>SiteKey: ${siteKey}</p>
75
+ <div id="recaptcha-container">
76
+ <div class="g-recaptcha"
77
+ data-sitekey="${siteKey}"
78
+ data-callback="recaptchaCallback"
79
+ data-expired-callback="recaptchaExpired"
80
+ data-error-callback="recaptchaError"
81
+ data-size="${isInvisible ? 'invisible' : 'normal'}"
82
+ data-theme="light"></div>
83
+ </div>
84
+ ${isInvisible ? '<button onclick="executeInvisible()">Execute reCAPTCHA</button>' : ''}
85
+ <button onclick="checkToken()">Check Token</button>
86
+ <div class="status" id="status">Waiting for reCAPTCHA...</div>
87
+ </div>
88
+
89
+ <script>
90
+ window.recaptchaToken = null;
91
+ window.recaptchaSolved = false;
92
+
93
+ window.recaptchaCallback = function(token) {
94
+ console.log('reCAPTCHA token received:', token);
95
+ window.recaptchaToken = token;
96
+ window.recaptchaSolved = true;
97
+
98
+ document.getElementById('status').innerHTML =
99
+ '✅ reCAPTCHA Solved! Token: ' + token.substring(0, 20) + '...';
100
+ document.getElementById('status').style.background = '#d4edda';
101
+ document.getElementById('status').style.color = '#155724';
102
+
103
+ var input = document.createElement('input');
104
+ input.type = 'hidden';
105
+ input.name = 'g-recaptcha-response';
106
+ input.value = token;
107
+ input.id = 'recaptcha-token-input';
108
+ document.body.appendChild(input);
109
+
110
+ localStorage.setItem('recaptcha_token', token);
111
+ };
112
+
113
+ window.recaptchaExpired = function() {
114
+ console.log('reCAPTCHA expired');
115
+ window.recaptchaToken = null;
116
+ window.recaptchaSolved = false;
117
+ document.getElementById('status').innerHTML = '❌ reCAPTCHA Expired - Refreshing...';
118
+ document.getElementById('status').style.background = '#fff3cd';
119
+ document.getElementById('status').style.color = '#856404';
120
+
121
+ var existing = document.getElementById('recaptcha-token-input');
122
+ if (existing) existing.remove();
123
+
124
+ setTimeout(() => { if (window.grecaptcha) grecaptcha.reset(); }, 1000);
125
+ };
126
+
127
+ window.recaptchaError = function() {
128
+ console.log('reCAPTCHA error');
129
+ document.getElementById('status').innerHTML = '❌ reCAPTCHA Error';
130
+ document.getElementById('status').style.background = '#f8d7da';
131
+ document.getElementById('status').style.color = '#721c24';
132
+ };
133
+
134
+ window.executeInvisible = function() {
135
+ if (window.grecaptcha) grecaptcha.execute();
136
+ };
137
+
138
+ window.checkToken = function() {
139
+ const token = window.recaptchaToken ||
140
+ document.getElementById('recaptcha-token-input')?.value;
141
+ document.getElementById('status').innerHTML = token
142
+ ? 'Token: ' + token
143
+ : 'No token yet';
144
+ };
145
+
146
+ window.onload = function() {
147
+ setTimeout(function() {
148
+ if (${isInvisible} && window.grecaptcha) {
149
+ grecaptcha.execute();
150
+ }
151
+ if (!${isInvisible}) {
152
+ var iframe = document.querySelector('iframe[src*="recaptcha"]');
153
+ if (iframe) {
154
+ console.log('Attempting to interact with reCAPTCHA');
155
+ var rect = iframe.getBoundingClientRect();
156
+ var clickEvent = new MouseEvent('click', {
157
+ view: window, bubbles: true, cancelable: true,
158
+ clientX: rect.left + rect.width / 2,
159
+ clientY: rect.top + rect.height / 2
160
+ });
161
+ iframe.dispatchEvent(clickEvent);
162
+ }
163
+ }
164
+ }, 2000);
165
+ };
166
+ </script>
167
+
168
+ <script src="https://www.google.com/recaptcha/api.js" async defer></script>
169
+ </body>
170
+ </html>
171
+ `;
172
+
173
  await page.setRequestInterception(true);
174
  page.removeAllListeners("request");
 
175
  page.on("request", async (req) => {
176
+ const url = req.url();
177
+ if ([domain, domain + "/"].includes(url) && req.resourceType() === "document") {
178
+ await req.respond({ status: 200, contentType: "text/html", body: htmlContent });
179
+ } else if (["image", "stylesheet", "font"].includes(req.resourceType())) {
180
  await req.abort();
181
  } else {
182
  await req.continue();
183
  }
184
  });
185
 
186
+ await page.goto(domain, { waitUntil: "domcontentloaded", timeout });
187
+ await page.waitForSelector('.g-recaptcha', { timeout: 10000 });
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
+ const tokenHandle = await page.waitForFunction(() => {
190
+ const input = document.querySelector('#recaptcha-token-input');
191
+ if (input?.value?.length > 10) return input.value;
192
+ const stored = localStorage.getItem('recaptcha_token');
193
+ if (stored?.length > 10) return stored;
194
+ if (window.recaptchaToken?.length > 10) return window.recaptchaToken;
195
+ return null;
196
+ }, { timeout, polling: 100 });
197
 
198
+ const tokenValue = await tokenHandle.jsonValue();
 
 
 
 
 
199
 
200
  isResolved = true;
201
  clearTimeout(cl);
202
 
203
+ if (!tokenValue || tokenValue.length < 10) {
204
+ reject(new Error("Failed to get valid reCAPTCHA token"));
205
  } else {
206
+ resolve({ token: tokenValue, type: 'recaptcha_v2' });
207
  }
 
208
  } catch (error) {
209
  if (!isResolved) {
210
  isResolved = true;
211
  clearTimeout(cl);
212
+ try {
213
+ const fallbackToken = await page.evaluate(() => {
214
+ const input = document.querySelector('#recaptcha-token-input');
215
+ return input ? input.value : null;
216
+ });
217
+ if (fallbackToken?.length > 10) {
218
+ resolve({ token: fallbackToken, type: 'recaptcha_v2' });
219
+ return;
220
+ }
221
+ } catch {}
222
+ reject(new Error(`reCAPTCHA solving failed: ${error.message}`));
223
  }
224
  }
225
  });
226
  }
227
 
228
+ module.exports = recaptchaV2;