/* note: this currently isn't exported because I will have to investigate the salting etc. */ const crypto = require('crypto') const Sequelize = require('sequelize') const db = require('../db') const User = db.define('user', { email: { type: Sequelize.STRING, unique: true, }, firstName: { type: Sequelize.STRING, }, lastName: { type: Sequelize.STRING, }, username: { type: Sequelize.STRING, unique: true, allowNull: false, }, imageUrl: { type: Sequelize.STRING, defaultValue: 'novatore.jpg', }, 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') }, }, }) module.exports = User /** * instanceMethods */ 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) { 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)