UNPKG

nhb-express

Version:

Minimal Express + TypeScript scaffolder with modular structure and flexible stack choices.

107 lines (96 loc) 2.21 kB
import { ErrorWithStatus } from '@/classes/ErrorWithStatus'; import { USER_ROLES } from '@/constants'; import type { IUserDoc, IUserModel } from '@/modules/user/user.types'; import type { TEmail } from '@/types'; import { hashPassword } from '@/utilities/authUtilities'; import { Schema, model } from 'mongoose'; import { STATUS_CODES } from 'nhb-toolbox/constants'; const userSchema = new Schema<IUserDoc>( { user_name: { type: String, trim: true, unique: true, }, email: { type: String, required: true, trim: true, unique: true, }, first_name: { type: String, required: true, trim: true, }, last_name: { type: String, required: true, trim: true, }, password: { type: String, required: true, trim: true, select: false, }, role: { type: String, enum: USER_ROLES, default: 'user', }, is_active: { type: Boolean, default: true, }, }, { timestamps: { createdAt: 'created_at', updatedAt: 'updated_at', }, versionKey: false, } ); // * Hash password and create username before saving the user in DB. userSchema.pre('save', async function () { const base = this.first_name?.toLowerCase()?.replace(/\s+/g, '_'); let userName = base; let suffix = 0; while (await User.exists({ user_name: userName })) { suffix += 1; userName = `${base}_${suffix}`; } this.user_name = userName; this.password = await hashPassword(this.password); }); /** Static method to check if user exists */ userSchema.statics.validateUser = async function (email?: TEmail) { if (!email) { throw new ErrorWithStatus( 'Authentication Error', 'Please provide a valid email!', STATUS_CODES.BAD_REQUEST, 'user' ); } const user: IUserDoc = await this.findOne({ email }).select('+password'); if (!user) { throw new ErrorWithStatus( 'Not Found Error', `No user found with email: ${email}!`, STATUS_CODES.NOT_FOUND, 'user' ); } if (!user.is_active) { throw new ErrorWithStatus( 'Authentication Error', `User with email ${email} is not active!`, STATUS_CODES.FORBIDDEN, 'user' ); } return user; }; export const User = model<IUserDoc, IUserModel>('User', userSchema);