Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Add a function that checks a Cloudflare Turnstile token on the server

クローズ 初心者向け
#228 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@bhushan4work がすでに取り組んでいます。

2026年10月21日 から。

  • #282 @bhushan4work による — マージ済み

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
88/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
typescript
領域
backend, security

調査の方向性

既存の fetch タイムアウトのパターンを確認するために packages/server/src/webhook.ts を読み、fetch のモック方法を確認するために packages/server/tests/webhook-delivery.test.ts を読んでください。packages/server/src/security/turnstile.ts を実装し、指定されたテストを packages/server/tests/security/turnstile.test.ts に追加してください。リクエストフィールド、不一致のケース、例外を投げず secret を公開しない失敗を含め、受け入れ基準を満たしたら完了です。

索引モデルが issue の本文から書いたものです。

説明

enhancement hacktoberfest help wanted server

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/siteverify as described in Cloudflare's server-side validation docs, with secret, response, remoteip (when given) and idempotency_key (when given).
  • A token can only be redeemed once. The idempotency_key lets the server retry the same check after a network error without it failing as already used, so pass it through.
  • Return missing_token without calling the API when the token is empty, and unavailable when the request fails, times out (AbortSignal.timeout) or doesn't return JSON. Never throw.
  • Check hostname and action from 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.ts has a similar fetch with a timeout
  • packages/server/tests/webhook-delivery.test.ts shows how the tests fake fetch

Acceptance criteria

  • New packages/server/src/security/turnstile.ts and packages/server/tests/security/turnstile.test.ts
  • Tests cover success, success: false with 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_key and remoteip
  • The secret never appears in a returned value or in a log line
  • Not exported from @chatcops/server yet, and no changeset needed (pnpm changeset --empty)
  • pnpm test:coverage and pnpm lint pass

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.

主要言語
TypeScript
スター
13
フォーク
7
平均マージ
3時間 41分
マージ済み PR(30日)
155

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

codercops/chatcops のほかの issue

codercops/chatcops の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。