kavion commited on
Commit
e6e5008
·
unverified ·
1 Parent(s): 60cf846

fix: rewrite token detection — polling + exposeFunction instead of waitForSelector

Browse files
Files changed (1) hide show
  1. turnstile-solver.js +28 -5
turnstile-solver.js CHANGED
@@ -149,21 +149,44 @@ class TurnstileSolver {
149
  const fakeHtml = FAKE_PAGE.replace(/<site-key>/g, siteKey);
150
  const baseUrl = url.endsWith('/') ? url : url + '/';
151
 
 
 
 
 
 
 
 
 
 
 
152
  await page.setRequestInterception(true);
153
  page.on('request', async (req) => {
154
  if ([url, baseUrl].includes(req.url()) && req.resourceType() === 'document') {
155
- await req.respond({ status: 200, contentType: 'text/html', body: fakeHtml });
156
  } else {
157
  await req.continue().catch(() => {});
158
  }
159
  });
160
 
161
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 25000 });
162
- await page.waitForSelector('[name="cf-response"]', { timeout: this.timeout });
163
 
164
- const token = await page.evaluate(() =>
165
- document.querySelector('[name="cf-response"]')?.value ?? null
166
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
  await this._stopRecording(rec);
169
  await page.close();
 
149
  const fakeHtml = FAKE_PAGE.replace(/<site-key>/g, siteKey);
150
  const baseUrl = url.endsWith('/') ? url : url + '/';
151
 
152
+ // Tangkap token via exposed function — dipanggil dari callback turnstile
153
+ let capturedToken = null;
154
+ await page.exposeFunction('__onTurnstileToken', (t) => { capturedToken = t; });
155
+
156
+ // Fake HTML pakai callback yang memanggil exposed function
157
+ const injectedHtml = fakeHtml.replace(
158
+ 'callback: function (token) {',
159
+ 'callback: function (token) { window.__onTurnstileToken(token);'
160
+ );
161
+
162
  await page.setRequestInterception(true);
163
  page.on('request', async (req) => {
164
  if ([url, baseUrl].includes(req.url()) && req.resourceType() === 'document') {
165
+ await req.respond({ status: 200, contentType: 'text/html', body: injectedHtml });
166
  } else {
167
  await req.continue().catch(() => {});
168
  }
169
  });
170
 
171
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 25000 });
 
172
 
173
+ // Poll: cek capturedToken atau window.turnstile.getResponse()
174
+ const deadline = Date.now() + this.timeout;
175
+ let token = null;
176
+ while (Date.now() < deadline) {
177
+ if (capturedToken) { token = capturedToken; break; }
178
+ token = await page.evaluate(() => {
179
+ try { return window.turnstile?.getResponse() || null; } catch { return null; }
180
+ });
181
+ if (token && token.length > 10) break;
182
+ // Cek juga DOM fallback
183
+ token = await page.evaluate(() =>
184
+ document.querySelector('[name="cf-response"]')?.value ?? null
185
+ );
186
+ if (token && token.length > 10) break;
187
+ token = null;
188
+ await new Promise(r => setTimeout(r, 500));
189
+ }
190
 
191
  await this._stopRecording(rec);
192
  await page.close();