kittu
kittu

Reputation: 7008

Multi user password reset concurrency issue in NodeJS and ExpressJS

Unable to reset password for multiple users. I am stuck while multiple users trying to reset the password

How I do capture the exact reset token sent to specific user in email as link? Lets say when two user are trying to reset the password, the resetQueryParameter will be overridden. How do I handle this?

Get the token from query parameters when users clicks on the reset link in email:

// global variable
var resetQueryParameters = '';

//CAPTURE TOKEN (QUERY PARAMS) FROM LINK
app.get('/resetQuery/', function (req, res) {

    //SET THE TOKEN TO VARIABLE
    resetQueryParameters = req.query.token;
    r.db('myDB').table('Reset_Password').filter(r.row('auth_key').eq(req.query.token)).
    run(myConnection, function (err, cursor) {
        if (err) {
            return next(err);
        }
        cursor.toArray(function (err, result) {
            if (err) {
                throw err;
            } else {
                if (result.length > 0) {
                    res.redirect(redirectResetPage);
                } else {
                    res.redirect(redirectLoginPage);
                }
                return result;
                console.log("printing reset link from db.....", JSON.stringify(result, null, 2));
            }
        });
    });
});

getting the token when user clicks on link and verify the signature:

function resetPassword(req, res, next) {
    console.log('reset password called from external link.....');

    nJwt.verify(resetQueryParameters, secretKey, function (err, verifiedJwt) {
        if (err) {
            console.log('reset token not valid...', err);
        } else {
            var params = {
                'username': verifiedJwt.body.details,
                'newPassword': req.params.newPassword
            };

            getApiResponse(resetURL, params, function (res1) {
                console.log('sending reset params to server...', params);
                if (res1.error) {
                    console.log('Could not reset password......', res1.error);
                } else {
                    console.log('reset password success.....');
                    resetQueryParameters = '';
                    res.json(res1);
                }
            });
        }
    });
}

Upvotes: 2

Views: 127

Answers (1)

Aruna
Aruna

Reputation: 12022

It's not a good practice to use global variables here and not for any scenario.

When you do the redirect, you should pass the req.query.token to the redirectResetPage as below,

if (result.length > 0) {
   res.redirect(redirectResetPage + '?token=' + req.query.token);
} else {
   res.redirect(redirectLoginPage);
}

and let the page pass the same token back to the resetPassword method and use it there from the request.query or request.body but not from the global variable.

function resetPassword(req, res, next) {
    console.log('reset password called from external link.....');

    nJwt.verify(req.query.token, secretKey, function (err, verifiedJwt) {
        if (err) {
            console.log('reset token not valid...', err);
        } else {
            var params = {
                'username': verifiedJwt.body.details,
                'newPassword': req.params.newPassword
            };

            getApiResponse(resetURL, params, function (res1) {
                console.log('sending reset params to server...', params);
                if (res1.error) {
                    console.log('Could not reset password......', res1.error);
                } else {
                    console.log('reset password success.....');
                    resetQueryParameters = '';
                    res.json(res1);
                }
            });
        }
    });
}

Note: The best practise is, store this token in the database if possible or store it in the cookie/jwt token.

Upvotes: 1

Related Questions