CHAINR / backend /src /controllers /authController.js
chainr-ai's picture
Upload 8536 files
4888678 verified
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' });
}
};