turnstile fix

This commit is contained in:
evanpelle
2026-05-03 19:27:32 -06:00
parent 257fb9b38e
commit c63d3f8a23
2 changed files with 43 additions and 5 deletions
+42 -2
View File
@@ -1013,6 +1013,17 @@ const hideCrazyGamesElements = () => {
}
};
// Concurrent renders into #turnstile-container tangle Cloudflare's widget
// bookkeeping and produce "already executing" + postMessage origin-mismatch
// errors plus malformed tokens that fail siteverify with invalid-input-response.
// Serialize callers so only one widget is alive at a time.
//
// Declared above bootstrap() because the boot-time prefetch in
// Client.initialize() runs synchronously when document.readyState !== "loading"
// and would otherwise hit a TDZ on this binding.
let inFlightTurnstileChain: Promise<unknown> = Promise.resolve();
const TURNSTILE_TIMEOUT_MS = 20_000;
// Initialize the client when the DOM is loaded
const bootstrap = () => {
initLayout();
@@ -1036,6 +1047,17 @@ if (document.readyState === "loading") {
async function getTurnstileToken(): Promise<{
token: string;
createdAt: number;
}> {
const myCall = inFlightTurnstileChain
.catch(() => {})
.then(() => fetchOneTurnstileToken());
inFlightTurnstileChain = myCall;
return myCall;
}
async function fetchOneTurnstileToken(): Promise<{
token: string;
createdAt: number;
}> {
// Wait for Turnstile script to load (handles slow connections)
let attempts = 0;
@@ -1056,15 +1078,33 @@ async function getTurnstileToken(): Promise<{
theme: "light",
});
let cleanedUp = false;
const cleanup = () => {
if (cleanedUp) return;
cleanedUp = true;
try {
window.turnstile.remove(widgetId);
} catch (e) {
console.warn("turnstile.remove failed", e);
}
};
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
cleanup();
reject(new Error(`Turnstile timed out after ${TURNSTILE_TIMEOUT_MS}ms`));
}, TURNSTILE_TIMEOUT_MS);
window.turnstile.execute(widgetId, {
callback: (token: string) => {
window.turnstile.remove(widgetId);
clearTimeout(timeoutId);
cleanup();
console.log(`Turnstile token received: ${token}`);
resolve({ token, createdAt: Date.now() });
},
"error-callback": (errorCode: string) => {
window.turnstile.remove(widgetId);
clearTimeout(timeoutId);
cleanup();
console.error(`Turnstile error: ${errorCode}`);
alert(`Turnstile error: ${errorCode}. Please refresh and try again.`);
reject(new Error(`Turnstile failed: ${errorCode}`));
+1 -3
View File
@@ -40,9 +40,7 @@ const workerId = parseInt(process.env.WORKER_ID ?? "0");
const log = logger.child({ comp: `w_${workerId}` });
const playlist = new MapPlaylist();
// TEMPORARY: Turnstile validation disabled while we diagnose intermittent
// invalid-input-response rejections in v31. Flip back to true to re-enable.
const TURNSTILE_ENABLED = false;
const TURNSTILE_ENABLED = true;
// Worker setup
export async function startWorker() {