Wolkendama-API / Controller / userController.js
userController.js
Raw
const jwt = require("jsonwebtoken");
const { promisify } = require("util");
const mongoose = require("mongoose");

const catchAsync = require("../utils/catchAsync");
const User = require("../Model/userModel");
const AppError = require("../utils/appError");

const createSendToken = (user, statusCode, req, res) => {
  const token = jwt.sign({ user }, process.env.JWT_SECRET, {
    expiresIn: process.env.JWT_EXPIRES_IN,
  });

  const cookieOptions = {
    expires: new Date(
      Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 1000 * 60 * 60
    ),
    httpOnly: true,
    secure: req.secure || req.headers["x-forwarded-proto"] === "https",
  };

  res.cookie("Woladmin", token, cookieOptions);

  res.status(statusCode).json({
    status: "success",
    token,
    data: {
      user,
    },
  });
};

exports.login = catchAsync(async (req, res, next) => {
  const { username, password } = req.body;

  if (!username || !password) {
    return next(new AppError("Please provide username or password", 400));
  }

  const user = await User.findOne({ username }).select("+password");

  if (!user) {
    return next(new AppError("Incorrect username or password", 400));
  }

  const passwordChecking = await user.correctPassword(password, user.password);

  if (!passwordChecking) {
    return next(new AppError("Incorrect username or password", 400));
  }

  user.password = undefined;
  createSendToken({ id: user._id }, 201, req, res);
});

exports.register = catchAsync(async (req, res, next) => {
  const user = await User.create({
    name: req.body.name,
    username: req.body.username,
    password: req.body.password,
    passwordConfirm: req.body.passwordConfirm,
  });

  user.password = undefined;

  res.status(201).json({
    status: "success",
    data: user,
  });
});

exports.isLoggedIn = catchAsync(async (req, res, next) => {
  // 1) Getting token and check of if it's there
  let token;

  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith("Bearer")
  ) {
    token = req.headers.authorization.split(" ")[1];
  } else if (req.cookies.Woladmin) {
    token = req.cookies.Woladmin;
  }

  if (!token) {
    return res.status(400).json({
      status: "error",
      data: `Please login to gain access!`,
    });
  }

  try {
    // 2) Verification token
    const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);

    const user = await User.findById(mongoose.Types.ObjectId(decoded.user.id));

    // 3) Check if user still exists
    if (user) {
      return res.status(201).json({
        status: "success",
        data: `Account is logged in!`,
      });
    } else {
      return res.status(400).json({
        status: "error",
        data: `Token ID does not exist, please log in again!`,
      });
    }
  } catch (err) {
    if (err.message === "jwt expired") {
      return res.status(400).json({
        status: "error",
        data: `Token has expired, please login again`,
      });
    }

    return res.status(400).json({
      status: "error",
      data: err,
    });
  }
});

exports.logout = (req, res, next) => {
  res.cookie("Woladmin", "Loggedout", {
    expires: new Date(Date.now() + 10 * 1000),
    httpOnly: true,
  });
  res.status(200).json({ status: "success" });
};