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" }) } }