Skip to content
Snippets Groups Projects
appController.js 7.15 KiB
Newer Older
Matt Kirby's avatar
Matt Kirby committed
import UserModel from "../model/User.model.js";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import ENV from "../config.js";
Matt Kirby's avatar
Matt Kirby committed
export async function verifyUser(req, res, next) {
  try {
    const { username } = req.method == "GET" ? req.query : req.body;
Matt Kirby's avatar
Matt Kirby committed
    // Check if user exists
    let exist = await UserModel.findOne({ username });
    if (!exist) return res.status(404).send({ error: "Can't find User" });
    next();
  } catch (error) {
    return res.status(404).send({ error: "Authentication Error" });
  }
/** POST: http://localhost:8080/api/register
 * @param : {
  "username" : "example123",
  "password" : "admin123",
  "email": "example@gmail.com",
  "profile": ""
}
*/
Matt Kirby's avatar
Matt Kirby committed
export async function register(req, res) {
Matt Kirby's avatar
Matt Kirby committed
    const { username, password, profile, email } = req.body;
Matt Kirby's avatar
Matt Kirby committed
    // Checking existing Username
    const existUsername = new Promise((resolve, reject) => {
      UserModel.findOne({ username }, function (err, user) {
        if (err) reject(new Error(err));
Matt Kirby's avatar
Matt Kirby committed
        if (user) reject({ error: "Username already exists!" });
Matt Kirby's avatar
Matt Kirby committed
        resolve();
Matt Kirby's avatar
Matt Kirby committed
    });
Matt Kirby's avatar
Matt Kirby committed
    // Checking existing Email
    const existEmail = new Promise((resolve, reject) => {
      UserModel.findOne({ email }, function (err, email) {
        if (err) reject(new Error(err));
Matt Kirby's avatar
Matt Kirby committed
        if (email) reject({ error: "An account with that email address already exists!" });
Matt Kirby's avatar
Matt Kirby committed
        resolve();
      });
    });

    Promise.all([existUsername, existEmail])
      .then(() => {
        if (password) {
          bcrypt
            .hash(password, 10)
            .then((hashedPassword) => {
              const user = new UserModel({
                username,
                password: hashedPassword,
                profile: profile || "",
                email,
              });

              // return save result as a response
              user
                .save()
                .then(async (result) => {
                  const user = await UserModel.findOne({ username: username });

                  // create jwt token
                  const token = jwt.sign(
                    {
                      userId: user._id,
                      username: user.username,
                      admin: false,
                    },
                    ENV.JWT_SECRET,
                    { expiresIn: "24h" }
                  );

                  res.status(201).send({
                    msg: "User Registered Successfully",
                    username: user.username,
                    token,
                  });
                })
                .catch((error) => res.status(500).send({ error }));
            })
            .catch((error) => {
              return res.status(500).send({
                error: "Enable to hash password",
              });
            });
        }
      })
      .catch((error) => {
        return res.status(500).send({ error });
Matt Kirby's avatar
Matt Kirby committed
    return res.status(500).send(error);
}

/** POST: http://localhost:8080/api/login 
 * @param: {
  "username" : "example123",
  "password" : "admin123"
}
*/
Matt Kirby's avatar
Matt Kirby committed
export async function login(req, res) {
  const { username, password } = req.body;
Matt Kirby's avatar
Matt Kirby committed
  try {
    UserModel.findOne({ username })
      .then((user) => {
        bcrypt
          .compare(password, user.password)
          .then((passwordCheck) => {
            if (!passwordCheck)
Matt Kirby's avatar
Matt Kirby committed
              return res.status(400).send({ error: "Incorrect username or password!" });
Matt Kirby's avatar
Matt Kirby committed

            // create jwt token
            const token = jwt.sign(
              {
                userId: user._id,
                username: user.username,
                admin: user.admin,
              },
              ENV.JWT_SECRET,
              { expiresIn: "24h" }
            );

            return res.status(200).send({
              msg: "Login Successful...!",
              username: user.username,
              token,
            });
          })
          .catch((error) => {
            return res.status(400).send({ error: "Password does not Match" });
          });
      })
      .catch((error) => {
        return res.status(404).send({ error: "Username not Found" });
      });
  } catch (error) {
    return res.status(500).send({ error });
  }
Matt Kirby's avatar
Matt Kirby committed
export async function getUser(req, res) {
  const { username } = req.params;
Matt Kirby's avatar
Matt Kirby committed
  try {
    if (!username) return res.status(401).send({ error: "Invalid Username" });
Matt Kirby's avatar
Matt Kirby committed
    UserModel.findOne({ username }, function (err, user) {
      if (err) return res.status(500).send({ err });
      if (!user)
        return res.status(501).send({ error: "Couldn't find the User" });
Matt Kirby's avatar
Matt Kirby committed
      const { password, ...rest } = Object.assign({}, user.toJSON());
Matt Kirby's avatar
Matt Kirby committed
      return res.status(201).send(rest);
    });
  } catch (err) {
    return res.status(404).send({ error: "Cannot find User Data" });
  }

/** PUT: http://localhost:8080/api/updateuser
 * 
. * @param: {
  "header" : "<token>"
}
body: {
    firstName: '',
    address : '',
    profile : ''
}
*/
Matt Kirby's avatar
Matt Kirby committed
export async function updateUser(req, res) {
  try {
    const { userId } = req.user;

    if (userId) {
      const body = req.body;

      // update the data
      UserModel.updateOne({ _id: userId }, body, function (err, data) {
        try {
          if (err) throw err;
          return res.status(201).send({ msg: "Record Updated...!" });
        } catch (error) {
          return res.status(401).send({ error });
Matt Kirby's avatar
Matt Kirby committed
      });
    } else {
      return res.status(401).send({ error: "User Not Found...!" });
Matt Kirby's avatar
Matt Kirby committed
  } catch (error) {
    return res.status(401).send({ error });
  }
Matt Kirby's avatar
Matt Kirby committed
 * POST /userlist
 * This DOES NOT return emails and passwords
Matt Kirby's avatar
Matt Kirby committed
 * @param {*} req
 * @param {*} res
 * @returns
 *
 * body: {userIdList: []}
 */
Matt Kirby's avatar
Matt Kirby committed
export const GetUserList = async (req, res) => {
Matt Kirby's avatar
Matt Kirby committed
    const { userIdList } = req.body;
    const users = await UserModel.find(
      { _id: { $in: userIdList } },
      { password: 0, email: 0 }
    );
    const userHash = users.map((obj) => [obj._id.toString(), obj]);

    return res.status(201).send({ userList: Array.from(userHash.entries()) });
  } catch (error) {
    return res.status(401).send({ error });
  }
 * GET /search
 * This endpoint OMITS the password and email fields
Matt Kirby's avatar
Matt Kirby committed
 * @param {*} req
 * @param {*} res
 * @returns
 *
 * query: {query: string}
 */
Matt Kirby's avatar
Matt Kirby committed
export const Search = async (req, res) => {
Matt Kirby's avatar
Matt Kirby committed
    const { searchQuery } = req.query;
Matt Kirby's avatar
Matt Kirby committed
    if (searchQuery === undefined || searchQuery.length === 0) {
      throw new Error("Please provide a valid query!");
Matt Kirby's avatar
Matt Kirby committed
    const usersWithMatchingUsername = await UserModel.find(
      { username: { $regex: `^${searchQuery}` } },
      { password: 0, email: 0 }
    );
    const usersWithMatchingName = await UserModel.find(
      {
        $or: [
          { firstName: { $regex: `^${searchQuery}`, $options: "i" } },
          { lastName: { $regex: `^${searchQuery}`, $options: "i" } },
        ],
      },
      { password: 0, email: 0 }
    );
    const resultHash = new Map(
      [...usersWithMatchingUsername, ...usersWithMatchingName].map((obj) => [
        obj._id.toString(),
        obj,
      ])
    );

    return res.status(201).send({ result: Array.from(resultHash.entries()) });
  } catch (error) {
    return res.status(401).send({ error: error.message });
  }