I've recently started to use Promises, and I still don't get a few things.
Let me give you the following example.
In a Node & Mongo application I am trying to implement an action that authenticates a user with a jwt token. The request has two parameters userName
and passWord
. What I need to do is to:
1) Verify if the users exists in the database 2) If the users exists verify if the hashed password from the database matches the password supplied in plain text from the request 3) If the two passwords are matching generate a jwt token from the user object I've obtained from the database.
For step 1) I've configured mongoose to use Q promises. For step 2) I am using bcrypt to compare the two passwords, and for the step 3) I am using the node jwt package to generate the token.
I've isolated the code like this (it's only a proof of concept):
// *** INSIDE AN API OBJECT *** //
action : function(req, res) {
return User.findOne({ userName : req.body.userName }).exec()
.then(function(user){
// If the user doesn't exist return invalid credentials
var defer = Q.defer();
if (user) defer.resolve(user);
else defer.reject(new CError(400, E.INVALID_CREDENTIALS));
return defer.promise;
// returns user
})
.then(function(user){
// See if the password matches the hash
return Q.nfcall(bcrypt.compare(req.body.passWord, user.passWordHash);
// Returns true || false
})
.then(function(result){
// How do I obtain the user that was calculated two levels before ??
if (result) {
return Q.nfcall(jwt.sign, /* user */ , config.secret, {});
} else {
return Q.defer().reject(new CError(400, E.INVALID_CREDENTIALS));
}
})
.then(function(token){
res.json({token: token});
})
.catch(function(err){
if (err instanceof CError) {
res.status(err.status).json({ error : err.message });
} else {
res.status(500).json({ error : err.toString() });
}
})
.done();
},
The "problem" I am having right now is that the third then()
, the one where I should generate the jwt token I don't have access to user
which was calculated two levels above.
How do I overcome this limitation ?
I have some solutions but I don't like them. What is the standard way (if such thing exists) of achieving this ?