sahat/satellizer

Double request to Redirect Url

BuffMcBigHuge opened this issue · 0 comments

I have integrated Microsoft Azure OAuth into my MEAN stack but I'm dealing with an odd issue where the /auth/live endpoint get's called a second time after a few seconds. Not sure if it's the timeout function in Satellizer that's causing this second call. The second call is actually terminating the first call on the front end, and I get this response from the access token request on the second call:

{ error: 'invalid_grant',
  error_description: 'AADSTS70000: The provided value for the \'code\' parameter is not valid. The code has expired.\r\n',
  error_codes: [ 70000 ],
  timestamp: '2017-07-31 23:05:07Z',
  trace_id: 'XYZ',
  correlation_id: 'WXY' }

My code (satellizer.js):

 live: {
     name: 'live',
     url: '/auth/live',
     authorizationEndpoint: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
     redirectUri: window.location.origin,
     requiredUrlParams: ['scope'],
     scope: ['offline_access', 'openid', 'profile', 'User.Read', 'Contacts.Read'],
     scopeDelimiter: ' ',
     oauthType: '2.0',
     popupOptions: { width: 500, height: 560 }
 },

Backend endpoint:

/*
 |--------------------------------------------------------------------------
 | /auth/live
 |--------------------------------------------------------------------------
 */
router.post('/live', ensureAuthenticated, function(req, res) {

    var endPoint = '/auth/live';
    var method = 'POST';

    if ((typeof req.body.code === 'undefined') || (typeof req.body.clientId === 'undefined') || (typeof req.body.redirectUri === 'undefined'))
        return log({message: 'Invalid parameters'}, {'status': 400, method : method, endPoint: endPoint}, req, res);

    User.findById(req.user, function (err, user) {

        if (!user)
            return log({message: 'User not found'}, {'status': 400, method: method, endPoint: endPoint}, req, res);

        if (err)
            return log(err, {'status': 500, method: method, endPoint: endPoint}, req, res);

        req.user = user;

        var accessTokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';

        var params = {
            code: req.body.code,
            client_id: req.body.clientId,
            client_secret: config.live.secret,
            redirect_uri: req.body.redirectUri,
            grant_type: 'authorization_code'
        };

        request.post(accessTokenUrl, {form: params, json: true}, function (err, response, body) {

            if (response.statusCode !== 200)
                return log(body, {'status': 500, method: method, endPoint: endPoint}, req, res);

            var profileUrl = 'https://graph.microsoft.com/v1.0/me';
            var headers = {Authorization: 'Bearer ' + body.access_token};

            request.get({url: profileUrl, headers : headers, json: true}, function (err, response, body) {

                if (response.statusCode !== 200)
                    return log(body, {'status': 500, method: method, endPoint: endPoint}, req, res);

                User.findOne({live: body.id}, function (err, existingUser) {

                    if ((existingUser) && (existingUser._id.toString() !== user._id.toString()))
                        return log({message: 'Microsoft Account Already Linked To User'}, {'status': 409, method : method, endPoint: endPoint}, req, res);

                    var profile = body;
                    user.live = profile.id;

                   user.save(function (err) {

                       if (err)
                           return log(err, {'status': 500, method: method, endPoint: endPoint}, req, res);

                       return log({message: 'Microsoft Account Linked'}, {
                           'status': 200,
                           method: method,
                           endPoint: endPoint
                       }, req, res);

                   });

                });

            });

        });

    });

});