create-tin
Version:
Scaffold a TypeScript or JavaScript Express boilerplate
135 lines (104 loc) • 3.27 kB
JavaScript
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import User from '../models/userModel.js';
import validator from 'validator';
// Generate JWT token with expiration
const generateToken = (userId) => {
return jwt.sign(
{ id: userId },
process.env.JWT_SECRET,
{ expiresIn: '30d' }
);
};
const registerUser = async (req, res) => {
try {
const { username, email, password } = req.body;
if (!username || !email || !password) {
return res.status(400).json({ success: false, message: "Please fill all required fields" });
}
if (!validator.isEmail(email)) {
return res.status(400).json({ success: false, message: "Please enter a valid email" });
}
if (password.length < 6) {
return res.status(400).json({ success: false, message: "Password must be at least 6 characters" });
}
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(409).json({ success: false, message: "User with this email already exists" });
}
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const newUser = new User({
username,
email: email.toLowerCase(),
password: hashedPassword,
});
const savedUser = await newUser.save();
const token = generateToken(savedUser._id);
res.status(201).json({
success: true,
message: "User registered successfully",
token,
user: {
id: savedUser._id,
username: savedUser.username,
email: savedUser.email,
}
});
} catch (error) {
console.error("Register error:", error);
if (error.code === 11000) {
return res.status(409).json({
success: false,
message: "User with this email already exists"
});
}
res.status(500).json({
success: false,
message: "Failed to register user"
});
}
};
const loginUser = async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({
success: false,
message: "Email and password are required"
});
}
const user = await User.findOne({ email: email.toLowerCase() });
if (!user) {
return res.status(401).json({
success: false,
message: "Invalid credentials"
});
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(401).json({
success: false,
message: "Invalid credentials"
});
}
const token = generateToken(user._id);
res.status(200).json({
success: true,
message: "Login successful",
token,
user: {
_id: user._id,
username: user.username,
email: user.email
}
});
} catch (error) {
console.error("Login error:", error);
res.status(500).json({
success: false,
message: "Failed to login"
});
}
};
export { registerUser, loginUser };