Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1108)

Side by Side Diff: remoting/webapp/crd/js/identity.js

Issue 1133913002: [Chromoting] Move shared webapp JS files from crd/js -> base/js (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/webapp/crd/js/host_settings.js ('k') | remoting/webapp/crd/js/identity_unittest.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview
7 * Wrapper class for Chrome's identity API.
8 */
9 /** @suppress {duplicate} */
10 var remoting = remoting || {};
11
12 (function(){
13
14 'use strict';
15
16 /**
17 * @type {remoting.Identity}
18 */
19 remoting.identity = null;
20
21 var USER_CANCELLED = 'The user did not approve access.';
22
23 /**
24 * @param {remoting.Identity.ConsentDialog=} opt_consentDialog
25 * @constructor
26 */
27 remoting.Identity = function(opt_consentDialog) {
28 /** @private */
29 this.consentDialog_ = opt_consentDialog;
30 /** @private {string} */
31 this.email_ = '';
32 /** @private {string} */
33 this.fullName_ = '';
34 /** @private {Object<base.Deferred<string>>} */
35 this.authTokensDeferred_ = {};
36 /** @private {boolean} */
37 this.interactive_ = false;
38 };
39
40 /**
41 * chrome.identity.getAuthToken should be initiated from user interactions if
42 * called with interactive equals true. This interface prompts a dialog for
43 * the user's consent.
44 *
45 * @interface
46 */
47 remoting.Identity.ConsentDialog = function() {};
48
49 /**
50 * @return {Promise} A Promise that resolves when permission to start an
51 * interactive flow is granted.
52 */
53 remoting.Identity.ConsentDialog.prototype.show = function() {};
54
55 /**
56 * Gets an access token.
57 *
58 * @param {Array<string>=} opt_scopes Optional OAuth2 scopes to request. If not
59 * specified, the scopes specified in the manifest will be used. No consent
60 * prompt will be needed as long as the requested scopes are a subset of
61 * those already granted (in most cases, the remoting.Application framework
62 * ensures that the scopes specified in the manifest are already authorized
63 * before any application code is executed). Callers can request scopes not
64 * specified in the manifest, but a consent prompt will be shown.
65 *
66 * @return {!Promise<string>} A promise resolved with an access token
67 * or rejected with a remoting.Error.
68 */
69 remoting.Identity.prototype.getToken = function(opt_scopes) {
70 var key = getScopesKey(opt_scopes);
71 if (!this.authTokensDeferred_[key]) {
72 this.authTokensDeferred_[key] = new base.Deferred();
73 var options = {
74 'interactive': this.interactive_,
75 'scopes': opt_scopes
76 };
77 chrome.identity.getAuthToken(options,
78 this.onAuthComplete_.bind(this, opt_scopes));
79 }
80 return this.authTokensDeferred_[key].promise();
81 };
82
83 /**
84 * Gets a fresh access token.
85 *
86 * @param {Array<string>=} opt_scopes Optional OAuth2 scopes to request, as
87 * documented in getToken().
88 * @return {!Promise<string>} A promise resolved with an access token
89 * or rejected with a remoting.Error.
90 */
91 remoting.Identity.prototype.getNewToken = function(opt_scopes) {
92 /** @type {remoting.Identity} */
93 var that = this;
94
95 return this.getToken(opt_scopes).then(function(/** string */ token) {
96 return new Promise(function(resolve, reject) {
97 chrome.identity.removeCachedAuthToken({'token': token }, function() {
98 resolve(that.getToken());
99 });
100 });
101 });
102 };
103
104 /**
105 * Removes the cached auth token, if any.
106 *
107 * @return {!Promise<null>} A promise resolved with the operation completes.
108 */
109 remoting.Identity.prototype.removeCachedAuthToken = function() {
110 return new Promise(function(resolve, reject) {
111 /** @param {string} token */
112 var onToken = function(token) {
113 if (token) {
114 chrome.identity.removeCachedAuthToken(
115 {'token': token}, resolve.bind(null, null));
116 } else {
117 resolve(null);
118 }
119 };
120 chrome.identity.getAuthToken({'interactive': false}, onToken);
121 });
122 };
123
124 /**
125 * Gets the user's email address and full name. The full name will be
126 * null unless the webapp has requested and been granted the
127 * userinfo.profile permission.
128 *
129 * TODO(jrw): Type declarations say the name can't be null. Are the
130 * types wrong, or is the documentation wrong?
131 *
132 * @return {!Promise<{email:string, name:string}>} Promise
133 * resolved with the user's email address and full name, or rejected
134 * with a remoting.Error.
135 */
136 remoting.Identity.prototype.getUserInfo = function() {
137 if (this.isAuthenticated()) {
138 /**
139 * The temp variable is needed to work around a compiler bug.
140 * @type {{email: string, name: string}}
141 */
142 var result = {email: this.email_, name: this.fullName_};
143 return Promise.resolve(result);
144 }
145
146 /** @type {remoting.Identity} */
147 var that = this;
148
149 return this.getToken().then(function(token) {
150 return new Promise(function(resolve, reject) {
151 /**
152 * @param {string} email
153 * @param {string} name
154 */
155 var onResponse = function(email, name) {
156 that.email_ = email;
157 that.fullName_ = name;
158 resolve({email: email, name: name});
159 };
160
161 remoting.oauth2Api.getUserInfo(onResponse, reject, token);
162 });
163 });
164 };
165
166 /**
167 * Gets the user's email address.
168 *
169 * @return {!Promise<string>} Promise resolved with the user's email
170 * address or rejected with a remoting.Error.
171 */
172 remoting.Identity.prototype.getEmail = function() {
173 return this.getUserInfo().then(function(userInfo) {
174 return userInfo.email;
175 });
176 };
177
178 /**
179 * Callback for the getAuthToken API.
180 *
181 * @param {Array<string>|undefined} scopes The explicit scopes passed to
182 * getToken, or undefined if no scopes were specified.
183 * @param {?string} token The auth token, or null if the request failed.
184 * @private
185 */
186 remoting.Identity.prototype.onAuthComplete_ = function(scopes, token) {
187 var key = getScopesKey(scopes);
188 var authTokenDeferred = this.authTokensDeferred_[key];
189
190 // Pass the token to the callback(s) if it was retrieved successfully.
191 if (token) {
192 var promise = this.authTokensDeferred_[key];
193 delete this.authTokensDeferred_[key];
194 promise.resolve(token);
195 return;
196 }
197
198 // If not, pass an error back to the callback(s) if we've already prompted the
199 // user for permission.
200 if (this.interactive_) {
201 var error_message =
202 chrome.runtime.lastError ? chrome.runtime.lastError.message
203 : 'Unknown error.';
204 console.error(error_message);
205 var error = (error_message == USER_CANCELLED) ?
206 new remoting.Error(remoting.Error.Tag.CANCELLED) :
207 new remoting.Error(remoting.Error.Tag.NOT_AUTHENTICATED);
208 this.authTokensDeferred_[key].reject(error);
209 delete this.authTokensDeferred_[key];
210 return;
211 }
212
213 // If there's no token, but we haven't yet prompted for permission, do so
214 // now.
215 var that = this;
216 var showConsentDialog =
217 (this.consentDialog_) ? this.consentDialog_.show() : Promise.resolve();
218 showConsentDialog.then(function() {
219 that.interactive_ = true;
220 var options = {
221 'interactive': that.interactive_,
222 'scopes': scopes
223 };
224 chrome.identity.getAuthToken(options,
225 that.onAuthComplete_.bind(that, scopes));
226 });
227 };
228
229 /**
230 * Returns whether the web app has authenticated with the Google services.
231 *
232 * @return {boolean}
233 */
234 remoting.Identity.prototype.isAuthenticated = function() {
235 return remoting.identity.email_ !== '';
236 };
237
238
239 /**
240 * @param {Array<string>=} opt_scopes
241 * @return {string}
242 */
243 function getScopesKey(opt_scopes) {
244 return opt_scopes ? JSON.stringify(opt_scopes) : '';
245 }
246
247 })();
OLDNEW
« no previous file with comments | « remoting/webapp/crd/js/host_settings.js ('k') | remoting/webapp/crd/js/identity_unittest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698