Monday, 24 April 2017

Promise not resolving in https call

I am writing an AWS Lambda function behind API Gateway, which validates tokens with Facebook and our app id so we can confirm the identity of the user so he can delete his resources. The user sends his user id and token from the Facebook login, I check if the token is valid and if it's for the same user. In the implementation I am using promises but the problem is that the first then is not executed at all. I first call getFacebookAccessToken so I can call the API and in the response I resolve or reject, but the code doesn't reach that point. Here is the function:

'use strict';

const https = require('https');
const querystring = require('querystring');

exports.handler = (event, context, callback) => {

        if (typeof event.body.token === 'undefined' || event.body.token === '') {

                context.succeed({
                        "result":"false",
                        "message": `InputError: token is not defined or it is empty`
                });
                return;
        }
        if (typeof event.body.userId === 'undefined' || event.body.userId === '') {

                context.succeed({
                        "result":"false",
                        "message": `InputError: userId is not defined or it is empty`
                });
                return;
        }

        getFacebookAccessToken()
                .then((appAccessToken) => {

                        return checkFacebookId(appAccessToken, event.body.token, event.body.userId);
                })
                .then((result) => {

                        console.log('Done');
                        context.succeed(result);
                })
                .catch((error) => {

                        context.succeed(error);
                });
};

let checkFacebookId = (appAccessToken, token, facebookId) => {

        return new Promise((resolve, reject) => {

                let params = {
                        input_token: token,
                        access_token: appAccessToken
                };

                let requestParams = querystring.stringify(params);

                let configOptions = {
                        method: "get",
                        hostname: "graph.facebook.com",
                        path: "/debug_token?" + requestParams
                };

                let request = https.request(configOptions, function (result) {

                        let response = "";
                        result.setEncoding('utf8');
                        result.on('data', function (chunk) {

                                response += chunk;
                        });

                        result.on('end', function () {

                                const fbResponse = JSON.parse(response);

                                if (result.statusCode.toString() === '200') {

                                        console.log(`Validating facebook token: OK`);

                                        if (typeof fbResponse.data === 'undefined') {
                                                reject({
                                                        "result": "false",
                                                        "message": "Token not valid"
                                                });
                                        }
                                        if (fbResponse.data.user_id === facebookId) {
                                                resolve({
                                                        "result": "true"
                                                });
                                        } else {
                                                reject({
                                                        "result": "false",
                                                        "message": "Token not valid"
                                                });
                                        }
                                }
                                else {

                                        reject({
                                                "result": "false",
                                                "error": {
                                                        "Message": `Failed validating facebook user access token`,
                                                        "statusCode": result.statusCode,
                                                        "token_valid": fbResponse
                                                }
                                        });
                                }
                        });
                });

                request.on('error', function (error) {
                        reject({
                                "result": "false",
                                "message": "Error in Facebook",
                                "error": error
                        });
                });

                console.log(`Validating facebook token: PENDING`);
                request.end();
        });
};

let getFacebookAccessToken = () => {

        return new Promise((resolve, reject) => {

                let params = {
                        client_id: event.stage.fb_app_id,
                        client_secret: event.stage.fb_app_secret,
                        grant_type: "client_credentials"
                };

                let requestParams = querystring.stringify(params);

                let configOptions = {
                        method: "get",
                        hostname: "graph.facebook.com",
                        path: "/oauth/access_token?" + requestParams
                };
                let request = https.request(configOptions, function (result) {

                        let responseData = "";
                        result.setEncoding('utf8');
                        result.on('data', function (chunk) {

                                responseData += chunk;
                        });

                        result.on('end', function () {
                                console.log(result);
                                if (result.statusCode.toString() === '200') {

                                        console.log(`Getting Facebook Access Token: OK`);
                                        resolve(JSON.parse(responseData).access_token);
                                }
                                else {

                                        reject({
                                                "result": "false",
                                                "error": {
                                                        "Message": `Failed getting facebook access token`,
                                                        "statusCode": result.statusCode
                                                }
                                        });
                                }
                        });
                });

                request.on('error', function (error) {
                        reject({
                                "result": "false",
                                "message": "Error in Facebook",
                                "error": error
                        });
                });

                console.log(`Getting Facebook Access Token: PENDING`);
                request.end();
        });
};


via Daniel Papukchiev

No comments:

Post a Comment