Snai3i-LandingPage-FormBuilder / backend / src / controllers / authController.ts
authController.ts
Raw
import { HttpCodes } from '../config/errors';
import { Request, Response, NextFunction } from 'express';
import { ErrorResponse, SuccessResponse } from '../utils/response';
import User, { UserD } from '../models/userModel';
import Logger from '../utils/logger';
import generateToken from '../utils/jwt';
import { RequestWithUser } from '../types/Express';

/**
 * @desc Authenticates an admin and sets token
 * @route POST /admin/login
 * @access public
 */
export const loginAdmin = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { email, password } = req.body;

  try {
    const user: UserD = await User.findOne({ email }).select('+password');

    if (user) {
      //verifier pass
      const isPasswordMatch = await user.matchPasswords(password);

      if (isPasswordMatch) {
        generateToken(res, { _id: user._id.toString() });
        Logger.info(
          `User ${user.lastName} ${user.firstName} has logged in successfully.`
        );
        return SuccessResponse(
          res,
          HttpCodes.Accepted.code,
          user.Optimize(),
          `User ${user.lastName} ${user.firstName} has logged in successfully.`
        );
      } else {
        Logger.error(`Failed to login password incorrect ${email}.`);
        return ErrorResponse(
          res,
          HttpCodes.BadRequest.code,
          `Failed to login password incorrect.`
        );
      }
    }

    Logger.error(`Failed to login user doesn't exist ${email}.`);
    return ErrorResponse(
      res,
      HttpCodes.BadRequest.code,
      `Failed to login user doesn't exist ${email}.`
    );
  } catch (err) {
    Logger.error(`Error occurred while login ${email} : ${err}`);
    return ErrorResponse(
      res,
      HttpCodes.InternalServerError.code,
      'Failed to login. Please try again!'
    );
  }
};

/**
 * @desc Register admin
 * @route POST /admin/register
 * @access private - superAdmin
 */
export const registerAdmin = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { email, password, firstName, lastName, role } = req.body;
  try {
    const userExists: UserD | null = await User.findOne({ email });
    if (userExists) {
      Logger.error(
        `Error occurred while creating user ${email} : User already exists`
      );
      return ErrorResponse(
        res,
        HttpCodes.Unauthorized.code,
        'User already exists'
      );
    }
    const user: UserD = await User.create({
      firstName,
      lastName,
      email,
      password,
      role,
    });

    if (user) {
      // generateToken(res, { _id: user._id.toString() });
      Logger.info(`User ${lastName} ${firstName} has created in successfully.`);
      return SuccessResponse(
        res,
        HttpCodes.Accepted.code,
        user.Optimize(),
        'User created successfully.'
      );
    }

    Logger.error(`Error occurred while creating user ${email}`);
    return ErrorResponse(
      res,
      HttpCodes.BadRequest.code,
      'Failed to create user. Please try again!'
    );
  } catch (err) {
    Logger.error(`Error occurred while creating user ${email} : ${err}`);
    return ErrorResponse(
      res,
      HttpCodes.InternalServerError.code,
      'Failed to create user. Please try again!'
    );
  }
};

/**
 *   @desc Logout
 *   @route POST /admin/logout
 *   @access private
 */
export const logoutAdmin = async (
  req: RequestWithUser,
  res: Response,
  next: NextFunction
) => {
  const firstName = req.user?.firstName;
  const lastName = req.user?.lastName;

  res.cookie('token', '', {
    sameSite: 'none',
    httpOnly: true,
    expires: new Date(0),
    secure : true,
  });

  Logger.info(
    `User ${firstName} ${lastName} has logged out successfully.`
  );
  SuccessResponse(
    res,
    HttpCodes.OK.code,
    null,
    `logged out successfully.`
  );
};

/**
 *   @desc Get admin profile
 *   @route GET /admin/profile
 *   @access private - superAdmin
 */
export const getProfile = async (
  req: RequestWithUser,
  res: Response,
  next: NextFunction
) => {
  const user = req.user as UserD;

  Logger.info(
    `User ${user.lastName} ${user.firstName} has logged back successfully.`
  );

  return SuccessResponse(
    res,
    HttpCodes.Accepted.code,
    user.Optimize(),
    `User ${user.lastName} ${user.firstName} has logged back successfully.`
  );
};

/**
 *   @desc update admin profile
 *   @route PUT /admin/profile
 *   @access private - superAdmin
 */
export const updateProfile = async (
  req: RequestWithUser,
  res: Response,
  next: NextFunction
) => {
  const { userId, firstName, lastName, email, role, password } = req.body;

  try {
    const user = await User.findById(userId).select('+password');
    if (!user) {
      Logger.error(
        `Failed to update profile information to ${userId} - User not found.`
      );
      return ErrorResponse(
        res,
        HttpCodes.InternalServerError.code,
        `Failed to update profile information to ${userId} - User not found.`
      );
    }
    if (firstName) user.firstName = firstName;
    if (lastName) user.lastName = lastName;
    if (email) user.email = email;
    if (role) user.role = role;
    if (password) user.password = password;
    await user.save();

    Logger.info(
      `User ${user.lastName} ${user.firstName} has updated his profile successfully.`
    );
    return SuccessResponse(
      res,
      HttpCodes.Accepted.code,
      user.Optimize(),
      `User ${user.lastName} ${user.firstName} has updated his profile successfully.`
    );
  } catch (err) {
    Logger.error(`Failed to update profile information to ${userId}.`);
    return ErrorResponse(
      res,
      HttpCodes.InternalServerError.code,
      `Failed to update profile information to ${userId}.`,
      err
    );
  }
};

/**
 *   @desc  update admin password
 *   @route PUT /admin/password
 *   @access private - Admin
 */
export const resetPassword = async (
  req: RequestWithUser,
  res: Response,
  next: NextFunction
) => {
  const { userId, password } = req.body;

  try {
    const user = await User.findById(userId).select('+password');
    if (!user) {
      Logger.error(
        `Failed to update password information to ${userId} - User not found.`
      );
      return ErrorResponse(
        res,
        HttpCodes.InternalServerError.code,
        `Failed to update password information to ${userId} - User not found.`
      );
    }

    if (password) user.password = password;
    await user.save();

    Logger.info(
      `User ${user.lastName} ${user.firstName} has updated his password successfully.`
    );
    return SuccessResponse(
      res,
      HttpCodes.Accepted.code,
      user.Optimize(),
      `User ${user.lastName} ${user.firstName} has updated his password successfully.`
    );
  } catch (err) {
    Logger.error(`Failed to update password information to ${userId}.`);
    return ErrorResponse(
      res,
      HttpCodes.InternalServerError.code,
      `Failed to update password information to ${userId}.`,
      err
    );
  }
};

/**
 *   @desc  delete admin
 *   @route DELETE /admin/delete
 *   @access private - superAdmin
 */
export const deleteAdmin = async (
  req: RequestWithUser,
  res: Response,
  next: NextFunction
) => {
  const {userId} = req.body;
  try {
    const user = await User.findById(userId);
    if (user) {
      await User.deleteOne({ _id: userId });
      Logger.info(
        `User ${user.lastName} ${user.firstName} has deleted successfully.`
      );
      return SuccessResponse(
        res,
        HttpCodes.Accepted.code,
        null,
        `User ${user.lastName} ${user.firstName} has deleted successfully.`
      );
    } else {
      Logger.error(`Failed to delete user ${userId} - User not found.`);
      return ErrorResponse(
        res,
        HttpCodes.InternalServerError.code,
        `Failed to delete user ${userId} - User not found.`
      );
    }
  } catch (error) {
    Logger.error(`Failed to delete user ${userId}.`);
    return ErrorResponse(
      res,
      HttpCodes.InternalServerError.code,
      `Failed to delete user ${userId}.`
    );
  }
};


/**
 *   @desc  get all users
 *   @route get /admin/users
 *   @access private - superAdmin
 */
export const getAllUsers = async (
  req: RequestWithUser,
  res: Response,
  next: NextFunction
) => {
  try {
    const users = await User.find({ _id: { $ne: req.user?._id } });

    Logger.info(`Users has fetched successfully.`);
    return SuccessResponse(
      res,
      HttpCodes.Accepted.code,
      users,
      `Users has fetched successfully.`
    );

  } catch (error) {
    Logger.error(`Failed to fetch users.`);
    return ErrorResponse(
      res,
      HttpCodes.InternalServerError.code,
      `Failed to fetch users.`
    );
  }

}