I have to following function that assesses if a password is in the user's password history. Here is the code:
isPasswordInPwdHistory : function(redisClient, userId, encPassword, cb) {
var key = 'user:' + userId + ':pwdhistory';
redisClient.llen(key, function(err, reply) {
if (err) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else {
var numPwds = reply;
var match = false;
var funcError;
for (i=0; i <= numPwds - 1; i++) {
var error;
var pwdValue;
redisClient.lindex(key, i, function(err, reply) {
if (err) {
console.log('lindex err = ' + err);
error = err;
}
else {
console.log('lindex reply = ' + reply);
console.log('lindex encPassword = ' + encPassword);
console.log('lindex (encPassword === reply) = ' + (encPassword === reply));
pwdValue = reply;
}
});
console.log('for-loop error = ' + error);
console.log('for-loop pwdValue = ' + pwdValue);
console.log('for-loop (encPassword === pwdValue) = ' + (encPassword === pwdValue));
if (error) {
funcError = error;
break;
}
else if (encPassword === pwdValue) {
console.log('passwords match');
match = true;
break;
}
}
console.log('funcError = ' + funcError);
console.log('match = ' + match);
if (funcError) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else
cb(match);
}
});
}
Here is the console output:
for-loop error = undefined
for-loop pwdValue = undefined
for-loop (encPassword === pwdValue) = false
funcError = undefined
match = false
isPasswordInPwdHistory = false
lindex reply = 5f4f68ed57af9cb064217e7c28124d9b
lindex encPassword = 5f4f68ed57af9cb064217e7c28124d9b
lindex (encPassword === reply) = true
Once I leave the scope of the redisClient.lindex() call I lose the values. How can I pass these values for evaluation in the for-loop?
UPDATE
I refactored the code a bit to handle the matching of the new password (encPassword) vs. the existing password at index i when the redisClient.lindex() callback is issued.
isPasswordInPwdHistory : function(redisClient, userId, encPassword, cb) {
var status = new Object();
var key = 'user:' + userId + ':pwdhistory';
redisClient.llen(key, function(err, reply) {
if (err) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else {
var numPwds = reply;
var loopCt = 0;
for (i=0; i <= numPwds - 1; i++) {
loopCt++;
redisClient.lindex(key, i, function(err, reply) {
if (err) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else if (encPassword === reply) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, null, 0, null, true);
cb(status);
}
else if (loopCt === numPwds && encPassword !== reply) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, null, 0, null, false);
cb(status);
}
});
}
}
});
}
Unfortunately, caller sees status === undefined even though encPassword === reply is true and I issue the cb(status). How can I exit the for-loop for good after issuing cb(status)?