diff --git a/models/user.js b/models/user.js index bce93d91..ddad3524 100644 --- a/models/user.js +++ b/models/user.js @@ -1,3 +1,7 @@ +'use strict'; +const bcrypt = require('bcrypt'); +const logger = require('winston'); + module.exports = (sequelize, { STRING }) => { const User = sequelize.define( 'User', @@ -20,10 +24,37 @@ module.exports = (sequelize, { STRING }) => { User.hasOne(db.Channel); }; - User.prototype.validPassword = (givenpassword, thispassword) => { - console.log(`${givenpassword} === ${thispassword}`); - return (givenpassword === thispassword); + User.prototype.comparePassword = function (password, callback) { + logger.debug(`User.prototype.comparePassword ${password} ${this.password}`); + bcrypt.compare(password, this.password, callback); }; + // pre-save hook method to hash the user's password before the user's info is saved to the db. + User.hook('beforeCreate', (user, options) => { + logger.debug('...beforeCreate hook...'); + return new Promise((resolve, reject) => { + // generate a salt string to use for hashing + bcrypt.genSalt((saltError, salt) => { + if (saltError) { + logger.error('salt error', saltError); + reject(saltError); + return; + } + // generate a hashed version of the user's password + bcrypt.hash(user.password, salt, (hashError, hash) => { + // if there is an error with the hash generation return the error + if (hashError) { + logger.error('hash error', hashError); + reject(hashError); + return; + } + // replace the password string with the hash password value + user.password = hash; + resolve(); + }); + }); + }); + }); + return User; }; diff --git a/package.json b/package.json index e7fe2cc2..f9acff82 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "homepage": "https://github.com/lbryio/spee.ch#readme", "dependencies": { "axios": "^0.16.1", + "bcrypt": "^1.0.3", "body-parser": "^1.17.1", "config": "^1.26.1", "connect-multiparty": "^2.0.0", diff --git a/passport/local-login.js b/passport/local-login.js index 75b31fef..f83dcc0e 100644 --- a/passport/local-login.js +++ b/passport/local-login.js @@ -1,3 +1,4 @@ + const PassportLocalStrategy = require('passport-local').Strategy; const db = require('../models'); const logger = require('winston'); @@ -19,27 +20,36 @@ module.exports = new PassportLocalStrategy( logger.debug('no user found'); return done(null, false, {message: 'Incorrect username or password.'}); } - if (!user.validPassword(password, user.password)) { - logger.debug('incorrect password'); - return done(null, false, {message: 'Incorrect username or password.'}); - } logger.debug('user found:', user.dataValues); - userInfo['id'] = user.id; - userInfo['userName'] = user.userName; - // channel stuff - return user.getChannel() - .then(channel => { - userInfo['channelName'] = channel.channelName; - userInfo['channelClaimId'] = channel.channelClaimId; - return db.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName); - }) - .then(shortChannelId => { - userInfo['shortChannelId'] = shortChannelId; - return done(null, userInfo); - }) - .catch(error => { - throw error; - }); + logger.debug('...comparing password...'); + return user.comparePassword(password, (passwordErr, isMatch) => { + if (passwordErr) { + logger.error('passwordErr:', passwordErr); + return done(passwordErr); + } + + if (!isMatch) { + logger.debug('incorrect password'); + return done(null, false, {message: 'Incorrect username or password.'}); + } + logger.debug('...password was a match...'); + userInfo['id'] = user.id; + userInfo['userName'] = user.userName; + // get the User's channel info + return user.getChannel() + .then(channel => { + userInfo['channelName'] = channel.channelName; + userInfo['channelClaimId'] = channel.channelClaimId; + return db.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName); + }) + .then(shortChannelId => { + userInfo['shortChannelId'] = shortChannelId; + return done(null, userInfo); + }) + .catch(error => { + throw error; + }); + }); }) .catch(error => { return done(error);