I have this function to findOneAndUpdate, it will find if the username if it exist then set the time field and increase number of other field.
function _lockIfFailedAttemptsReachLimit(username,next) {
colUser.findOneAndUpdate({ username }, { // increase failed attempt counter
$set: { failedLoginAt: new Date() },
$inc: { nFailedLogin: 1 },
}, { upsert: false, returnOriginal: false }, (err, result) => {
if (err) { // Undefined.
next('Undefined error!');
} else {
let foundUser = result.value;
if (_.isNil(foundUser)) { // cannot find username
//nothing here yet.
}
let nFailed = _.get(foundUser, 'nFailedLogin', 0);
let errMsg = `Invalid username or passsword. You have tried ${nFailed}/${MAX_FAILED_LOGIN_ATTEMPTS} login attempts`;
if (nFailed < MAX_FAILED_LOGIN_ATTEMPTS) {
next(errMsg);
} else {
_lockAccount(username, (err, result) => {
if (!err) {
errMsg += `. Your account has been locked for ${WAITING_TIME_AFTER_LOCKED} seconds.`;
}
next(errMsg);
});
}
}
});
}
Now I want in the same function if cannot find username, then it will insert username value and do the same process for that username. How could I do that in most effective coding ? I tried:
function _lockIfFailedAttemptsReachLimit(username, req, res, next) {
colUser.findOneAndUpdate({ username }, { // increase failed attempt counter
$set: { failedLoginAt: new Date() },
$inc: { nFailedLogin: 1 },
}, { upsert: false, returnOriginal: false }, (err, result) => {
if (err) { // Undefined.
next('Undefined error!');
} else {
let foundUser = result.value;
if (_.isNil(foundUser)) { // cannot find username
//I think can try to put the code here ?
let username = (req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress).split(",")[0];
// insert username to the table and call the function to continue from the beginning
}
let nFailed = _.get(foundUser, 'nFailedLogin', 0);
let errMsg = `Invalid username or passsword. You have tried ${nFailed}/${MAX_FAILED_LOGIN_ATTEMPTS} login attempts`;
if (nFailed < MAX_FAILED_LOGIN_ATTEMPTS) {
next(errMsg);
} else {
_lockAccount(username, (err, result) => {
if (!err) {
errMsg += `. Your account has been locked for ${WAITING_TIME_AFTER_LOCKED} seconds.`;
}
next(errMsg);
});
}
}
});
}