Fix-auth-hashing-update-worklog

This commit is contained in:
SpecialX
2026-02-24 15:50:38 +08:00
parent bb4555f611
commit a2e89ce795
5 changed files with 63 additions and 10 deletions

View File

@@ -1,4 +1,5 @@
import { Metadata } from "next"
import { hash } from "bcryptjs"
import { createId } from "@paralleldrive/cuid2"
import { eq } from "drizzle-orm"
@@ -10,6 +11,12 @@ export const metadata: Metadata = {
description: "Create an account",
}
const normalizeBcryptHash = (value: string) => {
if (value.startsWith("$2")) return value
if (value.startsWith("$")) return `$2b${value}`
return `$2b$${value}`
}
export default function RegisterPage() {
async function registerAction(formData: FormData): Promise<ActionState> {
"use server"
@@ -37,11 +44,12 @@ export default function RegisterPage() {
})
if (existing) return { success: false, message: "该邮箱已注册" }
const hashedPassword = normalizeBcryptHash(await hash(password, 10))
await db.insert(users).values({
id: createId(),
name: name.length ? name : null,
email,
password,
password: hashedPassword,
role: "student",
})

View File

@@ -1,6 +1,19 @@
import { compare, hash } from "bcryptjs"
import NextAuth from "next-auth"
import Credentials from "next-auth/providers/credentials"
const normalizeRole = (value: unknown) => {
const role = String(value ?? "").trim().toLowerCase()
if (role === "admin" || role === "student" || role === "teacher" || role === "parent") return role
return "student"
}
const normalizeBcryptHash = (value: string) => {
if (value.startsWith("$2")) return value
if (value.startsWith("$")) return `$2b${value}`
return `$2b$${value}`
}
export const { handlers, auth, signIn, signOut } = NextAuth({
trustHost: true,
secret: process.env.NEXTAUTH_SECRET,
@@ -29,17 +42,17 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
if (!user) return null
const storedPassword = user.password ?? null
if (storedPassword) {
if (storedPassword !== password) return null
} else if (process.env.NODE_ENV === "production") {
return null
}
if (!storedPassword) return null
const normalizedPassword = normalizeBcryptHash(storedPassword)
if (!normalizedPassword.startsWith("$2")) return null
const ok = await compare(password, normalizedPassword)
if (!ok) return null
return {
id: user.id,
name: user.name ?? undefined,
email: user.email,
role: (user.role ?? "student") as string,
role: normalizeRole(user.role),
}
},
}),
@@ -48,7 +61,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
jwt: async ({ token, user }) => {
if (user) {
token.id = (user as { id: string }).id
token.role = (user as { role?: string }).role ?? "student"
token.role = normalizeRole((user as { role?: string }).role)
token.name = (user as { name?: string }).name
}
@@ -66,7 +79,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
})
if (fresh) {
token.role = fresh.role ?? token.role ?? "student"
token.role = normalizeRole(fresh.role ?? token.role)
token.name = fresh.name ?? token.name
}
}
@@ -76,7 +89,7 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
session: async ({ session, token }) => {
if (session.user) {
session.user.id = String(token.id ?? "")
session.user.role = String(token.role ?? "student")
session.user.role = normalizeRole(token.role)
if (typeof token.name === "string") {
session.user.name = token.name
}