Promoting bcrypt-nodejs with Bluebird

I am using NodeJS, with bcrypt-nodejs ( https://github.com/shaneGirish/bcrypt-nodejs ) and Bluebird for promises. This code came in and wondered if there is a better way to do the same. I have a module with:

var Promise = require("bluebird"), bcrypt = Promise.promisifyAll(require('bcrypt-nodejs')); // ....[some othe code here] Users.prototype.setPassword = function(user) { return bcrypt.genSaltAsync(10).then(function(result) { return bcrypt.hashAsync(user.password, result); }); }; 

then from another module I call users.setPassword , as shown below:

 app.post('/api/v1/users/set-password', function(req, res, next) { users.setPassword(req.body).then(function(result) { // Store hash in your password DB. console.log(result[1]); res.json({ success: true }) }) .catch(function(err) { console.log(err); }); }); 

It always ends with the message “[Error: no callback function.]”, Since bcrypt.hashAsync seems to require 4 parameters. The original, not promised hash method requires 3 only. When I add an empty callback to hashAsync , it works fine:

 Users.prototype.setPassword = function(user) { return bcrypt.genSaltAsync(10).then(function(result) { return bcrypt.hashAsync(user.password, result,function() {}); }); }; 

Is there a better way to do this without providing an empty callback as above?

EDIT:

In response to Bergi's comment .. the function will eventually set a password, I just did not understand when I sent the question. Now it has come this far, please let me know if something is not entirely true:

  Users.prototype.setPassword = function(user) { return bcrypt.genSaltAsync(10).then(function(result) { return bcrypt.hashAsync(user.password, result, null); }) .then(function(result) { // store in database console.log("stored in database!"); return result; }); }; 
+6
source share
3 answers

bcrypt.hashAsync seems to require 4 parameters. An original, non-impersonal hash method requires 3 only.

This is the opposite. From the docs :

hash(data, salt, progress, cb)

  • data - [REQUIRED] - data to be encrypted.
  • salt - [REQUIRED] - The salt that will be used to hash the password.
  • progress - callback that will be called during the calculation of the hash to indicate progress
  • callback - [REQUIRED] - a callback that should be started after the data has been encrypted.

The original method took 4 arguments, hashAsync will take 3 and return a promise.

However, in your code you only went through two. You do not need to pass an empty function, although the parameter is not [REQUIRED] means you can pass null (or any other fake value) for it. bcrypt will create such an empty function . Therefore use

 function (data) { return bcrypt.genSaltAsync(10).then(function(result) { return bcrypt.hashAsync(data.password, result, null); }); } 
+9
source

This is my promised bcrypt from a project that I did some time ago. Bluebird is really not needed for such a small simple library.

 module.exports = { makeUser: function(username, password){ return new Promise(function(resolve, reject) { bcrypt.genSalt(10, function(err, salt){ bcrypt.hash(password, salt, null, function(err, hash) { if (err) { console.log("hashing the password failed, see user.js " + err); reject(err); } else { console.log("hash was successful."); resolve(hash); } }) }) }) .then(function(hash){ return db.createUser(username, hash) }) }, login: function(username, password){ return db.userFind(username) .then(function(userObj){ if(!userObj){ console.log("did not find " + username + " in database."); return new Promise(function(resolve, reject){ resolve({login:false, message:"Your username and/or password are incorrect."}) } } else { console.log("found user: " + userObj._id, userObj); return new Promise(function(resolve, reject){ bcrypt.compare(password, userObj.hashword, function(err, bool) { resolve({bool:bool, user:userObj._id, mindSeal: userObj }) }) }) } }) } } 

Usage example:

 app.post('/signup', function(req, res) { var username = req.body.username; var password = req.body.password; var user = handler.userExists(username) .then(function(answer){ if (answer !== null){ console.log(req.body.username + " was taken") res.send({login: false, message: req.body.username + " is taken"}); return null; } else if (answer === null) { console.log("username not taken") return handler.makeUser(username, password); } }) .catch(function(err){ console.log("error during user lookup:", err); res.status(404).send({message:"database error:", error:err}); }) if (user !== null){ user .then(function(x){ console.log("this is returned from handler.makeUser: ", x) console.log(x.ops[0]._id) req.session.user = x.ops[0]._id; var mindSeal = { userSettings: { username: x.ops[0]._id, newCardLimit: null, tValDefault: 128000000, lastEdit: req.body.time, todayCounter: 0, allTimeCounter: 0, cScaleDefault: {0: 0.9, 1: 1.2, 2: 1.8, 3: 2.5}, accountMade: req.body.time }, decks: {} }; handler.setMindSeal(req.session.user, mindSeal, req.body.time); res.send({ login: true, mindSeal: mindSeal }); }) .catch(function(error){ console.log("make user error: " + error); res.status(401).send({message:"failed.",error:error,login:false}); }) } }); app.post('/login', function(req, res) { var username = req.body.username; var password = req.body.password; handler.login(username, password) .then(function(obj){ if (obj.bool){ console.log("username and password are valid. login granted."); req.session.user = obj.user; console.log("obj is:", obj) var mindSeal = {decks:obj.mindSeal.decks, userSettings:obj.mindSeal.userSettings}; console.log("mindSeal sending:", mindSeal); res.status(200).send({ login: true, message:"Login Successful", mindSeal: obj.mindSeal }); } else { console.log("password invalid") res.status(401).send({login: false, message:"Your username and/or password are incorrect."}) } }) .catch(function(error){ console.log(error); res.status(404).send({message:"database error:", error:err}); }) }); 

just a conceptual example; borrowed and slightly modified the old old code on the fly. Working code (I see that I want to improve it now, but it works): https://github.com/finetype/mindseal/blob/master/server.js

0
source

Perhaps you could use a different bcrypt library with a better API that eliminates the need for promises.

 Users.prototype.setPassword = function(user) { return TwinBcrypt.hashSync(user.password, 10); }; 

Or with progress tracking:

 Users.prototype.setPassword = function(user) { function progress(p) { console.log( Math.floor(p*100) + '%' ); } TwinBcrypt.hash(user.password, 10, progress, function(result) { // store in database console.log("stored in database!"); return result; }); }; 
-5
source

Source: https://habr.com/ru/post/972432/


All Articles