feat(turnstile): integrate Cloudflare Turnstile for enhanced security in login and registration processes

This commit is contained in:
beilunyang
2025-10-22 23:31:48 +08:00
parent 1ffe920d47
commit e431c1fe5b
22 changed files with 480 additions and 56 deletions

View File

@@ -8,9 +8,10 @@ import { getRequestContext } from "@cloudflare/next-on-pages"
import { Permission, hasPermission, ROLES, Role } from "./permissions"
import CredentialsProvider from "next-auth/providers/credentials"
import { hashPassword, comparePassword } from "@/lib/utils"
import { authSchema } from "@/lib/validation"
import { authSchema, AuthSchema } from "@/lib/validation"
import { generateAvatarUrl } from "./avatar"
import { getUserId } from "./apiKey"
import { verifyTurnstileToken } from "./turnstile"
const ROLE_DESCRIPTIONS: Record<Role, string> = {
[ROLES.EMPEROR]: "皇帝(网站所有者)",
@@ -113,26 +114,35 @@ export const {
throw new Error("请输入用户名和密码")
}
const { username, password } = credentials
const { username, password, turnstileToken } = credentials as Record<string, string | undefined>
let parsedCredentials: AuthSchema
try {
authSchema.parse({ username, password })
parsedCredentials = authSchema.parse({ username, password, turnstileToken })
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
throw new Error("输入格式不正确")
}
const verification = await verifyTurnstileToken(parsedCredentials.turnstileToken)
if (!verification.success) {
if (verification.reason === "missing-token") {
throw new Error("请先完成安全验证")
}
throw new Error("安全验证未通过")
}
const db = createDb()
const user = await db.query.users.findFirst({
where: eq(users.username, username as string),
where: eq(users.username, parsedCredentials.username),
})
if (!user) {
throw new Error("用户名或密码错误")
}
const isValid = await comparePassword(password as string, user.password as string)
const isValid = await comparePassword(parsedCredentials.password, user.password as string)
if (!isValid) {
throw new Error("用户名或密码错误")
}