Skip to content

Commit cc1f24d

Browse files
committed
fix: reduce Turnstile verification timeouts from 15s to 8s on the client and 10s to 5s on the server, and check userAgent for bot patterns
1 parent 703bb9b commit cc1f24d

3 files changed

Lines changed: 59 additions & 16 deletions

File tree

packages/webapp/Helpers/validateTurnstileAccess.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,58 @@ import { type GetServerSidePropsContext } from 'next'
55
export const validateTurnstileAccess = (context: GetServerSidePropsContext): boolean => {
66
const cookies = cookie.parse(context.req.headers.cookie || '')
77

8+
// Always challenge bots and suspicious traffic
9+
const userAgent = context.req.headers['user-agent'] || ''
10+
const botPatterns = [
11+
// Generic patterns
12+
'bot',
13+
'crawler',
14+
'spider',
15+
'scraper',
16+
// Tools & scripts
17+
'curl',
18+
'wget',
19+
'python',
20+
'java',
21+
'ruby',
22+
'go-http',
23+
'postman',
24+
'insomnia',
25+
'httpie',
26+
// Social media bots
27+
'facebookexternalhit',
28+
'twitterbot',
29+
'linkedinbot',
30+
'slackbot',
31+
'discordbot',
32+
'telegrambot',
33+
'whatsapp',
34+
// Search engines
35+
'googlebot',
36+
'bingbot',
37+
'duckduckbot',
38+
'baiduspider',
39+
'yandexbot',
40+
'sogou',
41+
'msnbot',
42+
'applebot',
43+
// SEO & monitoring
44+
'ahrefsbot',
45+
'semrushbot',
46+
'mj12bot',
47+
'dotbot',
48+
'blexbot',
49+
'petalbot',
50+
'bytedance',
51+
'facebot',
52+
// Archives & misc
53+
'ia_archiver',
54+
'wayback'
55+
]
56+
57+
const isBot = new RegExp(botPatterns.join('|'), 'i').test(userAgent)
58+
if (isBot) return false // Always challenge bots
59+
860
const isTurnstileVerified = Config.app.turnstile.isEnabled
961
? cookies.turnstileVerified === 'true'
1062
: true

packages/webapp/components/skeleton/SlugPageLoaderWithTurnstile.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const TurnstileModal = ({ showTurnstile }: Props) => {
4747
method: 'POST',
4848
headers: { 'Content-Type': 'application/json' },
4949
body: JSON.stringify({ token }),
50-
signal: AbortSignal.timeout(15000)
50+
signal: AbortSignal.timeout(8000) // Reduced from 15s to 8s
5151
})
5252

5353
const data = await response.json()
@@ -62,20 +62,12 @@ const TurnstileModal = ({ showTurnstile }: Props) => {
6262
throw new Error(data.message || 'Verification failed')
6363
}
6464
} catch (err) {
65-
let errorMessage = 'Verification failed. Please try again.'
66-
67-
if (err instanceof Error) {
68-
if (err.name === 'TimeoutError') {
69-
errorMessage = 'Verification timed out. Please try again.'
70-
} else if (err.message.includes('fetch')) {
71-
errorMessage = 'Network error. Please check your connection.'
72-
} else {
73-
errorMessage = err.message
74-
}
75-
}
76-
7765
setState('error')
78-
setError(errorMessage)
66+
setError(
67+
err instanceof Error && err.name === 'TimeoutError'
68+
? 'Verification timed out. Please try again.'
69+
: 'Verification failed. Please try again.'
70+
)
7971
console.error('Turnstile verification error:', err)
8072
}
8173
},

packages/webapp/pages/api/verify-turnstile.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
4141
const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
4242
method: 'POST',
4343
body: formData,
44-
// Add timeout to prevent hanging
45-
signal: AbortSignal.timeout(10000)
44+
signal: AbortSignal.timeout(5000) // Reduced timeout
4645
})
4746

4847
if (!response.ok) {

0 commit comments

Comments
 (0)