fix: sanitize rbac error msg and enforce manager creation constraints
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m8s

- Prevented API error messages from leaking system roles.

- Updated POST /users to safely allow managers to create users while strictly forcing them to be agents assigned to the manager's team.
This commit is contained in:
Cauê Faleiros
2026-03-09 10:15:16 -03:00
parent 3481e698bc
commit 56b1f0c884

View File

@@ -118,7 +118,7 @@ const authenticateToken = (req, res, next) => {
}; };
const requireRole = (roles) => (req, res, next) => { const requireRole = (roles) => (req, res, next) => {
if (!roles.includes(req.user.role)) return res.status(403).json({ error: 'Acesso negado. Esta ação requer as seguintes permissões: ' + roles.join(', ') }); if (!roles.includes(req.user.role)) return res.status(403).json({ error: 'Acesso negado. Você não tem permissão para realizar esta ação.' });
next(); next();
}; };
@@ -319,9 +319,18 @@ apiRouter.get('/users/:idOrSlug', async (req, res) => {
}); });
// Convidar Novo Membro (Admin criando usuário) // Convidar Novo Membro (Admin criando usuário)
apiRouter.post('/users', requireRole(['admin', 'owner', 'super_admin']), async (req, res) => { apiRouter.post('/users', requireRole(['admin', 'manager', 'super_admin']), async (req, res) => {
const { name, email, role, team_id, tenant_id } = req.body; const { name, email, role, team_id, tenant_id } = req.body;
const effectiveTenantId = req.user.role === 'super_admin' ? tenant_id : req.user.tenant_id; const effectiveTenantId = req.user.role === 'super_admin' ? tenant_id : req.user.tenant_id;
// Strict RBAC: Managers can only create agents and assign them to their own team
let finalRole = role || 'agent';
let finalTeamId = team_id || null;
if (req.user.role === 'manager') {
finalRole = 'agent'; // Force manager creations to be agents
finalTeamId = req.user.team_id; // Force assignment to manager's team
}
try { try {
// 1. Verificar se e-mail já existe // 1. Verificar se e-mail já existe
const [existing] = await pool.query('SELECT id FROM users WHERE email = ?', [email]); const [existing] = await pool.query('SELECT id FROM users WHERE email = ?', [email]);
@@ -334,7 +343,7 @@ apiRouter.post('/users', requireRole(['admin', 'owner', 'super_admin']), async (
// 2. Criar Usuário // 2. Criar Usuário
await pool.query( await pool.query(
'INSERT INTO users (id, tenant_id, team_id, name, email, password_hash, slug, role, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', 'INSERT INTO users (id, tenant_id, team_id, name, email, password_hash, slug, role, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
[uid, effectiveTenantId, team_id || null, name, email, placeholderHash, slug, role || 'agent', 'active'] [uid, effectiveTenantId, finalTeamId, name, email, placeholderHash, slug, finalRole, 'active']
); );
// 3. Gerar Token de Setup de Senha (reusando lógica de reset) // 3. Gerar Token de Setup de Senha (reusando lógica de reset)