@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
344 lines (290 loc) • 8.48 kB
text/typescript
"use client";
import { useSession } from "next-auth/react";
import { useMemo } from "react";
import { UserRole } from "./middleware";
import {
Permission,
hasPermission,
hasAllPermissions,
hasAnyPermission,
hasResourcePermission,
canManageUser,
isHigherRole,
shouldShowComponent,
filterMenuItems,
type MenuItem,
} from "./rbac";
/**
* 현재 사용자의 인증 상태와 권한 정보를 제공하는 훅
*/
export function useAuth() {
const { data: session, status } = useSession();
const user = useMemo(() => {
if (!session?.user) return null;
return {
id: session.user.id,
email: session.user.email,
name: session.user.name,
image: session.user.image,
role: session.user.role as UserRole,
};
}, [session]);
const isAuthenticated = status === "authenticated" && !!user;
const isLoading = status === "loading";
return {
user,
isAuthenticated,
isLoading,
session,
status,
};
}
/**
* 권한 확인을 위한 훅
*/
export function usePermissions() {
const { user } = useAuth();
const checkPermission = useMemo(() => {
if (!user) return () => false;
return (permission: Permission) => hasPermission(user.role, permission);
}, [user]);
const checkAllPermissions = useMemo(() => {
if (!user) return () => false;
return (permissions: Permission[]) =>
hasAllPermissions(user.role, permissions);
}, [user]);
const checkAnyPermission = useMemo(() => {
if (!user) return () => false;
return (permissions: Permission[]) =>
hasAnyPermission(user.role, permissions);
}, [user]);
const checkResourcePermission = useMemo(() => {
if (!user) return () => false;
return (
resource:
| "USER"
| "SITE"
| "SECTION"
| "TEMPLATE"
| "FILE"
| "SYSTEM"
| "TENANT",
action:
| "create"
| "read"
| "update"
| "delete"
| "publish"
| "manage_roles"
| "upload"
) => hasResourcePermission(user.role, resource, action);
}, [user]);
const checkCanManageUser = useMemo(() => {
if (!user) return () => false;
return (targetRole: UserRole) => canManageUser(user.role, targetRole);
}, [user]);
const checkIsHigherRole = useMemo(() => {
if (!user) return () => false;
return (targetRole: UserRole) => isHigherRole(user.role, targetRole);
}, [user]);
return {
hasPermission: checkPermission,
hasAllPermissions: checkAllPermissions,
hasAnyPermission: checkAnyPermission,
hasResourcePermission: checkResourcePermission,
canManageUser: checkCanManageUser,
isHigherRole: checkIsHigherRole,
userRole: user?.role,
};
}
/**
* 관리자 권한 확인 훅
*/
export function useIsAdmin() {
const { user } = useAuth();
return user?.role === UserRole.ADMIN;
}
/**
* 편집자 이상 권한 확인 훅
*/
export function useIsEditor() {
const { user } = useAuth();
return user?.role === UserRole.ADMIN || user?.role === UserRole.EDITOR;
}
/**
* 인증된 사용자 확인 훅
*/
export function useIsAuthenticated() {
const { user } = useAuth();
return (
user?.role === UserRole.ADMIN ||
user?.role === UserRole.EDITOR ||
user?.role === UserRole.VIEWER
);
}
/**
* 특정 권한이 있는 경우에만 컴포넌트를 렌더링하는 훅
*/
export function usePermissionGuard(requiredPermissions: Permission[]) {
const { user } = useAuth();
const canRender = useMemo(() => {
if (!user) return false;
return shouldShowComponent(user.role, requiredPermissions);
}, [user, requiredPermissions]);
return canRender;
}
/**
* 권한 기반 메뉴 필터링 훅
*/
export function useFilteredMenu(menuItems: MenuItem[]) {
const { user } = useAuth();
const filteredMenu = useMemo(() => {
if (!user) return [];
return filterMenuItems(menuItems, user.role);
}, [menuItems, user]);
return filteredMenu;
}
/**
* 사용자 역할별 대시보드 설정 훅
*/
export function useDashboardConfig() {
const { user } = useAuth();
const dashboardConfig = useMemo(() => {
if (!user) return null;
switch (user.role) {
case UserRole.ADMIN:
return {
title: "관리자 대시보드",
sections: ["users", "sites", "templates", "system", "analytics"],
quickActions: [
"create-user",
"create-site",
"system-settings",
"backup",
],
widgets: [
"user-stats",
"site-stats",
"system-health",
"recent-activity",
],
};
case UserRole.EDITOR:
return {
title: "편집자 대시보드",
sections: ["sites", "sections", "templates", "files"],
quickActions: ["create-site", "create-section", "upload-file"],
widgets: [
"my-sites",
"recent-edits",
"draft-content",
"published-content",
],
};
case UserRole.VIEWER:
return {
title: "뷰어 대시보드",
sections: ["sites", "sections", "templates"],
quickActions: ["view-sites", "search-content"],
widgets: ["favorite-sites", "recent-views", "bookmarks"],
};
case UserRole.GUEST:
return {
title: "게스트 대시보드",
sections: ["public-sites"],
quickActions: ["browse-sites"],
widgets: ["featured-sites", "popular-content"],
};
default:
return null;
}
}, [user]);
return dashboardConfig;
}
/**
* 권한 기반 폼 필드 표시 훅
*/
export function useFormPermissions() {
const { hasPermission } = usePermissions();
const getFieldPermissions = useMemo(() => {
return (fieldPermissions: Record<string, Permission[]>) => {
const allowedFields: Record<string, boolean> = {};
Object.entries(fieldPermissions).forEach(([field, permissions]) => {
allowedFields[field] = permissions.some((permission) =>
hasPermission(permission)
);
});
return allowedFields;
};
}, [hasPermission]);
return { getFieldPermissions };
}
/**
* 권한 기반 액션 버튼 표시 훅
*/
export function useActionPermissions() {
const { hasPermission } = usePermissions();
const getActionPermissions = useMemo(() => {
return (actions: Record<string, Permission>) => {
const allowedActions: Record<string, boolean> = {};
Object.entries(actions).forEach(([action, permission]) => {
allowedActions[action] = hasPermission(permission);
});
return allowedActions;
};
}, [hasPermission]);
return { getActionPermissions };
}
/**
* 리소스별 CRUD 권한 확인 훅
*/
export function useResourcePermissions(
resource:
| "USER"
| "SITE"
| "SECTION"
| "TEMPLATE"
| "FILE"
| "SYSTEM"
| "TENANT"
) {
const { hasResourcePermission } = usePermissions();
const permissions = useMemo(
() => ({
canCreate: hasResourcePermission(resource, "create"),
canRead: hasResourcePermission(resource, "read"),
canUpdate: hasResourcePermission(resource, "update"),
canDelete: hasResourcePermission(resource, "delete"),
canPublish: hasResourcePermission(resource, "publish"),
canUpload:
resource === "FILE" ? hasResourcePermission(resource, "upload") : false,
canManageRoles:
resource === "USER"
? hasResourcePermission(resource, "manage_roles")
: false,
}),
[hasResourcePermission, resource]
);
return permissions;
}
/**
* 조건부 렌더링을 위한 권한 체크 훅
*/
export function useConditionalRender() {
const { user } = useAuth();
const { hasPermission, hasAnyPermission } = usePermissions();
const renderIf = useMemo(() => {
return {
isAuthenticated: () => !!user,
isAdmin: () => user?.role === UserRole.ADMIN,
isEditor: () =>
user?.role === UserRole.ADMIN || user?.role === UserRole.EDITOR,
hasRole: (role: UserRole) => user?.role === role,
hasPermission: (permission: Permission) => hasPermission(permission),
hasAnyPermission: (permissions: Permission[]) =>
hasAnyPermission(permissions),
isOwner: (ownerId: string) => user?.id === ownerId,
};
}, [user, hasPermission, hasAnyPermission]);
return renderIf;
}