| 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 * Wrapper class for Chrome's identity API. | 7 * Wrapper class for Chrome's identity API. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 'use strict'; | 10 'use strict'; |
| 11 | 11 |
| 12 /** @suppress {duplicate} */ | 12 /** @suppress {duplicate} */ |
| 13 var remoting = remoting || {}; | 13 var remoting = remoting || {}; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * TODO(jamiewalch): Remove remoting.OAuth2 from this type annotation when | 16 * TODO(jamiewalch): Remove remoting.OAuth2 from this type annotation when |
| 17 * the Apps v2 work is complete. | 17 * the Apps v2 work is complete. |
| 18 * | 18 * |
| 19 * @type {remoting.Identity|remoting.OAuth2} | 19 * @type {remoting.Identity} |
| 20 */ | 20 */ |
| 21 remoting.identity = null; | 21 remoting.identity = null; |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * @param {function(function():void):void} consentCallback Callback invoked if | 24 * @param {remoting.Identity.ConsentDialog} consentDialog |
| 25 * user consent is required. The callback is passed a continuation function | |
| 26 * which must be called from an interactive event handler (e.g. "click"). | |
| 27 * @constructor | 25 * @constructor |
| 28 */ | 26 */ |
| 29 remoting.Identity = function(consentCallback) { | 27 remoting.Identity = function(consentDialog) { |
| 30 /** @private */ | 28 /** @private */ |
| 31 this.consentCallback_ = consentCallback; | 29 this.consentDialog_ = consentDialog; |
| 32 /** @type {string} @private */ | 30 /** @type {string} @private */ |
| 33 this.email_ = ''; | 31 this.email_ = ''; |
| 34 /** @type {string} @private */ | 32 /** @type {string} @private */ |
| 35 this.fullName_ = ''; | 33 this.fullName_ = ''; |
| 36 /** @type {Array.<remoting.Identity.Callbacks>} */ | 34 /** @type {Array.<remoting.Identity.Callbacks>} */ |
| 37 this.pendingCallbacks_ = []; | 35 this.pendingCallbacks_ = []; |
| 38 }; | 36 }; |
| 39 | 37 |
| 40 /** | 38 /** |
| 39 * chrome.identity.getAuthToken must be initiated from user interactions if |
| 40 * called with interactive equals true. This interface prompts a dialog for |
| 41 * the user's consent. |
| 42 * |
| 43 * @interface |
| 44 */ |
| 45 remoting.Identity.ConsentDialog = function() {}; |
| 46 |
| 47 /** |
| 48 * @return {Promise} A Promise that resolves when permission to start an |
| 49 * interactive flow is granted. |
| 50 */ |
| 51 remoting.Identity.ConsentDialog.prototype.show = function() {}; |
| 52 |
| 53 /** |
| 41 * Call a function with an access token. | 54 * Call a function with an access token. |
| 42 * | 55 * |
| 43 * @param {function(string):void} onOk Function to invoke with access token if | 56 * @param {function(string):void} onOk Function to invoke with access token if |
| 44 * an access token was successfully retrieved. | 57 * an access token was successfully retrieved. |
| 45 * @param {function(remoting.Error):void} onError Function to invoke with an | 58 * @param {function(remoting.Error):void} onError Function to invoke with an |
| 46 * error code on failure. | 59 * error code on failure. |
| 47 * @return {void} Nothing. | 60 * @return {void} Nothing. |
| 48 */ | 61 */ |
| 49 remoting.Identity.prototype.callWithToken = function(onOk, onError) { | 62 remoting.Identity.prototype.callWithToken = function(onOk, onError) { |
| 50 this.pendingCallbacks_.push(new remoting.Identity.Callbacks(onOk, onError)); | 63 this.pendingCallbacks_.push(new remoting.Identity.Callbacks(onOk, onError)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 68 /** @type {remoting.Identity} */ | 81 /** @type {remoting.Identity} */ |
| 69 var that = this; | 82 var that = this; |
| 70 | 83 |
| 71 /** | 84 /** |
| 72 * @param {string} token | 85 * @param {string} token |
| 73 */ | 86 */ |
| 74 function revokeToken(token) { | 87 function revokeToken(token) { |
| 75 chrome.identity.removeCachedAuthToken( | 88 chrome.identity.removeCachedAuthToken( |
| 76 {'token': token }, | 89 {'token': token }, |
| 77 that.callWithToken.bind(that, onOk, onError)); | 90 that.callWithToken.bind(that, onOk, onError)); |
| 78 }; | 91 } |
| 79 | 92 |
| 80 this.callWithToken(revokeToken, onError); | 93 this.callWithToken(revokeToken, onError); |
| 81 }; | 94 }; |
| 82 | 95 |
| 83 /** | 96 /** |
| 84 * Remove the cached auth token, if any. | 97 * Remove the cached auth token, if any. |
| 85 * | 98 * |
| 86 * @param {function():void} onDone Completion callback. | 99 * @param {function():void=} opt_onDone Completion callback. |
| 87 * @return {void} Nothing. | 100 * @return {void} Nothing. |
| 88 */ | 101 */ |
| 89 remoting.Identity.prototype.removeCachedAuthToken = function(onDone) { | 102 remoting.Identity.prototype.removeCachedAuthToken = function(opt_onDone) { |
| 103 var onDone = (opt_onDone) ? opt_onDone : base.doNothing; |
| 104 |
| 90 /** @param {string} token */ | 105 /** @param {string} token */ |
| 91 var onToken = function(token) { | 106 var onToken = function(token) { |
| 92 if (token) { | 107 if (token) { |
| 93 chrome.identity.removeCachedAuthToken({ 'token': token }, onDone); | 108 chrome.identity.removeCachedAuthToken({'token': token}, onDone); |
| 94 } else { | 109 } else { |
| 95 onDone(); | 110 onDone(); |
| 96 } | 111 } |
| 97 }; | 112 }; |
| 98 chrome.identity.getAuthToken({ 'interactive': false }, onToken); | 113 chrome.identity.getAuthToken({'interactive': false}, onToken); |
| 99 }; | 114 }; |
| 100 | 115 |
| 101 /** | 116 /** |
| 102 * Get the user's email address and full name. | 117 * Get the user's email address and full name. |
| 103 * The full name will be null unless the webapp has requested and been | 118 * The full name will be null unless the webapp has requested and been |
| 104 * granted the userinfo.profile permission. | 119 * granted the userinfo.profile permission. |
| 105 * | 120 * |
| 106 * @param {function(string,string):void} onOk Callback invoked when the user's | 121 * @param {function(string,string):void} onOk Callback invoked when the user's |
| 107 * email address and full name are available. | 122 * email address and full name are available. |
| 108 * @param {function(remoting.Error):void} onError Callback invoked if an | 123 * @param {function(remoting.Error):void} onError Callback invoked if an |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 console.error(error_message); | 214 console.error(error_message); |
| 200 while (this.pendingCallbacks_.length > 0) { | 215 while (this.pendingCallbacks_.length > 0) { |
| 201 var callback = /** @type {remoting.Identity.Callbacks} */ | 216 var callback = /** @type {remoting.Identity.Callbacks} */ |
| 202 (this.pendingCallbacks_.shift()); | 217 (this.pendingCallbacks_.shift()); |
| 203 callback.onError(remoting.Error.NOT_AUTHENTICATED); | 218 callback.onError(remoting.Error.NOT_AUTHENTICATED); |
| 204 } | 219 } |
| 205 return; | 220 return; |
| 206 } | 221 } |
| 207 | 222 |
| 208 // If there's no token, but we haven't yet prompted for permission, do so | 223 // If there's no token, but we haven't yet prompted for permission, do so |
| 209 // now. The consent callback is responsible for continuing the auth flow. | 224 // now. |
| 210 this.consentCallback_(this.onAuthContinue_.bind(this)); | 225 var that = this; |
| 226 this.consentDialog_.show().then(function() { |
| 227 chrome.identity.getAuthToken({'interactive': true}, |
| 228 that.onAuthComplete_.bind(that, true)); |
| 229 }); |
| 211 }; | 230 }; |
| 212 | 231 |
| 213 /** | 232 /** |
| 214 * Called in response to the user signing in to the web-app. | |
| 215 * | |
| 216 * @private | |
| 217 */ | |
| 218 remoting.Identity.prototype.onAuthContinue_ = function() { | |
| 219 chrome.identity.getAuthToken( | |
| 220 { 'interactive': true }, | |
| 221 this.onAuthComplete_.bind(this, true)); | |
| 222 }; | |
| 223 | |
| 224 /** | |
| 225 * Internal representation for pair of callWithToken callbacks. | 233 * Internal representation for pair of callWithToken callbacks. |
| 226 * | 234 * |
| 227 * @param {function(string):void} onOk | 235 * @param {function(string):void} onOk |
| 228 * @param {function(remoting.Error):void} onError | 236 * @param {function(remoting.Error):void} onError |
| 229 * @constructor | 237 * @constructor |
| 230 * @private | 238 * @private |
| 231 */ | 239 */ |
| 232 remoting.Identity.Callbacks = function(onOk, onError) { | 240 remoting.Identity.Callbacks = function(onOk, onError) { |
| 233 /** @type {function(string):void} */ | 241 /** @type {function(string):void} */ |
| 234 this.onOk = onOk; | 242 this.onOk = onOk; |
| 235 /** @type {function(remoting.Error):void} */ | 243 /** @type {function(remoting.Error):void} */ |
| 236 this.onError = onError; | 244 this.onError = onError; |
| 237 }; | 245 }; |
| 238 | 246 |
| 239 /** | 247 /** |
| 240 * Returns whether the web app has authenticated with the Google services. | 248 * Returns whether the web app has authenticated with the Google services. |
| 241 * | 249 * |
| 242 * @return {boolean} | 250 * @return {boolean} |
| 243 */ | 251 */ |
| 244 remoting.Identity.prototype.isAuthenticated = function() { | 252 remoting.Identity.prototype.isAuthenticated = function() { |
| 245 return remoting.identity.email_ !== ''; | 253 return remoting.identity.email_ !== ''; |
| 246 }; | 254 }; |
| OLD | NEW |