Marco
Marco

Reputation: 1205

Saving hashed password to Sequelize is defying my simple wish to save a hashed password

This is my first day using Sequelize with postgreql so forgive my naive questions. I have a simple model to try it out:

var User = sequelize.define("user", {
username: Sequelize.STRING,
password: Sequelize.STRING

})

I use expressjs/node and passportJS for user to signup/register:

passport.use('local-register', new LocalStrategy({
   passReqToCallback: true
}, function (req, username, password, done) {

User.findOne({ where: { username: username } }).then(function (user) {
    if (user) {   
        return done(null, false, { message: "enter  email that belongs to you please..." }, 
       console.log('That email is already taken'));
    } else {
       
         //use bcrypt to salt and hash the password
         let saltRounds = 2;
         let hashedpass = bcrypt.hash(password, saltRounds);           

        var data = {
            username: username,
            password: hashedpass  //password
        };
        User.create(data).then(function (newUser, created) {
            if (!newUser) {
                return done(null, false);
            }
            if (newUser) {
                return done(null, newUser);
            }
        });
    }
}).catch(err => { console.log("catch error :", err) });
}));

Now, after I attempt to signup as a user, I get an error:

UnhandledPromiseRejectionWarning: SequelizeValidationError: string violation: password cannot be an array or an object
at InstanceValidator._validate (D:\mycode\postegresql\postee1\node_modules\sequelize\lib\instance-validator.js:78:13)
at processTicksAndRejections (internal/process/next_tick.js:81:5)

I understand that it is sequelize validation for the password STRING but I didn't add any validation and what type of sequelize datatype that would accept a hashed password?

I understand how to add hooks to my model and it does hash the password correctly before saving to the db:

   hooks: {
        beforeCreate: (user) => {
            const salt = bcrypt.genSaltSync(2);
            user.password = bcrypt.hashSync(user.password, salt);
        }
    },
    instanceMethods: {
        validPassword: function (password) {
            return bcrypt.compareSync(password, this.password);
        }
    }

But I want to hash the password in my server code as I attempted to do above. How do I fix the validation error above? I just want to use Bycrpt in my passport handle. Is the datatype wrong? How do I fix this error without touching my model? It shouldn't be an issue because I already hashed the password, I just need to save it but it seems that Sequelize is forcing a specific way to do that, so to all the sequelize NINJAS out there, How do I fix this?

Upvotes: 1

Views: 1300

Answers (1)

Anatoly
Anatoly

Reputation: 22758

You called hash w/o passing callback.

You need to use either the sync version hashSync instead of hash

let hashedpass = bcrypt.hashSync(password, saltRounds);

or use async version hash.

let hashedpass = await bcrypt.hash(password, saltRounds);
// OR
bcrypt.hash(password, saltRounds).then(hash => {
  hashedpass = hash
}

Upvotes: 1

Related Questions