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!
This commit is contained in:
wukko 2025-05-23 20:37:47 +06:00
parent 1c5e038372
commit add0ab4adf
No known key found for this signature in database
GPG Key ID: 3E30B3F26C7B4AA2
2 changed files with 41 additions and 31 deletions

View File

@ -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?", "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!" "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!"
} }

View File

@ -11,34 +11,56 @@ import { getServerInfo } from "$lib/api/server-info";
import type { Optional } from "$lib/types/generic"; import type { Optional } from "$lib/types/generic";
import type { CobaltAPIResponse, CobaltErrorResponse, CobaltSaveRequestBody } from "$lib/types/api"; 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 getAuthorization = async () => {
const processing = get(settings).processing; const processing = get(settings).processing;
if (processing.enableCustomApiKey && processing.customApiKey.length > 0) {
return `Api-Key ${processing.customApiKey}`;
}
if (get(turnstileEnabled)) { if (!get(turnstileEnabled)) {
if (!get(turnstileSolved)) { return;
}
if (!get(turnstileSolved)) {
try {
await waitForTurnstile();
} catch {
return { return {
status: "error", status: "error",
error: { error: {
code: "error.captcha_ongoing" code: "error.captcha_too_long"
} }
} as CobaltErrorResponse; } 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) { const session = await getSession();
return `Api-Key ${processing.customApiKey}`;
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 && !justRetried
) { ) {
resetSession(); resetSession();
await waitForTurnstile().catch(() => {}); await getAuthorization();
return request(requestBody, true); return request(requestBody, true);
} }
return response; return response;
} }
const waitForTurnstile = async () => {
await getAuthorization();
return new Promise<void>(resolve => {
const unsub = turnstileSolved.subscribe(solved => {
if (solved) {
unsub();
resolve();
}
});
});
}
const probeCobaltTunnel = async (url: string) => { const probeCobaltTunnel = async (url: string) => {
const request = await fetch(`${url}&p=1`).catch(() => {}); const request = await fetch(`${url}&p=1`).catch(() => {});
if (request?.status === 200) { if (request?.status === 200) {