Skip to content

Instantly share code, notes, and snippets.

@cadd
Last active October 25, 2019 15:45
Show Gist options
  • Save cadd/5688fbe1b4250aaa367e36647d077c3c to your computer and use it in GitHub Desktop.
Save cadd/5688fbe1b4250aaa367e36647d077c3c to your computer and use it in GitHub Desktop.
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const SALT_WORK_FACTOR = 10;
const schema = mongoose.Schema({
name: String,
email: String,
password: String,
active: {type: Boolean, default: false},
}, {collection: 'user'});
schema.index({"email": 1}, {unique: true}); // schema level
schema.index({"email": 1, active: 1}, {name: 'login_idx'}); // schema level
schema.methods.apiData = function () {
return {
id: this._id,
name: this.name,
email: this.email,
active: this.active,
}
};
/**
* Login user with given information
* @param email
* @param password
*/
schema.statics.login = async function (email, password) {
const user = await this.findOne({email: {$eq: email}, active: true}).exec();
if (!user) return false;
const doesMatch = await bcrypt.compare(password, user.password);
return doesMatch ? user : false;
};
schema.pre('save', async function (next) {
let user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
try {
// generate a salt
const salt = await bcrypt.genSalt(SALT_WORK_FACTOR);
// hash the password along with our new salt
// override the cleartext password with the hashed one
user.password = await bcrypt.hash(user.password, salt);
next();
} catch (e) {
return next(e);
}
});
mongoose.model('User', schema);
const crypto = require('crypto');
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Please add a name']
},
email: {
type: String,
required: [true, 'Please add an email'],
unique: true,
match: [
/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/,
'Please add a valid email'
]
},
role: {
type: String,
enum: ['user', 'publisher'],
default: 'user'
},
password: {
type: String,
required: [true, 'Please add a password'],
minlength: 6,
select: false
},
resetPasswordToken: String,
resetPasswordExpire: Date,
createdAt: {
type: Date,
default: Date.now
}
});
// Encrypt password using bcrypt
UserSchema.pre('save', async function(next) {
if (!this.isModified('password')) {
next();
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
});
// Sign JWT and return
UserSchema.methods.getSignedJwtToken = function() {
return jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRE
});
};
// Match user entered password to hashed password in database
UserSchema.methods.matchPassword = async function(enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
// Generate and hash password token
UserSchema.methods.getResetPasswordToken = function() {
// Generate token
const resetToken = crypto.randomBytes(20).toString('hex');
// Hash token and set to resetPasswordToken field
this.resetPasswordToken = crypto
.createHash('sha256')
.update(resetToken)
.digest('hex');
// Set expire
this.resetPasswordExpire = Date.now() + 10 * 60 * 1000;
return resetToken;
};
module.exports = mongoose.model('User', UserSchema);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment