Snai3i-LandingPage-FormBuilder / backend / src / models / userModel.ts
userModel.ts
Raw
import mongoose, { Document, Model, Schema } from 'mongoose';
import bcrypt from 'bcryptjs';
const emailRegexPattern: RegExp = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;

export interface UserI {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  role: string;
}

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

export interface UserModelI extends Model<UserD> {}

const usersSchema: Schema = new mongoose.Schema(
  {
    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'],
    },
    password: {
      type: String,
      required: [true, 'Please enter your password'],
      minlength: [6, 'Your password must be longer than 6 characters'],
      // match: [passwordRegexPattern, "Your password must contain at least 1 uppercase, 1 lowercase, and 1 number"],
      select: false,
    },
    role: {
      type: String,
      required: [true, 'Please set role'],
      enum: ['admin','superAdmin'],
    },
  },
  {
    timestamps: true,
  }
);

//hashing password before saving
usersSchema.pre<UserD>('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.matchPasswords = async function (
  enteredPassword: string
): Promise<boolean> {
  return await bcrypt.compare(enteredPassword, this.password);
};

const userModel: UserModelI = mongoose.model<UserI, UserModelI>(
  'User',
  usersSchema
);

export default userModel;