/** * 認證 Hook * 提供認證狀態和權限檢查功能 */ import { useSession } from 'next-auth/react' import { hasRole, hasAnyRole, hasAllRoles, inGroup } from '@/lib/auth' export function useAuth() { const { data: session, status } = useSession() return { // 認證狀態 session, status, isLoading: status === 'loading', isAuthenticated: status === 'authenticated', isUnauthenticated: status === 'unauthenticated', // 用戶資訊 user: session?.user, accessToken: session?.accessToken, error: session?.error, // 權限檢查 hasRole: (role: string) => hasRole(session, role), hasAnyRole: (roles: string[]) => hasAnyRole(session, roles), hasAllRoles: (roles: string[]) => hasAllRoles(session, roles), inGroup: (group: string) => inGroup(session, group), // 角色檢查快捷方式 isAdmin: hasRole(session, 'admin'), isHR: hasRole(session, 'hr'), isManager: hasRole(session, 'manager'), isEmployee: hasRole(session, 'employee'), } } /** * 權限保護 Hook * 檢查使用者是否有必要的權限,沒有則導向錯誤頁 */ export function useRequireAuth(requiredRoles?: string[]) { const auth = useAuth() if (auth.isLoading) { return { ...auth, isAuthorized: false } } if (!auth.isAuthenticated) { // 未登入,導向登入頁 if (typeof window !== 'undefined') { window.location.href = '/auth/signin' } return { ...auth, isAuthorized: false } } if (requiredRoles && requiredRoles.length > 0) { // 檢查是否有任一必要角色 const isAuthorized = auth.hasAnyRole(requiredRoles) if (!isAuthorized) { // 無權限,導向錯誤頁 if (typeof window !== 'undefined') { window.location.href = '/auth/error?error=Unauthorized' } return { ...auth, isAuthorized: false } } } return { ...auth, isAuthorized: true } } /** * 系統權限 Hook * 檢查使用者對特定系統的存取權限 */ export function useSystemPermission(systemName?: string) { const auth = useAuth() if (!systemName || !auth.user) { return { hasAccess: false, accessLevel: null, isAdmin: false, isUser: false, isReadonly: false, } } // 從用戶的 groups 中解析系統權限 // 格式: /systems/{system_name}/{access_level} const systemGroups = auth.user.groups?.filter((group: string) => group.startsWith(`/systems/${systemName}/`) ) if (!systemGroups || systemGroups.length === 0) { return { hasAccess: false, accessLevel: null, isAdmin: false, isUser: false, isReadonly: false, } } // 取得最高權限 const accessLevels = systemGroups.map((group: string) => { const parts = group.split('/') return parts[parts.length - 1] }) const hasAdmin = accessLevels.includes('admin') const hasUser = accessLevels.includes('user') const hasReadonly = accessLevels.includes('readonly') const accessLevel = hasAdmin ? 'admin' : hasUser ? 'user' : 'readonly' return { hasAccess: true, accessLevel, isAdmin: hasAdmin, isUser: hasUser || hasAdmin, isReadonly: hasReadonly || hasUser || hasAdmin, } }