Untitled
unknown
plain_text
a year ago
4.3 kB
6
Indexable
// Import required modules const crypto = require('crypto'); const mongoose = require('mongoose'); const validator = require('validator'); const bcrypt = require('bcryptjs'); const { type } = require('os'); // Define user schema const userSchema = new mongoose.Schema( { name: { type: String, required: [true, 'Please, tell us your name!'], unique: true }, email: { type: String, required: [true, 'Please provide your email!'], unique: true, lowercase: true, validate: [validator.default.isEmail, 'Please provide a valid email address!'] }, phone: { type: String, required: [true, 'Please type your phone!'] }, password: { type: String, required: [true, 'Please provide a password'], minlength: 8, select: false }, passwordConfirm: { type: String, required: [true, 'Please confirm your password'], validate: { // This only works on CREATE and SAVE validator: function (el) { return el === this.password; }, message: 'Passwords are not the same' } }, profile: { type: mongoose.Schema.Types.ObjectId, refPath: 'role' }, passwordChangedAt: Date, passwordResetToken: String, passwordResetExpires: Date, profileImage: { type: String, default: 'default.jpg' }, role: { type: String, enum: ['admin', 'partner', 'owner', 'agent'] }, commissionDetails:{ type: mongoose.Schema.Types.Mixed }, active: { type: Boolean, default: false, select: false } }, { toJSON: { virtuals: true }, toObject: { virtuals: true } } ); // Middleware to hash password before saving to database userSchema.pre('save', async function (next) { // Only run if password is modified if (!this.isModified('password')) return next(); // Hash new password this.password = await bcrypt.hash(this.password, 12); // Delete passwordConfirm field this.passwordConfirm = undefined; next(); }); // Middleware to update passwordChangedAt field when password is changed userSchema.pre('save', function (next) { if (!this.isModified('password') || this.isNew) return next(); this.passwordChangedAt = Date.now() - 1000; next(); }); // Middleware to eliminate inactive users from find queries userSchema.pre(/^find/, function (next) { this.find({ active: { $ne: true } }); next(); }); // Method to verify if passwords match userSchema.methods.correctPassword = async function (candidatePassword, userPassword) { return await bcrypt.compare(candidatePassword, userPassword); }; // Method to check if password was changed after token was issued userSchema.methods.changedPasswordAfter = function (JWTTimestamp) { if (this.passwordChangedAt) { const changedTimeStamp = parseInt(this.passwordChangedAt.getTime() / 1000, 10); return changedTimeStamp > JWTTimestamp; } // False means NOT changed return false; }; // Method to create password reset token userSchema.methods.createPasswordResetToken = function () { const resetToken = crypto.randomBytes(32).toString('hex'); this.passwordResetToken = crypto.createHash('sha256').update(resetToken).digest('hex'); // valid for 10 minutes this.passwordResetExpires = Date.now() + 10 * 60 * 1000; return resetToken; }; //Handling Different User Roles userSchema.pre('save', function(next) { if (this.role === 'agent') { // Set roleData to the agent role data structure this.commissionDetails = { commission: { type: Number, required: [true, 'Please provide commission percentage!'] }, currency: { type: String, required: [true, 'Please provide Currency'] }, target: { type: Number, required: [true, 'Please provide a target'] }, invoiceTime: { type: String, required: [true, 'Please provide an invoice time'] } }; } next(); }); // Create User model from schema const User = mongoose.model('User', userSchema); // Export User model module.exports = User;
Editor is loading...
Leave a Comment