Last active
May 6, 2024 12:33
-
-
Save yoavniran/06454e87a3b8d858614e to your computer and use it in GitHub Desktop.
class used to allow making authorized requests to google API that also allows streaming the response even if a token refresh is required
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var util = require("util"), | |
_ = require("underscore"), | |
events = require("events"), | |
request = require("request"), | |
AppAuthClient = require("../google/AppAuthClient"); //thin wrapper around the google oauth2client - simply initializing it with app's client id and secret | |
var SimpleAuthTransporter= (function () { | |
var _USER_AGENT = "css-server@node"; | |
var SimpleAuthTransporter = function () { | |
events.EventEmitter.call(this); | |
}; | |
util.inherits(SimpleAuthTransporter, events.EventEmitter); | |
SimpleAuthTransporter.prototype.request = function (options, responseCallback) { | |
var tokenInfo = options.tokens; | |
responseCallback = _wrapResponseCallback(responseCallback); | |
if (tokenInfo) { | |
if (!tokenInfo.access_token && !tokenInfo.refresh_token) { | |
responseCallback(new Error("access token or refresh tokens not supplied")); | |
return; | |
} | |
var isTokenExpired = tokenInfo.expiry_date ? tokenInfo.expiry_date <= (new Date()).getTime() : false; //logic taken from google's api node client: oauth2client class | |
if (!tokenInfo.access_token || isTokenExpired){ | |
_refreshToken.call(this, options, responseCallback); | |
return; | |
} | |
} | |
_makeApiRequest.call(this, options, responseCallback) ; | |
}; | |
function _makeApiRequest(options, responseCallback){ | |
options = _configure.call(this, options); | |
var req = request(options,responseCallback.bind(this)); | |
this.emit("request", req); //give access to the request result | |
} | |
function _onTokenRefresh(options, responseCallback, err, credentials){ | |
if (err){ | |
responseCallback(err); | |
return; | |
} | |
this.emit("refresh", _.clone(credentials)); //allow calling code use the new token | |
options.tokens = credentials; | |
_makeApiRequest.call(this, options, responseCallback) ; | |
} | |
function _configure(options) { | |
options.headers = options.headers || {}; | |
if (options.tokens) { | |
options.headers["Authorization"] = options.tokens.token_type + " " + options.tokens.access_token; | |
} | |
options.headers["User-Agent"] = options.headers["User-Agent"] ? options.headers["User-Agent"] : _USER_AGENT; | |
return options; | |
} | |
function _refreshToken(options, responseCallback) { | |
var authClient = new AppAuthClient();//thin wrapper around the google oauth2client - simply initializing it with app's client id and secret | |
authClient.setCredentials(_.clone(options.tokens)); | |
authClient.refreshAccessToken(_onTokenRefresh.bind(this, options, responseCallback)); | |
} | |
function _wrapResponseCallback(callback){ | |
return function(err, res, body){ | |
if (err) { | |
this.emit("error", err); | |
} | |
this.emit("response", err, res, body); | |
if (callback) { | |
callback(err, res, body); // res is: http://nodejs.org/api/http.html#http_http_incomingmessage | |
} | |
}; | |
} | |
return SimpleAuthTransporter; | |
})(); | |
module.exports = SimpleAuthTransporter; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment