@anpdgovbr/rbac-react
v0.3.0
Published
Hooks e HOC React para RBAC no cliente (UX).
Readme
@anpdgovbr/rbac-react
Hooks e HOCs React para RBAC — Integração client-side do sistema de autorização ANPD.
✨ Características
- ⚛️ React 18+ — Hooks modernos e Server Components friendly
- 🔄 SWR Integration — Cache inteligente com revalidação automática
- 🎭 HOC Pattern — Proteção declarativa de componentes
- 🎯 Type Safety — Totalmente tipado com TypeScript
- 🚀 Performance — Otimizado para re-renders mínimos
📦 Instalação
npm install @anpdgovbr/rbac-react@betaPeer Dependencies:
npm install react@^18 swr@^2🎯 Uso Básico
1. Provider de Contexto
Configure o provider no nível raiz da aplicação:
import { PermissionsProvider } from "@anpdgovbr/rbac-react"
function App() {
// Permissões podem vir do SSR, API, ou outros sources
const permissionsMap = useServerPermissions() // seu hook customizado
return (
<PermissionsProvider value={permissionsMap}>
<Dashboard />
</PermissionsProvider>
)
}2. Hook de Permissões
import { usePermissions } from "@anpdgovbr/rbac-react"
function Dashboard() {
const { permissoes, loading, error } = usePermissions({
endpoint: "/api/permissoes", // opcional
initial: preloadedPermissions, // opcional
})
if (loading) return <Loading />
if (error) return <Error />
return <div>Dashboard com permissões: {JSON.stringify(permissoes)}</div>
}3. Hook de Verificação
import { usePode } from "@anpdgovbr/rbac-react"
function ReportsPanel() {
const { pode, loading } = usePode()
if (loading) return <Skeleton />
return (
<div>
{pode("Exibir", "Relatorios") && <ReportsViewer />}
{pode("Criar", "Relatorios") && <CreateReportButton />}
{pode("Editar", "Relatorios") && <EditReportsPanel />}
</div>
)
}4. HOC de Proteção
import { withPermissao } from "@anpdgovbr/rbac-react"
// Componente original
function AdminPanel() {
return (
<div>
<h1>Painel Administrativo</h1>
<UserManagement />
<SystemSettings />
</div>
)
}
// Versão protegida
export default withPermissao(
AdminPanel,
"Acessar",
"PainelAdmin",
{ redirect: true } // ou false para mostrar "Acesso negado"
)🔧 API Completa
PermissionsProvider
Provider de contexto para injetar permissões pré-resolvidas.
interface PermissionsProviderProps {
children: React.ReactNode
value: PermissionsMap
}Uso típico com SSR:
// pages/_app.tsx ou app/layout.tsx
export default function RootLayout({
children,
permissions,
}: {
children: React.ReactNode
permissions: PermissionsMap
}) {
return <PermissionsProvider value={permissions}>{children}</PermissionsProvider>
}usePermissions(options?)
Hook para obter permissões via contexto ou endpoint.
interface PermissionsClientOptions {
endpoint?: string // padrão: "/api/permissoes"
fetcher?: (url: string) => Promise<unknown>
initial?: PermissionsMap
}
interface UsePermissionsReturn {
permissoes: PermissionsMap
loading: boolean
error?: Error
}Estratégias de carregamento:
- Contexto — Se
PermissionsProviderestiver presente, usa o valor do contexto - Initial — Se
initialfor fornecido, usa como fallback - Endpoint — Faz fetch via SWR se contexto não estiver disponível
usePode()
Hook para verificação reativa de permissões.
interface UsePodeReturn {
pode: (acao: Action, recurso: Resource) => boolean
loading: boolean
}Exemplo avançado:
function ConditionalUI() {
const { pode, loading } = usePode()
const actions = useMemo(
() => [
{ key: "view", show: pode("Exibir", "Docs"), label: "Ver Documentos" },
{ key: "edit", show: pode("Editar", "Docs"), label: "Editar Documentos" },
{ key: "delete", show: pode("Excluir", "Docs"), label: "Excluir Documentos" },
],
[pode]
)
if (loading) return <ActionsLoading />
return (
<ActionsList>
{actions
.filter((action) => action.show)
.map((action) => (
<ActionButton key={action.key}>{action.label}</ActionButton>
))}
</ActionsList>
)
}withPermissao(Component, acao, recurso, options?)
HOC para proteção declarativa de componentes.
interface WithPermissaoOptions {
redirect?: boolean // padrão: true
}
function withPermissao<TProps extends object>(
Component: React.ComponentType<TProps>,
acao: Action,
recurso: Resource,
options?: WithPermissaoOptions
): React.FC<TProps>Comportamentos:
redirect: true— Retornanull(não renderiza nada)redirect: false— Mostra mensagem "Acesso negado"- Durante loading — Retorna
null
Nota importante sobre uso em páginas (Next App Router):
withPermissaoé um HOC client-side pensado para proteger componentes e melhorar a UX. Ele não executa checagem server-side nem faz redirects no servidor. Se usado diretamente como export default de umapage.tsx(client component), pode ocorrer mismatch/hydration quando o servidor renderiza conteúdo diferente do cliente.Recomendação: para proteger páginas inteiras utilize o helper server-side
checkPermissiondo pacote@anpdgovbr/rbac-next(veja o README dorbac-next). O padrão é chamarcheckPermissionem um Server Component e, em caso de sucesso, renderizar um componente cliente protegido (carregado dinamicamente).
ℹ️ Desenvolvimento local com submódulos
Durante o desenvolvimento local com submódulos, este pacote pode depender de versões locais dos outros pacotes rbac-* (veja __local_dev_note__ em package.json). Há também TODO: (TEMP) em alguns arquivos para facilitar testes com mocks. Antes de publicar, reverta file: para as dependências publicadas e remova os fallbacks temporários.
🧪 Padrões de Uso
Proteção Multi-nível
// Layout protegido
const AdminLayout = withPermissao(BaseLayout, "Acessar", "AreaAdmin")
// Seções específicas
const UserManagement = withPermissao(UsersList, "Gerenciar", "Usuarios")
const SystemSettings = withPermissao(SettingsPanel, "Configurar", "Sistema")Composição com Outros Hooks
function useAdminPermissions() {
const { pode } = usePode()
return useMemo(
() => ({
canManageUsers: pode("Gerenciar", "Usuarios"),
canViewReports: pode("Exibir", "Relatorios"),
canConfigureSystem: pode("Configurar", "Sistema"),
}),
[pode]
)
}Loading States Customizados
function ProtectedComponent() {
const { permissoes, loading } = usePermissions()
if (loading) {
return <CustomSkeleton />
}
// Resto do componente...
}🔧 Desenvolvimento
# Build
npm run build
# Type checking
npm run typecheck
# Testes
npm test📚 Documentação Relacionada
📄 Licença
MIT © 2024 ANPD (Agência Nacional de Proteção de Dados)
