Duffer Derek

Current Path : /var/www/api-mk-planner.bitkit.dk/httpdocs/Backend/src/controllers/
Upload File :
Current File : /var/www/api-mk-planner.bitkit.dk/httpdocs/Backend/src/controllers/controller.js

import bcrypt from "bcrypt";
import { createHash } from "crypto";
import { matchedData, validationResult } from "express-validator";
import { Sequelize } from "sequelize";
import Log from "../configs/logger.js";
import refreshToken from "../database/models/refreshToken.js";
import User from "../database/models/users.js";
import { generateToken, verifyToken } from "../services/tokenHandler.js";

const validation_result = validationResult.withDefaults({
  formatter: (error) => error.msg,
});

export const validate = (req, res, next) => {
  const errors = validation_result(req).mapped();
  if (Object.keys(errors).length) {
    return res.status(422).json({
      status: 422,
      errors,
    });
  }
  next();
};

// If email already exists in database
export const fetchUserByEmailOrID = async (data, isEmail = true) => {
  let whereCondition = { id: data };
  if (isEmail) {
    whereCondition = { email: data };
  }
  const row = await User.findOne({
    attributes: [
      "id",
      "name",
      "email",
      "type",
      "item_id",
      "task_activation_span",
    ],
    where: whereCondition,
  });
  return row;
};

export const getUserByPhone = async (phone) => {
  let whereCondition = { phone: phone, type: { [Sequelize.Op.or]: [0, 1, 3] } };
  const row = await User.findOne({
    attributes: ["id", "name", "email", "phone", "type"],
    where: whereCondition,
  });
  return row;
};

export default {
  signup: async (req, res, next) => {
    try {
      const { name, email, password } = matchedData(req);

      const saltRounds = 10;
      // Hash the password
      const hashPassword = await bcrypt.hash(password, saltRounds);

      const result = await User.create({
        name: name,
        email: email,
        password: hashPassword,
      });

      res.status(201).json({
        status: 201,
        message: "You have been successfully registered.",
        user_id: result.id,
      });
    } catch (err) {
      next(err);
    }
  },

  login: async (req, res, next) => {
    try {
      const { user, password } = req.body;
      const verifyPassword = await bcrypt.compare(password, user.password);
      if (!verifyPassword) {
        return res.status(422).json({
          status: 422,
          message: "Incorrect password!",
        });
      }

      // Generating Access and Refresh Token
      const access_token = generateToken({ id: user.id });
      const refresh_token = generateToken({ id: user.id }, false);

      const md5Refresh = createHash("md5").update(refresh_token).digest("hex");

      // Storing refresh token in MD5 format
      const result = await refreshToken.create({
        user_id: user.id,
        token: md5Refresh,
      });

      if (!result.id) {
        throw new Error("Failed to whitelist the refresh token.");
      }
      res.json({
        status: 200,
        access_token,
        refresh_token,
      });
    } catch (err) {
      Log.error(err);
      next(err);
    }
  },

  getUser: async (req, res, next) => {
    try {
      // Verify the access token
      const data = verifyToken(req.headers.access_token);
      if (data && data.status) return res.status(data.status).json(data);
      // fetching user by the `id` (column)
      const user = await fetchUserByEmailOrID(data.id, false);

      if (!user) {
        return res.status(404).json({
          status: 404,
          message: "User not found",
        });
      }
      res.json({
        status: 200,
        user: user,
      });
    } catch (err) {
      Log.error(err);
      next(err);
    }
  },

  refreshToken: async (req, res, next) => {
    try {
      const token = req.headers.refresh_token;
      // Verify the refresh token
      const data = (token, false);
      if (data && data.status) return res.status(data.status).json(data);

      // Converting refresh token to md5 format
      const md5Refresh = createHash("md5").update(token).digest("hex");

      // Finding the refresh token in the database
      const refTokenRow = await refreshToken.findOne({
        where: {
          token: md5Refresh,
        },
      });

      if (!refTokenRow) {
        return res.json({
          status: 401,
          message: "Unauthorized: Invalid Refresh Token.",
        });
      }

      // Generating new access and refresh token
      const access_token = generateToken({ id: data.id });
      const refresh_token = generateToken({ id: data.id }, false);

      const newMd5Refresh = createHash("md5")
        .update(refresh_token)
        .digest("hex");

      // Replacing the old refresh token to new refresh token
      await refreshToken.update(
        { token: newMd5Refresh },
        {
          where: { token: md5Refresh },
        }
      );
      res.json({
        status: 200,
        access_token,
        refresh_token,
      });
    } catch (err) {
      next(err);
    }
  },
};

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists