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|remoting.OAuth2} |
20 */ | 20 */ |
21 remoting.identity = null; | 21 remoting.identity = null; |
22 | 22 |
23 /** | 23 /** |
24 * @param {function(function():void):void} consentCallback Callback invoked if | |
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 | 24 * @constructor |
28 */ | 25 */ |
29 remoting.Identity = function(consentCallback) { | 26 remoting.Identity = function() { |
30 /** @private */ | |
31 this.consentCallback_ = consentCallback; | |
32 /** @type {string} @private */ | 27 /** @type {string} @private */ |
33 this.email_ = ''; | 28 this.email_ = ''; |
34 /** @type {string} @private */ | 29 /** @type {string} @private */ |
35 this.fullName_ = ''; | 30 this.fullName_ = ''; |
36 /** @type {Array.<remoting.Identity.Callbacks>} */ | 31 /** @type {Array.<remoting.Identity.Callbacks>} */ |
37 this.pendingCallbacks_ = []; | 32 this.pendingCallbacks_ = []; |
33 /** @type {Promise} */ | |
34 this.handleAuthFailurePromise_ = null; | |
38 }; | 35 }; |
39 | 36 |
40 /** | 37 /** |
41 * Call a function with an access token. | 38 * Call a function with an access token. |
42 * | 39 * |
43 * @param {function(string):void} onOk Function to invoke with access token if | 40 * @param {function(string):void} onOk Function to invoke with access token if |
44 * an access token was successfully retrieved. | 41 * an access token was successfully retrieved. |
45 * @param {function(remoting.Error):void} onError Function to invoke with an | 42 * @param {function(remoting.Error):void} onError Function to invoke with an |
46 * error code on failure. | 43 * error code on failure. |
47 * @return {void} Nothing. | 44 * @return {void} Nothing. |
(...skipping 20 matching lines...) Expand all Loading... | |
68 /** @type {remoting.Identity} */ | 65 /** @type {remoting.Identity} */ |
69 var that = this; | 66 var that = this; |
70 | 67 |
71 /** | 68 /** |
72 * @param {string} token | 69 * @param {string} token |
73 */ | 70 */ |
74 function revokeToken(token) { | 71 function revokeToken(token) { |
75 chrome.identity.removeCachedAuthToken( | 72 chrome.identity.removeCachedAuthToken( |
76 {'token': token }, | 73 {'token': token }, |
77 that.callWithToken.bind(that, onOk, onError)); | 74 that.callWithToken.bind(that, onOk, onError)); |
78 }; | 75 } |
79 | 76 |
80 this.callWithToken(revokeToken, onError); | 77 this.callWithToken(revokeToken, onError); |
81 }; | 78 }; |
82 | 79 |
83 /** | 80 /** |
84 * Remove the cached auth token, if any. | 81 * Removes the cached token and prompts the user to get a new one. |
85 * | 82 * @return {Promise} A promise that resolves when a new token is fetched. |
86 * @param {function():void} onDone Completion callback. | |
87 * @return {void} Nothing. | |
88 */ | 83 */ |
89 remoting.Identity.prototype.removeCachedAuthToken = function(onDone) { | 84 remoting.Identity.prototype.handleAuthFailure = function() { |
90 /** @param {string} token */ | 85 if (!this.handleAuthFailurePromise_) { |
91 var onToken = function(token) { | 86 var that = this; |
92 if (token) { | 87 |
93 chrome.identity.removeCachedAuthToken({ 'token': token }, onDone); | 88 var revokeToken = this.removeCachedAuthToken_(); |
94 } else { | 89 |
95 onDone(); | 90 // Revoke the token. |
96 } | 91 this.handleAuthFailurePromise_= revokeToken.then(function() { |
97 }; | 92 // Showing the auth dialog is required as chrome.identity.getAuthToken |
98 chrome.identity.getAuthToken({ 'interactive': false }, onToken); | 93 // must be initiated from user action when interactive is set to true. |
94 return remoting.AuthDialog.show(); | |
95 }).then(function(){ | |
96 // Fetch the new token using the identity API. | |
97 return base.Promise.as( | |
98 chrome.identity.getAuthToken, [{ 'interactive': true }]); | |
99 }).then( | |
100 /** @param {string} token */ | |
101 function(token) { | |
102 that.handleAuthFailurePromise_ = null; | |
103 if (token) { | |
104 return Promise.resolve(token); | |
105 } | |
106 return Promise.reject(remoting.Error.NOT_AUTHENTICATED); | |
107 } | |
108 ); | |
109 } | |
110 return this.handleAuthFailurePromise_; | |
99 }; | 111 }; |
100 | 112 |
101 /** | 113 /** |
114 * Removes the cached token, prompts the user to get a new one and | |
115 * relaunches the current window. | |
116 * @return {void} Nothing. | |
117 */ | |
118 remoting.Identity.prototype.handleAuthFailureAndRelaunch = function() { | |
119 this.handleAuthFailure().then(function() { | |
120 base.IPC.invoke(remoting.ActivationHandler.IPC.RELAUNCH, | |
kelvinp
2015/01/28 00:26:46
Will be fixed later after I address your feedback
| |
121 chrome.app.window.current().id); | |
122 }); | |
123 }; | |
124 | |
125 /** | |
126 * Remove the cached auth token, if any. | |
127 * | |
128 * @return {Promise} Promise that resolves when the cached token is removed. | |
129 * @private | |
130 */ | |
131 remoting.Identity.prototype.removeCachedAuthToken_ = function() { | |
132 var getToken = | |
133 base.Promise.as(chrome.identity.getAuthToken, [{'interactive': false}]); | |
134 return getToken.then( | |
135 /** @param {string} token */ | |
136 function(token) { | |
137 if (token) { | |
138 return base.Promise.as(chrome.identity.removeCachedAuthToken, | |
139 [{'token': token}]); | |
140 } else { | |
141 return Promise.resolve(); | |
142 } | |
143 }); | |
144 }; | |
145 | |
146 /** | |
102 * Get the user's email address and full name. | 147 * Get the user's email address and full name. |
103 * The full name will be null unless the webapp has requested and been | 148 * The full name will be null unless the webapp has requested and been |
104 * granted the userinfo.profile permission. | 149 * granted the userinfo.profile permission. |
105 * | 150 * |
106 * @param {function(string,string):void} onOk Callback invoked when the user's | 151 * @param {function(string,string):void} onOk Callback invoked when the user's |
107 * email address and full name are available. | 152 * email address and full name are available. |
108 * @param {function(remoting.Error):void} onError Callback invoked if an | 153 * @param {function(remoting.Error):void} onError Callback invoked if an |
109 * error occurs. | 154 * error occurs. |
110 * @return {void} Nothing. | 155 * @return {void} Nothing. |
111 */ | 156 */ |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 console.error(error_message); | 244 console.error(error_message); |
200 while (this.pendingCallbacks_.length > 0) { | 245 while (this.pendingCallbacks_.length > 0) { |
201 var callback = /** @type {remoting.Identity.Callbacks} */ | 246 var callback = /** @type {remoting.Identity.Callbacks} */ |
202 (this.pendingCallbacks_.shift()); | 247 (this.pendingCallbacks_.shift()); |
203 callback.onError(remoting.Error.NOT_AUTHENTICATED); | 248 callback.onError(remoting.Error.NOT_AUTHENTICATED); |
204 } | 249 } |
205 return; | 250 return; |
206 } | 251 } |
207 | 252 |
208 // If there's no token, but we haven't yet prompted for permission, do so | 253 // 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. | 254 // now. |
210 this.consentCallback_(this.onAuthContinue_.bind(this)); | 255 this.handleAuthFailure().then(this.onAuthComplete_.bind(this, true)); |
211 }; | 256 }; |
212 | 257 |
213 /** | 258 /** |
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. | 259 * Internal representation for pair of callWithToken callbacks. |
226 * | 260 * |
227 * @param {function(string):void} onOk | 261 * @param {function(string):void} onOk |
228 * @param {function(remoting.Error):void} onError | 262 * @param {function(remoting.Error):void} onError |
229 * @constructor | 263 * @constructor |
230 * @private | 264 * @private |
231 */ | 265 */ |
232 remoting.Identity.Callbacks = function(onOk, onError) { | 266 remoting.Identity.Callbacks = function(onOk, onError) { |
233 /** @type {function(string):void} */ | 267 /** @type {function(string):void} */ |
234 this.onOk = onOk; | 268 this.onOk = onOk; |
235 /** @type {function(remoting.Error):void} */ | 269 /** @type {function(remoting.Error):void} */ |
236 this.onError = onError; | 270 this.onError = onError; |
237 }; | 271 }; |
238 | 272 |
239 /** | 273 /** |
240 * Returns whether the web app has authenticated with the Google services. | 274 * Returns whether the web app has authenticated with the Google services. |
241 * | 275 * |
242 * @return {boolean} | 276 * @return {boolean} |
243 */ | 277 */ |
244 remoting.Identity.prototype.isAuthenticated = function() { | 278 remoting.Identity.prototype.isAuthenticated = function() { |
245 return remoting.identity.email_ !== ''; | 279 return remoting.identity.email_ !== ''; |
246 }; | 280 }; |
OLD | NEW |