Files
hair-keeper/src/server/auth.ts

123 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'server-only'
import { NextAuthOptions } from "next-auth"
import type { User as NextAuthUser } from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import bcrypt from "bcryptjs"
import { db } from "./db"
export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
name: "credentials",
credentials: {
id: { label: "用户ID", type: "text" },
password: { label: "密码", type: "password" }
},
async authorize(credentials, req): Promise<NextAuthUser | null> {
if (!credentials?.id || !credentials?.password) {
return null
}
try {
// 查找用户
const user = await db.user.findUnique({
where: {
id: credentials.id
},
include: {
roles: {
include: { permissions: true }
},
dept: true
}
})
if (!user) {
return null
}
// 验证密码
const isPasswordValid = await bcrypt.compare(credentials.password, user.password)
if (!isPasswordValid) {
return null
}
// 更新最近登录时间
await db.user.update({
where: { id: user.id },
data: { lastLoginAt: new Date() }
})
// 返回用户信息、角色和权限
const roles = user.roles.map((r) => r.name)
const permissions = Array.from(
new Set(user.roles.flatMap((r) =>
r.permissions.map((p) => p.name)
))
)
return {
id: user.id,
name: user.name,
status: user.status,
deptCode: user.deptCode,
roles,
permissions,
isSuperAdmin: user.isSuperAdmin
} as any
} catch (error) {
console.error("Auth error:", error)
return null
}
}
})
],
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 days
},
jwt: {
maxAge: 30 * 24 * 60 * 60, // 30 days
},
pages: {
signIn: "/login",
},
callbacks: {
async jwt({ token, user }) {
// 初次登录时将用户信息保存到JWT token中
if (user) {
const u = user as any
token = {
...token,
id: u.id,
name: u.name,
status: u.status,
deptCode: u.deptCode,
roles: u.roles,
permissions: u.permissions,
isSuperAdmin: u.isSuperAdmin,
}
}
return token
},
async session({ session, token }) {
// 将JWT token中的信息传递给session
if (session.user) {
const t = token as any
session.user = {
...session.user,
id: t.id,
name: t.name,
status: t.status,
deptCode: t.deptCode,
roles: t.roles,
permissions: t.permissions,
isSuperAdmin: t.isSuperAdmin,
}
}
return session
}
},
secret: process.env.NEXTAUTH_SECRET,
}