MCPcopy Index your code
hub / github.com/simstudioai/sim / verifyTurnstileToken

Function verifyTurnstileToken

apps/sim/lib/core/security/turnstile.ts:39–101  ·  view source on GitHub ↗
({
  token,
  remoteIp,
  expectedHostname,
  idempotencyKey,
}: VerifyTurnstileOptions)

Source from the content-addressed store, hash-verified

37 * are single-use and expire after 300 seconds; never cache the result.
38 */
39export async function verifyTurnstileToken({
40 token,
41 remoteIp,
42 expectedHostname,
43 idempotencyKey,
44}: VerifyTurnstileOptions): Promise<VerifyTurnstileResult> {
45 const secret = env.TURNSTILE_SECRET_KEY
46 if (!secret) {
47 logger.warn('Turnstile verification called without TURNSTILE_SECRET_KEY configured')
48 return { success: false, errorCodes: ['missing-input-secret'] }
49 }
50
51 if (!token) {
52 return { success: false, errorCodes: ['missing-input-response'] }
53 }
54
55 const body = new URLSearchParams()
56 body.set('secret', secret)
57 body.set('response', token)
58 if (remoteIp && remoteIp !== 'unknown') body.set('remoteip', remoteIp)
59 if (idempotencyKey) body.set('idempotency_key', idempotencyKey)
60
61 const controller = new AbortController()
62 const timeout = setTimeout(() => controller.abort(), TURNSTILE_TIMEOUT_MS)
63
64 try {
65 const response = await fetch(TURNSTILE_SITEVERIFY_URL, {
66 method: 'POST',
67 body,
68 signal: controller.signal,
69 })
70
71 if (!response.ok) {
72 logger.warn('Turnstile siteverify returned non-2xx', { status: response.status })
73 return { success: false, transportError: true }
74 }
75
76 const data = (await response.json()) as TurnstileSiteverifyResponse
77
78 if (!data.success) {
79 return { success: false, errorCodes: data['error-codes'] }
80 }
81
82 if (expectedHostname && data.hostname && data.hostname !== expectedHostname) {
83 logger.warn('Turnstile hostname mismatch', {
84 expected: expectedHostname,
85 actual: data.hostname,
86 })
87 return { success: false, errorCodes: ['hostname-mismatch'] }
88 }
89
90 return { success: true }
91 } catch (err) {
92 const error = toError(err)
93 logger.warn('Turnstile siteverify request failed', {
94 aborted: error.name === 'AbortError',
95 error: error.message,
96 })

Callers 1

route.tsFile · 0.90

Calls 4

toErrorFunction · 0.90
warnMethod · 0.65
setMethod · 0.65
abortMethod · 0.65

Tested by

no test coverage detected