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;
};