const express = require('express'); const AuthManager = require('../utils/auth'); const { redirectIfAuthenticated } = require('../middleware/auth'); const securityLogger = require('../utils/security-logger'); const router = express.Router(); const authManager = new AuthManager(); // Initialize auth manager authManager.initialize().catch(console.error); // Login page router.get('/login', redirectIfAuthenticated, async (req, res) => { try { const isFirstUser = await authManager.isFirstUser(); if (isFirstUser) { // No users exist yet - redirect to registration return res.redirect('/register'); } const redirectUrl = req.query.redirect || '/'; res.render('auth/login', { title: 'Login', redirectUrl: redirectUrl, currentPage: 'login' }); } catch (error) { console.error('Error checking first user on login:', error); const redirectUrl = req.query.redirect || '/'; res.render('auth/login', { title: 'Login', redirectUrl: redirectUrl, currentPage: 'login' }); } }); // Register page (only for first user) router.get('/register', redirectIfAuthenticated, async (req, res) => { try { const isFirstUser = await authManager.isFirstUser(); if (!isFirstUser) { return res.status(403).render('error', { error: 'Registration Not Available', message: 'New accounts can only be created by existing administrators. Please contact an admin to create your account.' }); } res.render('auth/register', { title: 'Setup Administrator Account', isFirstUser: isFirstUser, currentPage: 'register' }); } catch (error) { console.error('Error checking first user:', error); res.status(500).render('error', { error: 'Failed to load registration page', message: error.message }); } }); // Process login router.post('/login', redirectIfAuthenticated, async (req, res) => { try { const { username, password, redirect } = req.body; if (!username || !password) { return res.render('auth/login', { title: 'Login', error: 'Username and password are required', redirectUrl: redirect || '/', currentPage: 'login', formData: { username } }); } const user = await authManager.authenticateUser(username, password); // Log successful authentication await securityLogger.logAuthSuccess(req, username); // Create session req.session.user = user; // Redirect to intended page or dashboard const redirectUrl = redirect && redirect !== '/login' ? redirect : '/'; res.redirect(redirectUrl); } catch (error) { console.error('Login error:', error); // Log failed authentication await securityLogger.logAuthFailure(req, username, error.message); res.render('auth/login', { title: 'Login', error: error.message, redirectUrl: req.body.redirect || '/', currentPage: 'login', formData: { username: req.body.username } }); } }); // Process registration (only for first user) router.post('/register', redirectIfAuthenticated, async (req, res) => { try { const isFirstUser = await authManager.isFirstUser(); if (!isFirstUser) { return res.status(403).render('error', { error: 'Registration Not Available', message: 'New accounts can only be created by existing administrators.' }); } const { username, password, confirmPassword } = req.body; // Validate inputs if (!username || !password || !confirmPassword) { return res.render('auth/register', { title: 'Setup Administrator Account', error: 'All fields are required', isFirstUser: true, currentPage: 'register', formData: { username } }); } if (password !== confirmPassword) { return res.render('auth/register', { title: 'Setup Administrator Account', error: 'Passwords do not match', isFirstUser: true, currentPage: 'register', formData: { username } }); } const user = await authManager.createUser(username, password); // Create session for new user req.session.user = { id: user.id, username: user.username, created_at: user.created_at }; // Redirect to dashboard res.redirect('/?registered=true'); } catch (error) { console.error('Registration error:', error); res.render('auth/register', { title: 'Register', error: error.message, isFirstUser: await authManager.isFirstUser(), currentPage: 'register', formData: { username: req.body.username } }); } }); // Logout router.post('/logout', (req, res) => { req.session.destroy((err) => { if (err) { console.error('Logout error:', err); return res.status(500).json({ error: 'Failed to logout' }); } if (req.headers.accept && req.headers.accept.includes('application/json')) { res.json({ message: 'Logged out successfully' }); } else { res.redirect('/login?message=You have been logged out'); } }); }); // Get logout (for convenience) router.get('/logout', (req, res) => { req.session.destroy((err) => { if (err) { console.error('Logout error:', err); } res.redirect('/login?message=You have been logged out'); }); }); // User profile page router.get('/profile', async (req, res) => { if (!req.session || !req.session.user) { return res.redirect('/login'); } try { const user = await authManager.getUserById(req.session.user.id); if (!user) { req.session.destroy(); return res.redirect('/login?error=User not found'); } res.render('auth/profile', { title: 'Profile', user: user, currentPage: 'profile' }); } catch (error) { console.error('Profile error:', error); res.status(500).render('error', { error: 'Failed to load profile', message: error.message }); } }); // Change password router.post('/change-password', async (req, res) => { if (!req.session || !req.session.user) { return res.status(401).json({ error: 'Authentication required' }); } try { const { currentPassword, newPassword, confirmPassword } = req.body; if (!currentPassword || !newPassword || !confirmPassword) { throw new Error('All fields are required'); } if (newPassword !== confirmPassword) { throw new Error('New passwords do not match'); } await authManager.changePassword(req.session.user.id, currentPassword, newPassword); if (req.headers.accept && req.headers.accept.includes('application/json')) { res.json({ message: 'Password changed successfully' }); } else { res.redirect('/profile?success=Password changed successfully'); } } catch (error) { console.error('Change password error:', error); if (req.headers.accept && req.headers.accept.includes('application/json')) { res.status(400).json({ error: error.message }); } else { res.redirect('/profile?error=' + encodeURIComponent(error.message)); } } }); module.exports = router;