/**
* Authentication Middleware
*
* This module provides JWT-based authentication middleware for the Social Media Dashboard API.
* It handles token verification, user authentication, and token generation for secure API access.
*
* @author Ignas Panavas
* @version 1.0.0
*/
const jwt = require('jsonwebtoken');
const User = require('../models/User');
/**
* Authenticate JWT Token Middleware
*
* Verifies JWT tokens from the Authorization header and attaches the authenticated user to the request object.
* This middleware should be used on protected routes that require user authentication.
*
* @param {Object} req - Express request object
* @param {Object} res - Express response object
* @param {Function} next - Express next middleware function
*
* @returns {void} Calls next() if authentication succeeds, sends error response if it fails
*
* @example
* // Protect a route
* router.get('/protected', authenticateToken, (req, res) => {
* // req.user is now available with the authenticated user
* res.json({ user: req.user });
* });
*/
const authenticateToken = async (req, res, next) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
if (!token) {
return res.status(401).json({ message: 'Access token required' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(decoded.userId);
if (!user) {
return res.status(401).json({ message: 'Invalid token - user not found' });
}
req.user = user;
next();
} catch (error) {
if (error.name === 'TokenExpiredError') {
return res.status(401).json({ message: 'Token expired' });
}
return res.status(403).json({ message: 'Invalid token' });
}
};
/**
* Generate JWT Access Token
*
* Creates a new JWT access token for the specified user. Access tokens are used for API authentication
* and have a shorter expiration time for security.
*
* @param {string} userId - The MongoDB ObjectId of the user
* @returns {string} JWT access token
*
* @example
* const token = generateToken('507f1f77bcf86cd799439011');
* // Returns: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
*/
const generateToken = (userId) => {
return jwt.sign(
{ userId },
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
);
};
/**
* Generate JWT Refresh Token
*
* Creates a new JWT refresh token for the specified user. Refresh tokens are used to obtain new
* access tokens without requiring the user to log in again. They have a longer expiration time.
*
* @param {string} userId - The MongoDB ObjectId of the user
* @returns {string} JWT refresh token
*
* @example
* const refreshToken = generateRefreshToken('507f1f77bcf86cd799439011');
* // Returns: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
*/
const generateRefreshToken = (userId) => {
return jwt.sign(
{ userId, type: 'refresh' },
process.env.JWT_REFRESH_SECRET,
{ expiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '30d' }
);
};
module.exports = {
authenticateToken,
generateToken,
generateRefreshToken
};
Source