feat: "itens sem permissão não aparecem" — filtro de menu por permission (secao 169)
getUserPermissionKeys(userId, tenantId?) (novo, packages/auth) devolve todas as permission keys do usuário no contexto atual, mesma query de userHasPermission só que retornando o conjunto inteiro. GET /auth/me agora inclui permissionKeys — leitura adicional só pra UX, nunca decisão de autorização (isso continua sendo o PermissionGuard em cada endpoint). NavLeaf/NavSection ganham campo opcional permission; todos os ~35 itens de menu (tenant e platform) anotados com a permission key mínima que o endpoint GET correspondente já exige. filterNavByPermissions() (novo, nav-types.ts) esconde o item, ou a seção inteira se nenhum filho sobrar. TenantSidebar/PlatformSidebar/*Topbar são client components que importam TENANT_NAV/PLATFORM_NAV direto (não recebem como prop do server) porque os ícones (LucideIcon, funções) não são serializáveis através da fronteira RSC — restrição já documentada desde a PHASE 23. O filtro roda dentro desses wrappers, client-side, recebendo só permissionKeys: string[] (serializável) como prop. Testado ponta a ponta com um supervisor de teste de verdade (convidado, senha trocada, logado via UI): menu perde Telefonia > Dialplan e a seção Administração inteira (nenhum permission bate). Confirmado que a autorização real continua valendo sem o item no menu: acesso direto a /app/administracao/usuarios continua batendo 403 no backend. Regressão: tenant_admin e platform_super_admin continuam vendo todo item do próprio menu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
@@ -3,6 +3,7 @@ import type { FastifyRequest } from "fastify";
|
||||
import { getPrismaClient } from "@b2bcall/database";
|
||||
import {
|
||||
changePassword,
|
||||
getUserPermissionKeys,
|
||||
isPlatformUser,
|
||||
listUserTenants,
|
||||
login,
|
||||
@@ -70,6 +71,10 @@ export class AuthController {
|
||||
...dbUser,
|
||||
isPlatformUser: await isPlatformUser(user.sub),
|
||||
tenant: tenant ? { id: tenant.id, code: tenant.code, name: tenant.tradeName ?? tenant.legalName } : null,
|
||||
// "Itens sem permissão não aparecem" (secao 169) — só UX de menu, o
|
||||
// PermissionGuard em cada endpoint continua sendo a única fonte
|
||||
// confiável de autorização.
|
||||
permissionKeys: await getUserPermissionKeys(user.sub, user.tenantId),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user