diff options
Diffstat (limited to 'lib/caldav/http/oauth2.js')
-rw-r--r-- | lib/caldav/http/oauth2.js | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/lib/caldav/http/oauth2.js b/lib/caldav/http/oauth2.js new file mode 100644 index 0000000..75e6334 --- /dev/null +++ b/lib/caldav/http/oauth2.js @@ -0,0 +1,114 @@ +(function(module, ns) { + + var XHR = ns.require('xhr'); + var QueryString = ns.require('querystring'); + var Connection = ns.require('connection'); + var OAuth = ns.require('oauth2'); + + /** + * Creates an XHR like object given a connection and a set of options + * (passed directly to the superclass) + * + * @param {Caldav.Connection} connection used for apiCredentials. + * @param {Object} options typical XHR options. + */ + function Oauth2(connection, options) { + if ( + !connection || + !connection.oauth || + ( + !connection.oauth.code && + !connection.oauth.refresh_token + ) + ) { + throw new Error('connection .oauth must have code or refresh_token'); + } + + this.connection = connection; + + this.oauth = + new OAuth(connection.apiCredentials); + + // create a clone of options + var clone = Object.create(null); + + if (typeof(options) !== 'undefined') { + for (var key in options) { + clone[key] = options[key]; + } + } + + XHR.call(this, clone); + } + + Oauth2.prototype = { + __proto__: XHR.prototype, + + _sendXHR: function(xhr) { + xhr.setRequestHeader( + 'Authorization', 'Bearer ' + this.connection.oauth.access_token + ); + + xhr.send(this._serialize()); + return xhr; + }, + + _updateConnection: function(credentials) { + var oauth = this.connection.oauth; + var update = { oauth: credentials }; + + if (oauth.refresh_token && !credentials.refresh_token) + credentials.refresh_token = oauth.refresh_token; + + if (credentials.user) { + update.user = credentials.user; + delete credentials.user; + } + + return this.connection.update(update); + }, + + send: function(callback) { + var xhr = this._buildXHR(callback); + var oauth = this.connection.oauth; + + // everything is fine just send + if (this.oauth.accessTokenValid(oauth)) { + return this._sendXHR(xhr); + } + + var handleTokenUpdates = (function handleTokenUpdates(err, credentials) { + if (err) { + return callback(err); + } + this._updateConnection(credentials); + return this._sendXHR(xhr); + }.bind(this)); + + if (oauth.code) { + this.oauth.authenticateCode(oauth.code, handleTokenUpdates); + + // it should be impossible to have both code and refresh_token + // but we return as a guard + return xhr; + } + + if (oauth.refresh_token) { + this.oauth.refreshToken(oauth.refresh_token, handleTokenUpdates); + return xhr; + } + } + + }; + + + module.exports = Oauth2; + +}.apply( + this, + (this.Caldav) ? + [Caldav('http/oauth2'), Caldav] : + [module, require('../caldav')] +)); + + |