File size: 4,045 Bytes
4888678 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const Joi = require('joi');
// Validation schemas
const registerSchema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required()
});
const loginSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(6).required()
});
// Generate JWT token
const generateToken = (userId) => {
return jwt.sign({ userId }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRE || '7d'
});
};
// Register user
exports.register = async (req, res) => {
try {
// Validate input
const { error } = registerSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
const { username, email, password } = req.body;
// Check if user already exists
const existingUser = await User.findOne({
$or: [{ email }, { username }]
});
if (existingUser) {
return res.status(400).json({
error: existingUser.email === email ? 'Email already registered' : 'Username already taken'
});
}
// Create new user
const user = new User({ username, email, password });
await user.save();
// Generate token
const token = generateToken(user._id);
res.status(201).json({
message: 'User registered successfully',
token,
user
});
} catch (error) {
console.error('Registration error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Login user
exports.login = async (req, res) => {
try {
// Validate input
const { error } = loginSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details[0].message });
}
const { email, password } = req.body;
// Find user and include password for comparison
const user = await User.findOne({ email }).select('+password');
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// Check password
const isPasswordValid = await user.comparePassword(password);
if (!isPasswordValid) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// Update last seen
user.lastSeen = new Date();
await user.save();
// Generate token
const token = generateToken(user._id);
res.json({
message: 'Login successful',
token,
user
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Get current user
exports.getMe = async (req, res) => {
try {
const user = await User.findById(req.userId);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json({ user });
} catch (error) {
console.error('Get user error:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
// Update user profile
exports.updateProfile = async (req, res) => {
try {
const { username, avatar } = req.body;
const updates = {};
if (username) {
// Check if username is already taken
const existingUser = await User.findOne({
username,
_id: { $ne: req.userId }
});
if (existingUser) {
return res.status(400).json({ error: 'Username already taken' });
}
updates.username = username;
}
if (avatar) updates.avatar = avatar;
const user = await User.findByIdAndUpdate(
req.userId,
updates,
{ new: true, runValidators: true }
);
res.json({
message: 'Profile updated successfully',
user
});
} catch (error) {
console.error('Update profile error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}; |