85 lines
1.8 KiB
JavaScript
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)
|