worldwide todo list: public todo list of 68 real, sourced problems (planet to street) at /projects/worldwide-todo. worldtodo schema (categories, tasks, change_requests), idempotent seed on deploy, public add/edit/delete requests with Turnstile + salted daily-rotating IP-hash rate limit, owner-only review queue (approve, edit & approve, reject) with live updates over /ws/worldtodo(-owner), JSON API, detail pages with OSM map and history; listed in projects, header, /start and sitemap
Some checks failed
Deploy production / deploy (push) Failing after 9s
Some checks failed
Deploy production / deploy (push) Failing after 9s
This commit is contained in:
32
src/lib/server/worldtodo/turnstile.ts
Normal file
32
src/lib/server/worldtodo/turnstile.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { TURNSTILE_SECRET_KEY } from '$app/env/private';
|
||||
import { PUBLIC_TURNSTILE_SITE_KEY } from '$app/env/public';
|
||||
|
||||
// Cloudflare Turnstile on the request form, checked server-side through Siteverify.
|
||||
// Widget "stanrunge.dev worldwide todo list" (managed mode, domain stanrunge.dev).
|
||||
// Without both keys, request submission is switched off and the form says so.
|
||||
|
||||
const SITEVERIFY = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
|
||||
|
||||
export const turnstileSiteKey = () => PUBLIC_TURNSTILE_SITE_KEY || '';
|
||||
export const turnstileConfigured = () => !!(TURNSTILE_SECRET_KEY && PUBLIC_TURNSTILE_SITE_KEY);
|
||||
|
||||
export async function verifyTurnstile(
|
||||
token: string,
|
||||
fetcher: typeof fetch = fetch
|
||||
): Promise<boolean> {
|
||||
if (!turnstileConfigured() || !token || token.length > 2048) return false;
|
||||
try {
|
||||
const body = new URLSearchParams({ secret: TURNSTILE_SECRET_KEY, response: token });
|
||||
const res = await fetcher(SITEVERIFY, {
|
||||
method: 'POST',
|
||||
body,
|
||||
signal: AbortSignal.timeout(8000)
|
||||
});
|
||||
if (!res.ok) return false;
|
||||
const data = (await res.json()) as { success?: boolean };
|
||||
return data.success === true;
|
||||
} catch (e) {
|
||||
console.error('[worldtodo] turnstile siteverify failed', (e as Error).message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user