From add0ab4adf7bd6ecb995b3de601f225d0bdcb50a Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 23 May 2025 20:37:47 +0600 Subject: [PATCH] web/lib/api: wait for turnstile solution, refactor now cobalt waits for turnstile for 15 seconds before showing an assistive dialog, instead of showing the dialog right away. much better ux! --- web/i18n/en/error.json | 2 +- web/src/lib/api/api.ts | 70 ++++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/web/i18n/en/error.json b/web/i18n/en/error.json index 4e6b74b3..f670962b 100644 --- a/web/i18n/en/error.json +++ b/web/i18n/en/error.json @@ -5,7 +5,7 @@ "tunnel.probe": "couldn't test this tunnel. your browser or network configuration may be blocking access to one of cobalt servers. are you sure you don't have any weird browser extensions?", - "captcha_ongoing": "cloudflare turnstile is still checking if you're not a bot. if it takes too long, you can try: disabling weird browser extensions, changing networks, using a different browser, or checking your device for malware.", + "captcha_too_long": "cloudflare turnstile is taking too long to check if you're not a bot. try again, but if it takes way too long again, you can try: disabling weird browser extensions, changing networks, using a different browser, or checking your device for malware.", "pipeline.missing_response_data": "the processing instance didn't return required file info, so i can't create a local processing pipeline for you. try again in a few seconds and report the issue if it sticks!" } diff --git a/web/src/lib/api/api.ts b/web/src/lib/api/api.ts index 1eab6e24..0467adf3 100644 --- a/web/src/lib/api/api.ts +++ b/web/src/lib/api/api.ts @@ -11,34 +11,56 @@ import { getServerInfo } from "$lib/api/server-info"; import type { Optional } from "$lib/types/generic"; import type { CobaltAPIResponse, CobaltErrorResponse, CobaltSaveRequestBody } from "$lib/types/api"; +const waitForTurnstile = async () => { + return await new Promise((resolve, reject) => { + const unsub = turnstileSolved.subscribe((solved) => { + if (solved) { + unsub(); + resolve(true); + } + }); + + // wait for turnstile to finish for 15 seconds + setTimeout(() => { + unsub(); + reject(false); + }, 15 * 1000) + }); +} + const getAuthorization = async () => { const processing = get(settings).processing; + if (processing.enableCustomApiKey && processing.customApiKey.length > 0) { + return `Api-Key ${processing.customApiKey}`; + } - if (get(turnstileEnabled)) { - if (!get(turnstileSolved)) { + if (!get(turnstileEnabled)) { + return; + } + + if (!get(turnstileSolved)) { + try { + await waitForTurnstile(); + } catch { return { status: "error", error: { - code: "error.captcha_ongoing" + code: "error.captcha_too_long" } } as CobaltErrorResponse; } - - const session = await getSession(); - - if (session) { - if ("error" in session) { - if (session.error.code !== "error.api.auth.not_configured") { - return session; - } - } else { - return `Bearer ${session.token}`; - } - } } - if (processing.enableCustomApiKey && processing.customApiKey.length > 0) { - return `Api-Key ${processing.customApiKey}`; + const session = await getSession(); + + if (session) { + if ("error" in session) { + if (session.error.code !== "error.api.auth.not_configured") { + return session; + } + } else { + return `Bearer ${session.token}`; + } } } @@ -100,25 +122,13 @@ const request = async (requestBody: CobaltSaveRequestBody, justRetried = false) && !justRetried ) { resetSession(); - await waitForTurnstile().catch(() => {}); + await getAuthorization(); return request(requestBody, true); } return response; } -const waitForTurnstile = async () => { - await getAuthorization(); - return new Promise(resolve => { - const unsub = turnstileSolved.subscribe(solved => { - if (solved) { - unsub(); - resolve(); - } - }); - }); -} - const probeCobaltTunnel = async (url: string) => { const request = await fetch(`${url}&p=1`).catch(() => {}); if (request?.status === 200) {