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 /** @suppress {duplicate} */ | |
10 var remoting = remoting || {}; | |
11 | |
12 (function(){ | |
9 | 13 |
10 'use strict'; | 14 'use strict'; |
11 | 15 |
12 /** @suppress {duplicate} */ | |
13 var remoting = remoting || {}; | |
14 | |
15 /** | 16 /** |
16 * @type {remoting.Identity} | 17 * @type {remoting.Identity} |
17 */ | 18 */ |
18 remoting.identity = null; | 19 remoting.identity = null; |
19 | 20 |
21 var USER_CANCELLED = 'The user did not approve access.'; | |
22 | |
20 /** | 23 /** |
21 * @param {remoting.Identity.ConsentDialog=} opt_consentDialog | 24 * @param {remoting.Identity.ConsentDialog=} opt_consentDialog |
22 * @constructor | 25 * @constructor |
23 */ | 26 */ |
24 remoting.Identity = function(opt_consentDialog) { | 27 remoting.Identity = function(opt_consentDialog) { |
25 /** @private */ | 28 /** @private */ |
26 this.consentDialog_ = opt_consentDialog; | 29 this.consentDialog_ = opt_consentDialog; |
27 /** @type {string} @private */ | 30 /** @private {string} */ |
28 this.email_ = ''; | 31 this.email_ = ''; |
29 /** @type {string} @private */ | 32 /** @private {string} */ |
30 this.fullName_ = ''; | 33 this.fullName_ = ''; |
31 /** @type {base.Deferred<string>} */ | 34 /** @type {base.Deferred<string>} */ |
32 this.authTokenDeferred_ = null; | 35 this.authTokenDeferred_ = null; |
36 /** @private {boolean} */ | |
37 this.interactive_ = false; | |
33 }; | 38 }; |
34 | 39 |
35 /** | 40 /** |
36 * chrome.identity.getAuthToken should be initiated from user interactions if | 41 * chrome.identity.getAuthToken should be initiated from user interactions if |
37 * called with interactive equals true. This interface prompts a dialog for | 42 * called with interactive equals true. This interface prompts a dialog for |
38 * the user's consent. | 43 * the user's consent. |
39 * | 44 * |
40 * @interface | 45 * @interface |
41 */ | 46 */ |
42 remoting.Identity.ConsentDialog = function() {}; | 47 remoting.Identity.ConsentDialog = function() {}; |
(...skipping 10 matching lines...) Expand all Loading... | |
53 * @return {!Promise<string>} A promise resolved with an access token | 58 * @return {!Promise<string>} A promise resolved with an access token |
54 * or rejected with a remoting.Error. | 59 * or rejected with a remoting.Error. |
55 */ | 60 */ |
56 remoting.Identity.prototype.getToken = function() { | 61 remoting.Identity.prototype.getToken = function() { |
57 /** @const */ | 62 /** @const */ |
58 var that = this; | 63 var that = this; |
59 | 64 |
60 if (this.authTokenDeferred_ == null) { | 65 if (this.authTokenDeferred_ == null) { |
61 this.authTokenDeferred_ = new base.Deferred(); | 66 this.authTokenDeferred_ = new base.Deferred(); |
62 chrome.identity.getAuthToken( | 67 chrome.identity.getAuthToken( |
63 { 'interactive': false }, | 68 { 'interactive': this.interactive_ }, |
64 that.onAuthComplete_.bind(that, false)); | 69 this.onAuthComplete_.bind(this)); |
65 } | 70 } |
66 return this.authTokenDeferred_.promise(); | 71 return this.authTokenDeferred_.promise(); |
67 }; | 72 }; |
68 | 73 |
69 /** | 74 /** |
70 * Gets a fresh access token. | 75 * Gets a fresh access token. |
71 * | 76 * |
72 * @return {!Promise<string>} A promise resolved with an access token | 77 * @return {!Promise<string>} A promise resolved with an access token |
73 * or rejected with a remoting.Error. | 78 * or rejected with a remoting.Error. |
74 */ | 79 */ |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 */ | 160 */ |
156 remoting.Identity.prototype.getEmail = function() { | 161 remoting.Identity.prototype.getEmail = function() { |
157 return this.getUserInfo().then(function(userInfo) { | 162 return this.getUserInfo().then(function(userInfo) { |
158 return userInfo.email; | 163 return userInfo.email; |
159 }); | 164 }); |
160 }; | 165 }; |
161 | 166 |
162 /** | 167 /** |
163 * Callback for the getAuthToken API. | 168 * Callback for the getAuthToken API. |
164 * | 169 * |
165 * @param {boolean} interactive The value of the "interactive" parameter to | |
166 * getAuthToken. | |
167 * @param {?string} token The auth token, or null if the request failed. | 170 * @param {?string} token The auth token, or null if the request failed. |
168 * @private | 171 * @private |
169 */ | 172 */ |
170 remoting.Identity.prototype.onAuthComplete_ = function(interactive, token) { | 173 remoting.Identity.prototype.onAuthComplete_ = function(token) { |
171 var authTokenDeferred = this.authTokenDeferred_; | 174 var authTokenDeferred = this.authTokenDeferred_; |
172 | 175 |
173 // Pass the token to the callback(s) if it was retrieved successfully. | 176 // Pass the token to the callback(s) if it was retrieved successfully. |
174 if (token) { | 177 if (token) { |
175 authTokenDeferred.resolve(token); | 178 authTokenDeferred.resolve(token); |
176 this.authTokenDeferred_ = null; | 179 this.authTokenDeferred_ = null; |
177 return; | 180 return; |
178 } | 181 } |
179 | 182 |
180 // If not, pass an error back to the callback(s) if we've already prompted the | 183 // If not, pass an error back to the callback(s) if we've already prompted the |
181 // user for permission. | 184 // user for permission. |
182 if (interactive) { | 185 if (this.interactive_) { |
183 var error_message = | 186 var error_message = |
184 chrome.runtime.lastError ? chrome.runtime.lastError.message | 187 chrome.runtime.lastError ? chrome.runtime.lastError.message |
185 : 'Unknown error.'; | 188 : 'Unknown error.'; |
186 console.error(error_message); | 189 console.error(error_message); |
kelvinp
2015/03/05 02:12:14
Should we set this.interactive_ to false here? Or
Jamie
2015/03/05 02:31:27
That's intentional. Part of the reason for this ch
| |
187 authTokenDeferred.reject(remoting.Error.NOT_AUTHENTICATED); | 190 var error = (error_message == USER_CANCELLED) ? |
191 remoting.Error.CANCELLED : remoting.Error.NOT_AUTHENTICATED; | |
Jamie
2015/03/05 01:35:56
courage@, is this the recommended way of determini
Michael Courage
2015/03/05 01:43:55
Sorry, that's still the only way until there is an
| |
192 authTokenDeferred.reject(error); | |
188 this.authTokenDeferred_ = null; | 193 this.authTokenDeferred_ = null; |
189 return; | 194 return; |
190 } | 195 } |
191 | 196 |
192 // If there's no token, but we haven't yet prompted for permission, do so | 197 // If there's no token, but we haven't yet prompted for permission, do so |
193 // now. | 198 // now. |
194 var that = this; | 199 var that = this; |
195 var showConsentDialog = | 200 var showConsentDialog = |
196 (this.consentDialog_) ? this.consentDialog_.show() : Promise.resolve(); | 201 (this.consentDialog_) ? this.consentDialog_.show() : Promise.resolve(); |
197 showConsentDialog.then(function() { | 202 showConsentDialog.then(function() { |
198 chrome.identity.getAuthToken( | 203 that.interactive_ = true; |
199 {'interactive': true}, that.onAuthComplete_.bind(that, true)); | 204 chrome.identity.getAuthToken({'interactive': that.interactive_}, |
205 that.onAuthComplete_.bind(that)); | |
200 }); | 206 }); |
201 }; | 207 }; |
202 | 208 |
203 /** | 209 /** |
204 * Returns whether the web app has authenticated with the Google services. | 210 * Returns whether the web app has authenticated with the Google services. |
205 * | 211 * |
206 * @return {boolean} | 212 * @return {boolean} |
207 */ | 213 */ |
208 remoting.Identity.prototype.isAuthenticated = function() { | 214 remoting.Identity.prototype.isAuthenticated = function() { |
209 return remoting.identity.email_ !== ''; | 215 return remoting.identity.email_ !== ''; |
210 }; | 216 }; |
217 | |
218 })(); | |
OLD | NEW |