feat: align with upstream 1.5.9.9

This commit is contained in:
2026-09-12 18:21:11 +08:00
commit 34f0679117
805 changed files with 376275 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
/**
* 图形验证码校验与销毁
* 统一使用 captchaStore(Redis 或内存 Map),与 /api/auth/captcha 生成接口共享存储。
*
* 注意:生成端写入的 key 形如 `captcha:<id>`,本文件必须使用相同前缀,
* 否则会出现"验证码输对了仍不通过"的问题。
*/
import {
delStore,
getAndDelStore,
getStore,
hashStateCode,
setStore,
verifyStateCode
} from './captchaStore'
const keyOf = (id: string) => `captcha:${id}`
// 与生成端保持一致:5 分钟有效
const CAPTCHA_TTL_SECONDS = 300
/** 保存验证码(保留以兼容直接调用此函数的旧代码) */
export async function saveCaptcha(id: string, text: string) {
const key = keyOf(id)
await setStore(key, hashStateCode(key, String(text).toLowerCase()), CAPTCHA_TTL_SECONDS)
}
/** 只校验验证码是否正确,不删除 */
export async function verifyCaptcha(captchaId: string, userInput: string): Promise<boolean> {
if (!captchaId || !userInput) return false
const stored = await getStore(keyOf(captchaId))
if (!stored) return false
return verifyStateCode(keyOf(captchaId), String(userInput).toLowerCase(), stored)
}
/** 仅删除验证码,不校验 */
export async function consumeCaptcha(captchaId: string): Promise<void> {
if (!captchaId) return
await delStore(keyOf(captchaId))
}
/** 校验并立即销毁验证码(无论成功与否均销毁) */
export async function verifyAndConsumeCaptcha(
captchaId: string,
userInput: string
): Promise<boolean> {
if (!captchaId || !userInput) return false
const stored = await getAndDelStore(keyOf(captchaId))
if (!stored) return false
return verifyStateCode(keyOf(captchaId), String(userInput).toLowerCase(), stored)
}