Search code examples
node.jspromisebcrypt

Using bcrypt to make sure password hasn't been repeated


I'm using bcrypt to hash passwords in the database. I'm trying to add a feature to make sure when a user cannot reuse passwords. What I would like to do is loop through a list of previous passwords to check for reuse. Right now I can do something simple like this:

var reused = false;
for (let i = 0; i < oldPWs.length; i++) {
   reused = bcrypt.compareSync(newPassword, oldPWs[i].PASSWORD);
   if (reused){
      console.log("Password is a repeat");
      break;
   }
}

However, according to the documentation doing this with the Sync function isn't recommended since it this can block other server requests. Is there a recommended method for checking if a password is valid for a list of hashes? I don't think it could be done with the callback function of the bcrypt.compare() function but maybe with promises... Any recommendations would be appreciated.


@Zhephard gave me a push in the right direction so I marked his answer as correct. The actual code I used is below:


var promises = [];
for (let i = 0; i < oldPWs.length; i++) {
    promises.push(bcrypt.compare(newPassword, oldPWs[i].PASSWORD))
}

Promise.all(promises).then((results)=>{
    console.log("All done:", results)
    if (results.includes(true)) {
        // alert users password has been repeated
        console.log("Password is repeat")
    } else {
        // allow password change
        console.log("Password is new")
    }
})


Solution

  • By what i read on the API you seem to be doing the right thing, if using promises is one of your options you could do something like

    oldPWs.map((p) => bcrypt.compare(p.PASSWORD, hash)
      .then((res) => {
        if (res) console.log('Password repeated');
      }));
    

    This way is quite short, and you don't have to mind using indexes across the old retrieved passwords as well