feat(auth): enforce strict admin role checks for configuration and management routes

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