'use strict' /** * teamAuth.js — Autenticação para contas de equipe (tabela accounts) * Separado do auth.js que cuida dos admins (tabela admins) * * Cookie: team_token (JWT) * Payload: { accountId, tenantId, role, name } */ const jwt = require('jsonwebtoken') // Secret compartilhado (mesmo process.env.JWT_SECRET) — fallbacks distintos por tipo const TEAM_SECRET = process.env.JWT_SECRET || 'alemao-secret-2024' // Admin usa o mesmo JWT_SECRET mas com fallback diferente se não configurado — importa de auth.js const { JWT_SECRET: ADMIN_SECRET } = require('./auth') /** * verifyTeamToken — middleware que exige cookie team_token válido * Injeta req.teamAccount = { accountId, tenantId, role, name } */ function verifyTeamToken(req, res, next) { const token = req.cookies?.team_token if (!token) return res.status(401).json({ error: 'Não autenticado' }) try { const payload = jwt.verify(token, TEAM_SECRET) req.teamAccount = payload if (!req.tenantId) req.tenantId = payload.tenantId next() } catch { return res.status(401).json({ error: 'Sessão expirada' }) } } /** * verifyAnyToken — aceita admin (cloud_token) OU equipe (team_token) * SEGURANÇA: * - Admin: verifica com ADMIN_SECRET e popula req.admin * - Equipe: verifica com TEAM_SECRET e popula req.teamAccount * - Nunca aceita team_token quando cloud_token está presente e válido */ function verifyAnyToken(req, res, next) { const adminToken = req.cookies?.cloud_token const teamToken = req.cookies?.team_token // Tenta admin primeiro — usa o secret correto e popula req.admin if (adminToken) { try { const payload = jwt.verify(adminToken, ADMIN_SECRET) req.admin = payload if (!req.tenantId && payload.tenant_id) req.tenantId = payload.tenant_id return next() } catch { // cloud_token presente mas inválido — rejeita imediatamente (evita escalada de privilégio) return res.status(401).json({ error: 'Token inválido ou expirado' }) } } // Tenta equipe apenas se não havia cloud_token if (teamToken) { try { const payload = jwt.verify(teamToken, TEAM_SECRET) req.teamAccount = payload if (!req.tenantId) req.tenantId = payload.tenantId return next() } catch {} } return res.status(401).json({ error: 'Não autenticado' }) } function signTeamToken(account) { return jwt.sign( { accountId: account.id, tenantId: account.tenant_id, role: account.role, name: account.name }, TEAM_SECRET, { expiresIn: '7d' } ) } module.exports = { verifyTeamToken, verifyAnyToken, signTeamToken }