You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
5.1 KiB
JavaScript

const jwt = require("jsonwebtoken")
const bcrypt = require("bcrypt")
const faker = require("faker")
const User = require("../model/User")
const auth = require("../auth")
// Secret Sauce
require("dotenv").config()
// Controller function for user registration
exports.registerUser = async (req, res) => {
try {
const { email, password, firstName, lastName } = req.body
// Check if the email already exists
const existingUser = await User.findOne({ email })
if (existingUser) {
return res
.status(400)
.json({ message: "This Email is already registered." })
}
// If firstName and lastName are not provided, generate default values using faker
const autoGeneratedFirstName = firstName || faker.name.firstName()
const autoGeneratedLastName = lastName || faker.name.lastName()
// Hash the password before saving it
const hashedPassword = await bcrypt.hash(password, 10)
const newUser = new User({
email,
password: hashedPassword,
firstName: autoGeneratedFirstName,
lastName: autoGeneratedLastName,
})
await newUser.save()
res.status(201).json({
message:
"User registered successfully. To update account details, acess user/update",
})
} catch (error) {
console.error(error)
res.status(500).json({ message: "Internal server error" })
}
}
// Controller function for user authentication
exports.authenticateUser = async (req, res) => {
try {
const { email, password } = req.body
const user = await User.findOne({ email })
if (!user) {
return res.status(401).json({ message: "Invalid credentials" })
}
const passwordMatch = await bcrypt.compare(password, user.password)
if (!passwordMatch) {
return res.status(401).json({ message: "Invalid credentials" })
}
// Generate JWT token using the function from auth.js
const token = auth.generateToken(user._id, user.email, user.isAdmin)
// Decode JWT token to get expiration time
const decodedToken = jwt.decode(token)
if (decodedToken) {
const expiration = new Date(decodedToken.exp * 1000) // Convert seconds to milliseconds
// Log token expiration
console.log(
`Authenticate success. Token will expire on: ${expiration}`
)
} else {
console.error("Error decoding token")
}
// Return user details and token
res.status(200).json({
userId: user._id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
isAdmin: user.isAdmin,
token: token,
})
} catch (error) {
console.error(error)
res.status(500).json({ message: "Internal server error" })
}
}
// Controller function for updating user data (including email, firstName, lastName, and password)
exports.updateUserData = async (req, res) => {
try {
const { userId, newEmail, newFirstName, newLastName, newPassword } =
req.body
const userIdFromToken = req.user.userId
if (userIdFromToken !== userId) {
return res.status(403).json({
message:
"Permission denied. You can only update your own data.",
})
}
const user = await User.findById(userId)
if (!user) {
return res.status(404).json({ message: "User not found" })
}
// Update email if provided
if (newEmail) {
user.email = newEmail
}
// Update firstName if provided
if (newFirstName) {
user.firstName = newFirstName
}
// Update lastName if provided
if (newLastName) {
user.lastName = newLastName
}
// Update password if provided
if (newPassword) {
const hashedPassword = await bcrypt.hash(newPassword, 10)
user.password = hashedPassword
}
// Save the updated user data
await user.save()
// Fetch the updated user details
const updatedUser = await User.findById(userId)
// Return the updated user details in the response
res.status(200).json({
message: "User data updated successfully",
user: updatedUser,
})
} catch (error) {
console.error(error)
res.status(500).json({ message: "Internal server error" })
}
}
exports.getUserDetails = async (req, res) => {
try {
const { userId } = req.body;
const user = await User.findById(userId);
if (!user) {
return res.status(404).json({ message: "User not found" });
}
// Create a new object with only the desired properties (excluding password)
const userWithoutPassword = {
_id: user._id,
username: user.username,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
orderedProducts: user.orderedProducts,
// Add other properties you want to include in the response
};
// Return the user details in the response
res.status(200).json({
user: userWithoutPassword,
});
} catch (error) {
console.error(error);
res.status(500).json({ message: false });
}
};
exports.setAdmin = async (req, res) => {
try {
const { userId } = req.body // assuming userId is sent in the request body
const user = await User.findById(userId)
if (!user) {
return res.status(404).json({ error: "User not found." })
}
user.isAdmin = true
await user.save()
res.json({ message: "User is now an admin." })
} catch (error) {
console.error(error)
res.status(500).json({ error: "Internal server error" })
}
}