routes/api/auth.js

/**
 * Auth API routes module.
 * @module routes/api/auth
 * @requires express
 * @requires express.Router
 * @requires middleware/auth
 * @requires models/User
 * @requires jsonwebtoken
 * @requires express-validator
 * @requires bcryptjs
 * @requires config
 * 
 * @example
 * // GET api/auth
 * // Usage:
 * // 1. Include auth middleware in your express app
 * const auth = require('../../middleware/auth');
 *
 * // 2. Add the following route in your express app
 * app.get('/api/auth', auth, async (req, res) => {
 *   try {
 *     const user = await User.findById(req.user.id).select('-password');
 *     res.json(user);
 *   } catch (err) {
 *     console.error(err.message);
 *     res.status(500).send('Server Error');
 *   }
 * });
 *
 * // 3. Send a request with the token in the 'x-auth-token' header
 * // e.g., using axios:
 * const axios = require('axios');
 *
 * axios.get('http://localhost:5000/api/auth', {
 *   headers: {
 *     'x-auth-token': 'your_token_here'
 *   }
 * }).then(response => {
 *   console.log(response.data);
 * }).catch(error => {
 *   console.error('Error:', error);
 * });
 * 
 * @example
 * // POST api/auth
 * // Usage:
 * // 1. Include validation middleware in your express app
 * const { check, validationResult } = require('express-validator');
 *
 * // 2. Add the following route in your express app
 * app.post('/api/auth', [
 *   check('email', 'Please include a valid email').isEmail(),
 *   check('password', 'Password is required').exists(),
 * ], async (req, res) => {
 *   // Your route handler logic
 * });
 *
 * // 3. Send a request with email and password in the request body
 * // e.g., using axios:
 * const axios = require('axios');
 *
 * axios.post('http://localhost:5000/api/auth', {
 *   email: 'user@example.com',
 *   password: 'user_password',
 * }).then(response => {
 *   console.log(response.data); // JWT token
 * }).catch(error => {
 *   console.error('Error:', error);
 * });
 */


const express = require('express');
const router = express.Router();
const auth = require('../../middleware/auth');

const User = require('../../models/User');
const jwt = require('jsonwebtoken');
const { check, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
const config = require('config');


/**
 * @route   GET api/auth
 * @desc    Get authenticated user
 * @access  Protected
 * @param {function} auth - Authentication middleware function.
 * @param {function} asyncHandler - Express async handler function.
 * @returns {Object} User object without password.
 */
router.get('/', auth, async (req, res) => {
  try {
    const user = await User.findById(req.user.id).select('-password');
    res.json(user);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});


/**
 * @route   POST api/auth
 * @desc    Authenticate user & get token
 * @access  Public
 * @param {Array} validationRules - Array of Express Validator rules.
 * @param {function} asyncHandler - Express async handler function.
 * @returns {Object} JWT token.
 */
router.post(
  '/',
  [
    check('email', 'Please include a valid email').isEmail(),
    check('password', 'Password is required').exists(),
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { email, password } = req.body;

    try {
      let user = await User.findOne({ email });
      // See if user exists
      if (!user) {
        return res.status(400).json({ errors: [{ msg: 'Invalid Credentials' }] });
      }

      const isMatch = await bcrypt.compare(password, user.password);

      if (!isMatch) {
        return res.status(400).json({ errors: [{ msg: 'Invalid Credentials' }] });
      }

      const payload = {
        user: {
          id: user.id
        }
      };

      jwt.sign(
        payload,
        config.get('jwtSecret'),
        { expiresIn: '6 days' },
        (err, token) => {
          if (err) throw err;
          res.json({ token });
        }
      );
    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server error');
    }
  }
);


/**
 * Auth API router.
 * @type {express.Router}
 */
module.exports = router;