i face a problem on my project. when i click on link. it shows error. i dont know why and what happened. anyone there please help. i request.
i expect when i click on link, the login page comes
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');
app.set('layout extractScripts', true);
app.set('layout extractStyles', true);
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 - MOVED BEFORE ROUTES
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;`
here is the "auth.js"
`/**
- Authentication Middleware
- Handles authentication and authorization for protected routes */
const { jwtHelpers } = require('../config/security');
const User = require('../models/user');
const { createError } = require('../utils/errorHandler');
const logger = require('../utils/logger');
/**
- Authenticate user based on JWT token
- @param {Object} req - Express request object
- @param {Object} res - Express response object
-
@param {Function} next - Express next middleware function
*/
exports.authenticate = async (req, res, next) => {
try {
// Get token from Authorization header
let token = req.headers.authorization;// Check if token exists
if (!token || !token.startsWith('Bearer ')) {
return res.status(401).json({
status: 'error',
message: 'Authentication required. Please login.',
code: 'AUTH_REQUIRED'
});
}// Extract token value (remove "Bearer " prefix)
token = token.split(' ')[1];// Verify token
const decoded = jwtHelpers.verifyToken(token);
if (!decoded) {
return res.status(401).json({
status: 'error',
message: 'Invalid or expired token. Please login again.',
code: 'INVALID_TOKEN'
});
}// Find user by ID
const user = await User.findById(decoded.userId);
if (!user) {
return res.status(401).json({
status: 'error',
message: 'User associated with this token no longer exists.',
code: 'USER_NOT_FOUND'
});
}// Check if user is active
if (user.status !== 'active') {
return res.status(403).json({
status: 'error',
message:Your account is ${user.status}. Please contact an administrator.,
code: 'ACCOUNT_INACTIVE'
});
}// Add user object to request
req.user = {
_id: user._id,
username: user.username,
email: user.email,
role: user.role,
permissions: user.permissions,
firstName: user.firstName,
lastName: user.lastName,
studentId: user.studentId
};// Proceed to next middleware
next();
} catch (error) {
logger.error(Authentication error: ${error.message});
return res.status(401).json({
status: 'error',
message: 'Authentication failed',
code: 'AUTH_FAILED'
});
}
};
/**
- Authorize user based on roles
- @param {Array} roles - Array of allowed roles
-
@returns {Function} Middleware function
*/
exports.authorize = (roles = []) => {
return (req, res, next) => {
// Check if user exists and has a role
if (!req.user || !req.user.role) {
return res.status(401).json({
status: 'error',
message: 'Authentication required',
code: 'AUTH_REQUIRED'
});
}// Superadmin has access to everything
if (req.user.role === 'superadmin') {
return next();
}// Check if user's role is in the allowed roles
if (roles.length > 0 && !roles.includes(req.user.role)) {
return res.status(403).json({
status: 'error',
message: 'You do not have permission to perform this action',
code: 'UNAUTHORIZED_ROLE'
});
}if (roles.length === 0) {
return res.status(403).json({
status: 'error',
message: 'Access denied. No roles are allowed for this action.',
code: 'NO_ROLES_ALLOWED'
});
}// Proceed to next middleware
next();
};
};
/**
- Check if user has specific permissions
- @param {Array|String} permissions - Required permission(s)
- @returns {Function} Middleware function */ exports.checkPermission = (permissions = []) => { // Convert string to array if single permission is passed if (typeof permissions === 'string') { permissions = [permissions]; }
return (req, res, next) => {
// Check if user exists
if (!req.user) {
return res.status(401).json({
status: 'error',
message: 'Authentication required',
code: 'AUTH_REQUIRED'
});
}
// Superadmin has all permissions
if (req.user.role === 'superadmin') {
return next();
}
// Check if user has any of the required permissions
const hasPermission = permissions.some(permission =>
req.user.permissions && req.user.permissions.includes(permission)
);
if (!hasPermission) {
return res.status(403).json({
status: 'error',
message: 'You do not have the required permissions for this action',
code: 'INSUFFICIENT_PERMISSIONS'
});
}
if (permissions.length === 0) {
return res.status(403).json({
status: 'error',
message: 'Access denied. No permissions are allowed for this action.',
code: 'NO_PERMISSIONS_ALLOWED'
});
}
// Proceed to next middleware
next();
};
};
/**
- Middleware to check if user is accessing their own data or has admin rights
- @param {Function} getResourceUserId - Function to extract user ID from resource
-
@returns {Function} Middleware function
*/
exports.checkResourceOwnership = (getResourceUserId) => {
return async (req, res, next) => {
try {
// Get user ID associated with the resource
const resourceUserId = await getResourceUserId(req);// If no resource user ID found, proceed (might be a creation operation)
if (!resourceUserId) {
return res.status(403).json({
status: 'error',
message: 'Unable to verify resource ownership.',
code: 'RESOURCE_OWNERSHIP_FAILED'
});
}// Check if current user is the owner of the resource
const isOwner = req.user._id.toString() === resourceUserId.toString();// Check if current user has admin privileges
const isAdmin = ['superadmin', 'admin'].includes(req.user.role);// Allow access if user is owner or has admin rights
if (isOwner || isAdmin) {
return next();
}// Deny access
return res.status(403).json({
status: 'error',
message: 'You do not have permission to access this resource',
code: 'NOT_RESOURCE_OWNER'
});
} catch (error) {
logger.error(Resource ownership check error: ${error.message});
return res.status(500).json({
status: 'error',
message: 'Failed to verify resource ownership',
code: 'OWNERSHIP_CHECK_FAILED'
});
}
};
};`
here 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('/');
}
}
// Render login page with layout
res.render('auth/login', {
title: 'Login',
page: 'auth',
message: req.flash('error'),
success: req.flash('success'),
layout: 'layouts/main'
});
});
// 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;`
here is error.ejs
`<%- contentFor('body') %>Bugema University
Vocational Training School
<div class="card-body p-4 text-center"> <div class="error-icon mb-4"> <i class="fas fa-exclamation-circle fa-4x text-danger"></i> </div> <h3 class="error-title mb-3"> <% if (locals.status === 404) { %> Page Not Found <% } else if (locals.status === 403) { %> Access Denied <% } else if (locals.status === 500) { %> Server Error <% } else { %> Error <%= locals.status %> <% } %> </h3> <p class="error-message mb-4"> <% if (locals.message) { %> <%= message %> <% } else if (locals.status === 404) { %> The page you are looking for might have been removed, had its name changed, or is temporarily unavailable. <% } else if (locals.status === 403) { %> You don't have permission to access this resource. <% } else if (locals.status === 500) { %> Something went wrong on our end. Please try again later. <% } else { %> An unexpected error occurred. Please try again later. <% } %> </p> <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> Go to Homepage </a> </div> <% if (locals.error && !env.isProd) { %> <div class="error-details mt-4"> <div class="card"> <div class="card-header bg-light"> <h5 class="mb-0">Error Details</h5> </div> <div class="card-body"> <pre class="error-stack"><%= error.stack %></pre> </div> </div> </div> <% } %> </div> <div class="card-footer text-center py-3"> <div class="small"> Need help? Contact <a href="mailto:ict@bugema.ac.ug">ICT Support</a> </div> </div> </div> </div>
<%- contentFor('styles') %>
.error-container { max-width: 800px; margin: 2rem auto; } .error-card { border: none; border-radius: 12px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); overflow: hidden; } .error-card .card-header { background-color: #0f4c81; color: white; padding: 1.5rem; text-align: center; border-bottom: none; } .error-card .card-body { padding: 2rem; } .error-icon { color: #dc3545; } .error-title { color: #2d3748; font-weight: 600; } .error-message { color: #4a5568; font-size: 1.1rem; } .error-actions { margin-top: 2rem; } .error-details { text-align: left; } .error-stack { background-color: #f8f9fa; padding: 1rem; border-radius: 6px; font-size: 0.9rem; color: #2d3748; white-space: pre-wrap; word-wrap: break-word; } @media (max-width: 576px) { .error-container { margin: 1rem; } .error-card .card-body { padding: 1.5rem; } .error-actions .btn { display: block; width: 100%; margin: 0.5rem 0; } }<%- contentFor('scripts') %>
<br> // Add any error page specific JavaScript here<br> document.addEventListener('DOMContentLoaded', function() {<br> // Example: Log error details to console in development<br> <% if (locals.error && !env.isProd) { %><br> console.error('Error Details:', <%= JSON.stringify(error) %>);<br> <% } %><br> });<br> `this is what i suffer from
`snow@snow:~/Desktop/ERMS$ npm run deverms@1.0.0 dev
nodemon app.js[nodemon] 3.1.10
[nodemon] to restart at any time, enterrs
[nodemon] watching path(s): .
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] startingnode app.js
Step 1: Starting app.js execution...
2025-05-21 06:05:45 info: Attempting to connect to MongoDB at cluster0.wcahcli.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0
Middleware setup complete.
(node:34440) [MONGOOSE] Warning: Duplicate schema index on {"email":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.
(Usenode --trace-warnings ...to show where the warning was created)
(node:34440) [MONGOOSE] Warning: Duplicate schema index on {"username":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.
(node:34440) [MONGOOSE] Warning: Duplicate schema index on {"studentId":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.
(node:34440) [MONGOOSE] Warning: Duplicate schema index on {"programCode":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.
(node:34440) [MONGOOSE] Warning: Duplicate schema index on {"courseCode":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.
2025-05-21 06:05:48 info: Successfully connected to MongoDB Atlas
2025-05-21 06:05:48 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-21 06:05:53 info: GET / 404 2.736 ms - 139
`


Top comments (0)