Untitled

 avatar
unknown
plain_text
a year ago
2.8 kB
8
Indexable
// Import required modules
const crypto = require('crypto');
const mongoose = require('mongoose');
const validator = require('validator');
const bcrypt = require('bcryptjs');

// Define the base 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: {
      validator: function(el) { return el === this.password; },
      message: 'Passwords are not the same'
    }
  },
  passwordChangedAt: Date,
  passwordResetToken: String,
  passwordResetExpires: Date,
  profileImage: {
    type: String,
    default: 'default.jpg'
  },
  role: {
    type: String,
    enum: ['admin', 'partner', 'owner', 'agent'],
    required: true
  },
  active: {
    type: Boolean,
    default: false,
    select: false
  }
}, {
  discriminatorKey: 'role', // Discriminator Key
  toJSON: { virtuals: true },
  toObject: { virtuals: true }
});

// Middleware to hash password before saving to database
userSchema.pre('save', async function(next) {
  if (!this.isModified('password')) return next();
  this.password = await bcrypt.hash(this.password, 12);
  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();
});

// Create the base User model
const User = mongoose.model('User', userSchema);

// Create a discriminator for the 'Agent' role with specific fields
const Agent = User.discriminator('Agent', new mongoose.Schema({
  commissionDetails: {
    commission: {
      type: Number,
      required: true
    },
    currency: {
      type: String,
      required: true
    },
    target: {
      type: Number,
      required: true
    },
    invoiceTime: {
      type: String,
      required: true
    }
  }
}));

// Export the User model and Agent discriminator
module.exports = { User, Agent };
Editor is loading...
Leave a Comment