1

This might be opinion based. But I'd like to get some advice.

So, what I want to do can be done in the way mentioned in this thread. But this thread made a good point why I would want to use async.

Here's what I have so far, and it works.

User.create({email: req.body.email, password: req.body.password}).catch(function(err){
  console.log(err);
});

User.beforeCreate(function(user) {
  const password = user.password;
  user.password = '';
  bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
    if(err) console.error(err);
    bcrypt.hash(user.password, salt, null, function(err, hash) {
      if(err) console.error(err);
      user.password = hash;
      user.save();
    });
  });
});

Since I am using bcrypt async, I would have to persist the encrypted password in another query. My gut feeling tells me there might be a better way using bcrypt async with sequelize.

My question is, what is the preferred / better approach? Or should I just settle with using bcrypt synchronously?

Community
  • 1
  • 1
Edmund Lee
  • 2,514
  • 20
  • 29

1 Answers1

3

Async is the way to go just tidy up you code a bit and use callback in the hook

function cryptPassword(password, callback) {
    bcrypt.genSalt(10, function(err, salt) { // Encrypt password using bycrpt module
        if (err)
            return callback(err);

        bcrypt.hash(password, salt, function(err, hash) {
            return callback(err, hash);
        });
    });
}

User.beforeCreate(function(model, options, cb) {
  debug('Info: ' + 'Storing the password');    
  cryptPassword(user.password, function(err, hash) {
    if (err) return cb(err);
    debug('Info: ' + 'getting ' + hash);

    user.password = hash;
    return cb(null, options);
  });
});
Keval
  • 3,246
  • 20
  • 28
  • Thanks for the answer. The main reason I don't like about this approach is, there will be two sql calls to persist one new user. – Edmund Lee Feb 06 '17 at 06:59
  • There is just one sql call, we are not calling save here, we are changing the data before the sql call is fiered, you have written save call which is not required – Keval Feb 06 '17 at 07:02
  • hmm... The record might be persisted before the password hash is generated, no? since it's async.. – Edmund Lee Feb 06 '17 at 07:06
  • It wont be saved because we are using callback in both the cases. – Keval Feb 06 '17 at 07:11
  • aha. thanks. I totally missed those extra arguments in the callback of `beforeCreate`. Can you elaborate on how the `options` and the `callback` should be used? Didn't find much detail in their doc. – Edmund Lee Feb 06 '17 at 07:20
  • 1
    Its not clear in the docs need to deep dive in the code, docs focus more on promises, I refered : http://stackoverflow.com/questions/31427566/sequelize-create-model-with-beforecreate-hook – Keval Feb 06 '17 at 07:28
  • This may help! Https://stackoverflow.com/a/52087581/1274820 – user1274820 Aug 30 '18 at 00:15