@nuanu-ai/agentbrowse 0.2.12 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/agentpay-stagehand-llm.d.ts +16 -0
- package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
- package/dist/agentpay-stagehand-llm.js +35 -10
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +16 -15
- package/dist/commands/action-acceptance.d.ts +1 -0
- package/dist/commands/action-acceptance.d.ts.map +1 -1
- package/dist/commands/action-acceptance.js +77 -1
- package/dist/commands/extract-snapshot-sanitizer.d.ts +2 -0
- package/dist/commands/extract-snapshot-sanitizer.d.ts.map +1 -0
- package/dist/commands/extract-snapshot-sanitizer.js +65 -0
- package/dist/commands/extract-stagehand-executor.d.ts.map +1 -1
- package/dist/commands/extract-stagehand-executor.js +33 -3
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +29 -0
- package/dist/commands/launch.js +0 -7
- package/dist/commands/observe-inventory.d.ts.map +1 -1
- package/dist/commands/observe-inventory.js +43 -0
- package/dist/commands/observe-persistence.d.ts +1 -0
- package/dist/commands/observe-persistence.d.ts.map +1 -1
- package/dist/commands/observe-persistence.js +52 -1
- package/dist/commands/observe-projection.d.ts +28 -5
- package/dist/commands/observe-projection.d.ts.map +1 -1
- package/dist/commands/observe-projection.js +189 -9
- package/dist/commands/observe-semantics.d.ts.map +1 -1
- package/dist/commands/observe-semantics.js +13 -2
- package/dist/commands/observe-surfaces.d.ts +1 -0
- package/dist/commands/observe-surfaces.d.ts.map +1 -1
- package/dist/commands/observe-surfaces.js +65 -0
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +49 -19
- package/dist/commands/observe.test-harness.d.ts +1 -0
- package/dist/commands/observe.test-harness.d.ts.map +1 -1
- package/dist/commands/observe.test-harness.js +53 -16
- package/dist/commands/semantic-observe.d.ts +2 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -1
- package/dist/commands/semantic-observe.js +4 -0
- package/dist/playwright-runtime.d.ts +3 -1
- package/dist/playwright-runtime.d.ts.map +1 -1
- package/dist/playwright-runtime.js +42 -2
- package/dist/runtime-state.d.ts +3 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +2 -0
- package/dist/secrets/fill-ordering.d.ts +1 -2
- package/dist/secrets/fill-ordering.d.ts.map +1 -1
- package/dist/secrets/fill-ordering.js +0 -3
- package/dist/secrets/form-matcher.d.ts.map +1 -1
- package/dist/secrets/form-matcher.js +0 -9
- package/dist/secrets/types.d.ts +0 -9
- package/dist/secrets/types.d.ts.map +1 -1
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +492 -55
- package/dist/solver/captcha-detector.d.ts.map +1 -1
- package/dist/solver/captcha-detector.js +187 -12
- package/dist/solver/captcha-runtime.d.ts.map +1 -1
- package/dist/solver/captcha-runtime.js +8 -0
- package/dist/solver/captcha-solver.d.ts +11 -1
- package/dist/solver/captcha-solver.d.ts.map +1 -1
- package/dist/solver/captcha-solver.js +11 -4
- package/dist/solver/turnstile-challenge.d.ts +3 -0
- package/dist/solver/turnstile-challenge.d.ts.map +1 -0
- package/dist/solver/turnstile-challenge.js +173 -0
- package/dist/solver/types.d.ts +10 -8
- package/dist/solver/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/secrets/request-guidance.d.ts +0 -24
- package/dist/secrets/request-guidance.d.ts.map +0 -1
- package/dist/secrets/request-guidance.js +0 -142
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import puppeteerExtra from 'puppeteer-extra';
|
|
6
6
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
|
7
|
+
import { buildTurnstileApiShimSource, isTurnstileApiRequest } from './turnstile-challenge.js';
|
|
7
8
|
const enhancedPuppeteer = puppeteerExtra;
|
|
8
9
|
enhancedPuppeteer.use(StealthPlugin());
|
|
9
|
-
const
|
|
10
|
-
const
|
|
10
|
+
const AUTO_CDP_PORT = 0;
|
|
11
|
+
const CDP_DISCOVERY_TIMEOUT_MS = 30_000;
|
|
11
12
|
const CDP_DISCOVERY_INTERVAL_MS = 500;
|
|
13
|
+
const INTERCEPTED_PAGES = new WeakSet();
|
|
12
14
|
const CHROME_PATHS = [
|
|
13
15
|
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
14
16
|
'/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
|
@@ -21,31 +23,22 @@ const CHROME_PATHS = [
|
|
|
21
23
|
];
|
|
22
24
|
export async function launchSolver(profile, opts) {
|
|
23
25
|
const fp = withWindowSize(profile.fingerprint, opts?.windowSize);
|
|
24
|
-
const cdpPort = opts?.cdpPort ??
|
|
26
|
+
const cdpPort = opts?.cdpPort ?? AUTO_CDP_PORT;
|
|
25
27
|
const executablePath = resolveChromeExecutable(opts?.executablePath);
|
|
26
|
-
const
|
|
28
|
+
const chromeProcess = spawnChromeProcess(executablePath, profile, fp, cdpPort, opts?.windowSize, opts?.headless, undefined);
|
|
27
29
|
try {
|
|
28
|
-
const cdpUrl = await discoverCdpUrl(
|
|
30
|
+
const cdpUrl = await discoverCdpUrl({
|
|
31
|
+
requestedPort: opts?.cdpPort,
|
|
32
|
+
userDataDir: profile.userDataDir,
|
|
33
|
+
});
|
|
29
34
|
if (!cdpUrl) {
|
|
30
|
-
throw
|
|
35
|
+
throw buildCdpDiscoveryError(chromeProcess, opts?.cdpPort, profile.userDataDir);
|
|
31
36
|
}
|
|
32
37
|
const browser = await enhancedPuppeteer.connect({ browserWSEndpoint: cdpUrl });
|
|
33
38
|
let page;
|
|
34
39
|
if (opts?.url) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
page = existingPages[0] ?? (await browser.newPage());
|
|
38
|
-
await applyFingerprint(page, fp);
|
|
39
|
-
if (fp.proxy?.username && fp.proxy.password) {
|
|
40
|
-
await page.authenticate({ username: fp.proxy.username, password: fp.proxy.password });
|
|
41
|
-
}
|
|
42
|
-
// If Chrome hasn't finished loading yet, wait for it.
|
|
43
|
-
const currentUrl = page.url();
|
|
44
|
-
if (!currentUrl || currentUrl === 'about:blank' || currentUrl === 'chrome://newtab/') {
|
|
45
|
-
await page
|
|
46
|
-
.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 15_000 })
|
|
47
|
-
.catch(() => { });
|
|
48
|
-
}
|
|
40
|
+
page = await createConfiguredPage(browser, fp);
|
|
41
|
+
page = await navigateConfiguredPage(browser, page, fp, opts.url);
|
|
49
42
|
}
|
|
50
43
|
else {
|
|
51
44
|
page = await createConfiguredPage(browser, fp);
|
|
@@ -72,7 +65,7 @@ export async function launchSolver(profile, opts) {
|
|
|
72
65
|
await browser.disconnect();
|
|
73
66
|
}
|
|
74
67
|
finally {
|
|
75
|
-
terminateProcessGroup(
|
|
68
|
+
terminateProcessGroup(chromeProcess.pid);
|
|
76
69
|
}
|
|
77
70
|
},
|
|
78
71
|
disconnect: async () => {
|
|
@@ -81,30 +74,93 @@ export async function launchSolver(profile, opts) {
|
|
|
81
74
|
};
|
|
82
75
|
}
|
|
83
76
|
catch (error) {
|
|
84
|
-
terminateProcessGroup(
|
|
77
|
+
terminateProcessGroup(chromeProcess.pid);
|
|
85
78
|
throw error;
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
|
-
async function discoverCdpUrl(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return json.webSocketDebuggerUrl;
|
|
81
|
+
async function discoverCdpUrl(options) {
|
|
82
|
+
const deadline = Date.now() + CDP_DISCOVERY_TIMEOUT_MS;
|
|
83
|
+
const activePortPath = path.join(options.userDataDir, 'DevToolsActivePort');
|
|
84
|
+
while (Date.now() < deadline) {
|
|
85
|
+
if (typeof options.requestedPort === 'number') {
|
|
86
|
+
const cdpUrl = await discoverCdpUrlOnPort(options.requestedPort);
|
|
87
|
+
if (cdpUrl) {
|
|
88
|
+
return cdpUrl;
|
|
97
89
|
}
|
|
98
90
|
}
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
else {
|
|
92
|
+
const activePort = readDevToolsActivePort(activePortPath);
|
|
93
|
+
if (activePort?.browserWSEndpoint) {
|
|
94
|
+
return activePort.browserWSEndpoint;
|
|
95
|
+
}
|
|
96
|
+
if (activePort?.port) {
|
|
97
|
+
const cdpUrl = await discoverCdpUrlOnPort(activePort.port);
|
|
98
|
+
if (cdpUrl) {
|
|
99
|
+
return cdpUrl;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
101
102
|
}
|
|
102
|
-
await
|
|
103
|
+
await sleep(CDP_DISCOVERY_INTERVAL_MS);
|
|
103
104
|
}
|
|
104
105
|
return null;
|
|
105
106
|
}
|
|
107
|
+
async function discoverCdpUrlOnPort(port) {
|
|
108
|
+
try {
|
|
109
|
+
const res = await fetch(`http://127.0.0.1:${port}/json/version`);
|
|
110
|
+
if (!res.ok) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const json = (await res.json());
|
|
114
|
+
return json.webSocketDebuggerUrl ?? null;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function readDevToolsActivePort(activePortPath) {
|
|
121
|
+
if (!existsSync(activePortPath)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const raw = readFileSync(activePortPath, 'utf-8').trim();
|
|
126
|
+
if (!raw) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const [portLine = '', wsPathLine = ''] = raw.split(/\r?\n/, 2);
|
|
130
|
+
const port = Number(portLine.trim());
|
|
131
|
+
if (!Number.isFinite(port) || port <= 0) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const wsPath = wsPathLine.trim();
|
|
135
|
+
return {
|
|
136
|
+
port,
|
|
137
|
+
browserWSEndpoint: wsPath
|
|
138
|
+
? wsPath.startsWith('ws://')
|
|
139
|
+
? wsPath
|
|
140
|
+
: `ws://127.0.0.1:${port}${wsPath.startsWith('/') ? wsPath : `/${wsPath}`}`
|
|
141
|
+
: undefined,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function buildCdpDiscoveryError(chromeProcess, requestedPort, userDataDir) {
|
|
149
|
+
const details = [`pid ${chromeProcess.pid ?? 'unknown'}`];
|
|
150
|
+
if (typeof chromeProcess.exitCode === 'number') {
|
|
151
|
+
details.push(`exitCode ${chromeProcess.exitCode}`);
|
|
152
|
+
}
|
|
153
|
+
if (chromeProcess.signalCode) {
|
|
154
|
+
details.push(`signal ${chromeProcess.signalCode}`);
|
|
155
|
+
}
|
|
156
|
+
if (typeof requestedPort === 'number') {
|
|
157
|
+
return new Error(`Chrome launched but CDP not reachable on port ${requestedPort} within ${CDP_DISCOVERY_TIMEOUT_MS}ms (${details.join(', ')}).`);
|
|
158
|
+
}
|
|
159
|
+
return new Error(`Chrome launched but CDP not reachable via auto discovery within ${CDP_DISCOVERY_TIMEOUT_MS}ms (${details.join(', ')}). Checked ${path.join(userDataDir, 'DevToolsActivePort')}.`);
|
|
160
|
+
}
|
|
106
161
|
async function createConfiguredPage(browser, fp) {
|
|
107
162
|
const page = await browser.newPage();
|
|
163
|
+
await installTurnstileApiInterception(page);
|
|
108
164
|
await applyFingerprint(page, fp);
|
|
109
165
|
if (fp.proxy?.username && fp.proxy.password) {
|
|
110
166
|
await page.authenticate({
|
|
@@ -114,6 +170,41 @@ async function createConfiguredPage(browser, fp) {
|
|
|
114
170
|
}
|
|
115
171
|
return page;
|
|
116
172
|
}
|
|
173
|
+
async function installTurnstileApiInterception(page) {
|
|
174
|
+
if (INTERCEPTED_PAGES.has(page)) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
await page.setRequestInterception(true);
|
|
178
|
+
page.on('request', (request) => {
|
|
179
|
+
void (async () => {
|
|
180
|
+
try {
|
|
181
|
+
if (isTurnstileApiRequest(request.url())) {
|
|
182
|
+
await request.respond({
|
|
183
|
+
status: 200,
|
|
184
|
+
contentType: 'application/javascript',
|
|
185
|
+
headers: {
|
|
186
|
+
'access-control-allow-origin': '*',
|
|
187
|
+
'cross-origin-resource-policy': 'cross-origin',
|
|
188
|
+
'cache-control': 'no-store',
|
|
189
|
+
},
|
|
190
|
+
body: buildTurnstileApiShimSource(request.url()),
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
await request.continue();
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
try {
|
|
198
|
+
await request.continue();
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Ignore navigations or already-handled requests.
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
})();
|
|
205
|
+
});
|
|
206
|
+
INTERCEPTED_PAGES.add(page);
|
|
207
|
+
}
|
|
117
208
|
async function navigateConfiguredPage(browser, page, fp, url) {
|
|
118
209
|
try {
|
|
119
210
|
await page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
@@ -166,6 +257,7 @@ function spawnChromeProcess(executablePath, profile, fp, cdpPort, windowSize, he
|
|
|
166
257
|
'--remote-debugging-address=127.0.0.1',
|
|
167
258
|
`--user-data-dir=${profile.userDataDir}`,
|
|
168
259
|
`--window-size=${width},${height}`,
|
|
260
|
+
`--user-agent=${fp.userAgent}`,
|
|
169
261
|
'--disable-blink-features=AutomationControlled',
|
|
170
262
|
'--no-first-run',
|
|
171
263
|
'--no-default-browser-check',
|
|
@@ -189,7 +281,7 @@ function spawnChromeProcess(executablePath, profile, fp, cdpPort, windowSize, he
|
|
|
189
281
|
if (!proc.pid) {
|
|
190
282
|
throw new Error('Failed to launch Chrome process');
|
|
191
283
|
}
|
|
192
|
-
return proc
|
|
284
|
+
return proc;
|
|
193
285
|
}
|
|
194
286
|
function terminateProcessGroup(pid) {
|
|
195
287
|
try {
|
|
@@ -206,6 +298,9 @@ function terminateProcessGroup(pid) {
|
|
|
206
298
|
// Ignore already terminated process.
|
|
207
299
|
}
|
|
208
300
|
}
|
|
301
|
+
function sleep(ms) {
|
|
302
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
303
|
+
}
|
|
209
304
|
function withWindowSize(fingerprint, windowSize) {
|
|
210
305
|
if (!windowSize)
|
|
211
306
|
return fingerprint;
|
|
@@ -238,25 +333,367 @@ async function applyFingerprint(page, fp) {
|
|
|
238
333
|
});
|
|
239
334
|
await page.emulateTimezone(fp.timezone);
|
|
240
335
|
await page.evaluateOnNewDocument((fingerprint) => {
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
336
|
+
const win = window;
|
|
337
|
+
const callbacksKey = '__agentbrowseTurnstileCallbacks';
|
|
338
|
+
const challengesKey = '__agentbrowseTurnstileChallenges';
|
|
339
|
+
const stateKey = '__agentbrowseTurnstileState';
|
|
340
|
+
if (!Array.isArray(win[challengesKey])) {
|
|
341
|
+
win[challengesKey] = [];
|
|
342
|
+
}
|
|
343
|
+
if (!win[callbacksKey] || typeof win[callbacksKey] !== 'object') {
|
|
344
|
+
win[callbacksKey] = {};
|
|
345
|
+
}
|
|
346
|
+
if (!win[stateKey] || typeof win[stateKey] !== 'object') {
|
|
347
|
+
win[stateKey] = { nextCallbackId: 1 };
|
|
348
|
+
}
|
|
349
|
+
let turnstileValue = win.turnstile;
|
|
350
|
+
if (turnstileValue && typeof turnstileValue === 'object') {
|
|
351
|
+
const turnstile = turnstileValue;
|
|
352
|
+
if (typeof turnstile.render === 'function' && !turnstile.__agentbrowseWrapped) {
|
|
353
|
+
const originalRender = turnstile.render.bind(turnstile);
|
|
354
|
+
turnstile.render = (container, options) => {
|
|
355
|
+
const state = win[stateKey];
|
|
356
|
+
const callbacks = win[callbacksKey];
|
|
357
|
+
const challenges = win[challengesKey];
|
|
358
|
+
const callbackId = typeof options?.callback === 'function'
|
|
359
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
360
|
+
: '';
|
|
361
|
+
if (callbackId) {
|
|
362
|
+
callbacks[callbackId] = options.callback;
|
|
363
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
364
|
+
}
|
|
365
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
366
|
+
? options.sitekey
|
|
367
|
+
: typeof options?.siteKey === 'string'
|
|
368
|
+
? options.siteKey
|
|
369
|
+
: '';
|
|
370
|
+
if (siteKey) {
|
|
371
|
+
challenges.push({
|
|
372
|
+
siteKey,
|
|
373
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
374
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
375
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
376
|
+
callbackId,
|
|
377
|
+
userAgent: navigator.userAgent,
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
return originalRender(container, options);
|
|
381
|
+
};
|
|
382
|
+
turnstile.__agentbrowseWrapped = true;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
let renderValue = turnstile.render;
|
|
386
|
+
try {
|
|
387
|
+
Object.defineProperty(turnstile, 'render', {
|
|
388
|
+
configurable: true,
|
|
389
|
+
enumerable: true,
|
|
390
|
+
get: () => renderValue,
|
|
391
|
+
set: (value) => {
|
|
392
|
+
if (typeof value !== 'function') {
|
|
393
|
+
renderValue = value;
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const originalRender = value.bind(turnstile);
|
|
397
|
+
renderValue = (container, options) => {
|
|
398
|
+
const state = win[stateKey];
|
|
399
|
+
const callbacks = win[callbacksKey];
|
|
400
|
+
const challenges = win[challengesKey];
|
|
401
|
+
const callbackId = typeof options?.callback === 'function'
|
|
402
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
403
|
+
: '';
|
|
404
|
+
if (callbackId) {
|
|
405
|
+
callbacks[callbackId] = options.callback;
|
|
406
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
407
|
+
}
|
|
408
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
409
|
+
? options.sitekey
|
|
410
|
+
: typeof options?.siteKey === 'string'
|
|
411
|
+
? options.siteKey
|
|
412
|
+
: '';
|
|
413
|
+
if (siteKey) {
|
|
414
|
+
challenges.push({
|
|
415
|
+
siteKey,
|
|
416
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
417
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
418
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
419
|
+
callbackId,
|
|
420
|
+
userAgent: navigator.userAgent,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return originalRender(container, options);
|
|
424
|
+
};
|
|
425
|
+
turnstile.__agentbrowseWrapped = true;
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
catch {
|
|
430
|
+
// Ignore non-configurable render properties.
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
Object.defineProperty(win, 'turnstile', {
|
|
436
|
+
configurable: true,
|
|
437
|
+
enumerable: true,
|
|
438
|
+
get: () => turnstileValue,
|
|
439
|
+
set: (value) => {
|
|
440
|
+
turnstileValue = value;
|
|
441
|
+
if (!value || typeof value !== 'object')
|
|
442
|
+
return;
|
|
443
|
+
const turnstile = value;
|
|
444
|
+
if (typeof turnstile.render !== 'function' || turnstile.__agentbrowseWrapped) {
|
|
445
|
+
let renderValue = turnstile.render;
|
|
446
|
+
try {
|
|
447
|
+
Object.defineProperty(turnstile, 'render', {
|
|
448
|
+
configurable: true,
|
|
449
|
+
enumerable: true,
|
|
450
|
+
get: () => renderValue,
|
|
451
|
+
set: (nextValue) => {
|
|
452
|
+
if (typeof nextValue !== 'function') {
|
|
453
|
+
renderValue = nextValue;
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const originalRender = nextValue.bind(turnstile);
|
|
457
|
+
renderValue = (container, options) => {
|
|
458
|
+
const state = win[stateKey];
|
|
459
|
+
const callbacks = win[callbacksKey];
|
|
460
|
+
const challenges = win[challengesKey];
|
|
461
|
+
const callbackId = typeof options?.callback === 'function'
|
|
462
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
463
|
+
: '';
|
|
464
|
+
if (callbackId) {
|
|
465
|
+
callbacks[callbackId] = options.callback;
|
|
466
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
467
|
+
}
|
|
468
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
469
|
+
? options.sitekey
|
|
470
|
+
: typeof options?.siteKey === 'string'
|
|
471
|
+
? options.siteKey
|
|
472
|
+
: '';
|
|
473
|
+
if (siteKey) {
|
|
474
|
+
challenges.push({
|
|
475
|
+
siteKey,
|
|
476
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
477
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
478
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
479
|
+
callbackId,
|
|
480
|
+
userAgent: navigator.userAgent,
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
return originalRender(container, options);
|
|
484
|
+
};
|
|
485
|
+
turnstile.__agentbrowseWrapped = true;
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
catch {
|
|
490
|
+
// Ignore non-configurable render properties.
|
|
491
|
+
}
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const originalRender = turnstile.render.bind(turnstile);
|
|
495
|
+
turnstile.render = (container, options) => {
|
|
496
|
+
const state = win[stateKey];
|
|
497
|
+
const callbacks = win[callbacksKey];
|
|
498
|
+
const challenges = win[challengesKey];
|
|
499
|
+
const callbackId = typeof options?.callback === 'function'
|
|
500
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
501
|
+
: '';
|
|
502
|
+
if (callbackId) {
|
|
503
|
+
callbacks[callbackId] = options.callback;
|
|
504
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
505
|
+
}
|
|
506
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
507
|
+
? options.sitekey
|
|
508
|
+
: typeof options?.siteKey === 'string'
|
|
509
|
+
? options.siteKey
|
|
510
|
+
: '';
|
|
511
|
+
if (siteKey) {
|
|
512
|
+
challenges.push({
|
|
513
|
+
siteKey,
|
|
514
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
515
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
516
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
517
|
+
callbackId,
|
|
518
|
+
userAgent: navigator.userAgent,
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
return originalRender(container, options);
|
|
522
|
+
};
|
|
523
|
+
turnstile.__agentbrowseWrapped = true;
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
const fallbackTurnstile = win.turnstile;
|
|
529
|
+
if (fallbackTurnstile && typeof fallbackTurnstile === 'object') {
|
|
530
|
+
const turnstile = fallbackTurnstile;
|
|
531
|
+
if (typeof turnstile.render === 'function' && !turnstile.__agentbrowseWrapped) {
|
|
532
|
+
const originalRender = turnstile.render.bind(turnstile);
|
|
533
|
+
turnstile.render = (container, options) => {
|
|
534
|
+
const state = win[stateKey];
|
|
535
|
+
const callbacks = win[callbacksKey];
|
|
536
|
+
const challenges = win[challengesKey];
|
|
537
|
+
const callbackId = typeof options?.callback === 'function'
|
|
538
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
539
|
+
: '';
|
|
540
|
+
if (callbackId) {
|
|
541
|
+
callbacks[callbackId] = options.callback;
|
|
542
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
543
|
+
}
|
|
544
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
545
|
+
? options.sitekey
|
|
546
|
+
: typeof options?.siteKey === 'string'
|
|
547
|
+
? options.siteKey
|
|
548
|
+
: '';
|
|
549
|
+
if (siteKey) {
|
|
550
|
+
challenges.push({
|
|
551
|
+
siteKey,
|
|
552
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
553
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
554
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
555
|
+
callbackId,
|
|
556
|
+
userAgent: navigator.userAgent,
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
return originalRender(container, options);
|
|
560
|
+
};
|
|
561
|
+
turnstile.__agentbrowseWrapped = true;
|
|
562
|
+
}
|
|
563
|
+
else if (!turnstile.__agentbrowseWrapped) {
|
|
564
|
+
let renderValue = turnstile.render;
|
|
565
|
+
try {
|
|
566
|
+
Object.defineProperty(turnstile, 'render', {
|
|
567
|
+
configurable: true,
|
|
568
|
+
enumerable: true,
|
|
569
|
+
get: () => renderValue,
|
|
570
|
+
set: (value) => {
|
|
571
|
+
if (typeof value !== 'function') {
|
|
572
|
+
renderValue = value;
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
const originalRender = value.bind(turnstile);
|
|
576
|
+
renderValue = (container, options) => {
|
|
577
|
+
const state = win[stateKey];
|
|
578
|
+
const callbacks = win[callbacksKey];
|
|
579
|
+
const challenges = win[challengesKey];
|
|
580
|
+
const callbackId = typeof options?.callback === 'function'
|
|
581
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
582
|
+
: '';
|
|
583
|
+
if (callbackId) {
|
|
584
|
+
callbacks[callbackId] = options.callback;
|
|
585
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
586
|
+
}
|
|
587
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
588
|
+
? options.sitekey
|
|
589
|
+
: typeof options?.siteKey === 'string'
|
|
590
|
+
? options.siteKey
|
|
591
|
+
: '';
|
|
592
|
+
if (siteKey) {
|
|
593
|
+
challenges.push({
|
|
594
|
+
siteKey,
|
|
595
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
596
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
597
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
598
|
+
callbackId,
|
|
599
|
+
userAgent: navigator.userAgent,
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
return originalRender(container, options);
|
|
603
|
+
};
|
|
604
|
+
turnstile.__agentbrowseWrapped = true;
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
catch {
|
|
609
|
+
// Ignore non-configurable render properties.
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
const pollId = window.setInterval(() => {
|
|
615
|
+
const candidate = window.turnstile;
|
|
616
|
+
if (!candidate || typeof candidate !== 'object')
|
|
617
|
+
return;
|
|
618
|
+
const turnstile = candidate;
|
|
619
|
+
if (typeof turnstile.render !== 'function' || turnstile.__agentbrowseWrapped) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const originalRender = turnstile.render.bind(turnstile);
|
|
623
|
+
turnstile.render = (container, options) => {
|
|
624
|
+
const state = win[stateKey];
|
|
625
|
+
const callbacks = win[callbacksKey];
|
|
626
|
+
const challenges = win[challengesKey];
|
|
627
|
+
const callbackId = typeof options?.callback === 'function'
|
|
628
|
+
? `cf-turnstile-callback-${state.nextCallbackId ?? 1}`
|
|
629
|
+
: '';
|
|
630
|
+
if (callbackId) {
|
|
631
|
+
callbacks[callbackId] = options.callback;
|
|
632
|
+
state.nextCallbackId = (state.nextCallbackId ?? 1) + 1;
|
|
633
|
+
}
|
|
634
|
+
const siteKey = typeof options?.sitekey === 'string'
|
|
635
|
+
? options.sitekey
|
|
636
|
+
: typeof options?.siteKey === 'string'
|
|
637
|
+
? options.siteKey
|
|
638
|
+
: '';
|
|
639
|
+
if (siteKey) {
|
|
640
|
+
challenges.push({
|
|
641
|
+
siteKey,
|
|
642
|
+
action: typeof options?.action === 'string' ? options.action : '',
|
|
643
|
+
cData: typeof options?.cData === 'string' ? options.cData : '',
|
|
644
|
+
chlPageData: typeof options?.chlPageData === 'string' ? options.chlPageData : '',
|
|
645
|
+
callbackId,
|
|
646
|
+
userAgent: navigator.userAgent,
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
return originalRender(container, options);
|
|
650
|
+
};
|
|
651
|
+
turnstile.__agentbrowseWrapped = true;
|
|
652
|
+
}, 50);
|
|
653
|
+
window.setTimeout(() => {
|
|
654
|
+
window.clearInterval(pollId);
|
|
655
|
+
}, 30_000);
|
|
656
|
+
try {
|
|
657
|
+
if (typeof WebGLRenderingContext !== 'undefined') {
|
|
658
|
+
const getParameter = WebGLRenderingContext.prototype.getParameter;
|
|
659
|
+
WebGLRenderingContext.prototype.getParameter = function (parameter) {
|
|
660
|
+
const UNMASKED_VENDOR = 0x9245;
|
|
661
|
+
const UNMASKED_RENDERER = 0x9246;
|
|
662
|
+
if (parameter === UNMASKED_VENDOR)
|
|
663
|
+
return fingerprint.webglVendor;
|
|
664
|
+
if (parameter === UNMASKED_RENDERER)
|
|
665
|
+
return fingerprint.webglRenderer;
|
|
666
|
+
return getParameter.call(this, parameter);
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
catch {
|
|
671
|
+
// Some environments block prototype patching; keep the turnstile hook alive.
|
|
672
|
+
}
|
|
673
|
+
try {
|
|
674
|
+
Object.defineProperty(navigator, 'hardwareConcurrency', {
|
|
675
|
+
get: () => fingerprint.hardwareConcurrency,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
catch {
|
|
679
|
+
// Ignore non-configurable navigator fields.
|
|
680
|
+
}
|
|
681
|
+
try {
|
|
682
|
+
Object.defineProperty(navigator, 'deviceMemory', {
|
|
683
|
+
get: () => fingerprint.deviceMemory,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
catch {
|
|
687
|
+
// Ignore non-configurable navigator fields.
|
|
688
|
+
}
|
|
689
|
+
try {
|
|
690
|
+
Object.defineProperty(screen, 'width', { get: () => fingerprint.screen.width });
|
|
691
|
+
Object.defineProperty(screen, 'height', { get: () => fingerprint.screen.height });
|
|
692
|
+
Object.defineProperty(screen, 'colorDepth', { get: () => fingerprint.screen.colorDepth });
|
|
693
|
+
}
|
|
694
|
+
catch {
|
|
695
|
+
// Ignore non-configurable screen fields.
|
|
696
|
+
}
|
|
260
697
|
}, {
|
|
261
698
|
webglVendor: fp.webglVendor,
|
|
262
699
|
webglRenderer: fp.webglRenderer,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captcha-detector.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,2BAA2B,GAAG;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;IACpD,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"captcha-detector.d.ts","sourceRoot":"","sources":["../../src/solver/captcha-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,2BAA2B,GAAG;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;IACpD,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAyI3E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7F;AAED,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,2BAA2B,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAuHhC;AA4YD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA4B3E"}
|