mirror of
https://github.com/yamadashy/repomix.git
synced 2026-05-30 11:18:53 +02:00
fix(website): Address PR review feedback on isBot pre-mint guard
Four items from gemini and claude reviews:
- botDetect.ts: Memoize isBot() result. navigator.userAgent is immutable
for the page lifetime, so re-running the isbot regex on every Turnstile
pre-mint debounce and post-submit re-mint check is wasted work. SSR
fallback is intentionally not cached so a module instance reused across
SSR/CSR still reaches the real UA check on first CSR call.
- usePackRequest.ts: Disambiguate the "submit-path NOT gated" comment —
it was confusing because the new post-submit re-mint also lives inside
submitRequest's finally. Reworded to "click-path acquireTurnstileToken"
to make clear which call site is intentionally skipped.
- usePackRequest.ts: Update the userTouched comment to reflect autofill
reality — modern Chromium/Firefox DO fire input events on autofill, so
the rationale ("autofill doesn't trigger") was already stale. The new
isBot() guard covers the gap for well-behaved crawler UAs.
- usePackRequest.ts: Add English glosses for the Japanese CF dashboard
labels (提示チャレンジ / 未解決) so non-Japanese-reading maintainers can
follow the comment.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,10 +32,16 @@ export function usePackRequest() {
|
||||
const uploadedFile = ref<File | null>(null);
|
||||
// True once the user has signalled real intent: typed/pasted a URL,
|
||||
// uploaded a file/folder, switched modes, or tweaked options. Used to
|
||||
// gate the Turnstile pre-mint so URL-parameter hydration (`?repo=...`),
|
||||
// browser autofill, form restoration, and JS-executing link unfurlers
|
||||
// don't trigger background challenges. Set-only — once true, it stays
|
||||
// true for the session.
|
||||
// gate the Turnstile pre-mint so URL-parameter hydration (`?repo=...`)
|
||||
// and form restoration don't trigger background challenges. Set-only —
|
||||
// once true, it stays true for the session.
|
||||
//
|
||||
// Caveat: modern Chromium / Firefox DO fire `input` events on browser
|
||||
// autofill, which would flip this flag through TryItUrlInput's handler
|
||||
// and trigger a wasted pre-mint for JS-executing crawlers that have
|
||||
// autofill-like behaviour. The `isBot()` check at the pre-mint trigger
|
||||
// sites covers that gap for well-behaved crawler UAs; sophisticated
|
||||
// bots that spoof UA still get filtered server-side by siteverify.
|
||||
const userTouched = ref(false);
|
||||
|
||||
// Request states
|
||||
@@ -93,12 +99,15 @@ export function usePackRequest() {
|
||||
// Skip background pre-mint for known crawlers. These visitors can't
|
||||
// solve the Turnstile challenge anyway (the JS challenge requires
|
||||
// real browser fingerprints), so issuing one only inflates the CF
|
||||
// dashboard "提示チャレンジ" / "未解決" counters without producing a
|
||||
// usable token. The actual security gate is the server-side
|
||||
// siteverify in turnstileMiddleware — that stays unchanged, so a
|
||||
// crawler that spoofs UA past `isBot()` still gets blocked there.
|
||||
// Submit-path takeToken is intentionally NOT gated to avoid
|
||||
// false-positive lockouts of legit users with unusual UAs.
|
||||
// dashboard "提示チャレンジ" (issued challenges) / "未解決"
|
||||
// (unsolved) counters without producing a usable token. The actual
|
||||
// security gate is the server-side siteverify in
|
||||
// turnstileMiddleware — that stays unchanged, so a crawler that
|
||||
// spoofs UA past `isBot()` still gets blocked there. The click-path
|
||||
// `acquireTurnstileToken()` (cold-mint at submit time) is
|
||||
// intentionally NOT gated to avoid false-positive lockouts of legit
|
||||
// users with unusual UAs; only the warm-up paths short-circuit here
|
||||
// and at the post-submit re-mint below.
|
||||
if (isBot()) return;
|
||||
turnstile.preMintToken().catch(() => {
|
||||
/* errors surface on the actual submit path */
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { isbot } from 'isbot';
|
||||
|
||||
// Cache the per-session result. `navigator.userAgent` is immutable for the
|
||||
// life of the page, and `isbot()` runs a non-trivial regex match — caching
|
||||
// avoids re-parsing the UA on every Turnstile pre-mint debounce or
|
||||
// post-submit re-mint check. The SSR fallback (`navigator === undefined`)
|
||||
// is intentionally NOT cached so that if the same module instance is
|
||||
// somehow reused between SSR and CSR, the CSR path still reaches the real
|
||||
// UA check on first call.
|
||||
let cached: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Detects whether the current user agent is a bot/crawler.
|
||||
* Used to prevent automatic API calls when bots render pages with JavaScript.
|
||||
@@ -8,5 +17,8 @@ export function isBot(): boolean {
|
||||
if (typeof navigator === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
return isbot(navigator.userAgent);
|
||||
if (cached === undefined) {
|
||||
cached = isbot(navigator.userAgent);
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user