Hair Keeper v1.0.0:一个高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑

This commit is contained in:
2025-11-13 15:24:54 +08:00
commit 42be39b343
249 changed files with 38843 additions and 0 deletions

123
src/server/auth.ts Normal file
View File

@@ -0,0 +1,123 @@
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,
}