OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * OAuth2 class that handles retrieval/storage of an OAuth2 token. | 7 * OAuth2 class that handles retrieval/storage of an OAuth2 token. |
8 * | 8 * |
9 * Uses a content script to trampoline the OAuth redirect page back into the | 9 * Uses a content script to trampoline the OAuth redirect page back into the |
10 * extension context. This works around the lack of native support for | 10 * extension context. This works around the lack of native support for |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 remoting.OAuth2.prototype.isAuthenticated = function() { | 77 remoting.OAuth2.prototype.isAuthenticated = function() { |
78 if (this.getRefreshToken()) { | 78 if (this.getRefreshToken()) { |
79 return true; | 79 return true; |
80 } | 80 } |
81 return false; | 81 return false; |
82 }; | 82 }; |
83 | 83 |
84 /** | 84 /** |
85 * Remove the cached auth token, if any. | 85 * Remove the cached auth token, if any. |
86 * | 86 * |
87 * @param {function():void=} opt_onDone Completion callback. | 87 * @return {!Promise<null>} A promise resolved with the operation completes. |
88 * @return {void} Nothing. | |
89 */ | 88 */ |
90 remoting.OAuth2.prototype.removeCachedAuthToken = function(opt_onDone) { | 89 remoting.OAuth2.prototype.removeCachedAuthToken = function() { |
91 window.localStorage.removeItem(this.KEY_EMAIL_); | 90 window.localStorage.removeItem(this.KEY_EMAIL_); |
92 window.localStorage.removeItem(this.KEY_FULLNAME_); | 91 window.localStorage.removeItem(this.KEY_FULLNAME_); |
93 this.clearAccessToken_(); | 92 this.clearAccessToken_(); |
94 this.clearRefreshToken_(); | 93 this.clearRefreshToken_(); |
95 if (opt_onDone) { | 94 return Promise.resolve(null); |
96 opt_onDone(); | |
97 } | |
98 }; | 95 }; |
99 | 96 |
100 /** | 97 /** |
101 * Sets the refresh token. | 98 * Sets the refresh token. |
102 * | 99 * |
103 * @param {string} token The new refresh token. | 100 * @param {string} token The new refresh token. |
104 * @return {void} Nothing. | 101 * @return {void} Nothing. |
105 * @private | 102 * @private |
106 */ | 103 */ |
107 remoting.OAuth2.prototype.setRefreshToken_ = function(token) { | 104 remoting.OAuth2.prototype.setRefreshToken_ = function(token) { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 '%c/opt/google/chrome-remote-desktop/start-host' + | 343 '%c/opt/google/chrome-remote-desktop/start-host' + |
347 ' --code=' + code + | 344 ' --code=' + code + |
348 ' --redirect-url=' + redirectUri + | 345 ' --redirect-url=' + redirectUri + |
349 ' --name=$HOSTNAME', 'font-weight: bold;'); | 346 ' --name=$HOSTNAME', 'font-weight: bold;'); |
350 } | 347 } |
351 }; | 348 }; |
352 this.getAuthorizationCode(onAuthorizationCode); | 349 this.getAuthorizationCode(onAuthorizationCode); |
353 }; | 350 }; |
354 | 351 |
355 /** | 352 /** |
356 * Call a function with an access token, refreshing it first if necessary. | 353 * Get an access token, refreshing it first if necessary. The access |
357 * The access token will remain valid for at least 2 minutes. | 354 * token will remain valid for at least 2 minutes. |
358 * | 355 * |
359 * @param {function(string):void} onOk Function to invoke with access token if | 356 * @return {!Promise<string>} A promise resolved the an access token or |
360 * an access token was successfully retrieved. | 357 * rejected with a remoting.Error. |
361 * @param {function(remoting.Error):void} onError Function to invoke with an | |
362 * error code on failure. | |
363 * @return {void} Nothing. | |
364 */ | 358 */ |
365 remoting.OAuth2.prototype.callWithToken = function(onOk, onError) { | 359 remoting.OAuth2.prototype.getToken = function() { |
366 var refreshToken = this.getRefreshToken(); | 360 /** @const */ |
367 if (refreshToken) { | 361 var that = this; |
368 if (this.needsNewAccessToken_()) { | 362 |
369 remoting.oauth2Api.refreshAccessToken( | 363 return new Promise(function(resolve, reject) { |
370 this.onAccessToken_.bind(this, onOk), onError, | 364 var refreshToken = that.getRefreshToken(); |
371 this.getClientId_(), this.getClientSecret_(), | 365 if (refreshToken) { |
372 refreshToken); | 366 if (that.needsNewAccessToken_()) { |
| 367 remoting.oauth2Api.refreshAccessToken( |
| 368 that.onAccessToken_.bind(that, resolve), reject, |
| 369 that.getClientId_(), that.getClientSecret_(), |
| 370 refreshToken); |
| 371 } else { |
| 372 resolve(that.getAccessTokenInternal_()['token']); |
| 373 } |
373 } else { | 374 } else { |
374 onOk(this.getAccessTokenInternal_()['token']); | 375 reject(remoting.Error.NOT_AUTHENTICATED); |
375 } | 376 } |
376 } else { | 377 }); |
377 onError(remoting.Error.NOT_AUTHENTICATED); | |
378 } | |
379 }; | 378 }; |
380 | 379 |
381 /** | 380 /** |
382 * Get the user's email address. | 381 * Get the user's email address. |
383 * | 382 * |
384 * @param {function(string):void} onOk Callback invoked when the email | 383 * @return {!Promise<string>} Promise resolved with the user's email |
385 * address is available. | 384 * address or rejected with a remoting.Error. |
386 * @param {function(remoting.Error):void} onError Callback invoked if an | |
387 * error occurs. | |
388 * @return {void} Nothing. | |
389 */ | 385 */ |
390 remoting.OAuth2.prototype.getEmail = function(onOk, onError) { | 386 remoting.OAuth2.prototype.getEmail = function() { |
391 var cached = window.localStorage.getItem(this.KEY_EMAIL_); | 387 var cached = window.localStorage.getItem(this.KEY_EMAIL_); |
392 if (typeof cached == 'string') { | 388 if (typeof cached == 'string') { |
393 onOk(cached); | 389 return Promise.resolve(cached); |
394 return; | |
395 } | 390 } |
396 /** @type {remoting.OAuth2} */ | 391 /** @type {remoting.OAuth2} */ |
397 var that = this; | 392 var that = this; |
398 /** @param {string} email */ | |
399 var onResponse = function(email) { | |
400 window.localStorage.setItem(that.KEY_EMAIL_, email); | |
401 window.localStorage.setItem(that.KEY_FULLNAME_, ''); | |
402 onOk(email); | |
403 }; | |
404 | 393 |
405 this.callWithToken( | 394 return new Promise(function(resolve, reject) { |
406 remoting.oauth2Api.getEmail.bind(remoting.oauth2Api, onResponse, onError), | 395 /** @param {string} email */ |
407 onError); | 396 var onResponse = function(email) { |
| 397 window.localStorage.setItem(that.KEY_EMAIL_, email); |
| 398 window.localStorage.setItem(that.KEY_FULLNAME_, ''); |
| 399 resolve(email); |
| 400 }; |
| 401 |
| 402 that.getToken().then( |
| 403 remoting.oauth2Api.getEmail.bind( |
| 404 remoting.oauth2Api, onResponse, reject), |
| 405 reject); |
| 406 }); |
408 }; | 407 }; |
409 | 408 |
410 /** | 409 /** |
411 * Get the user's email address and full name. | 410 * Get the user's email address and full name. |
412 * | 411 * |
413 * @param {function(string,string):void} onOk Callback invoked when the user's | 412 * @return {!Promise<{email: string, name: string}>} Promise |
414 * email address and full name are available. | 413 * resolved with the user's email address and full name, or rejected |
415 * @param {function(remoting.Error):void} onError Callback invoked if an | 414 * with a remoting.Error. |
416 * error occurs. | |
417 * @return {void} Nothing. | |
418 */ | 415 */ |
419 remoting.OAuth2.prototype.getUserInfo = function(onOk, onError) { | 416 remoting.OAuth2.prototype.getUserInfo = function() { |
420 var cachedEmail = window.localStorage.getItem(this.KEY_EMAIL_); | 417 var cachedEmail = window.localStorage.getItem(this.KEY_EMAIL_); |
421 var cachedName = window.localStorage.getItem(this.KEY_FULLNAME_); | 418 var cachedName = window.localStorage.getItem(this.KEY_FULLNAME_); |
422 if (typeof cachedEmail == 'string' && typeof cachedName == 'string') { | 419 if (typeof cachedEmail == 'string' && typeof cachedName == 'string') { |
423 onOk(cachedEmail, cachedName); | 420 /** |
424 return; | 421 * The temp variable is needed to work around a compiler bug. |
| 422 * @type {{email: string, name: string}} |
| 423 */ |
| 424 var result = {email: cachedEmail, name: cachedName}; |
| 425 return Promise.resolve(result); |
425 } | 426 } |
| 427 |
426 /** @type {remoting.OAuth2} */ | 428 /** @type {remoting.OAuth2} */ |
427 var that = this; | 429 var that = this; |
428 /** | |
429 * @param {string} email | |
430 * @param {string} name | |
431 */ | |
432 var onResponse = function(email, name) { | |
433 window.localStorage.setItem(that.KEY_EMAIL_, email); | |
434 window.localStorage.setItem(that.KEY_FULLNAME_, name); | |
435 onOk(email, name); | |
436 }; | |
437 | 430 |
438 this.callWithToken( | 431 return new Promise(function(resolve, reject) { |
439 remoting.oauth2Api.getUserInfo.bind( | 432 /** |
440 remoting.oauth2Api, onResponse, onError), | 433 * @param {string} email |
441 onError); | 434 * @param {string} name |
| 435 */ |
| 436 var onResponse = function(email, name) { |
| 437 window.localStorage.setItem(that.KEY_EMAIL_, email); |
| 438 window.localStorage.setItem(that.KEY_FULLNAME_, name); |
| 439 resolve({email: email, name: name}); |
| 440 }; |
| 441 |
| 442 that.getToken().then( |
| 443 remoting.oauth2Api.getUserInfo.bind( |
| 444 remoting.oauth2Api, onResponse, reject), |
| 445 reject); |
| 446 }); |
442 }; | 447 }; |
443 | 448 |
444 /** | 449 /** |
445 * If the user's email address is cached, return it, otherwise return null. | 450 * If the user's email address is cached, return it, otherwise return null. |
446 * | 451 * |
447 * @return {?string} The email address, if it has been cached by a previous call | 452 * @return {?string} The email address, if it has been cached by a previous call |
448 * to getEmail or getUserInfo, otherwise null. | 453 * to getEmail or getUserInfo, otherwise null. |
449 */ | 454 */ |
450 remoting.OAuth2.prototype.getCachedEmail = function() { | 455 remoting.OAuth2.prototype.getCachedEmail = function() { |
451 var value = window.localStorage.getItem(this.KEY_EMAIL_); | 456 var value = window.localStorage.getItem(this.KEY_EMAIL_); |
452 if (typeof value == 'string') { | 457 if (typeof value == 'string') { |
453 return value; | 458 return value; |
454 } | 459 } |
455 return null; | 460 return null; |
456 }; | 461 }; |
457 | 462 |
458 /** | 463 /** |
459 * If the user's full name is cached, return it, otherwise return null. | 464 * If the user's full name is cached, return it, otherwise return null. |
460 * | 465 * |
461 * @return {?string} The user's full name, if it has been cached by a previous | 466 * @return {?string} The user's full name, if it has been cached by a previous |
462 * call to getUserInfo, otherwise null. | 467 * call to getUserInfo, otherwise null. |
463 */ | 468 */ |
464 remoting.OAuth2.prototype.getCachedUserFullName = function() { | 469 remoting.OAuth2.prototype.getCachedUserFullName = function() { |
465 var value = window.localStorage.getItem(this.KEY_FULLNAME_); | 470 var value = window.localStorage.getItem(this.KEY_FULLNAME_); |
466 if (typeof value == 'string') { | 471 if (typeof value == 'string') { |
467 return value; | 472 return value; |
468 } | 473 } |
469 return null; | 474 return null; |
470 }; | 475 }; |
OLD | NEW |