mirror of https://github.com/perkeep/perkeep.git
593 lines
22 KiB
JavaScript
593 lines
22 KiB
JavaScript
/**
|
|
* Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
|
|
* source code is governed by a BSD-style license that can be found in the
|
|
* LICENSE file.
|
|
*/
|
|
|
|
/**
|
|
* Constructor - no need to invoke directly, call initBackgroundPage instead.
|
|
* @constructor
|
|
* @param {String} url_request_token The OAuth request token URL.
|
|
* @param {String} url_auth_token The OAuth authorize token URL.
|
|
* @param {String} url_access_token The OAuth access token URL.
|
|
* @param {String} consumer_key The OAuth consumer key.
|
|
* @param {String} consumer_secret The OAuth consumer secret.
|
|
* @param {String} oauth_scope The OAuth scope parameter.
|
|
* @param {Object} opt_args Optional arguments. Recognized parameters:
|
|
* "app_name" {String} Name of the current application
|
|
* "callback_page" {String} If you renamed chrome_ex_oauth.html, the name
|
|
* this file was renamed to.
|
|
*/
|
|
function ChromeExOAuth(url_request_token, url_auth_token, url_access_token,
|
|
consumer_key, consumer_secret, oauth_scope, opt_args) {
|
|
this.url_request_token = url_request_token;
|
|
this.url_auth_token = url_auth_token;
|
|
this.url_access_token = url_access_token;
|
|
this.consumer_key = consumer_key;
|
|
this.consumer_secret = consumer_secret;
|
|
this.oauth_scope = oauth_scope;
|
|
this.app_name = opt_args && opt_args['app_name'] ||
|
|
"ChromeExOAuth Library";
|
|
this.key_token = "oauth_token";
|
|
this.key_token_secret = "oauth_token_secret";
|
|
this.callback_page = opt_args && opt_args['callback_page'] ||
|
|
"chrome_ex_oauth.html";
|
|
this.auth_params = {};
|
|
if (opt_args && opt_args['auth_params']) {
|
|
for (key in opt_args['auth_params']) {
|
|
if (opt_args['auth_params'].hasOwnProperty(key)) {
|
|
this.auth_params[key] = opt_args['auth_params'][key];
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/*******************************************************************************
|
|
* PUBLIC API METHODS
|
|
* Call these from your background page.
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* Initializes the OAuth helper from the background page. You must call this
|
|
* before attempting to make any OAuth calls.
|
|
* @param {Object} oauth_config Configuration parameters in a JavaScript object.
|
|
* The following parameters are recognized:
|
|
* "request_url" {String} OAuth request token URL.
|
|
* "authorize_url" {String} OAuth authorize token URL.
|
|
* "access_url" {String} OAuth access token URL.
|
|
* "consumer_key" {String} OAuth consumer key.
|
|
* "consumer_secret" {String} OAuth consumer secret.
|
|
* "scope" {String} OAuth access scope.
|
|
* "app_name" {String} Application name.
|
|
* "auth_params" {Object} Additional parameters to pass to the
|
|
* Authorization token URL. For an example, 'hd', 'hl', 'btmpl':
|
|
* http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth
|
|
* @return {ChromeExOAuth} An initialized ChromeExOAuth object.
|
|
*/
|
|
ChromeExOAuth.initBackgroundPage = function(oauth_config) {
|
|
window.chromeExOAuthConfig = oauth_config;
|
|
window.chromeExOAuth = ChromeExOAuth.fromConfig(oauth_config);
|
|
window.chromeExOAuthRedirectStarted = false;
|
|
window.chromeExOAuthRequestingAccess = false;
|
|
|
|
var url_match = chrome.extension.getURL(window.chromeExOAuth.callback_page);
|
|
var tabs = {};
|
|
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
|
|
if (changeInfo.url &&
|
|
changeInfo.url.substr(0, url_match.length) === url_match &&
|
|
changeInfo.url != tabs[tabId] &&
|
|
window.chromeExOAuthRequestingAccess == false) {
|
|
chrome.tabs.create({ 'url' : changeInfo.url }, function(tab) {
|
|
tabs[tab.id] = tab.url;
|
|
chrome.tabs.remove(tabId);
|
|
});
|
|
}
|
|
});
|
|
|
|
return window.chromeExOAuth;
|
|
};
|
|
|
|
/**
|
|
* Authorizes the current user with the configued API. You must call this
|
|
* before calling sendSignedRequest.
|
|
* @param {Function} callback A function to call once an access token has
|
|
* been obtained. This callback will be passed the following arguments:
|
|
* token {String} The OAuth access token.
|
|
* secret {String} The OAuth access token secret.
|
|
*/
|
|
ChromeExOAuth.prototype.authorize = function(callback) {
|
|
if (this.hasToken()) {
|
|
callback(this.getToken(), this.getTokenSecret());
|
|
} else {
|
|
window.chromeExOAuthOnAuthorize = function(token, secret) {
|
|
callback(token, secret);
|
|
};
|
|
chrome.tabs.create({ 'url' :chrome.extension.getURL(this.callback_page) });
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Clears any OAuth tokens stored for this configuration. Effectively a
|
|
* "logout" of the configured OAuth API.
|
|
*/
|
|
ChromeExOAuth.prototype.clearTokens = function() {
|
|
delete localStorage[this.key_token + encodeURI(this.oauth_scope)];
|
|
delete localStorage[this.key_token_secret + encodeURI(this.oauth_scope)];
|
|
};
|
|
|
|
/**
|
|
* Returns whether a token is currently stored for this configuration.
|
|
* Effectively a check to see whether the current user is "logged in" to
|
|
* the configured OAuth API.
|
|
* @return {Boolean} True if an access token exists.
|
|
*/
|
|
ChromeExOAuth.prototype.hasToken = function() {
|
|
return !!this.getToken();
|
|
};
|
|
|
|
/**
|
|
* Makes an OAuth-signed HTTP request with the currently authorized tokens.
|
|
* @param {String} url The URL to send the request to. Querystring parameters
|
|
* should be omitted.
|
|
* @param {Function} callback A function to be called once the request is
|
|
* completed. This callback will be passed the following arguments:
|
|
* responseText {String} The text response.
|
|
* xhr {XMLHttpRequest} The XMLHttpRequest object which was used to
|
|
* send the request. Useful if you need to check response status
|
|
* code, etc.
|
|
* @param {Object} opt_params Additional parameters to configure the request.
|
|
* The following parameters are accepted:
|
|
* "method" {String} The HTTP method to use. Defaults to "GET".
|
|
* "body" {String} A request body to send. Defaults to null.
|
|
* "parameters" {Object} Query parameters to include in the request.
|
|
* "headers" {Object} Additional headers to include in the request.
|
|
*/
|
|
ChromeExOAuth.prototype.sendSignedRequest = function(url, callback,
|
|
opt_params) {
|
|
var method = opt_params && opt_params['method'] || 'GET';
|
|
var body = opt_params && opt_params['body'] || null;
|
|
var params = opt_params && opt_params['parameters'] || {};
|
|
var headers = opt_params && opt_params['headers'] || {};
|
|
|
|
var signedUrl = this.signURL(url, method, params);
|
|
|
|
ChromeExOAuth.sendRequest(method, signedUrl, headers, body, function (xhr) {
|
|
if (xhr.readyState == 4) {
|
|
callback(xhr.responseText, xhr);
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Adds the required OAuth parameters to the given url and returns the
|
|
* result. Useful if you need a signed url but don't want to make an XHR
|
|
* request.
|
|
* @param {String} method The http method to use.
|
|
* @param {String} url The base url of the resource you are querying.
|
|
* @param {Object} opt_params Query parameters to include in the request.
|
|
* @return {String} The base url plus any query params plus any OAuth params.
|
|
*/
|
|
ChromeExOAuth.prototype.signURL = function(url, method, opt_params) {
|
|
var token = this.getToken();
|
|
var secret = this.getTokenSecret();
|
|
if (!token || !secret) {
|
|
throw new Error("No oauth token or token secret");
|
|
}
|
|
|
|
var params = opt_params || {};
|
|
|
|
var result = OAuthSimple().sign({
|
|
action : method,
|
|
path : url,
|
|
parameters : params,
|
|
signatures: {
|
|
consumer_key : this.consumer_key,
|
|
shared_secret : this.consumer_secret,
|
|
oauth_secret : secret,
|
|
oauth_token: token
|
|
}
|
|
});
|
|
|
|
return result.signed_url;
|
|
};
|
|
|
|
/**
|
|
* Generates the Authorization header based on the oauth parameters.
|
|
* @param {String} url The base url of the resource you are querying.
|
|
* @param {Object} opt_params Query parameters to include in the request.
|
|
* @return {String} An Authorization header containing the oauth_* params.
|
|
*/
|
|
ChromeExOAuth.prototype.getAuthorizationHeader = function(url, method,
|
|
opt_params) {
|
|
var token = this.getToken();
|
|
var secret = this.getTokenSecret();
|
|
if (!token || !secret) {
|
|
throw new Error("No oauth token or token secret");
|
|
}
|
|
|
|
var params = opt_params || {};
|
|
|
|
return OAuthSimple().getHeaderString({
|
|
action: method,
|
|
path : url,
|
|
parameters : params,
|
|
signatures: {
|
|
consumer_key : this.consumer_key,
|
|
shared_secret : this.consumer_secret,
|
|
oauth_secret : secret,
|
|
oauth_token: token
|
|
}
|
|
});
|
|
};
|
|
|
|
/*******************************************************************************
|
|
* PRIVATE API METHODS
|
|
* Used by the library. There should be no need to call these methods directly.
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* Creates a new ChromeExOAuth object from the supplied configuration object.
|
|
* @param {Object} oauth_config Configuration parameters in a JavaScript object.
|
|
* The following parameters are recognized:
|
|
* "request_url" {String} OAuth request token URL.
|
|
* "authorize_url" {String} OAuth authorize token URL.
|
|
* "access_url" {String} OAuth access token URL.
|
|
* "consumer_key" {String} OAuth consumer key.
|
|
* "consumer_secret" {String} OAuth consumer secret.
|
|
* "scope" {String} OAuth access scope.
|
|
* "app_name" {String} Application name.
|
|
* "auth_params" {Object} Additional parameters to pass to the
|
|
* Authorization token URL. For an example, 'hd', 'hl', 'btmpl':
|
|
* http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth
|
|
* @return {ChromeExOAuth} An initialized ChromeExOAuth object.
|
|
*/
|
|
ChromeExOAuth.fromConfig = function(oauth_config) {
|
|
return new ChromeExOAuth(
|
|
oauth_config['request_url'],
|
|
oauth_config['authorize_url'],
|
|
oauth_config['access_url'],
|
|
oauth_config['consumer_key'],
|
|
oauth_config['consumer_secret'],
|
|
oauth_config['scope'],
|
|
{
|
|
'app_name' : oauth_config['app_name'],
|
|
'auth_params' : oauth_config['auth_params']
|
|
}
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Initializes chrome_ex_oauth.html and redirects the page if needed to start
|
|
* the OAuth flow. Once an access token is obtained, this function closes
|
|
* chrome_ex_oauth.html.
|
|
*/
|
|
ChromeExOAuth.initCallbackPage = function() {
|
|
var background_page = chrome.extension.getBackgroundPage();
|
|
var oauth_config = background_page.chromeExOAuthConfig;
|
|
var oauth = ChromeExOAuth.fromConfig(oauth_config);
|
|
background_page.chromeExOAuthRedirectStarted = true;
|
|
oauth.initOAuthFlow(function (token, secret) {
|
|
background_page.chromeExOAuthOnAuthorize(token, secret);
|
|
background_page.chromeExOAuthRedirectStarted = false;
|
|
chrome.tabs.getSelected(null, function (tab) {
|
|
chrome.tabs.remove(tab.id);
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Sends an HTTP request. Convenience wrapper for XMLHttpRequest calls.
|
|
* @param {String} method The HTTP method to use.
|
|
* @param {String} url The URL to send the request to.
|
|
* @param {Object} headers Optional request headers in key/value format.
|
|
* @param {String} body Optional body content.
|
|
* @param {Function} callback Function to call when the XMLHttpRequest's
|
|
* ready state changes. See documentation for XMLHttpRequest's
|
|
* onreadystatechange handler for more information.
|
|
*/
|
|
ChromeExOAuth.sendRequest = function(method, url, headers, body, callback) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.onreadystatechange = function(data) {
|
|
callback(xhr, data);
|
|
}
|
|
xhr.open(method, url, true);
|
|
if (headers) {
|
|
for (var header in headers) {
|
|
if (headers.hasOwnProperty(header)) {
|
|
xhr.setRequestHeader(header, headers[header]);
|
|
}
|
|
}
|
|
}
|
|
xhr.send(body);
|
|
};
|
|
|
|
/**
|
|
* Decodes a URL-encoded string into key/value pairs.
|
|
* @param {String} encoded An URL-encoded string.
|
|
* @return {Object} An object representing the decoded key/value pairs found
|
|
* in the encoded string.
|
|
*/
|
|
ChromeExOAuth.formDecode = function(encoded) {
|
|
var params = encoded.split("&");
|
|
var decoded = {};
|
|
for (var i = 0, param; param = params[i]; i++) {
|
|
var keyval = param.split("=");
|
|
if (keyval.length == 2) {
|
|
var key = ChromeExOAuth.fromRfc3986(keyval[0]);
|
|
var val = ChromeExOAuth.fromRfc3986(keyval[1]);
|
|
decoded[key] = val;
|
|
}
|
|
}
|
|
return decoded;
|
|
};
|
|
|
|
/**
|
|
* Returns the current window's querystring decoded into key/value pairs.
|
|
* @return {Object} A object representing any key/value pairs found in the
|
|
* current window's querystring.
|
|
*/
|
|
ChromeExOAuth.getQueryStringParams = function() {
|
|
var urlparts = window.location.href.split("?");
|
|
if (urlparts.length >= 2) {
|
|
var querystring = urlparts.slice(1).join("?");
|
|
return ChromeExOAuth.formDecode(querystring);
|
|
}
|
|
return {};
|
|
};
|
|
|
|
/**
|
|
* Binds a function call to a specific object. This function will also take
|
|
* a variable number of additional arguments which will be prepended to the
|
|
* arguments passed to the bound function when it is called.
|
|
* @param {Function} func The function to bind.
|
|
* @param {Object} obj The object to bind to the function's "this".
|
|
* @return {Function} A closure that will call the bound function.
|
|
*/
|
|
ChromeExOAuth.bind = function(func, obj) {
|
|
var newargs = Array.prototype.slice.call(arguments).slice(2);
|
|
return function() {
|
|
var combinedargs = newargs.concat(Array.prototype.slice.call(arguments));
|
|
func.apply(obj, combinedargs);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Encodes a value according to the RFC3986 specification.
|
|
* @param {String} val The string to encode.
|
|
*/
|
|
ChromeExOAuth.toRfc3986 = function(val){
|
|
return encodeURIComponent(val)
|
|
.replace(/\!/g, "%21")
|
|
.replace(/\*/g, "%2A")
|
|
.replace(/'/g, "%27")
|
|
.replace(/\(/g, "%28")
|
|
.replace(/\)/g, "%29");
|
|
};
|
|
|
|
/**
|
|
* Decodes a string that has been encoded according to RFC3986.
|
|
* @param {String} val The string to decode.
|
|
*/
|
|
ChromeExOAuth.fromRfc3986 = function(val){
|
|
var tmp = val
|
|
.replace(/%21/g, "!")
|
|
.replace(/%2A/g, "*")
|
|
.replace(/%27/g, "'")
|
|
.replace(/%28/g, "(")
|
|
.replace(/%29/g, ")");
|
|
return decodeURIComponent(tmp);
|
|
};
|
|
|
|
/**
|
|
* Adds a key/value parameter to the supplied URL.
|
|
* @param {String} url An URL which may or may not contain querystring values.
|
|
* @param {String} key A key
|
|
* @param {String} value A value
|
|
* @return {String} The URL with URL-encoded versions of the key and value
|
|
* appended, prefixing them with "&" or "?" as needed.
|
|
*/
|
|
ChromeExOAuth.addURLParam = function(url, key, value) {
|
|
var sep = (url.indexOf('?') >= 0) ? "&" : "?";
|
|
return url + sep +
|
|
ChromeExOAuth.toRfc3986(key) + "=" + ChromeExOAuth.toRfc3986(value);
|
|
};
|
|
|
|
/**
|
|
* Stores an OAuth token for the configured scope.
|
|
* @param {String} token The token to store.
|
|
*/
|
|
ChromeExOAuth.prototype.setToken = function(token) {
|
|
localStorage[this.key_token + encodeURI(this.oauth_scope)] = token;
|
|
};
|
|
|
|
/**
|
|
* Retrieves any stored token for the configured scope.
|
|
* @return {String} The stored token.
|
|
*/
|
|
ChromeExOAuth.prototype.getToken = function() {
|
|
return localStorage[this.key_token + encodeURI(this.oauth_scope)];
|
|
};
|
|
|
|
/**
|
|
* Stores an OAuth token secret for the configured scope.
|
|
* @param {String} secret The secret to store.
|
|
*/
|
|
ChromeExOAuth.prototype.setTokenSecret = function(secret) {
|
|
localStorage[this.key_token_secret + encodeURI(this.oauth_scope)] = secret;
|
|
};
|
|
|
|
/**
|
|
* Retrieves any stored secret for the configured scope.
|
|
* @return {String} The stored secret.
|
|
*/
|
|
ChromeExOAuth.prototype.getTokenSecret = function() {
|
|
return localStorage[this.key_token_secret + encodeURI(this.oauth_scope)];
|
|
};
|
|
|
|
/**
|
|
* Starts an OAuth authorization flow for the current page. If a token exists,
|
|
* no redirect is needed and the supplied callback is called immediately.
|
|
* If this method detects that a redirect has finished, it grabs the
|
|
* appropriate OAuth parameters from the URL and attempts to retrieve an
|
|
* access token. If no token exists and no redirect has happened, then
|
|
* an access token is requested and the page is ultimately redirected.
|
|
* @param {Function} callback The function to call once the flow has finished.
|
|
* This callback will be passed the following arguments:
|
|
* token {String} The OAuth access token.
|
|
* secret {String} The OAuth access token secret.
|
|
*/
|
|
ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
|
|
if (!this.hasToken()) {
|
|
var params = ChromeExOAuth.getQueryStringParams();
|
|
if (params['chromeexoauthcallback'] == 'true') {
|
|
var oauth_token = params['oauth_token'];
|
|
var oauth_verifier = params['oauth_verifier']
|
|
this.getAccessToken(oauth_token, oauth_verifier, callback);
|
|
} else {
|
|
var request_params = {
|
|
'url_callback_param' : 'chromeexoauthcallback'
|
|
}
|
|
this.getRequestToken(function(url) {
|
|
window.location.href = url;
|
|
}, request_params);
|
|
}
|
|
} else {
|
|
callback(this.getToken(), this.getTokenSecret());
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Requests an OAuth request token.
|
|
* @param {Function} callback Function to call once the authorize URL is
|
|
* calculated. This callback will be passed the following arguments:
|
|
* url {String} The URL the user must be redirected to in order to
|
|
* approve the token.
|
|
* @param {Object} opt_args Optional arguments. The following parameters
|
|
* are accepted:
|
|
* "url_callback" {String} The URL the OAuth provider will redirect to.
|
|
* "url_callback_param" {String} A parameter to include in the callback
|
|
* URL in order to indicate to this library that a redirect has
|
|
* taken place.
|
|
*/
|
|
ChromeExOAuth.prototype.getRequestToken = function(callback, opt_args) {
|
|
if (typeof callback !== "function") {
|
|
throw new Error("Specified callback must be a function.");
|
|
}
|
|
var url = opt_args && opt_args['url_callback'] ||
|
|
window && window.top && window.top.location &&
|
|
window.top.location.href;
|
|
|
|
var url_param = opt_args && opt_args['url_callback_param'] ||
|
|
"chromeexoauthcallback";
|
|
var url_callback = ChromeExOAuth.addURLParam(url, url_param, "true");
|
|
|
|
var result = OAuthSimple().sign({
|
|
path : this.url_request_token,
|
|
parameters: {
|
|
"xoauth_displayname" : this.app_name,
|
|
"scope" : this.oauth_scope,
|
|
"oauth_callback" : url_callback
|
|
},
|
|
signatures: {
|
|
consumer_key : this.consumer_key,
|
|
shared_secret : this.consumer_secret
|
|
}
|
|
});
|
|
var onToken = ChromeExOAuth.bind(this.onRequestToken, this, callback);
|
|
ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken);
|
|
};
|
|
|
|
/**
|
|
* Called when a request token has been returned. Stores the request token
|
|
* secret for later use and sends the authorization url to the supplied
|
|
* callback (for redirecting the user).
|
|
* @param {Function} callback Function to call once the authorize URL is
|
|
* calculated. This callback will be passed the following arguments:
|
|
* url {String} The URL the user must be redirected to in order to
|
|
* approve the token.
|
|
* @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the
|
|
* request token.
|
|
*/
|
|
ChromeExOAuth.prototype.onRequestToken = function(callback, xhr) {
|
|
if (xhr.readyState == 4) {
|
|
if (xhr.status == 200) {
|
|
var params = ChromeExOAuth.formDecode(xhr.responseText);
|
|
var token = params['oauth_token'];
|
|
this.setTokenSecret(params['oauth_token_secret']);
|
|
var url = ChromeExOAuth.addURLParam(this.url_auth_token,
|
|
"oauth_token", token);
|
|
for (var key in this.auth_params) {
|
|
if (this.auth_params.hasOwnProperty(key)) {
|
|
url = ChromeExOAuth.addURLParam(url, key, this.auth_params[key]);
|
|
}
|
|
}
|
|
callback(url);
|
|
} else {
|
|
throw new Error("Fetching request token failed. Status " + xhr.status);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Requests an OAuth access token.
|
|
* @param {String} oauth_token The OAuth request token.
|
|
* @param {String} oauth_verifier The OAuth token verifier.
|
|
* @param {Function} callback The function to call once the token is obtained.
|
|
* This callback will be passed the following arguments:
|
|
* token {String} The OAuth access token.
|
|
* secret {String} The OAuth access token secret.
|
|
*/
|
|
ChromeExOAuth.prototype.getAccessToken = function(oauth_token, oauth_verifier,
|
|
callback) {
|
|
if (typeof callback !== "function") {
|
|
throw new Error("Specified callback must be a function.");
|
|
}
|
|
var bg = chrome.extension.getBackgroundPage();
|
|
if (bg.chromeExOAuthRequestingAccess == false) {
|
|
bg.chromeExOAuthRequestingAccess = true;
|
|
|
|
var result = OAuthSimple().sign({
|
|
path : this.url_access_token,
|
|
parameters: {
|
|
"oauth_token" : oauth_token,
|
|
"oauth_verifier" : oauth_verifier
|
|
},
|
|
signatures: {
|
|
consumer_key : this.consumer_key,
|
|
shared_secret : this.consumer_secret,
|
|
oauth_secret : this.getTokenSecret(this.oauth_scope)
|
|
}
|
|
});
|
|
|
|
var onToken = ChromeExOAuth.bind(this.onAccessToken, this, callback);
|
|
ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Called when an access token has been returned. Stores the access token and
|
|
* access token secret for later use and sends them to the supplied callback.
|
|
* @param {Function} callback The function to call once the token is obtained.
|
|
* This callback will be passed the following arguments:
|
|
* token {String} The OAuth access token.
|
|
* secret {String} The OAuth access token secret.
|
|
* @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the
|
|
* access token.
|
|
*/
|
|
ChromeExOAuth.prototype.onAccessToken = function(callback, xhr) {
|
|
if (xhr.readyState == 4) {
|
|
var bg = chrome.extension.getBackgroundPage();
|
|
if (xhr.status == 200) {
|
|
var params = ChromeExOAuth.formDecode(xhr.responseText);
|
|
var token = params["oauth_token"];
|
|
var secret = params["oauth_token_secret"];
|
|
this.setToken(token);
|
|
this.setTokenSecret(secret);
|
|
bg.chromeExOAuthRequestingAccess = false;
|
|
callback(token, secret);
|
|
} else {
|
|
bg.chromeExOAuthRequestingAccess = false;
|
|
throw new Error("Fetching access token failed with status " + xhr.status);
|
|
}
|
|
}
|
|
}; |