Files
chinese-family-tree-2/lib/permissions.ts
T
freedakgmail e44dd0bd95 0.0.8.0
2025-11-23 18:03:04 +08:00

283 lines
5.9 KiB
TypeScript

import { prisma } from "./prisma"
import { Role as PrismaRole } from "@prisma/client"
// 导出 Role 类型供前端使用
export type Role = "OWNER" | "EDITOR" | "VIEWER"
export async function checkPermission(
userId: string,
treeId: string,
requiredRole: PrismaRole = PrismaRole.VIEWER
) {
// 检查是否是所有者
const tree = await prisma.familyTree.findFirst({
where: {
id: treeId,
ownerId: userId
}
})
if (tree) {
return { hasPermission: true, role: PrismaRole.OWNER as Role }
}
// 检查协作者权限
const collaborator = await prisma.treeCollaborator.findFirst({
where: {
treeId,
userId
}
})
if (!collaborator) {
return { hasPermission: false, role: null }
}
const roleHierarchy = {
[PrismaRole.OWNER]: 3,
[PrismaRole.EDITOR]: 2,
[PrismaRole.VIEWER]: 1
}
const hasPermission = roleHierarchy[collaborator.role] >= roleHierarchy[requiredRole]
return { hasPermission, role: collaborator.role as Role }
}
export async function requireAuth(userId: string | undefined) {
if (!userId) {
throw new Error("未授权")
}
return userId
}
/**
* 权限控制工具函数
* 用于基于角色的访问控制 (RBAC)
*/
/**
* 权限检查函数集合
*/
export const permissions = {
// ==================== 增加权限 ====================
/**
* 是否可以创建/添加成员
* OWNER | EDITOR | VIEWER
*/
canCreate: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
/**
* 是否可以创建家族树
* 所有登录用户都可以创建自己的家族树
*/
canCreateTree: (role?: Role): boolean => {
return true // 所有人都可以创建新家族树
},
// ==================== 修改权限 ====================
/**
* 是否可以编辑/更新成员信息
* OWNER | EDITOR | VIEWER
*/
canUpdate: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
/**
* 是否可以导入数据
* OWNER | EDITOR | VIEWER
*/
canImport: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
// ==================== 删除权限 ====================
/**
* 是否可以删除成员
* OWNER | EDITOR | VIEWER
*/
canDeleteMember: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
/**
* 是否可以删除家族树
* OWNER | EDITOR | VIEWER
*/
canDeleteTree: (role?: Role): boolean => {
return role === "OWNER"
},
/**
* 是否可以清空数据
* OWNER | EDITOR | VIEWER
*/
canClearData: (role?: Role): boolean => {
return role === "OWNER"
},
// ==================== 协作者管理权限 ====================
/**
* 是否可以邀请协作者
* OWNER | EDITOR | VIEWER
*/
canInviteCollaborators: (role?: Role): boolean => {
return role === "OWNER"
},
/**
* 是否可以移除协作者
* OWNER | EDITOR | VIEWER
*/
canRemoveCollaborators: (role?: Role): boolean => {
return role === "OWNER"
},
/**
* 是否可以管理协作者(邀请和移除)
* OWNER | EDITOR | VIEWER
*/
canManageCollaborators: (role?: Role): boolean => {
return role === "OWNER"
},
// ==================== 查看权限 ====================
/**
* 是否可以查看信息
* OWNER | EDITOR | VIEWER
*/
canView: (role?: Role): boolean => {
return true //
},
/**
* 是否可以搜索和查询
* OWNER | EDITOR | VIEWER
*/
canSearch: (role?: Role): boolean => {
return true //
},
/**
* 是否可以导出数据
* OWNER | EDITOR | VIEWER
*/
canExport: (role?: Role): boolean => {
return true //
},
/**
* 是否可以打印
* OWNER | EDITOR | VIEWER
*/
canPrint: (role?: Role): boolean => {
return true //
},
}
// ==================== 兼容旧代码的函数 ====================
/**
* @deprecated
*/
export function canEditTree(role?: Role): boolean {
return permissions.canUpdate(role)
}
/**
* @deprecated
*/
export function canDeleteTree(role?: Role): boolean {
return permissions.canDeleteTree(role)
}
/**
* @deprecated
*/
export function canInviteCollaborators(role?: Role): boolean {
return permissions.canInviteCollaborators(role)
}
// ==================== 权限验证辅助函数 ====================
/**
*
*/
export function requirePermission(
role: Role | undefined,
permissionCheck: (role?: Role) => boolean,
errorMessage: string = "您没有权限执行此操作"
): void {
if (!permissionCheck(role)) {
throw new Error(errorMessage)
}
}
/**
*
*/
export function getRoleDisplayName(role: Role): string {
const roleNames: Record<Role, string> = {
OWNER: "所有者",
EDITOR: "编辑者",
VIEWER: "查看者",
}
return roleNames[role] || role
}
/**
*
*/
export function getRoleDescription(role: Role): string {
const descriptions: Record<Role, string> = {
OWNER: "拥有全部权限,可以管理家族树和协作者",
EDITOR: "可以添加、编辑和删除成员,但不能删除家族树或管理协作者",
VIEWER: "只能查看、搜索和导出数据,不能进行任何修改操作",
}
return descriptions[role] || ""
}
/**
*
*/
export function getRolePermissions(role: Role): string[] {
const allPermissions = {
OWNER: [
"查看所有信息",
"搜索和筛选",
"导出和打印",
"添加成员",
"编辑成员",
"删除成员",
"导入数据",
"邀请协作者",
"移除协作者",
"删除家族树",
"清空数据",
],
EDITOR: [
"查看所有信息",
"搜索和筛选",
"导出和打印",
"添加成员",
"编辑成员",
"删除成员",
"导入数据",
],
VIEWER: [
"查看所有信息",
"搜索和筛选",
"导出和打印",
],
}
return allPermissions[role] || []
}