structure of the project this is app.js /** * Bugema University Vocational Training School Electronic Records Management System * Main application entry point */ // Import required modules const express = require('express'); const path = require('path'); const morgan = require('morgan'); const compression = require('compression'); const cookieParser = require('cookie-parser'); const session = require('express-session'); const MongoStore = require('connect-mongo'); const helmet = require('helmet'); const cors = require('cors'); const flash = require('connect-flash'); const mongoose = require('mongoose'); const expressLayouts = require('express-ejs-layouts'); // Import custom modules const env = require('./config/env'); const { connectToDatabase } = require('./config/database'); const { securityHeaders } = require('./config/security'); const logger = require('./utils/logger'); const { notFoundHandler, errorHandler } = require('./utils/errorHandler'); // Create Express application const app = express(); // Set up view engine and views directory app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); // Set up express layouts app.use(expressLayouts); app.set('layout', 'layouts/main'); console.log('Step 1: Starting app.js execution...'); // Database connection and server startup connectToDatabase() .then(() => { logger.info('MongoDB Atlas connection established successfully'); // Start server after successful database connection const PORT = env.port || 3000; console.log('Attempting to start the server...'); const server = app.listen(PORT, '0.0.0.0', function(err) { if (err) { console.error('ERROR STARTING SERVER:', err); process.exit(1); } const serverInfo = server.address(); console.log('\n\n=========================================================='); console.log(`*** SERVER STARTED SUCCESSFULLY ***`); console.log(` App URL: http://localhost:${serverInfo.port}`); console.log('==========================================================\n'); }); }) .catch((err) => { logger.error(`Failed to connect to MongoDB Atlas: ${err.message}`); process.exit(1); }); // Security middleware app.use(helmet({ contentSecurityPolicy: securityHeaders.contentSecurityPolicy, xContentTypeOptions: true, xFrameOptions: securityHeaders.xFrameOptions, xXssProtection: true, hsts: env.isProd ? securityHeaders.hsts : false, referrerPolicy: securityHeaders.referrerPolicy, })); console.log('Middleware setup complete.'); // Request parsing middleware app.use(express.json({ limit: '1mb' })); app.use(express.urlencoded({ extended: true, limit: '1mb' })); // Cookie parser middleware app.use(cookieParser(env.sessionSecret)); // Server-side session configuration app.use(session({ secret: env.sessionSecret, resave: false, saveUninitialized: false, store: process.env.SKIP_DB_CONNECT === 'true' ? undefined : MongoStore.create({ mongoUrl: env.mongodbUri, ttl: 14 * 24 * 60 * 60, autoRemove: 'native', collectionName: 'sessions', crypto: { secret: env.sessionSecret, }, }), cookie: { httpOnly: true, secure: env.isProd, sameSite: 'strict', maxAge: 14 * 24 * 60 * 60 * 1000, }, })); // Verify session is being tracked if (!env.isProd) { app.use((req, res, next) => { console.log(' Session Check:', req.session); next(); }); } // Flash messages middleware app.use(flash()); // Cross-Origin Resource Sharing app.use(cors({ origin: env.isProd ? 'https://erms.bugema.ac.ug' : true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true, })); // HTTP request logging app.use(morgan(env.isProd ? 'combined' : 'dev', { stream: logger.stream })); // Compression middleware app.use(compression()); // Serve static files app.use(express.static(path.join(__dirname, 'public'))); // Custom middleware to make some variables available to all templates app.use((req, res, next) => { res.locals.user = req.session.user || null; res.locals.flashMessages = req.flash(); res.locals.currentPath = req.path; res.locals.appName = 'Bugema ERMS'; res.locals.year = new Date().getFullYear(); next(); }); // Import routes const authRoutes = require('./routes/auth'); const authWebRoutes = require('./routes/auth-web'); const studentRoutes = require('./routes/students'); const programRoutes = require('./routes/programs'); const courseRoutes = require('./routes/courses'); const enrollmentRoutes = require('./routes/enrollments'); const assessmentRoutes = require('./routes/assessments'); const paymentRoutes = require('./routes/payments'); const documentRoutes = require('./routes/documents'); const reportRoutes = require('./routes/reports'); const adminRoutes = require('./routes/admin'); const registrarRoutes = require('./routes/registrar'); const financeRoutes = require('./routes/finance'); const userRoutes = require('./routes/users'); const dashboardRoutes = require('./routes/dashboard'); // API routes app.use('/api/auth', authRoutes); app.use('/api/students', studentRoutes); app.use('/api/programs', programRoutes); app.use('/api/courses', courseRoutes); app.use('/api/enrollments', enrollmentRoutes); app.use('/api/assessments', assessmentRoutes); app.use('/api/payments', paymentRoutes); app.use('/api/documents', documentRoutes); app.use('/api/reports', reportRoutes); app.use('/api/users', userRoutes); // Web routes app.use('/auth', authWebRoutes); app.use('/admin', adminRoutes); app.use('/registrar', registrarRoutes); app.use('/finance', financeRoutes); app.use('/dashboard', dashboardRoutes); console.log('Routes registered.'); // Root route - redirect to login or dashboard app.get('/', (req, res) => { console.log('➡️ Root route hit'); if (req.session.user) { const role = req.session.user.role; switch (role) { case 'admin': return res.redirect('/admin/dashboard'); case 'registrar': return res.redirect('/registrar/dashboard'); case 'finance': return res.redirect('/finance/dashboard'); case 'student': return res.redirect('/dashboard'); default: return res.redirect('/auth/login'); } } else { console.log(' No session found — redirecting to /auth/login'); res.redirect('/auth/login'); } }); // Error handling middleware app.use(notFoundHandler); app.use(errorHandler); // Handle uncaught exceptions process.on('uncaughtException', (err) => { logger.error('UNCAUGHT EXCEPTION! Shutting down...'); logger.error(`${err.name}: ${err.message}`, { stack: err.stack }); process.exit(1); }); // Handle unhandled promise rejections process.on('unhandledRejection', (err) => { logger.error('UNHANDLED REJECTION! Shutting down...'); logger.error(`${err.name}: ${err.message}`, { stack: err.stack }); process.exit(1); }); // Check for required environment variables if (!env.port || !env.mongodbUri || !env.jwtSecret) { console.error('Missing required environment variables. Please check your configuration.'); process.exit(1); } module.exports = app; this is auth-web.js /** * Authentication Web Routes * Routes for web authentication UI */ const express = require('express'); const router = express.Router(); const { authenticate } = require('../middleware/auth'); const authWebController = require('../controllers/authWebController'); // Login page router.get('/login', (req, res) => { // If user is already logged in, redirect to appropriate dashboard if (req.session.user) { const role = req.session.user.role; switch (role) { case 'admin': case 'superadmin': return res.redirect('/admin/dashboard'); case 'registrar': return res.redirect('/registrar/dashboard'); case 'finance': return res.redirect('/finance/dashboard'); case 'student': return res.redirect('/dashboard'); default: return res.redirect('/'); } } res.render('auth/login', { title: 'Login', page: 'auth', message: req.flash('error'), success: req.flash('success') }); }); // Forgot password page router.get('/forgot-password', (req, res) => { res.render('auth/forgot-password', { title: 'Forgot Password', page: 'auth', message: req.flash('error'), success: req.flash('success') }); }); // Process forgot password form router.post('/forgot-password', authWebController.forgotPassword); // Reset password page router.get('/reset-password/:token', (req, res) => { res.render('auth/reset-password', { title: 'Reset Password', page: 'auth', token: req.params.token, message: req.flash('error'), success: req.flash('success') }); }); // Process reset password form router.post('/reset-password/:token', authWebController.resetPassword); // Account activation page router.get('/activate/:token', authWebController.activateAccount); // Process login form router.post('/login', authWebController.login); // Logout - must be authenticated router.get('/logout', authenticate, authWebController.logout); module.exports = router; this is error.ejs <%- contentFor('body') %> <div class="container"> <div class="row justify-content-center"> <div class="col-md-8 text-center"> <div class="error-page mt-5"> <h1 class="display-1 text-danger mb-4"> <i class="fas fa-exclamation-triangle"></i> </h1> <h2 class="mb-4"><%= locals.title || 'Oops! Something went wrong' %></h2> <div class="error-details mb-4"> <p class="lead text-muted"> <%= locals.message || 'We encountered an error while processing your request.' %> </p> <% if (locals.error && process.env.NODE_ENV === 'development') { %> <div class="alert alert-danger text-start"> <h5 class="alert-heading">Error Details:</h5> <pre class="mb-0"><%= error.stack %></pre> </div> <% } %> </div> <div class="error-actions"> <a href="javascript:history.back()" class="btn btn-outline-primary me-2"> <i class="fas fa-arrow-left"></i> Go Back </a> <a href="/" class="btn btn-primary"> <i class="fas fa-home"></i> Return Home </a> </div> </div> </div> </div> </div> <style> .error-page { padding: 2rem; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .error-page h1 { font-size: 5rem; color: #dc3545; } .error-page h2 { color: #343a40; } .error-details { max-width: 600px; margin: 0 auto; } .error-actions { margin-top: 2rem; } pre { background-color: #f8f9fa; padding: 1rem; border-radius: 4px; overflow-x: auto; } </style> this is auth.js /** * Authentication Routes * Defines routes for user authentication and profile management */ const express = require('express'); const router = express.Router(); const { check } = require('express-validator'); const authController = require('../controllers/authController'); const { authenticate, authorize } = require('../middleware/auth'); // Validation schemas const registerValidation = [ check('username').trim().isLength({ min: 4, max: 20 }).withMessage('Username must be between 4 and 20 characters'), check('email').trim().isEmail().withMessage('Please provide a valid email address'), check('password').isLength({ min: 8 }).withMessage('Password must be at least 8 characters long'), check('firstName').trim().notEmpty().withMessage('First name is required'), check('lastName').trim().notEmpty().withMessage('Last name is required'), check('role').optional().isIn(['superadmin', 'admin', 'registrar', 'finance', 'student', 'lecturer']).withMessage('Invalid role') ]; const loginValidation = [ check('login').trim().notEmpty().withMessage('Email or username is required'), check('password').notEmpty().withMessage('Password is required') ]; const passwordResetValidation = [ check('password').isLength({ min: 8 }).withMessage('Password must be at least 8 characters long') ]; const passwordChangeValidation = [ check('currentPassword').notEmpty().withMessage('Current password is required'), check('newPassword').isLength({ min: 8 }).withMessage('New password must be at least 8 characters long') ]; const forgotPasswordValidation = [ check('email').trim().isEmail().withMessage('Please provide a valid email address') ]; const refreshTokenValidation = [ check('refreshToken').notEmpty().withMessage('Refresh token is required') ]; const profileValidation = [ check('firstName').optional().trim().notEmpty().withMessage('First name cannot be empty'), check('lastName').optional().trim().notEmpty().withMessage('Last name cannot be empty'), check('phoneNumber').optional().trim().matches(/^\+?[0-9]{10,15}$/).withMessage('Please provide a valid phone number') ]; // Public routes (no authentication required) router.post('/register', registerValidation, authController.register); router.post('/login', loginValidation, authController.login); router.get('/verify/:token', authController.verifyEmail); router.post('/forgot-password', forgotPasswordValidation, authController.forgotPassword); router.post('/reset-password/:token', passwordResetValidation, authController.resetPassword); router.post('/refresh-token', refreshTokenValidation, authController.refreshToken); router.post('/logout', refreshTokenValidation, authController.logout); // Protected routes (authentication required) router.use(authenticate); router.get('/me', authController.getProfile); router.patch('/profile', profileValidation, authController.updateProfile); router.post('/change-password', passwordChangeValidation, authController.changePassword); // Admin-only routes router.post('/register-admin', authenticate, authorize(['superadmin', 'admin']), registerValidation, authController.register ); module.exports = router; here is how it acts when i click the link 2025-05-18 20:42:13 info: Successfully connected to MongoDB Atlas 2025-05-18 20:42:13 info: MongoDB Atlas connection established successfully Attempting to start the server... ========================================================== *** SERVER STARTED SUCCESSFULLY *** App URL: http://localhost:3000 ========================================================== Session Check: Session { cookie: { path: '/', _expires: 2025-05-31T07:25:36.990Z, originalMaxAge: 1209600000, httpOnly: true, secure: false, sameSite: 'strict' }, flash: {} } 2025-05-18 20:42:19 info: GET / 404 1.789 ms - 139 ^Z [1]+ Stopped npm run dev snow@snow:~/Desktop/ERMS$ i want when i click the link. the pages (login) open as expected. Continue reading...