0

Is there an elegant way to return a bcrypt hash value to a separate module?

In the example below function hashPassword() uses bcrypt to hash a password. It is located in the file hashpassword.js. I'd like to return its hash value to the variable myHashedPassword in app.js. I'm sure there must be a brute force way to do this. But is there any sort of clever or elegant way to return the value?

app.js

let password = '123';
let myHashedPassword = hashPassword(password);

hashpassword.js

function hashPassword(password) {
    bcrypt.genSalt(10, function(error, salt) {
        bcrypt.hash(password, salt, function(error, hash) {
            // In most cases at this point hash is saved to the database.
            // However is there a pattern to return its value to the outer function and then app.js?
            // With this being async is that even possible?
        });
    }); 
}
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – nicholaswmin Sep 29 '19 at 21:48

2 Answers2

1

The bcrypt package has synchronous equivalents to the functions you are using, see example. If you still want to leverage the async versions, then you would need to return a Promise which you can then await e.g.

function hashPassword(password) {
  return new Promise((resolve, reject) => {
    bcrypt.genSalt(10, (error, salt) => {
      if (error) return reject(error);

      bcrypt.hash(
        password, 
        salt, 
        (error, hash) => err ? reject(err) : resolve(hash)
      );
    }); 
  });
}
...
let hashed = await hashPassword(password);

In terms of then exporting in a way that the consumer simply calls the function, if using ES6 or newer

export default function hashPassword(password) {
  ...
}

Otherwise

function hashPassword(password) {
  ...
}

module.exports = hashPassword
James
  • 75,060
  • 17
  • 154
  • 220
  • That part is no problem. I'm already exporting the function and using it in app.js. – stackedAndOverflowed Sep 29 '19 at 21:48
  • 1
    @stackedAndOverflowed was in the middle of updating as I missed your original point (see update) – James Sep 29 '19 at 21:49
  • You are right, the sync function would work fine. Unfortunately hashing burns up a lot of CPU and blocks things so I have to use async. I see this is a duplicate. I think my brain is going to have to stretch on this one. – stackedAndOverflowed Sep 29 '19 at 21:51
0

If you prefer to use out of the box non-blocking bcrypt functions with await/async:

import bcrypt from 'bcrypt';

const salt = await bcrypt.genSalt(10);
var hash = await bcrypt.hash(clear_text_password, salt);

Then to authenticate

const match = await bcrypt.compare(clear_text_password, hash);

if(match) { // do something awesome }
sday
  • 921
  • 11
  • 20