Untitled
unknown
plain_text
2 years ago
4.3 kB
7
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