auth.js•4.64 kB
/**
* Authentication routes
* Handles Facebook OAuth authentication
*/
const express = require('express');
const router = express.Router();
const passport = require('passport');
const { validate, schemas } = require('../middleware/validator');
const { authLimiter } = require('../middleware/rateLimiter');
const { protect } = require('../middleware/auth');
const tokenManager = require('../utils/tokenManager');
const { sendSuccess, sendError } = require('../utils/responseFormatter');
const { AuthenticationError } = require('../utils/errorTypes');
const User = require('../models/user');
const logger = require('../utils/logger');
/**
* @route GET /auth/facebook
* @desc Initiate Facebook OAuth flow
* @access Public
*/
router.get('/facebook', authLimiter, passport.authenticate('facebook', {
session: false
}));
/**
* @route GET /auth/facebook/callback
* @desc Handle Facebook OAuth callback
* @access Public
*/
router.get('/facebook/callback', authLimiter, (req, res, next) => {
passport.authenticate('facebook', { session: false }, (err, user, info) => {
if (err) {
logger.error(`Facebook authentication error: ${err.message}`);
return res.redirect(`/auth-error?error=${encodeURIComponent('Authentication failed')}`);
}
if (!user) {
logger.error('Facebook authentication failed: No user returned');
return res.redirect(`/auth-error?error=${encodeURIComponent('Authentication failed')}`);
}
// Generate JWT token
const token = tokenManager.generateJWT(user);
// Set token in cookie
res.cookie('jwt', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 24 * 60 * 60 * 1000 // 24 hours
});
// Redirect to dashboard
return res.redirect('/dashboard');
})(req, res, next);
});
/**
* @route POST /auth/refresh
* @desc Refresh JWT token
* @access Private
*/
router.post('/refresh', protect, async (req, res, next) => {
try {
const user = req.user;
// Generate new JWT token
const token = tokenManager.generateJWT(user);
// Set token in cookie
res.cookie('jwt', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 24 * 60 * 60 * 1000 // 24 hours
});
return sendSuccess(res, { token }, 'Token refreshed successfully');
} catch (error) {
logger.error(`Token refresh error: ${error.message}`);
return next(new AuthenticationError('Failed to refresh token'));
}
});
/**
* @route POST /auth/logout
* @desc Logout user
* @access Private
*/
router.post('/logout', protect, (req, res) => {
// Clear JWT cookie
res.clearCookie('jwt');
return sendSuccess(res, null, 'Logged out successfully');
});
/**
* @route GET /auth/me
* @desc Get current user
* @access Private
*/
router.get('/me', protect, (req, res) => {
return sendSuccess(res, req.user, 'User retrieved successfully');
});
/**
* @route PUT /auth/me
* @desc Update current user
* @access Private
*/
router.put('/me', protect, validate(schemas.user.update), async (req, res, next) => {
try {
const user = req.user;
// Update user fields
if (req.body.name) user.name = req.body.name;
if (req.body.email) user.email = req.body.email;
// Save updated user
await user.save();
return sendSuccess(res, user, 'User updated successfully');
} catch (error) {
logger.error(`User update error: ${error.message}`);
return next(error);
}
});
/**
* @route GET /auth/status
* @desc Check authentication status
* @access Public
*/
router.get('/status', (req, res) => {
try {
// Check for token in cookies
const token = req.cookies.jwt;
if (!token) {
return sendSuccess(res, { authenticated: false });
}
// Verify token
const decoded = tokenManager.verifyJWT(token);
return sendSuccess(res, {
authenticated: true,
userId: decoded.id
});
} catch (error) {
return sendSuccess(res, { authenticated: false });
}
});
/**
* @route GET /auth/facebook-status
* @desc Check Facebook token status
* @access Private
*/
router.get('/facebook-status', protect, async (req, res, next) => {
try {
const user = req.user;
// Check if token is valid
const isValid = user.hasValidToken();
return sendSuccess(res, {
isValid,
expiresAt: user.tokenExpiry
});
} catch (error) {
logger.error(`Facebook token status check error: ${error.message}`);
return next(error);
}
});
module.exports = router;