import express from 'express'; import { mongoose } from 'mongoose'; import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; import {SECRET_KEY} from "../passport.js"; import {isValidEmail} from "../utils.js"; /** * Create an Express router instance. * * @type {Express.Router} */ const router = express.Router(); /** * Set the salt rounds for password hashing (10). * * @type {number} */ const saltRounds = 10; /** * Define a Mongoose schema for users. * * @typedef {Object} UserSchema * @property {String} email - The user's email address. * @property {String} password - The user's password. */ /** * Create a new Mongoose model from the user schema. * * @type {Model} */ const userSchema = new mongoose.Schema({ /** * The user's email address. * * @type {String} * @required */ email: { type: String, required: true }, /** * The user's password. * * @type {String} * @required */ password: { type: String, required: true } }) const User = mongoose.model('User', userSchema, 'users'); /** * Generate a JWT token for the given user. * * @param {Object} user - The user object. * @returns {String} The generated JWT token. */ function generateToken(user) { const payload = { id: user._id }; return jwt.sign(payload, SECRET_KEY, {expiresIn: '6h'}); } /** * Handle a login request. */ router.post('/login', function (req, res) { const email = req.body.email; const password = req.body.password; if (!password || !email) { return res.status(400).json({ message: 'parameters invalid' }); } if (!isValidEmail(email)) { return res.status(400).json({ message: 'email is invalid' }); } User.findOne({ email: email }) .then(user => { if (!user) { return res.status(422).json({ message: 'user not found' }); } bcrypt.compare(password, user.password, function (err, result) { if (result) { res.json({ token: generateToken(user) }); } else { res.status(401).json({ error: "Wrong password" }); } }); }) .catch(err => { console.log(err); res.status(500).json({ error: err.message }); }); }); /** * Handle a registration request. */ router.post('/register', async function (req, res) { const email = req.body.email; const password = req.body.password; if (!password || !email) { return res.status(400).json({ message: 'parameters invalid' }); } if (!isValidEmail(email)) { return res.status(400).json({ message: 'email is invalid' }); } try { const existingUser = await User.findOne({ email: email }); if (existingUser) { return res.status(403).json({ message: 'user already exists' }); } // Hash the password bcrypt.hash(password, saltRounds, async function (err, hash) { if (err) { return res.status(500).json({ error: err.message }); } else if (hash) { await User.collection.insertOne({ email: email, password: hash }); const user = await User.findOne({ email: email }); return res.json({ token: generateToken(user) }); } }); } catch (err) { console.error(err); return res.status(500).json({ error: 'Internal Server Error' }); } }); export { router, User };