OLD | NEW |
| (Empty) |
1 /** | |
2 * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this | |
3 * source code is governed by a BSD-style license that can be found in the | |
4 * LICENSE file. | |
5 */ | |
6 | |
7 /** | |
8 * Constructor - no need to invoke directly, call initBackgroundPage instead. | |
9 * @constructor | |
10 * @param {String} url_request_token The OAuth request token URL. | |
11 * @param {String} url_auth_token The OAuth authorize token URL. | |
12 * @param {String} url_access_token The OAuth access token URL. | |
13 * @param {String} consumer_key The OAuth consumer key. | |
14 * @param {String} consumer_secret The OAuth consumer secret. | |
15 * @param {String} oauth_scope The OAuth scope parameter. | |
16 * @param {Object} opt_args Optional arguments. Recognized parameters: | |
17 * "app_name" {String} Name of the current application | |
18 * "callback_page" {String} If you renamed chrome_ex_oauth.html, the name | |
19 * this file was renamed to. | |
20 */ | |
21 function ChromeExOAuth(url_request_token, url_auth_token, url_access_token, | |
22 consumer_key, consumer_secret, oauth_scope, opt_args) { | |
23 this.url_request_token = url_request_token; | |
24 this.url_auth_token = url_auth_token; | |
25 this.url_access_token = url_access_token; | |
26 this.consumer_key = consumer_key; | |
27 this.consumer_secret = consumer_secret; | |
28 this.oauth_scope = oauth_scope; | |
29 this.app_name = opt_args && opt_args['app_name'] || | |
30 "ChromeExOAuth Library"; | |
31 this.key_token = "oauth_token"; | |
32 this.key_token_secret = "oauth_token_secret"; | |
33 this.callback_page = opt_args && opt_args['callback_page'] || | |
34 "chrome_ex_oauth.html"; | |
35 this.auth_params = {}; | |
36 if (opt_args && opt_args['auth_params']) { | |
37 for (key in opt_args['auth_params']) { | |
38 if (opt_args['auth_params'].hasOwnProperty(key)) { | |
39 this.auth_params[key] = opt_args['auth_params'][key]; | |
40 } | |
41 } | |
42 } | |
43 }; | |
44 | |
45 /******************************************************************************* | |
46 * PUBLIC API METHODS | |
47 * Call these from your background page. | |
48 ******************************************************************************/ | |
49 | |
50 /** | |
51 * Initializes the OAuth helper from the background page. You must call this | |
52 * before attempting to make any OAuth calls. | |
53 * @param {Object} oauth_config Configuration parameters in a JavaScript object. | |
54 * The following parameters are recognized: | |
55 * "request_url" {String} OAuth request token URL. | |
56 * "authorize_url" {String} OAuth authorize token URL. | |
57 * "access_url" {String} OAuth access token URL. | |
58 * "consumer_key" {String} OAuth consumer key. | |
59 * "consumer_secret" {String} OAuth consumer secret. | |
60 * "scope" {String} OAuth access scope. | |
61 * "app_name" {String} Application name. | |
62 * "auth_params" {Object} Additional parameters to pass to the | |
63 * Authorization token URL. For an example, 'hd', 'hl', 'btmpl': | |
64 * http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth | |
65 * @return {ChromeExOAuth} An initialized ChromeExOAuth object. | |
66 */ | |
67 ChromeExOAuth.initBackgroundPage = function(oauth_config) { | |
68 window.chromeExOAuthConfig = oauth_config; | |
69 window.chromeExOAuth = ChromeExOAuth.fromConfig(oauth_config); | |
70 window.chromeExOAuthRedirectStarted = false; | |
71 window.chromeExOAuthRequestingAccess = false; | |
72 | |
73 var url_match = chrome.extension.getURL(window.chromeExOAuth.callback_page); | |
74 var tabs = {}; | |
75 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { | |
76 if (changeInfo.url && | |
77 changeInfo.url.substr(0, url_match.length) === url_match && | |
78 changeInfo.url != tabs[tabId] && | |
79 window.chromeExOAuthRequestingAccess == false) { | |
80 chrome.tabs.create({ 'url' : changeInfo.url }, function(tab) { | |
81 tabs[tab.id] = tab.url; | |
82 chrome.tabs.remove(tabId); | |
83 }); | |
84 } | |
85 }); | |
86 | |
87 return window.chromeExOAuth; | |
88 }; | |
89 | |
90 /** | |
91 * Authorizes the current user with the configued API. You must call this | |
92 * before calling sendSignedRequest. | |
93 * @param {Function} callback A function to call once an access token has | |
94 * been obtained. This callback will be passed the following arguments: | |
95 * token {String} The OAuth access token. | |
96 * secret {String} The OAuth access token secret. | |
97 */ | |
98 ChromeExOAuth.prototype.authorize = function(callback) { | |
99 if (this.hasToken()) { | |
100 callback(this.getToken(), this.getTokenSecret()); | |
101 } else { | |
102 window.chromeExOAuthOnAuthorize = function(token, secret) { | |
103 callback(token, secret); | |
104 }; | |
105 chrome.tabs.create({ 'url' :chrome.extension.getURL(this.callback_page) }); | |
106 } | |
107 }; | |
108 | |
109 /** | |
110 * Clears any OAuth tokens stored for this configuration. Effectively a | |
111 * "logout" of the configured OAuth API. | |
112 */ | |
113 ChromeExOAuth.prototype.clearTokens = function() { | |
114 delete localStorage[this.key_token + encodeURI(this.oauth_scope)]; | |
115 delete localStorage[this.key_token_secret + encodeURI(this.oauth_scope)]; | |
116 }; | |
117 | |
118 /** | |
119 * Returns whether a token is currently stored for this configuration. | |
120 * Effectively a check to see whether the current user is "logged in" to | |
121 * the configured OAuth API. | |
122 * @return {Boolean} True if an access token exists. | |
123 */ | |
124 ChromeExOAuth.prototype.hasToken = function() { | |
125 return !!this.getToken(); | |
126 }; | |
127 | |
128 /** | |
129 * Makes an OAuth-signed HTTP request with the currently authorized tokens. | |
130 * @param {String} url The URL to send the request to. Querystring parameters | |
131 * should be omitted. | |
132 * @param {Function} callback A function to be called once the request is | |
133 * completed. This callback will be passed the following arguments: | |
134 * responseText {String} The text response. | |
135 * xhr {XMLHttpRequest} The XMLHttpRequest object which was used to | |
136 * send the request. Useful if you need to check response status | |
137 * code, etc. | |
138 * @param {Object} opt_params Additional parameters to configure the request. | |
139 * The following parameters are accepted: | |
140 * "method" {String} The HTTP method to use. Defaults to "GET". | |
141 * "body" {String} A request body to send. Defaults to null. | |
142 * "parameters" {Object} Query parameters to include in the request. | |
143 * "headers" {Object} Additional headers to include in the request. | |
144 */ | |
145 ChromeExOAuth.prototype.sendSignedRequest = function(url, callback, | |
146 opt_params) { | |
147 var method = opt_params && opt_params['method'] || 'GET'; | |
148 var body = opt_params && opt_params['body'] || null; | |
149 var params = opt_params && opt_params['parameters'] || {}; | |
150 var headers = opt_params && opt_params['headers'] || {}; | |
151 | |
152 var signedUrl = this.signURL(url, method, params); | |
153 | |
154 ChromeExOAuth.sendRequest(method, signedUrl, headers, body, function (xhr) { | |
155 if (xhr.readyState == 4) { | |
156 callback(xhr.responseText, xhr); | |
157 } | |
158 }); | |
159 }; | |
160 | |
161 /** | |
162 * Adds the required OAuth parameters to the given url and returns the | |
163 * result. Useful if you need a signed url but don't want to make an XHR | |
164 * request. | |
165 * @param {String} method The http method to use. | |
166 * @param {String} url The base url of the resource you are querying. | |
167 * @param {Object} opt_params Query parameters to include in the request. | |
168 * @return {String} The base url plus any query params plus any OAuth params. | |
169 */ | |
170 ChromeExOAuth.prototype.signURL = function(url, method, opt_params) { | |
171 var token = this.getToken(); | |
172 var secret = this.getTokenSecret(); | |
173 if (!token || !secret) { | |
174 throw new Error("No oauth token or token secret"); | |
175 } | |
176 | |
177 var params = opt_params || {}; | |
178 | |
179 var result = OAuthSimple().sign({ | |
180 action : method, | |
181 path : url, | |
182 parameters : params, | |
183 signatures: { | |
184 consumer_key : this.consumer_key, | |
185 shared_secret : this.consumer_secret, | |
186 oauth_secret : secret, | |
187 oauth_token: token | |
188 } | |
189 }); | |
190 | |
191 return result.signed_url; | |
192 }; | |
193 | |
194 /** | |
195 * Generates the Authorization header based on the oauth parameters. | |
196 * @param {String} url The base url of the resource you are querying. | |
197 * @param {Object} opt_params Query parameters to include in the request. | |
198 * @return {String} An Authorization header containing the oauth_* params. | |
199 */ | |
200 ChromeExOAuth.prototype.getAuthorizationHeader = function(url, method, | |
201 opt_params) { | |
202 var token = this.getToken(); | |
203 var secret = this.getTokenSecret(); | |
204 if (!token || !secret) { | |
205 throw new Error("No oauth token or token secret"); | |
206 } | |
207 | |
208 var params = opt_params || {}; | |
209 | |
210 return OAuthSimple().getHeaderString({ | |
211 action: method, | |
212 path : url, | |
213 parameters : params, | |
214 signatures: { | |
215 consumer_key : this.consumer_key, | |
216 shared_secret : this.consumer_secret, | |
217 oauth_secret : secret, | |
218 oauth_token: token | |
219 } | |
220 }); | |
221 }; | |
222 | |
223 /******************************************************************************* | |
224 * PRIVATE API METHODS | |
225 * Used by the library. There should be no need to call these methods directly. | |
226 ******************************************************************************/ | |
227 | |
228 /** | |
229 * Creates a new ChromeExOAuth object from the supplied configuration object. | |
230 * @param {Object} oauth_config Configuration parameters in a JavaScript object. | |
231 * The following parameters are recognized: | |
232 * "request_url" {String} OAuth request token URL. | |
233 * "authorize_url" {String} OAuth authorize token URL. | |
234 * "access_url" {String} OAuth access token URL. | |
235 * "consumer_key" {String} OAuth consumer key. | |
236 * "consumer_secret" {String} OAuth consumer secret. | |
237 * "scope" {String} OAuth access scope. | |
238 * "app_name" {String} Application name. | |
239 * "auth_params" {Object} Additional parameters to pass to the | |
240 * Authorization token URL. For an example, 'hd', 'hl', 'btmpl': | |
241 * http://code.google.com/apis/accounts/docs/OAuth_ref.html#GetAuth | |
242 * @return {ChromeExOAuth} An initialized ChromeExOAuth object. | |
243 */ | |
244 ChromeExOAuth.fromConfig = function(oauth_config) { | |
245 return new ChromeExOAuth( | |
246 oauth_config['request_url'], | |
247 oauth_config['authorize_url'], | |
248 oauth_config['access_url'], | |
249 oauth_config['consumer_key'], | |
250 oauth_config['consumer_secret'], | |
251 oauth_config['scope'], | |
252 { | |
253 'app_name' : oauth_config['app_name'], | |
254 'auth_params' : oauth_config['auth_params'] | |
255 } | |
256 ); | |
257 }; | |
258 | |
259 /** | |
260 * Initializes chrome_ex_oauth.html and redirects the page if needed to start | |
261 * the OAuth flow. Once an access token is obtained, this function closes | |
262 * chrome_ex_oauth.html. | |
263 */ | |
264 ChromeExOAuth.initCallbackPage = function() { | |
265 var background_page = chrome.extension.getBackgroundPage(); | |
266 var oauth_config = background_page.chromeExOAuthConfig; | |
267 var oauth = ChromeExOAuth.fromConfig(oauth_config); | |
268 background_page.chromeExOAuthRedirectStarted = true; | |
269 oauth.initOAuthFlow(function (token, secret) { | |
270 background_page.chromeExOAuthOnAuthorize(token, secret); | |
271 background_page.chromeExOAuthRedirectStarted = false; | |
272 chrome.tabs.getSelected(null, function (tab) { | |
273 chrome.tabs.remove(tab.id); | |
274 }); | |
275 }); | |
276 }; | |
277 | |
278 /** | |
279 * Sends an HTTP request. Convenience wrapper for XMLHttpRequest calls. | |
280 * @param {String} method The HTTP method to use. | |
281 * @param {String} url The URL to send the request to. | |
282 * @param {Object} headers Optional request headers in key/value format. | |
283 * @param {String} body Optional body content. | |
284 * @param {Function} callback Function to call when the XMLHttpRequest's | |
285 * ready state changes. See documentation for XMLHttpRequest's | |
286 * onreadystatechange handler for more information. | |
287 */ | |
288 ChromeExOAuth.sendRequest = function(method, url, headers, body, callback) { | |
289 var xhr = new XMLHttpRequest(); | |
290 xhr.onreadystatechange = function(data) { | |
291 callback(xhr, data); | |
292 } | |
293 xhr.open(method, url, true); | |
294 if (headers) { | |
295 for (var header in headers) { | |
296 if (headers.hasOwnProperty(header)) { | |
297 xhr.setRequestHeader(header, headers[header]); | |
298 } | |
299 } | |
300 } | |
301 xhr.send(body); | |
302 }; | |
303 | |
304 /** | |
305 * Decodes a URL-encoded string into key/value pairs. | |
306 * @param {String} encoded An URL-encoded string. | |
307 * @return {Object} An object representing the decoded key/value pairs found | |
308 * in the encoded string. | |
309 */ | |
310 ChromeExOAuth.formDecode = function(encoded) { | |
311 var params = encoded.split("&"); | |
312 var decoded = {}; | |
313 for (var i = 0, param; param = params[i]; i++) { | |
314 var keyval = param.split("="); | |
315 if (keyval.length == 2) { | |
316 var key = ChromeExOAuth.fromRfc3986(keyval[0]); | |
317 var val = ChromeExOAuth.fromRfc3986(keyval[1]); | |
318 decoded[key] = val; | |
319 } | |
320 } | |
321 return decoded; | |
322 }; | |
323 | |
324 /** | |
325 * Returns the current window's querystring decoded into key/value pairs. | |
326 * @return {Object} A object representing any key/value pairs found in the | |
327 * current window's querystring. | |
328 */ | |
329 ChromeExOAuth.getQueryStringParams = function() { | |
330 var urlparts = window.location.href.split("?"); | |
331 if (urlparts.length >= 2) { | |
332 var querystring = urlparts.slice(1).join("?"); | |
333 return ChromeExOAuth.formDecode(querystring); | |
334 } | |
335 return {}; | |
336 }; | |
337 | |
338 /** | |
339 * Binds a function call to a specific object. This function will also take | |
340 * a variable number of additional arguments which will be prepended to the | |
341 * arguments passed to the bound function when it is called. | |
342 * @param {Function} func The function to bind. | |
343 * @param {Object} obj The object to bind to the function's "this". | |
344 * @return {Function} A closure that will call the bound function. | |
345 */ | |
346 ChromeExOAuth.bind = function(func, obj) { | |
347 var newargs = Array.prototype.slice.call(arguments).slice(2); | |
348 return function() { | |
349 var combinedargs = newargs.concat(Array.prototype.slice.call(arguments)); | |
350 func.apply(obj, combinedargs); | |
351 }; | |
352 }; | |
353 | |
354 /** | |
355 * Encodes a value according to the RFC3986 specification. | |
356 * @param {String} val The string to encode. | |
357 */ | |
358 ChromeExOAuth.toRfc3986 = function(val){ | |
359 return encodeURIComponent(val) | |
360 .replace(/\!/g, "%21") | |
361 .replace(/\*/g, "%2A") | |
362 .replace(/'/g, "%27") | |
363 .replace(/\(/g, "%28") | |
364 .replace(/\)/g, "%29"); | |
365 }; | |
366 | |
367 /** | |
368 * Decodes a string that has been encoded according to RFC3986. | |
369 * @param {String} val The string to decode. | |
370 */ | |
371 ChromeExOAuth.fromRfc3986 = function(val){ | |
372 var tmp = val | |
373 .replace(/%21/g, "!") | |
374 .replace(/%2A/g, "*") | |
375 .replace(/%27/g, "'") | |
376 .replace(/%28/g, "(") | |
377 .replace(/%29/g, ")"); | |
378 return decodeURIComponent(tmp); | |
379 }; | |
380 | |
381 /** | |
382 * Adds a key/value parameter to the supplied URL. | |
383 * @param {String} url An URL which may or may not contain querystring values. | |
384 * @param {String} key A key | |
385 * @param {String} value A value | |
386 * @return {String} The URL with URL-encoded versions of the key and value | |
387 * appended, prefixing them with "&" or "?" as needed. | |
388 */ | |
389 ChromeExOAuth.addURLParam = function(url, key, value) { | |
390 var sep = (url.indexOf('?') >= 0) ? "&" : "?"; | |
391 return url + sep + | |
392 ChromeExOAuth.toRfc3986(key) + "=" + ChromeExOAuth.toRfc3986(value); | |
393 }; | |
394 | |
395 /** | |
396 * Stores an OAuth token for the configured scope. | |
397 * @param {String} token The token to store. | |
398 */ | |
399 ChromeExOAuth.prototype.setToken = function(token) { | |
400 localStorage[this.key_token + encodeURI(this.oauth_scope)] = token; | |
401 }; | |
402 | |
403 /** | |
404 * Retrieves any stored token for the configured scope. | |
405 * @return {String} The stored token. | |
406 */ | |
407 ChromeExOAuth.prototype.getToken = function() { | |
408 return localStorage[this.key_token + encodeURI(this.oauth_scope)]; | |
409 }; | |
410 | |
411 /** | |
412 * Stores an OAuth token secret for the configured scope. | |
413 * @param {String} secret The secret to store. | |
414 */ | |
415 ChromeExOAuth.prototype.setTokenSecret = function(secret) { | |
416 localStorage[this.key_token_secret + encodeURI(this.oauth_scope)] = secret; | |
417 }; | |
418 | |
419 /** | |
420 * Retrieves any stored secret for the configured scope. | |
421 * @return {String} The stored secret. | |
422 */ | |
423 ChromeExOAuth.prototype.getTokenSecret = function() { | |
424 return localStorage[this.key_token_secret + encodeURI(this.oauth_scope)]; | |
425 }; | |
426 | |
427 /** | |
428 * Starts an OAuth authorization flow for the current page. If a token exists, | |
429 * no redirect is needed and the supplied callback is called immediately. | |
430 * If this method detects that a redirect has finished, it grabs the | |
431 * appropriate OAuth parameters from the URL and attempts to retrieve an | |
432 * access token. If no token exists and no redirect has happened, then | |
433 * an access token is requested and the page is ultimately redirected. | |
434 * @param {Function} callback The function to call once the flow has finished. | |
435 * This callback will be passed the following arguments: | |
436 * token {String} The OAuth access token. | |
437 * secret {String} The OAuth access token secret. | |
438 */ | |
439 ChromeExOAuth.prototype.initOAuthFlow = function(callback) { | |
440 if (!this.hasToken()) { | |
441 var params = ChromeExOAuth.getQueryStringParams(); | |
442 if (params['chromeexoauthcallback'] == 'true') { | |
443 var oauth_token = params['oauth_token']; | |
444 var oauth_verifier = params['oauth_verifier'] | |
445 this.getAccessToken(oauth_token, oauth_verifier, callback); | |
446 } else { | |
447 var request_params = { | |
448 'url_callback_param' : 'chromeexoauthcallback' | |
449 } | |
450 this.getRequestToken(function(url) { | |
451 window.location.href = url; | |
452 }, request_params); | |
453 } | |
454 } else { | |
455 callback(this.getToken(), this.getTokenSecret()); | |
456 } | |
457 }; | |
458 | |
459 /** | |
460 * Requests an OAuth request token. | |
461 * @param {Function} callback Function to call once the authorize URL is | |
462 * calculated. This callback will be passed the following arguments: | |
463 * url {String} The URL the user must be redirected to in order to | |
464 * approve the token. | |
465 * @param {Object} opt_args Optional arguments. The following parameters | |
466 * are accepted: | |
467 * "url_callback" {String} The URL the OAuth provider will redirect to. | |
468 * "url_callback_param" {String} A parameter to include in the callback | |
469 * URL in order to indicate to this library that a redirect has | |
470 * taken place. | |
471 */ | |
472 ChromeExOAuth.prototype.getRequestToken = function(callback, opt_args) { | |
473 if (typeof callback !== "function") { | |
474 throw new Error("Specified callback must be a function."); | |
475 } | |
476 var url = opt_args && opt_args['url_callback'] || | |
477 window && window.top && window.top.location && | |
478 window.top.location.href; | |
479 | |
480 var url_param = opt_args && opt_args['url_callback_param'] || | |
481 "chromeexoauthcallback"; | |
482 var url_callback = ChromeExOAuth.addURLParam(url, url_param, "true"); | |
483 | |
484 var result = OAuthSimple().sign({ | |
485 path : this.url_request_token, | |
486 parameters: { | |
487 "xoauth_displayname" : this.app_name, | |
488 "scope" : this.oauth_scope, | |
489 "oauth_callback" : url_callback | |
490 }, | |
491 signatures: { | |
492 consumer_key : this.consumer_key, | |
493 shared_secret : this.consumer_secret | |
494 } | |
495 }); | |
496 var onToken = ChromeExOAuth.bind(this.onRequestToken, this, callback); | |
497 ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken); | |
498 }; | |
499 | |
500 /** | |
501 * Called when a request token has been returned. Stores the request token | |
502 * secret for later use and sends the authorization url to the supplied | |
503 * callback (for redirecting the user). | |
504 * @param {Function} callback Function to call once the authorize URL is | |
505 * calculated. This callback will be passed the following arguments: | |
506 * url {String} The URL the user must be redirected to in order to | |
507 * approve the token. | |
508 * @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the | |
509 * request token. | |
510 */ | |
511 ChromeExOAuth.prototype.onRequestToken = function(callback, xhr) { | |
512 if (xhr.readyState == 4) { | |
513 if (xhr.status == 200) { | |
514 var params = ChromeExOAuth.formDecode(xhr.responseText); | |
515 var token = params['oauth_token']; | |
516 this.setTokenSecret(params['oauth_token_secret']); | |
517 var url = ChromeExOAuth.addURLParam(this.url_auth_token, | |
518 "oauth_token", token); | |
519 for (var key in this.auth_params) { | |
520 if (this.auth_params.hasOwnProperty(key)) { | |
521 url = ChromeExOAuth.addURLParam(url, key, this.auth_params[key]); | |
522 } | |
523 } | |
524 callback(url); | |
525 } else { | |
526 throw new Error("Fetching request token failed. Status " + xhr.status); | |
527 } | |
528 } | |
529 }; | |
530 | |
531 /** | |
532 * Requests an OAuth access token. | |
533 * @param {String} oauth_token The OAuth request token. | |
534 * @param {String} oauth_verifier The OAuth token verifier. | |
535 * @param {Function} callback The function to call once the token is obtained. | |
536 * This callback will be passed the following arguments: | |
537 * token {String} The OAuth access token. | |
538 * secret {String} The OAuth access token secret. | |
539 */ | |
540 ChromeExOAuth.prototype.getAccessToken = function(oauth_token, oauth_verifier, | |
541 callback) { | |
542 if (typeof callback !== "function") { | |
543 throw new Error("Specified callback must be a function."); | |
544 } | |
545 var bg = chrome.extension.getBackgroundPage(); | |
546 if (bg.chromeExOAuthRequestingAccess == false) { | |
547 bg.chromeExOAuthRequestingAccess = true; | |
548 | |
549 var result = OAuthSimple().sign({ | |
550 path : this.url_access_token, | |
551 parameters: { | |
552 "oauth_token" : oauth_token, | |
553 "oauth_verifier" : oauth_verifier | |
554 }, | |
555 signatures: { | |
556 consumer_key : this.consumer_key, | |
557 shared_secret : this.consumer_secret, | |
558 oauth_secret : this.getTokenSecret(this.oauth_scope) | |
559 } | |
560 }); | |
561 | |
562 var onToken = ChromeExOAuth.bind(this.onAccessToken, this, callback); | |
563 ChromeExOAuth.sendRequest("GET", result.signed_url, null, null, onToken); | |
564 } | |
565 }; | |
566 | |
567 /** | |
568 * Called when an access token has been returned. Stores the access token and | |
569 * access token secret for later use and sends them to the supplied callback. | |
570 * @param {Function} callback The function to call once the token is obtained. | |
571 * This callback will be passed the following arguments: | |
572 * token {String} The OAuth access token. | |
573 * secret {String} The OAuth access token secret. | |
574 * @param {XMLHttpRequest} xhr The XMLHttpRequest object used to fetch the | |
575 * access token. | |
576 */ | |
577 ChromeExOAuth.prototype.onAccessToken = function(callback, xhr) { | |
578 if (xhr.readyState == 4) { | |
579 var bg = chrome.extension.getBackgroundPage(); | |
580 if (xhr.status == 200) { | |
581 var params = ChromeExOAuth.formDecode(xhr.responseText); | |
582 var token = params["oauth_token"]; | |
583 var secret = params["oauth_token_secret"]; | |
584 this.setToken(token); | |
585 this.setTokenSecret(secret); | |
586 bg.chromeExOAuthRequestingAccess = false; | |
587 callback(token, secret); | |
588 } else { | |
589 bg.chromeExOAuthRequestingAccess = false; | |
590 throw new Error("Fetching access token failed with status " + xhr.status); | |
591 } | |
592 } | |
593 }; | |
OLD | NEW |