auth.routes.js•5.11 kB
const express = require('express');
const jwt = require('jsonwebtoken');
const User = require('../models/user.model');
const config = require('../config/config');
const { logger } = require('../utils/logger');
const router = express.Router();
/**
* @route POST /api/auth/register
* @desc Register a new user
* @access Public
*/
router.post('/register', async (req, res) => {
try {
const { username, email, password, firstName, lastName } = req.body;
// Check if user already exists
const existingUser = await User.findOne({
$or: [{ email }, { username }]
});
if (existingUser) {
return res.status(400).json({
success: false,
message: 'User with that email or username already exists'
});
}
// Create new user
const newUser = new User({
username,
email,
password,
firstName,
lastName,
role: 'user' // Default role
});
await newUser.save();
// Don't send back the password
newUser.password = undefined;
res.status(201).json({
success: true,
message: 'User registered successfully',
data: newUser
});
} catch (error) {
logger.error('Registration error:', error);
res.status(500).json({
success: false,
message: 'Error registering user',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route POST /api/auth/login
* @desc Authenticate user and get token
* @access Public
*/
router.post('/login', async (req, res) => {
try {
const { username, password } = req.body;
// Find user by username (could be email or actual username)
const user = await User.findOne({
$or: [
{ email: username },
{ username }
]
});
if (!user) {
return res.status(401).json({
success: false,
message: 'Invalid credentials'
});
}
// Check if user is active
if (!user.isActive) {
return res.status(403).json({
success: false,
message: 'Account is disabled'
});
}
// Check password
const isMatch = await user.comparePassword(password);
if (!isMatch) {
return res.status(401).json({
success: false,
message: 'Invalid credentials'
});
}
// Update last login
user.lastLogin = new Date();
await user.save();
// Create token payload
const payload = {
id: user._id,
username: user.username,
email: user.email,
role: user.role
};
// Sign token
const token = jwt.sign(
payload,
config.jwt.secret,
{ expiresIn: config.jwt.expiresIn }
);
res.json({
success: true,
message: 'Login successful',
token: `Bearer ${token}`,
user: {
id: user._id,
username: user.username,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: user.role
}
});
} catch (error) {
logger.error('Login error:', error);
res.status(500).json({
success: false,
message: 'Error during login',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route GET /api/auth/validate
* @desc Validate user token
* @access Private
*/
router.get('/validate', async (req, res) => {
try {
// Extract token from header
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
success: false,
message: 'No token provided'
});
}
const token = authHeader.split(' ')[1];
// Verify token
const decoded = jwt.verify(token, config.jwt.secret);
// Check if user exists
const user = await User.findById(decoded.id).select('-password');
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
// Check if user is active
if (!user.isActive) {
return res.status(403).json({
success: false,
message: 'Account is disabled'
});
}
res.json({
success: true,
message: 'Token is valid',
user: {
id: user._id,
username: user.username,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
role: user.role
}
});
} catch (error) {
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
success: false,
message: 'Invalid token'
});
} else if (error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: 'Token expired'
});
}
logger.error('Token validation error:', error);
res.status(500).json({
success: false,
message: 'Error validating token',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
module.exports = router;