auth.js•2.65 kB
/**
* Authentication middleware
* Verifies JWT tokens and attaches user to request
*/
const { AuthenticationError } = require('../utils/errorTypes');
const tokenManager = require('../utils/tokenManager');
const User = require('../models/user');
const logger = require('../utils/logger');
/**
* Protect routes - require authentication
* Verifies JWT token from Authorization header or cookies
*/
const protect = async (req, res, next) => {
try {
let token;
// Check for token in Authorization header
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
token = req.headers.authorization.split(' ')[1];
}
// Check for token in cookies
else if (req.cookies && req.cookies.jwt) {
token = req.cookies.jwt;
}
// If no token found, return authentication error
if (!token) {
return next(new AuthenticationError('You are not logged in. Please log in to get access.'));
}
// Verify token
const decoded = tokenManager.verifyJWT(token);
// Check if user still exists
const user = await User.findById(decoded.id);
if (!user) {
return next(new AuthenticationError('The user belonging to this token no longer exists.'));
}
// Attach user to request
req.user = user;
next();
} catch (error) {
logger.error(`Authentication error: ${error.message}`);
return next(new AuthenticationError('Authentication failed. Please log in again.'));
}
};
/**
* Check if Facebook token is valid and refresh if needed
*/
const checkFacebookToken = async (req, res, next) => {
try {
const user = req.user;
// Check if token is expired
if (user.tokenExpiry && new Date(user.tokenExpiry) < new Date()) {
logger.info(`Facebook token expired for user ${user._id}, refreshing...`);
// Decrypt refresh token
const refreshToken = await tokenManager.decryptToken(user.refreshToken);
// Refresh token
const { accessToken, expiresIn } = await tokenManager.refreshFacebookToken(refreshToken);
// Update user with new token
user.accessToken = await tokenManager.encryptToken(accessToken);
user.tokenExpiry = new Date(Date.now() + (expiresIn * 1000));
await user.save();
logger.info(`Facebook token refreshed for user ${user._id}`);
}
next();
} catch (error) {
logger.error(`Facebook token refresh error: ${error.message}`);
return next(new AuthenticationError('Failed to refresh Facebook token. Please log in again.'));
}
};
module.exports = {
protect,
checkFacebookToken
};