73 lines
1.8 KiB
JavaScript
73 lines
1.8 KiB
JavaScript
const mongoose = require('mongoose');
|
|
const bcrypt = require('bcryptjs');
|
|
|
|
const UserSchema = new mongoose.Schema({
|
|
email: {
|
|
type: String,
|
|
required: true,
|
|
unique: true,
|
|
trim: true,
|
|
lowercase: true
|
|
},
|
|
password: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
password_plain: {
|
|
type: String,
|
|
select: false // Only retrievable when explicitly requested
|
|
},
|
|
role: {
|
|
type: String,
|
|
enum: ['superadmin', 'companyadmin', 'employer'],
|
|
required: true
|
|
},
|
|
companyId: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Company',
|
|
required: function() {
|
|
return this.role !== 'superadmin'; // Only required for companyadmin and employer
|
|
}
|
|
},
|
|
createdBy: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'User'
|
|
},
|
|
createdAt: {
|
|
type: Date,
|
|
default: Date.now
|
|
}
|
|
});
|
|
|
|
// Hash password before saving
|
|
UserSchema.pre('save', async function(next) {
|
|
if (!this.isModified('password')) return next();
|
|
|
|
try {
|
|
// Store plain text password if provided (for superadmin use)
|
|
if (this.password) {
|
|
this.password_plain = this.password;
|
|
}
|
|
|
|
// Hash the password
|
|
const salt = await bcrypt.genSalt(10);
|
|
this.password = await bcrypt.hash(this.password, salt);
|
|
next();
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
// Method to compare password
|
|
UserSchema.methods.comparePassword = async function(password) {
|
|
// If we have a plain text password stored and we're in development, use it for comparison
|
|
if (this.password_plain && process.env.NODE_ENV !== 'production' && password === this.password_plain) {
|
|
return true;
|
|
}
|
|
|
|
// Otherwise use bcrypt to compare the hashed passwords
|
|
return await bcrypt.compare(password, this.password);
|
|
};
|
|
|
|
module.exports = mongoose.model('User', UserSchema);
|