feat(auth): enforce strict admin role checks for configuration and management routes
This commit is contained in:
@@ -229,13 +229,13 @@ export const routeConfig: RouteDefinition[] = [
|
||||
{
|
||||
path: '/configuracoes',
|
||||
component: () => import('@/pages/Configuracoes'),
|
||||
guard: 'resource',
|
||||
guard: 'admin',
|
||||
resourceKey: 'configuracoes-gerais',
|
||||
},
|
||||
{
|
||||
path: '/admin/theme-customization',
|
||||
component: () => import('@/pages/ThemeCustomizationPage'),
|
||||
guard: 'resource',
|
||||
guard: 'admin',
|
||||
resourceKey: 'theme-customization',
|
||||
},
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useUserRole } from '@/hooks/useUserRole';
|
||||
import { toast } from 'sonner';
|
||||
import type {
|
||||
UserPermissions,
|
||||
@@ -14,7 +13,6 @@ import type {
|
||||
|
||||
export function useUserPermissions() {
|
||||
const { user } = useAuth();
|
||||
const { isAdmin } = useUserRole();
|
||||
const [userPermissions, setUserPermissions] = useState<UserPermissions>({
|
||||
can_admin: false,
|
||||
can_create_update_delete: false,
|
||||
@@ -88,10 +86,9 @@ export function useUserPermissions() {
|
||||
loadUserPermissions();
|
||||
}, [loadUserPermissions]);
|
||||
|
||||
// Check if user has access to a resource
|
||||
const hasAccess = useCallback((resourceKey?: string): boolean => {
|
||||
// Admin always has access
|
||||
if (isAdmin) {
|
||||
if (userPermissions.can_admin) {
|
||||
console.log(`✅ Admin access granted for resource: ${resourceKey || 'general'}`);
|
||||
return true;
|
||||
}
|
||||
@@ -124,7 +121,7 @@ export function useUserPermissions() {
|
||||
const hasFunctionalAccess = Object.values(userPermissions).some(Boolean);
|
||||
console.log(`🔄 Fallback functional access for ${resourceKey}: ${hasFunctionalAccess}`, userPermissions);
|
||||
return hasFunctionalAccess;
|
||||
}, [isAdmin, userPermissions, resourcePermissions]);
|
||||
}, [userPermissions, resourcePermissions]);
|
||||
|
||||
// Check if user can access a specific route
|
||||
const canAccessRoute = useCallback((route: string): boolean => {
|
||||
@@ -148,10 +145,9 @@ export function useUserPermissions() {
|
||||
return hasAccess();
|
||||
}, [hasAccess]);
|
||||
|
||||
// Get permission level for a specific resource
|
||||
const getResourcePermission = useCallback((resourceKey: ResourceKey): PermissionLevel => {
|
||||
// Admin always has full permissions
|
||||
if (isAdmin) return 'can_admin';
|
||||
if (userPermissions.can_admin) return 'can_admin';
|
||||
|
||||
// Check specific resource permission
|
||||
if (resourcePermissions[resourceKey]) {
|
||||
@@ -165,7 +161,7 @@ export function useUserPermissions() {
|
||||
if (userPermissions.can_view_only) return 'can_view_only';
|
||||
|
||||
return 'no_access';
|
||||
}, [isAdmin, userPermissions, resourcePermissions]);
|
||||
}, [userPermissions, resourcePermissions]);
|
||||
|
||||
// Check if user can perform a specific action on a resource
|
||||
const canPerformActionByResource = useCallback((
|
||||
@@ -190,9 +186,8 @@ export function useUserPermissions() {
|
||||
}
|
||||
}, [getResourcePermission]);
|
||||
|
||||
// Generic permission check for functional permissions
|
||||
const canPerformAction = useCallback((action: ActionType): boolean => {
|
||||
if (isAdmin) return true;
|
||||
if (userPermissions.can_admin) return true;
|
||||
|
||||
switch (action) {
|
||||
case 'admin':
|
||||
@@ -208,7 +203,7 @@ export function useUserPermissions() {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}, [isAdmin, userPermissions]);
|
||||
}, [userPermissions]);
|
||||
|
||||
// Set specific resource permission
|
||||
const setResourcePermission = useCallback(async (
|
||||
|
||||
+15
-10
@@ -1,14 +1,17 @@
|
||||
// Hook que retorna role/permissões do usuário
|
||||
// Migrado pra Logto: não depende mais do Supabase
|
||||
// Qualquer usuário autenticado via Logto tem acesso Total
|
||||
// Migrado pra consumir as permissões reais do banco via useUserPermissions
|
||||
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useUserPermissions } from '@/hooks/useUserPermissions';
|
||||
import type { UserRole, AppRole } from '@/hooks/useUserPermissions/types';
|
||||
|
||||
export type AccessLevel = 'Total' | 'Parcial' | 'Restrita';
|
||||
|
||||
export const useUserRole = () => {
|
||||
const { user, loading } = useAuth();
|
||||
const { user, loading: authLoading } = useAuth();
|
||||
const { userPermissions, loading: permsLoading } = useUserPermissions();
|
||||
|
||||
const loading = authLoading || permsLoading;
|
||||
|
||||
// Sem usuário = sem permissão
|
||||
if (!user) {
|
||||
@@ -18,18 +21,20 @@ export const useUserRole = () => {
|
||||
isGerencia: false,
|
||||
isDiretoria: false,
|
||||
role: 'user' as UserRole,
|
||||
loading: false,
|
||||
loading,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Com usuário autenticado via Logto = Total
|
||||
// Com usuário autenticado + validações do json de privilégios do DB
|
||||
const isAdminCheck = Boolean(userPermissions.can_admin);
|
||||
|
||||
return {
|
||||
accessLevel: 'Total' as AccessLevel,
|
||||
isAdmin: true,
|
||||
isGerencia: true,
|
||||
isDiretoria: true,
|
||||
role: 'admin' as UserRole,
|
||||
accessLevel: isAdminCheck ? 'Total' : 'Parcial' as AccessLevel,
|
||||
isAdmin: isAdminCheck,
|
||||
isGerencia: isAdminCheck, // fallback para componentes legados
|
||||
isDiretoria: isAdminCheck, // fallback para componentes legados
|
||||
role: (isAdminCheck ? 'admin' : 'user') as UserRole,
|
||||
loading,
|
||||
error: null,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user