Add a function that checks a Cloudflare Turnstile token on the server
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 88/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
Línea de trabajo
Lee packages/server/src/webhook.ts para ver el patrón existente de timeout de fetch y packages/server/tests/webhook-delivery.test.ts para ver cómo se simula fetch. Implementa packages/server/src/security/turnstile.ts y añade las pruebas especificadas en packages/server/tests/security/turnstile.test.ts. El trabajo estará terminado cuando se cumplan los criterios de aceptación, incluidos los campos de la solicitud, los casos de discrepancia y los errores que no deben lanzar excepciones ni exponer el secreto.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
ChatCops is getting optional Cloudflare Turnstile checks: the widget gets a token from Turnstile when a visitor first opens the chat, and the server checks it before it starts a session. This issue is the server half of that check, as one small function in a new file. Wiring it into a route comes later, so this PR doesn't touch anything else.
What to do
Create packages/server/src/security/turnstile.ts with:
export interface TurnstileConfig {
secretKey: string;
/** The action set in the widget, if any. A token for another action is rejected. */
action?: string;
/** Hostnames the token may come from. Unset means any. */
expectedHostnames?: string[];
/** Default 5000. */
timeoutMs?: number;
}
export type TurnstileResult =
| { ok: true; hostname?: string; action?: string }
| { ok: false; code: 'missing_token' | 'invalid_token' | 'hostname_mismatch' | 'action_mismatch' | 'unavailable'; errorCodes?: string[] };
export async function verifyTurnstile(
token: string | undefined,
config: TurnstileConfig,
opts?: { remoteIp?: string; idempotencyKey?: string; fetch?: typeof fetch }
): Promise<TurnstileResult>;
- POST to
https://challenges.cloudflare.com/turnstile/v0/siteverifyas described in Cloudflare's server-side validation docs, withsecret,response,remoteip(when given) andidempotency_key(when given). - A token can only be redeemed once. The
idempotency_keylets the server retry the same check after a network error without it failing as already used, so pass it through. - Return
missing_tokenwithout calling the API when the token is empty, andunavailablewhen the request fails, times out (AbortSignal.timeout) or doesn't return JSON. Never throw. - Check
hostnameandactionfrom the response against the config. - Use
opts.fetch ?? globalThis.fetch, so tests can pass a fake. Don't import anything from Node; this has to run on Workers too.
Where to look
packages/server/src/webhook.tshas a similar fetch with a timeoutpackages/server/tests/webhook-delivery.test.tsshows how the tests fakefetch
Acceptance criteria
- New
packages/server/src/security/turnstile.tsandpackages/server/tests/security/turnstile.test.ts - Tests cover success,
success: falsewith error codes, hostname and action mismatch, an empty token (no request sent), a network error, a timeout and a non-JSON reply - A test checks the request body, including
idempotency_keyandremoteip - The secret never appears in a returned value or in a log line
- Not exported from
@chatcops/serveryet, and no changeset needed (pnpm changeset --empty) -
pnpm test:coverageandpnpm lintpass
Want to work on this? Comment below and I'll assign it to you. Please take one issue at a time, branch off dev, and open your PR against dev with Closes #<this issue number>. Setup notes (pnpm, build before test) are in CONTRIBUTING.md.
- Lenguaje dominante
- TypeScript
- Estrellas
- 13
- Forks
- 7
- Merge medio
- 3 h 33 min
- PR fusionados (30 d)
- 176
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de codercops/chatcops
-
Add startup checks that catch weak or leaked security settingsPosiblemente ocupada @varun-pahuja la tomó hace 2 días. Abiertoenhancement good first issue hacktoberfest server
codercops/chatcops#231 · 3 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Type-check the TypeScript samples in the docsPosiblemente ocupada @An16og la tomó hace 1 día. Abiertodocumentation hacktoberfest help wanted testing
Dificultad 4/5 3-5 días Aptitud para principiantes 70/100
codercops/chatcops#201 · 7 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Hacktoberfest 2026: start hereAbiertohacktoberfest
Dificultad 1/5 Menos de una hora Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
Add built-in translations to the widgetPosiblemente ocupada @piyusshhjangid la tomó hoy. Abiertohelp wanted widget
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
codercops/chatcops#55 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
Todos los issues de codercops/chatcops
Issues similares
-
createAI: the ai peer range allows ai@6, which the provider cannot work withPosiblemente ocupada @akhil9tiet la tomó hoy. Abiertobug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 83/100
cloudflare/agents#2690 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
[fullsend] E2E: theme — global-header ignores app.branding.fullLogo (RHDHBUGS-3670)Posiblemente ocupada @fullsend-ai-coder la tomó hoy. Abiertoe2e-failure ready-to-code
Dificultad 1/5 Menos de una hora Aptitud para principiantes 78/100
redhat-developer/rhdh-plugin-export-overlays#4503 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
needs triage 📥
Dificultad 1/5 Menos de una hora Aptitud para principiantes 86/100
ethereum/ethereum-org-website#19601 ·
Los mantenedores suelen responder en 1 día
-
[Bug]: Circular app layout navigation and help icons are shifted upward in the official demoAbiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
cloudscape-design/components#5184 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
agilepathway/label-checker#805 ·
Los mantenedores suelen responder en 1 día