/**
* Users API routes module.
* @module routes/api/users
* @requires express
* @requires gravatar
* @requires bcrypt
* @requires jwt
* @requires config
* @requires express-validator
* @requires models/User
*
* @example
* // POST api/users
* // Usage:
* // 1. Add the following route in your express app
* app.post('/api/users', async (req, res) => { ... });
*
* // 2. Send a POST request with user's registration information
* // e.g., using axios:
* const axios = require('axios');
* const userData = {
* name: 'John Doe',
* email: 'johndoe@example.com',
* password: 'mypassword',
* };
*
* axios.post('http://localhost:5000/api/users', userData)
* .then(response => {
* console.log(response.data); // User's JWT
* })
* .catch(error => {
* console.error('Error:', error);
* });
*/
const express = require('express');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const { check, validationResult } = require('express-validator');
const normalize = require('normalize-url');
const User = require('../../models/User');
/**
* @route POST api/users
* @desc Register user
* @access Public
* @param {Object} req - Express request object
* @param {Object} req.body - Request body containing the user's registration information
* @param {string} req.body.name - User's name
* @param {string} req.body.email - User's email address
* @param {string} req.body.password - User's password
* @param {Object} res - Express response object
* @returns {Object} - JSON response containing the user's JWT or an error message
* @throws {Error} - If there's a server error
*/
router.post(
'/',
[
check('name', 'Name is required').notEmpty(),
check('email', 'Please include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({ min: 6 })
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, email, password } = req.body;
try {
let user = await User.findOne({ email });
// See if user exists
if (user) {
return res.status(400).json({ errors: [{ msg: 'User already exists' }] });
}
// Get users gravatar
const avatar = normalize(
gravatar.url(email, {
s: '200',
r: 'pg',
d: 'mm'
}),
{ forceHttps: true }
);
user = new User({
name,
email,
avatar,
password
});
// Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
// Return jsonwebtoken
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
config.get('jwtSecret'),
{ expiresIn: '5 days' },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
}
);
/**
* Users API router.
* @type {express.Router}
*/
module.exports = router;