Files
evse-backend/routes/users.js
2025-12-07 14:32:46 +00:00

111 lines
2.8 KiB
JavaScript
Executable File

const express = require('express');
const router = express.Router();
const db = require('../db');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const rateLimit = require('express-rate-limit');
if (!process.env.JWT_SECRET) {
throw new Error('JWT_SECRET não definido no .env');
}
// limiter só para auth
const authLimiter = rateLimit({
windowMs: 60 * 1000,
max: 10,
standardHeaders: true,
legacyHeaders: false,
});
// POST /api/users/login
router.post('/login', authLimiter, async (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res
.status(400)
.json({ success: false, message: 'Usuário e senha são obrigatórios' });
}
try {
const user = await db('users').where({ username }).first();
if (!user) {
return res
.status(401)
.json({ success: false, message: 'Credenciais inválidas' });
}
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
return res
.status(401)
.json({ success: false, message: 'Credenciais inválidas' });
}
const token = jwt.sign(
{ id: user.id, username: user.username },
process.env.JWT_SECRET,
{ expiresIn: '24h' }
);
return res.json({ success: true, data: { token } });
} catch (err) {
console.error('Erro ao autenticar usuário:', err);
return res
.status(500)
.json({ success: false, message: 'Erro interno do servidor' });
}
});
// POST /api/users/register
router.post('/register', authLimiter, async (req, res) => {
const { username, password } = req.body;
if (
!username ||
!password ||
typeof username !== 'string' ||
typeof password !== 'string' ||
username.length < 3 ||
password.length < 4
) {
return res.status(400).json({
success: false,
message:
'Nome de usuário deve ter pelo menos 3 caracteres e senha pelo menos 4 caracteres',
});
}
try {
const existing = await db('users').where({ username }).first();
if (existing) {
return res
.status(409)
.json({ success: false, message: 'Nome de usuário já está em uso' });
}
const hashedPassword = await bcrypt.hash(password, 10);
const [row] = await db('users')
.insert({ username, password: hashedPassword })
.returning('id');
const token = jwt.sign(
{ id: row.id, username },
process.env.JWT_SECRET,
{ expiresIn: '24h' }
);
return res.status(201).json({ success: true, data: { token } });
} catch (err) {
console.error('Erro ao registrar usuário:', err);
return res.status(500).json({
success: false,
message: 'Erro interno ao registrar usuário',
});
}
});
module.exports = router;