You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

44 lines
1.1 KiB

import svgCaptcha from 'svg-captcha'
interface CaptchaRecord {
text: string
createdAt: number
}
const captchaStore = new Map<string, CaptchaRecord>()
const CAPTCHA_TTL = 5 * 60 * 1000
function cleanupExpired(): void {
const now = Date.now()
for (const [token, record] of captchaStore) {
if (now - record.createdAt > CAPTCHA_TTL) {
captchaStore.delete(token)
}
}
}
export function generateCaptcha(): { token: string; svg: string } {
cleanupExpired()
const { text, data: svg } = svgCaptcha.create({
noise: 3,
color: true,
background: '#f8f9fa',
})
const token = crypto.randomUUID()
captchaStore.set(token, { text, createdAt: Date.now() })
return { token, svg }
}
export function verifyCaptcha(token: string, text: string): boolean {
const record = captchaStore.get(token)
if (!record) return false
if (Date.now() - record.createdAt > CAPTCHA_TTL) {
captchaStore.delete(token)
return false
}
const match = record.text.toLowerCase() === text.toLowerCase()
if (match) {
captchaStore.delete(token)
}
return match
}