mirror of
https://github.com/germondai/trawl.git
synced 2026-08-17 12:11:23 +02:00
fix(tiers): escalate JS-shell challenge pages from Tier 1 to browser
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { FINGERPRINT } from "@trawl/browser"
|
||||
import type { TierResult } from "@trawl/types"
|
||||
import { isBlocked, isCloudflarePage } from "./detect"
|
||||
import { hasHcaptcha, hasRecaptcha, hasTurnstile, isBlocked, isCloudflarePage } from "./detect"
|
||||
import { normalizeHtml } from "./html"
|
||||
|
||||
export interface Tier1Result extends TierResult {
|
||||
@@ -42,6 +42,21 @@ export async function runTier1(
|
||||
return { tier: 1, status: "needs-js", durationMs: Date.now() - start, reason: "cloudflare-challenge" }
|
||||
}
|
||||
|
||||
// JS-only challenges: the page's static HTML is just a shell that loads the
|
||||
// captcha widget via <script src="...api.js">. Plain fetch sees the shell and
|
||||
// would otherwise report success — but the real content (including the widget)
|
||||
// only renders after JS executes. Escalate so Tier 3 runs the page in a browser,
|
||||
// executes JS, and the solver can engage the actual widget.
|
||||
if (hasHcaptcha(html)) {
|
||||
return { tier: 1, status: "needs-js", durationMs: Date.now() - start, reason: "hcaptcha-shell" }
|
||||
}
|
||||
if (hasRecaptcha(html)) {
|
||||
return { tier: 1, status: "needs-js", durationMs: Date.now() - start, reason: "recaptcha-shell" }
|
||||
}
|
||||
if (hasTurnstile(html)) {
|
||||
return { tier: 1, status: "needs-js", durationMs: Date.now() - start, reason: "turnstile-shell" }
|
||||
}
|
||||
|
||||
if (isBlocked(res.status, html)) {
|
||||
return { tier: 1, status: "blocked", durationMs: Date.now() - start, reason: `http-${res.status}` }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user