0
function Auth() {
    this.accessTokenError = false;

}
Auth.prototype.validateToken = function (accessToken, refreshToken) {
    var token;
    var self = this;
    return new Promise(function (resolve, reject) {
        AuthCron.secret()
            .then(function (secret) {

                if (self.accessTokenError) {
                    token = refreshToken;
                    secret = secret.substr(0, secret.length / 2);
                }
                else
                    token = accessToken;
                JWT.verify(token, secret, function (error, decoded) {
                    console.log(error, decoded);
                    if (error) {
                        if (!self.accessTokenError) {
                            self.accessTokenError = true;
                             // I don't know how to handle  this
                            self.validateToken(accessToken, refreshToken)
                        }
                        else {
                            self.accessTokenError = false;
                            reject(error);
                        }
                    }
                    else
                        resolve(decoded.user);
                });

            })
            .catch(function (err) {

                reject(err)
            });
    })
};

I am bit confused on how to handle recursive promise. The problem here is first promise never resolves nor rejects. What is the best way to handle this situation? This function accepts two tokens if access token is expired or invalid then refresh token is validated, if refresh token is also invalid then promise should reject.

venkatvb
  • 681
  • 1
  • 9
  • 24
Rayees
  • 57
  • 3
  • 15

1 Answers1

0

With problems like this, it's generally best to separate the creation of promises from the higher order application logic. This is done by promisifying at the lowest possible level - JWT.verify() in this case.

JWT.verifyAsync = function(token, secret) {
    return new Promise((resolve, reject) => {
        JWT.verify(token, secret, (error, decoded) => {
            error ? reject(error) : resolve(decoded);
        });
    });
};

Now, you could still write the Auth.prototype.validateToken() method to perform its tries recursively, but, as there would only ever be a maximum of two levels of recursion, it's far simpler to hard-code both tries with (pseudo-code) first_try().catch(() => second_try()). As a bonus, the need for that awkward .accessTokenError boolean disappears.

Here it is in full :

Auth.prototype.validateToken = function(accessToken, refreshToken) {
    return AuthCron.secret()
    .then(secret => {
        return JWT.verifyAsync(accessToken, secret) // first try
        .catch(() => JWT.verifyAsync(refreshToken, secret.substr(0, secret.length / 2))); // second try
    })
    .then(decoded => decoded.user);
};
Graham
  • 7,431
  • 18
  • 59
  • 84
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44