const Sequelize = require('sequelize') const crypto = require('crypto') const db = require('../db') const User = db.define('users', { name: { type: Sequelize.STRING, allowNull: false, }, email: { type: Sequelize.STRING, }, password: { type: Sequelize.STRING, // Making `.password` act like a func hides it when serializing to JSON. // This is a hack to get around Sequelize's lack of a "private" option. get() { return () => this.getDataValue('password') }, }, salt: { type: Sequelize.STRING, // Making `.salt` act like a function hides it when serializing to JSON. // This is a hack to get around Sequelize's lack of a "private" option. get() { return () => this.getDataValue('salt') }, }, avatar: { type: Sequelize.STRING, defaultValue: 'default-user-img.png', }, }) module.exports = User User.prototype.correctPassword = function(candidatePwd) { return User.encryptPassword(candidatePwd, this.salt()) === this.password() } /** * classMethods */ User.generateSalt = function() { return crypto.randomBytes(16).toString('base64') } User.encryptPassword = function(plainText, salt) { console.log('inside of encryptPassword', plainText, salt) return crypto .createHash('RSA-SHA256') .update(plainText) .update(salt) .digest('hex') } /** * hooks */ const setSaltAndPassword = user => { if (user.changed('password')) { user.salt = User.generateSalt() user.password = User.encryptPassword(user.password(), user.salt()) } } User.beforeCreate(setSaltAndPassword) User.beforeUpdate(setSaltAndPassword) User.beforeBulkCreate(users => { users.forEach(setSaltAndPassword) })