UNPKG

@kapvm/create-express-app

Version:

A CLI tool to scaffold an Express.js boilerplate project

133 lines (112 loc) 3.25 kB
const crypto = require('crypto'); const mongoose = require('mongoose'); const validator = require('validator'); const bcrypt = require('bcryptjs'); //modeling the database collection const userSchema = new mongoose.Schema({ name: { type: String, require: [true, 'User must enter name'], }, email: { type: String, required: [true, 'User must enter email'], unique: [true, 'Email already in use'], lowercase: true, validate: [validator.isEmail, 'Please enter a valid email'], }, photo: { type: String, default: 'default.jpg', }, password: { type: String, required: [true, 'User must enter password'], minlength: 8, maxlength: 64, select: false, }, passwordConfirm: { type: String, required: [true, 'User must enter password'], minlength: 8, maxlength: 64, validate: { validator: function (val) { return this.password === val; }, message: 'Password and Password Confirm must be same', }, }, passwordChangedAt: { type: Date, }, passwordResetToken: String, passwordResetExpires: Date, active: { type: Boolean, default: true, select: false, }, deletedAt: { type: Date, }, createdAt: { type: Date, default: Date.now(), }, }); //LABEL // HOOKS //=> Password Encryption logic userSchema.pre('save', async function (next) { if (!this.isModified('password')) return next(); this.password = await bcrypt.hash(this.password, 12); this.passwordConfirm = undefined; }); //=> set password changed at property dynamically userSchema.pre('save', function (next) { if (!this.isModified('password') || this.isNew) return next(); this.passwordChangedAt = Date.now() - 1000; next(); }); //=> filter to get only active users userSchema.pre(/^find/g, function (next) { this.find({ active: { $ne: false } }); next(); }); //LABEL // Methods //=> check if user entered password is correct or not (return false if not same) userSchema.methods.checkPassword = async function ( candidatePassword, userPassword, ) { //candidatePassword = password that is entered by user in forms (from req) //userPassword = password that is stored in db (actual password) //Use the 'bcrypt' package's compare method, which compares both strings even if either is encrypted return await bcrypt.compare(candidatePassword, userPassword); }; //=> method to check if password is changed after the token generated or not userSchema.methods.isPasswordChangedAfter = function (JWTTokenTime) { if (this.passwordChangedAt) { const passwordChangedTime = parseInt( this.passwordChangedAt.getTime() / 1000, ); return JWTTokenTime < passwordChangedTime; } return false; }; //=> getting the password reset token [simply generating and returning the token] userSchema.methods.getPasswordResetToken = function () { const resetToken = crypto.randomBytes(32).toString('hex'); this.passwordResetToken = crypto .createHash('sha256') .update(resetToken) .digest('hex'); this.passwordResetExpires = Date.now() + 10 * 60 * 1000; return resetToken; }; //=> creating the collection const User = mongoose.model('User', userSchema); module.exports = User;