hacker-news-cli/db/models/user.js

85 lines
1.8 KiB
JavaScript

/*
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)