- Adiciona widget de cotações ao vivo (USD/BRL e EUR/BRL) com design estilo terminal de trading (dark theme, tipografia mono, glow effects) - Proxy server-side /api/cotacao com cache 3s e token AwesomeAPI - Auto-refresh a cada 3 segundos apenas quando a página está aberta - Corrige cálculo de spread negativo: remove Math.abs() em USD→BRL e Math.max(0,...) no spread líquido - Corrige seção USD→BRL que não aparecia (filtro status !== 'finalizado') - Corrige valor_reais no fluxo USD→BRL: agora calcula valor * cotação - Adiciona classe CSS spread-negative para destacar spreads negativos - Bandeiras de fluxo (BR/US/EU) nos botões de compra e venda Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
86 lines
2.2 KiB
JavaScript
86 lines
2.2 KiB
JavaScript
/**
|
|
* Autenticacao Unificada — login/logout com bcrypt + express-session
|
|
* Suporta roles: 'agente' | 'corporate' | 'admin'
|
|
*/
|
|
const bcrypt = require('bcrypt');
|
|
const db = require('./db-local');
|
|
|
|
const SALT_ROUNDS = 10;
|
|
|
|
/**
|
|
* Cria um novo usuario (agente, corporate ou admin)
|
|
*/
|
|
async function createUser(email, senha, nome, role = 'agente', agenteId = 0) {
|
|
const hash = await bcrypt.hash(senha, SALT_ROUNDS);
|
|
return db.prepare(
|
|
'INSERT INTO agentes (email, senha_hash, agente_id, nome, role) VALUES (?, ?, ?, ?, ?)'
|
|
).run(email, hash, agenteId, nome, role);
|
|
}
|
|
|
|
/**
|
|
* Cria agente (retrocompatibilidade)
|
|
*/
|
|
async function createAgente(email, senha, agenteId, nome) {
|
|
return createUser(email, senha, nome, 'agente', agenteId);
|
|
}
|
|
|
|
/**
|
|
* Autentica usuario por email/senha
|
|
* Retorna usuario com role ou null se invalido
|
|
*/
|
|
async function authenticate(email, senha) {
|
|
const row = db.prepare(
|
|
'SELECT * FROM agentes WHERE email = ? AND ativo = 1'
|
|
).get(email);
|
|
if (!row) return null;
|
|
const match = await bcrypt.compare(senha, row.senha_hash);
|
|
return match ? row : null;
|
|
}
|
|
|
|
/**
|
|
* Middleware que verifica autenticacao e roles
|
|
* Uso: requireRole() - qualquer usuario logado
|
|
* requireRole('admin') - apenas admins
|
|
* requireRole('corporate', 'admin') - corporate e admins
|
|
* requireRole('agente') - apenas agentes
|
|
*/
|
|
function requireRole(...roles) {
|
|
return (req, res, next) => {
|
|
if (!req.session?.user) {
|
|
return res.redirect('/login');
|
|
}
|
|
if (roles.length && !roles.includes(req.session.user.role)) {
|
|
return res.status(403).send('Acesso negado');
|
|
}
|
|
next();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Middleware simples - apenas verifica se esta logado
|
|
* Retrocompatibilidade com requireAuth
|
|
*/
|
|
function requireAuth(req, res, next) {
|
|
if (req.session && req.session.user) return next();
|
|
res.redirect('/login');
|
|
}
|
|
|
|
/**
|
|
* Atualiza senha de usuario
|
|
*/
|
|
async function updatePassword(id, novaSenha) {
|
|
const hash = await bcrypt.hash(novaSenha, SALT_ROUNDS);
|
|
return db.prepare(
|
|
'UPDATE agentes SET senha_hash = ? WHERE id = ?'
|
|
).run(hash, id);
|
|
}
|
|
|
|
module.exports = {
|
|
createUser,
|
|
createAgente,
|
|
authenticate,
|
|
requireAuth,
|
|
requireRole,
|
|
updatePassword
|
|
};
|