MicroHack-Registrations-RestAPI / src / models / user.model.ts
user.model.ts
Raw
import { Model, Schema, model, Document } from "mongoose";
import bcrypt from "bcrypt";
import { RandomEmail } from "../utils/Function";

const emailRegexPattern: RegExp = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;

export interface UserD extends Document<UserI>, UserI {
  comparePasswords(password: string): Promise<boolean>;
  Optimize(): OptimizedUser;
}

export interface UserModel extends Model<UserD> {}

const usersSchema = new Schema<UserI>(
  {
    firstName: {
      type: String,
      required: [true, "Please enter your firstName"],
    },
    lastName: { type: String, required: [true, "Please enter your lastName"] },
    email: {
      type: String,
      required: [true, "Please enter your email"],
      unique: true,
      match: [emailRegexPattern, "Please enter a valid email address"],
    },
    role : { type: String, default: "user" },
    password: { type: String, required: [true, "Please enter your password"] },
  },
  {
    timestamps: true,
    discriminatorKey: "kind",
  }
);


usersSchema.index({ email: 1 }, { unique: true });

usersSchema.pre("save", async function (next) {
  if (!this.isModified("password")) {
    next();
  }

  const salt = await bcrypt.genSalt(10);
  this.password = await bcrypt.hash(this.password, salt);
});

usersSchema.methods.Optimize = function () {
  const obj = this.toObject();
  delete obj.password;
  return obj;
};

usersSchema.methods.comparePasswords = async function (
  enteredPassword: string
): Promise<boolean> {
  return await bcrypt.compare(enteredPassword, this.password);
};

export const UserModel = model<UserI, UserModel>("Users", usersSchema);

export const createUserFactory = async (
  props: Partial<UserI>
): Promise<UserD> => {
  const user = new UserModel({
    firstName: props.firstName || "John",
    lastName: props.lastName || "Doe",
    email: props.email || RandomEmail(),
    password: props.password || "password",
  });
  const savedUser = await user.save();
  return savedUser;
};