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 { comparePasswords(password: string): Promise; Optimize(): OptimizedUser; } export interface UserModel extends Model {} const usersSchema = new 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"], }, 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 { return await bcrypt.compare(enteredPassword, this.password); }; export const UserModel = model("Users", usersSchema); export const createUserFactory = async ( props: Partial ): Promise => { 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; };