<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Snow Virus</title>
    <description>The latest articles on DEV Community by Snow Virus (@snow_virus_6da173c4383e63).</description>
    <link>https://dev.to/snow_virus_6da173c4383e63</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3189431%2F0e9bf9b8-bcd3-4f0d-ad4e-53a860231445.jpg</url>
      <title>DEV Community: Snow Virus</title>
      <link>https://dev.to/snow_virus_6da173c4383e63</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/snow_virus_6da173c4383e63"/>
    <language>en</language>
    <item>
      <title>the "npm run dev" link can't open the login page i want</title>
      <dc:creator>Snow Virus</dc:creator>
      <pubDate>Wed, 21 May 2025 03:11:51 +0000</pubDate>
      <link>https://dev.to/snow_virus_6da173c4383e63/the-npm-run-dev-link-cant-open-the-login-page-i-want-5ae1</link>
      <guid>https://dev.to/snow_virus_6da173c4383e63/the-npm-run-dev-link-cant-open-the-login-page-i-want-5ae1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;this is the project structure&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bqfdxhk3zcv3fhtn2mf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bqfdxhk3zcv3fhtn2mf.png" alt="Image description" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlliq7yfqdl0teehi2d9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlliq7yfqdl0teehi2d9.png" alt="Image description" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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.&lt;br&gt;
i expect when i click on link, the login page comes&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;this is app.js&lt;br&gt;
`/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bugema University Vocational Training School Electronic Records Management System&lt;/li&gt;
&lt;li&gt;Main application entry point
*/&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;// Import required modules&lt;br&gt;
const express = require('express');&lt;br&gt;
const path = require('path');&lt;br&gt;
const morgan = require('morgan');&lt;br&gt;
const compression = require('compression');&lt;br&gt;
const cookieParser = require('cookie-parser');&lt;br&gt;
const session = require('express-session');&lt;br&gt;
const MongoStore = require('connect-mongo');&lt;br&gt;
const helmet = require('helmet');&lt;br&gt;
const cors = require('cors');&lt;br&gt;
const flash = require('connect-flash');&lt;br&gt;
const mongoose = require('mongoose');&lt;br&gt;
const expressLayouts = require('express-ejs-layouts');&lt;/p&gt;

&lt;p&gt;// Import custom modules&lt;br&gt;
const env = require('./config/env');&lt;br&gt;
const { connectToDatabase } = require('./config/database');&lt;br&gt;
const { securityHeaders } = require('./config/security');&lt;br&gt;
const logger = require('./utils/logger');&lt;br&gt;
const { notFoundHandler, errorHandler } = require('./utils/errorHandler');&lt;/p&gt;

&lt;p&gt;// Create Express application&lt;br&gt;
const app = express();&lt;/p&gt;

&lt;p&gt;// Set up view engine and views directory&lt;br&gt;
app.set('view engine', 'ejs');&lt;br&gt;
app.set('views', path.join(__dirname, 'views'));&lt;/p&gt;

&lt;p&gt;// Set up express layouts&lt;br&gt;
app.use(expressLayouts);&lt;br&gt;
app.set('layout', 'layouts/main');&lt;br&gt;
app.set('layout extractScripts', true);&lt;br&gt;
app.set('layout extractStyles', true);&lt;/p&gt;

&lt;p&gt;console.log('Step 1: Starting app.js execution...');&lt;/p&gt;

&lt;p&gt;// Database connection and server startup&lt;br&gt;
connectToDatabase()&lt;br&gt;
  .then(() =&amp;gt; {&lt;br&gt;
    logger.info('MongoDB Atlas connection established successfully');&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;})&lt;br&gt;
  .catch((err) =&amp;gt; {&lt;br&gt;
    logger.error(&lt;code&gt;Failed to connect to MongoDB Atlas: ${err.message}&lt;/code&gt;);&lt;br&gt;
    process.exit(1);&lt;br&gt;
  });&lt;/p&gt;

&lt;p&gt;// Security middleware&lt;br&gt;
app.use(helmet({&lt;br&gt;
  contentSecurityPolicy: securityHeaders.contentSecurityPolicy,&lt;br&gt;
  xContentTypeOptions: true,&lt;br&gt;
  xFrameOptions: securityHeaders.xFrameOptions,&lt;br&gt;
  xXssProtection: true,&lt;br&gt;
  hsts: env.isProd ? securityHeaders.hsts : false,&lt;br&gt;
  referrerPolicy: securityHeaders.referrerPolicy,&lt;br&gt;
}));&lt;br&gt;
console.log('Middleware setup complete.');&lt;/p&gt;

&lt;p&gt;// Request parsing middleware&lt;br&gt;
app.use(express.json({ limit: '1mb' }));&lt;br&gt;
app.use(express.urlencoded({ extended: true, limit: '1mb' }));&lt;/p&gt;

&lt;p&gt;// Cookie parser middleware&lt;br&gt;
app.use(cookieParser(env.sessionSecret));&lt;/p&gt;

&lt;p&gt;// Server-side session configuration&lt;br&gt;
app.use(session({&lt;br&gt;
  secret: env.sessionSecret,&lt;br&gt;
  resave: false,&lt;br&gt;
  saveUninitialized: false,&lt;br&gt;
  store: process.env.SKIP_DB_CONNECT === 'true' ? undefined : MongoStore.create({&lt;br&gt;
    mongoUrl: env.mongodbUri,&lt;br&gt;
    ttl: 14 * 24 * 60 * 60,&lt;br&gt;
    autoRemove: 'native',&lt;br&gt;
    collectionName: 'sessions',&lt;br&gt;
    crypto: {&lt;br&gt;
      secret: env.sessionSecret,&lt;br&gt;
    },&lt;br&gt;
  }),&lt;br&gt;
  cookie: {&lt;br&gt;
    httpOnly: true,&lt;br&gt;
    secure: env.isProd,&lt;br&gt;
    sameSite: 'strict',&lt;br&gt;
    maxAge: 14 * 24 * 60 * 60 * 1000,&lt;br&gt;
  },&lt;br&gt;
}));&lt;/p&gt;

&lt;p&gt;// Verify session is being tracked&lt;br&gt;
if (!env.isProd) {&lt;br&gt;
  app.use((req, res, next) =&amp;gt; {&lt;br&gt;
    console.log('🔐 Session Check:', req.session);&lt;br&gt;
    next();&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Flash messages middleware&lt;br&gt;
app.use(flash());&lt;/p&gt;

&lt;p&gt;// Cross-Origin Resource Sharing&lt;br&gt;
app.use(cors({&lt;br&gt;
  origin: env.isProd ? '&lt;a href="https://erms.bugema.ac.ug" rel="noopener noreferrer"&gt;https://erms.bugema.ac.ug&lt;/a&gt;' : true,&lt;br&gt;
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],&lt;br&gt;
  allowedHeaders: ['Content-Type', 'Authorization'],&lt;br&gt;
  credentials: true,&lt;br&gt;
}));&lt;/p&gt;

&lt;p&gt;// HTTP request logging&lt;br&gt;
app.use(morgan(env.isProd ? 'combined' : 'dev', { stream: logger.stream }));&lt;/p&gt;

&lt;p&gt;// Compression middleware&lt;br&gt;
app.use(compression());&lt;/p&gt;

&lt;p&gt;// Serve static files - MOVED BEFORE ROUTES&lt;br&gt;
app.use(express.static(path.join(__dirname, 'public')));&lt;/p&gt;

&lt;p&gt;// Custom middleware to make some variables available to all templates&lt;br&gt;
app.use((req, res, next) =&amp;gt; {&lt;br&gt;
  res.locals.user = req.session.user || null;&lt;br&gt;
  res.locals.flashMessages = req.flash();&lt;br&gt;
  res.locals.currentPath = req.path;&lt;br&gt;
  res.locals.appName = 'Bugema ERMS';&lt;br&gt;
  res.locals.year = new Date().getFullYear();&lt;br&gt;
  next();&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Import routes&lt;br&gt;
const authRoutes = require('./routes/auth');&lt;br&gt;
const authWebRoutes = require('./routes/auth-web');&lt;br&gt;
const studentRoutes = require('./routes/students');&lt;br&gt;
const programRoutes = require('./routes/programs');&lt;br&gt;
const courseRoutes = require('./routes/courses');&lt;br&gt;
const enrollmentRoutes = require('./routes/enrollments');&lt;br&gt;
const assessmentRoutes = require('./routes/assessments');&lt;br&gt;
const paymentRoutes = require('./routes/payments');&lt;br&gt;
const documentRoutes = require('./routes/documents');&lt;br&gt;
const reportRoutes = require('./routes/reports');&lt;br&gt;
const adminRoutes = require('./routes/admin');&lt;br&gt;
const registrarRoutes = require('./routes/registrar');&lt;br&gt;
const financeRoutes = require('./routes/finance');&lt;br&gt;
const userRoutes = require('./routes/users');&lt;br&gt;
const dashboardRoutes = require('./routes/dashboard');&lt;/p&gt;

&lt;p&gt;// API routes&lt;br&gt;
app.use('/api/auth', authRoutes);&lt;br&gt;
app.use('/api/students', studentRoutes);&lt;br&gt;
app.use('/api/programs', programRoutes);&lt;br&gt;
app.use('/api/courses', courseRoutes);&lt;br&gt;
app.use('/api/enrollments', enrollmentRoutes);&lt;br&gt;
app.use('/api/assessments', assessmentRoutes);&lt;br&gt;
app.use('/api/payments', paymentRoutes);&lt;br&gt;
app.use('/api/documents', documentRoutes);&lt;br&gt;
app.use('/api/reports', reportRoutes);&lt;br&gt;
app.use('/api/users', userRoutes);&lt;/p&gt;

&lt;p&gt;// Web routes&lt;br&gt;
app.use('/auth', authWebRoutes);&lt;br&gt;
app.use('/admin', adminRoutes);&lt;br&gt;
app.use('/registrar', registrarRoutes);&lt;br&gt;
app.use('/finance', financeRoutes);&lt;br&gt;
app.use('/dashboard', dashboardRoutes);&lt;/p&gt;

&lt;p&gt;console.log('Routes registered.');&lt;/p&gt;

&lt;p&gt;// Root route - redirect to login or dashboard&lt;br&gt;
app.get('/', (req, res) =&amp;gt; {&lt;br&gt;
  console.log('➡️ Root route hit');&lt;/p&gt;

&lt;p&gt;if (req.session.user) {&lt;br&gt;
    const role = req.session.user.role;&lt;br&gt;
    switch (role) {&lt;br&gt;
      case 'admin':&lt;br&gt;
        return res.redirect('/admin/dashboard');&lt;br&gt;
      case 'registrar':&lt;br&gt;
        return res.redirect('/registrar/dashboard');&lt;br&gt;
      case 'finance':&lt;br&gt;
        return res.redirect('/finance/dashboard');&lt;br&gt;
      case 'student':&lt;br&gt;
        return res.redirect('/dashboard');&lt;br&gt;
      default:&lt;br&gt;
        return res.redirect('/auth/login');&lt;br&gt;
    }&lt;br&gt;
  } else {&lt;br&gt;
    console.log('🧑‍🚫 No session found — redirecting to /auth/login');&lt;br&gt;
    res.redirect('/auth/login');&lt;br&gt;
  }&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Error handling middleware&lt;br&gt;
app.use(notFoundHandler);&lt;br&gt;
app.use(errorHandler);&lt;/p&gt;

&lt;p&gt;// Handle uncaught exceptions&lt;br&gt;
process.on('uncaughtException', (err) =&amp;gt; {&lt;br&gt;
  logger.error('UNCAUGHT EXCEPTION! 💥 Shutting down...');&lt;br&gt;
  logger.error(&lt;code&gt;${err.name}: ${err.message}&lt;/code&gt;, { stack: err.stack });&lt;br&gt;
  process.exit(1);&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Handle unhandled promise rejections&lt;br&gt;
process.on('unhandledRejection', (err) =&amp;gt; {&lt;br&gt;
  logger.error('UNHANDLED REJECTION! 💥 Shutting down...');&lt;br&gt;
  logger.error(&lt;code&gt;${err.name}: ${err.message}&lt;/code&gt;, { stack: err.stack });&lt;br&gt;
  process.exit(1);&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Check for required environment variables&lt;br&gt;
if (!env.port || !env.mongodbUri || !env.jwtSecret) {&lt;br&gt;
  console.error('Missing required environment variables. Please check your configuration.');&lt;br&gt;
  process.exit(1);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;module.exports = app;`&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;here is the "auth.js"&lt;br&gt;
`/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication Middleware&lt;/li&gt;
&lt;li&gt;Handles authentication and authorization for protected routes
*/&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;const { jwtHelpers } = require('../config/security');&lt;br&gt;
const User = require('../models/user');&lt;br&gt;
const { createError } = require('../utils/errorHandler');&lt;br&gt;
const logger = require('../utils/logger');&lt;/p&gt;

&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticate user based on JWT token&lt;/li&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt; {Object} req - Express request object&lt;/li&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt; {Object} res - Express response object&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt; {Function} next - Express next middleware function&lt;br&gt;
*/&lt;br&gt;
exports.authenticate = async (req, res, next) =&amp;gt; {&lt;br&gt;
try {&lt;br&gt;
// Get token from Authorization header&lt;br&gt;
let token = req.headers.authorization;&lt;/p&gt;

&lt;p&gt;// Check if token exists&lt;br&gt;
if (!token || !token.startsWith('Bearer ')) {&lt;br&gt;
  return res.status(401).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'Authentication required. Please login.',&lt;br&gt;
    code: 'AUTH_REQUIRED'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Extract token value (remove "Bearer " prefix)&lt;br&gt;
token = token.split(' ')[1];&lt;/p&gt;

&lt;p&gt;// Verify token&lt;br&gt;
const decoded = jwtHelpers.verifyToken(token);&lt;br&gt;
if (!decoded) {&lt;br&gt;
  return res.status(401).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'Invalid or expired token. Please login again.',&lt;br&gt;
    code: 'INVALID_TOKEN'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Find user by ID&lt;br&gt;
const user = await User.findById(decoded.userId);&lt;br&gt;
if (!user) {&lt;br&gt;
  return res.status(401).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'User associated with this token no longer exists.',&lt;br&gt;
    code: 'USER_NOT_FOUND'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Check if user is active&lt;br&gt;
if (user.status !== 'active') {&lt;br&gt;
  return res.status(403).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: &lt;code&gt;Your account is ${user.status}. Please contact an administrator.&lt;/code&gt;,&lt;br&gt;
    code: 'ACCOUNT_INACTIVE'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Add user object to request&lt;br&gt;
req.user = {&lt;br&gt;
  _id: user._id,&lt;br&gt;
  username: user.username,&lt;br&gt;
  email: user.email,&lt;br&gt;
  role: user.role,&lt;br&gt;
  permissions: user.permissions,&lt;br&gt;
  firstName: user.firstName,&lt;br&gt;
  lastName: user.lastName,&lt;br&gt;
  studentId: user.studentId&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;// Proceed to next middleware&lt;br&gt;
next();&lt;br&gt;
} catch (error) {&lt;br&gt;
logger.error(&lt;code&gt;Authentication error: ${error.message}&lt;/code&gt;);&lt;br&gt;
return res.status(401).json({&lt;br&gt;
  status: 'error',&lt;br&gt;
  message: 'Authentication failed',&lt;br&gt;
  code: 'AUTH_FAILED'&lt;br&gt;
});&lt;br&gt;
}&lt;br&gt;
};&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorize user based on roles&lt;/li&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt; {Array} roles - Array of allowed roles&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@returns {Function} Middleware function&lt;br&gt;
*/&lt;br&gt;
exports.authorize = (roles = []) =&amp;gt; {&lt;br&gt;
return (req, res, next) =&amp;gt; {&lt;br&gt;
// Check if user exists and has a role&lt;br&gt;
if (!req.user || !req.user.role) {&lt;br&gt;
  return res.status(401).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'Authentication required',&lt;br&gt;
    code: 'AUTH_REQUIRED'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Superadmin has access to everything&lt;br&gt;
if (req.user.role === 'superadmin') {&lt;br&gt;
  return next();&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Check if user's role is in the allowed roles&lt;br&gt;
if (roles.length &amp;gt; 0 &amp;amp;&amp;amp; !roles.includes(req.user.role)) {&lt;br&gt;
  return res.status(403).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'You do not have permission to perform this action',&lt;br&gt;
    code: 'UNAUTHORIZED_ROLE'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;if (roles.length === 0) {&lt;br&gt;
  return res.status(403).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'Access denied. No roles are allowed for this action.',&lt;br&gt;
    code: 'NO_ROLES_ALLOWED'&lt;br&gt;
  });&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Proceed to next middleware&lt;br&gt;
next();&lt;br&gt;
};&lt;br&gt;
};&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if user has specific permissions&lt;/li&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt; {Array|String} permissions - Required permission(s)&lt;/li&gt;
&lt;li&gt;@returns {Function} Middleware function
*/
exports.checkPermission = (permissions = []) =&amp;gt; {
// Convert string to array if single permission is passed
if (typeof permissions === 'string') {
permissions = [permissions];
}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;return (req, res, next) =&amp;gt; {&lt;br&gt;
    // Check if user exists&lt;br&gt;
    if (!req.user) {&lt;br&gt;
      return res.status(401).json({&lt;br&gt;
        status: 'error',&lt;br&gt;
        message: 'Authentication required',&lt;br&gt;
        code: 'AUTH_REQUIRED'&lt;br&gt;
      });&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 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 =&amp;gt; 
  req.user.permissions &amp;amp;&amp;amp; 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();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;};&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Middleware to check if user is accessing their own data or has admin rights&lt;/li&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/param"&gt;@param&lt;/a&gt; {Function} getResourceUserId - Function to extract user ID from resource&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@returns {Function} Middleware function&lt;br&gt;
*/&lt;br&gt;
exports.checkResourceOwnership = (getResourceUserId) =&amp;gt; {&lt;br&gt;
return async (req, res, next) =&amp;gt; {&lt;br&gt;
try {&lt;br&gt;
  // Get user ID associated with the resource&lt;br&gt;
  const resourceUserId = await getResourceUserId(req);&lt;/p&gt;

&lt;p&gt;// If no resource user ID found, proceed (might be a creation operation)&lt;br&gt;
  if (!resourceUserId) {&lt;br&gt;
    return res.status(403).json({&lt;br&gt;
      status: 'error',&lt;br&gt;
      message: 'Unable to verify resource ownership.',&lt;br&gt;
      code: 'RESOURCE_OWNERSHIP_FAILED'&lt;br&gt;
    });&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// Check if current user is the owner of the resource&lt;br&gt;
  const isOwner = req.user._id.toString() === resourceUserId.toString();&lt;/p&gt;

&lt;p&gt;// Check if current user has admin privileges&lt;br&gt;
  const isAdmin = ['superadmin', 'admin'].includes(req.user.role);&lt;/p&gt;

&lt;p&gt;// Allow access if user is owner or has admin rights&lt;br&gt;
  if (isOwner || isAdmin) {&lt;br&gt;
    return next();&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;// Deny access&lt;br&gt;
  return res.status(403).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'You do not have permission to access this resource',&lt;br&gt;
    code: 'NOT_RESOURCE_OWNER'&lt;br&gt;
  });&lt;br&gt;
} catch (error) {&lt;br&gt;
  logger.error(&lt;code&gt;Resource ownership check error: ${error.message}&lt;/code&gt;);&lt;br&gt;
  return res.status(500).json({&lt;br&gt;
    status: 'error',&lt;br&gt;
    message: 'Failed to verify resource ownership',&lt;br&gt;
    code: 'OWNERSHIP_CHECK_FAILED'&lt;br&gt;
  });&lt;br&gt;
}&lt;br&gt;
};&lt;br&gt;
};`&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;here is "auth-web.js"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;`/**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication Web Routes&lt;/li&gt;
&lt;li&gt;Routes for web authentication UI
*/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;const express = require('express');&lt;br&gt;
const router = express.Router();&lt;br&gt;
const { authenticate } = require('../middleware/auth');&lt;br&gt;
const authWebController = require('../controllers/authWebController');&lt;/p&gt;

&lt;p&gt;// Login page&lt;br&gt;
router.get('/login', (req, res) =&amp;gt; {&lt;br&gt;
  // If user is already logged in, redirect to appropriate dashboard&lt;br&gt;
  if (req.session.user) {&lt;br&gt;
    const role = req.session.user.role;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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('/');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Render login page with layout&lt;br&gt;
  res.render('auth/login', { &lt;br&gt;
    title: 'Login', &lt;br&gt;
    page: 'auth',&lt;br&gt;
    message: req.flash('error'),&lt;br&gt;
    success: req.flash('success'),&lt;br&gt;
    layout: 'layouts/main'&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Forgot password page&lt;br&gt;
router.get('/forgot-password', (req, res) =&amp;gt; {&lt;br&gt;
  res.render('auth/forgot-password', { &lt;br&gt;
    title: 'Forgot Password',&lt;br&gt;
    page: 'auth',&lt;br&gt;
    message: req.flash('error'),&lt;br&gt;
    success: req.flash('success')&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Process forgot password form&lt;br&gt;
router.post('/forgot-password', authWebController.forgotPassword);&lt;/p&gt;

&lt;p&gt;// Reset password page&lt;br&gt;
router.get('/reset-password/:token', (req, res) =&amp;gt; {&lt;br&gt;
  res.render('auth/reset-password', { &lt;br&gt;
    title: 'Reset Password', &lt;br&gt;
    page: 'auth',&lt;br&gt;
    token: req.params.token,&lt;br&gt;
    message: req.flash('error'),&lt;br&gt;
    success: req.flash('success')&lt;br&gt;
  });&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;// Process reset password form&lt;br&gt;
router.post('/reset-password/:token', authWebController.resetPassword);&lt;/p&gt;

&lt;p&gt;// Account activation page&lt;br&gt;
router.get('/activate/:token', authWebController.activateAccount);&lt;/p&gt;

&lt;p&gt;// Process login form&lt;br&gt;
router.post('/login', authWebController.login);&lt;/p&gt;

&lt;p&gt;// Logout - must be authenticated&lt;br&gt;
router.get('/logout', authenticate, authWebController.logout);&lt;/p&gt;

&lt;p&gt;module.exports = router;`&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;here is error.ejs&lt;br&gt;
`&amp;lt;%- contentFor('body') %&amp;gt;&lt;/p&gt;


  
    
      
        
          &lt;h2&gt;Bugema University&lt;/h2&gt;
          &lt;p&gt;Vocational Training School&lt;/p&gt;
        

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;div class="card-body p-4 text-center"&amp;gt;
      &amp;lt;div class="error-icon mb-4"&amp;gt;
        &amp;lt;i class="fas fa-exclamation-circle fa-4x text-danger"&amp;gt;&amp;lt;/i&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;h3 class="error-title mb-3"&amp;gt;
        &amp;lt;% if (locals.status === 404) { %&amp;gt;
          Page Not Found
        &amp;lt;% } else if (locals.status === 403) { %&amp;gt;
          Access Denied
        &amp;lt;% } else if (locals.status === 500) { %&amp;gt;
          Server Error
        &amp;lt;% } else { %&amp;gt;
          Error &amp;lt;%= locals.status %&amp;gt;
        &amp;lt;% } %&amp;gt;
      &amp;lt;/h3&amp;gt;

      &amp;lt;p class="error-message mb-4"&amp;gt;
        &amp;lt;% if (locals.message) { %&amp;gt;
          &amp;lt;%= message %&amp;gt;
        &amp;lt;% } else if (locals.status === 404) { %&amp;gt;
          The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
        &amp;lt;% } else if (locals.status === 403) { %&amp;gt;
          You don't have permission to access this resource.
        &amp;lt;% } else if (locals.status === 500) { %&amp;gt;
          Something went wrong on our end. Please try again later.
        &amp;lt;% } else { %&amp;gt;
          An unexpected error occurred. Please try again later.
        &amp;lt;% } %&amp;gt;
      &amp;lt;/p&amp;gt;

      &amp;lt;div class="error-actions"&amp;gt;
        &amp;lt;a href="javascript:history.back()" class="btn btn-outline-primary me-2"&amp;gt;
          &amp;lt;i class="fas fa-arrow-left"&amp;gt;&amp;lt;/i&amp;gt; Go Back
        &amp;lt;/a&amp;gt;
        &amp;lt;a href="/" class="btn btn-primary"&amp;gt;
          &amp;lt;i class="fas fa-home"&amp;gt;&amp;lt;/i&amp;gt; Go to Homepage
        &amp;lt;/a&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;% if (locals.error &amp;amp;&amp;amp; !env.isProd) { %&amp;gt;
        &amp;lt;div class="error-details mt-4"&amp;gt;
          &amp;lt;div class="card"&amp;gt;
            &amp;lt;div class="card-header bg-light"&amp;gt;
              &amp;lt;h5 class="mb-0"&amp;gt;Error Details&amp;lt;/h5&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="card-body"&amp;gt;
              &amp;lt;pre class="error-stack"&amp;gt;&amp;lt;%= error.stack %&amp;gt;&amp;lt;/pre&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;% } %&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="card-footer text-center py-3"&amp;gt;
      &amp;lt;div class="small"&amp;gt;
        Need help? Contact &amp;lt;a href="mailto:ict@bugema.ac.ug"&amp;gt;ICT Support&amp;lt;/a&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;br&gt;


&lt;p&gt;&amp;lt;%- contentFor('styles') %&amp;gt;&lt;/p&gt;


  .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;
  }
  
  &lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (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;
    }
  }


&lt;p&gt;&amp;lt;%- contentFor('scripts') %&amp;gt;&lt;br&gt;
&amp;lt;br&amp;gt;
  // Add any error page specific JavaScript here&amp;lt;br&amp;gt;
  document.addEventListener(&amp;amp;#39;DOMContentLoaded&amp;amp;#39;, function() {&amp;lt;br&amp;gt;
    // Example: Log error details to console in development&amp;lt;br&amp;gt;
    &amp;amp;lt;% if (locals.error &amp;amp;amp;&amp;amp;amp; !env.isProd) { %&amp;amp;gt;&amp;lt;br&amp;gt;
      console.error(&amp;amp;#39;Error Details:&amp;amp;#39;, &amp;amp;lt;%= JSON.stringify(error) %&amp;amp;gt;);&amp;lt;br&amp;gt;
    &amp;amp;lt;% } %&amp;amp;gt;&amp;lt;br&amp;gt;
  });&amp;lt;br&amp;gt;
 `&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;this is what i suffer from&lt;br&gt;
`snow@snow:~/Desktop/ERMS$ npm run dev&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:erms@1.0.0"&gt;erms@1.0.0&lt;/a&gt; dev&lt;br&gt;
nodemon app.js&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;[nodemon] 3.1.10&lt;br&gt;
[nodemon] to restart at any time, enter &lt;code&gt;rs&lt;/code&gt;&lt;br&gt;
[nodemon] watching path(s): &lt;em&gt;.&lt;/em&gt;&lt;br&gt;
[nodemon] watching extensions: js,mjs,cjs,json&lt;br&gt;
[nodemon] starting &lt;code&gt;node app.js&lt;/code&gt;&lt;br&gt;
Step 1: Starting app.js execution...&lt;br&gt;
2025-05-21 06:05:45 info: Attempting to connect to MongoDB at cluster0.wcahcli.mongodb.net/?retryWrites=true&amp;amp;w=majority&amp;amp;appName=Cluster0&lt;br&gt;
Middleware setup complete.&lt;br&gt;
(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.&lt;br&gt;
(Use &lt;code&gt;node --trace-warnings ...&lt;/code&gt; to show where the warning was created)&lt;br&gt;
(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.&lt;br&gt;
(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.&lt;br&gt;
(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.&lt;br&gt;
(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.&lt;br&gt;
2025-05-21 06:05:48 info: Successfully connected to MongoDB Atlas&lt;br&gt;
2025-05-21 06:05:48 info: MongoDB Atlas connection established successfully&lt;br&gt;
Attempting to start the server...&lt;/p&gt;

&lt;p&gt;==========================================================&lt;br&gt;
*** SERVER STARTED SUCCESSFULLY ***&lt;/p&gt;

&lt;h1&gt;
  
  
  🌐 App URL: &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;🔐 Session Check: Session {&lt;br&gt;
  cookie: {&lt;br&gt;
    path: '/',&lt;br&gt;
    _expires: 2025-05-31T07:25:36.990Z,&lt;br&gt;
    originalMaxAge: 1209600000,&lt;br&gt;
    httpOnly: true,&lt;br&gt;
    secure: false,&lt;br&gt;
    sameSite: 'strict'&lt;br&gt;
  },&lt;br&gt;
  flash: {}&lt;br&gt;
}&lt;br&gt;
2025-05-21 06:05:53 info: GET / 404 2.736 ms - 139&lt;br&gt;
`&lt;/p&gt;


&lt;/blockquote&gt;

</description>
    </item>
  </channel>
</rss>
