const express = require('express'); const router = express.Router(); const bcrypt = require('bcryptjs'); const User = require('../models/User'); const Company = require('../models/Company'); const Department = require('../models/Department'); router.get('/login', (req, res) => { if (req.session.user) return res.redirect('/'); res.render('auth/login'); }); router.post('/login', async (req, res) => { const { email, password } = req.body; try { const user = await User.findByEmail(email); if (!user) { req.flash('error_msg', 'Email o contraseña incorrectos'); return res.redirect('/login'); } if (!user.is_active) { req.flash('error_msg', 'Cuenta desactivada'); return res.redirect('/login'); } const company = await Company.findById(user.company_id); if (company && !company.is_active) { req.flash('error_msg', 'Tu empresa está desactivada'); return res.redirect('/login'); } const match = await bcrypt.compare(password, user.password); if (!match) { req.flash('error_msg', 'Email o contraseña incorrectos'); return res.redirect('/login'); } req.session.user = { id: user.id, company_id: user.company_id, nombre: user.nombre, email: user.email, rol: user.rol }; req.flash('success_msg', 'Inicio de sesión exitoso'); res.redirect('/'); } catch (error) { console.error(error); req.flash('error_msg', 'Error al iniciar sesión'); res.redirect('/login'); } }); router.get('/register', (req, res) => { if (req.session.user) return res.redirect('/'); res.render('auth/register'); }); router.post('/register', async (req, res) => { const { nombre, email, password, confirm_password, company_name } = req.body; if (!nombre || !email || !password || !confirm_password) { req.flash('error_msg', 'Todos los campos son obligatorios'); return res.redirect('/register'); } if (password !== confirm_password) { req.flash('error_msg', 'Las contraseñas no coinciden'); return res.redirect('/register'); } if (password.length < 6) { req.flash('error_msg', 'La contraseña debe tener al menos 6 caracteres'); return res.redirect('/register'); } try { const existing = await User.findByEmail(email); if (existing) { req.flash('error_msg', 'El email ya está registrado'); return res.redirect('/register'); } // Create company or use default let companyId = 1; if (company_name) { const slug = company_name.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').slice(0, 100); const slugExists = await Company.findBySlug(slug); if (slugExists) { req.flash('error_msg', 'El nombre de empresa ya está registrado'); return res.redirect('/register'); } companyId = await Company.create(company_name, slug, 'free'); // Seed default departments for new company await Department.create(companyId, 'Soporte Técnico', 'Problemas técnicos y de software'); await Department.create(companyId, 'Facturación', 'Problemas de facturación y pagos'); await Department.create(companyId, 'General', 'Consultas generales'); } const hashedPassword = await bcrypt.hash(password, 10); await User.create(companyId, nombre, email, hashedPassword, company_name ? 'admin' : 'client'); req.flash('success_msg', 'Registro exitoso, ahora puedes iniciar sesión'); res.redirect('/login'); } catch (error) { console.error(error); req.flash('error_msg', 'Error al registrarse'); res.redirect('/register'); } }); router.get('/invite/:token', async (req, res) => { try { const invite = await User.findByInviteToken(req.params.token); if (!invite) { req.flash('error_msg', 'Invitación inválida o expirada'); return res.redirect('/login'); } res.render('auth/accept-invite', { token: req.params.token, email: invite.email }); } catch (error) { console.error(error); req.flash('error_msg', 'Error al procesar invitación'); res.redirect('/login'); } }); router.post('/invite/:token', async (req, res) => { const { nombre, password, confirm_password } = req.body; if (!nombre || !password || !confirm_password) { req.flash('error_msg', 'Todos los campos son obligatorios'); return res.redirect(`/invite/${req.params.token}`); } if (password !== confirm_password) { req.flash('error_msg', 'Las contraseñas no coinciden'); return res.redirect(`/invite/${req.params.token}`); } try { const invite = await User.findByInviteToken(req.params.token); if (!invite) { req.flash('error_msg', 'Invitación inválida o expirada'); return res.redirect('/login'); } const hashedPassword = await bcrypt.hash(password, 10); await User.update(invite.id, { nombre, password: hashedPassword, is_active: 1, invite_token: null, invite_token_expires: null }); req.flash('success_msg', 'Cuenta activada, ahora puedes iniciar sesión'); res.redirect('/login'); } catch (error) { console.error(error); req.flash('error_msg', 'Error al aceptar invitación'); res.redirect(`/invite/${req.params.token}`); } }); router.get('/logout', (req, res) => { req.session.destroy(); res.redirect('/login'); }); module.exports = router;