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

Side by Side Diff: appengine/config_service/ui/common/third-party/google-signin-aware.html

Issue 2963963003: config_service: Added google-signin-aware.html for Polymer 2.0. (Closed)
Patch Set: Created 3 years, 5 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!--
2 Copyright 2014 Google Inc
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 https://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 -->
16
17 <link rel="import" href="../polymer/polymer.html">
18 <link rel="import" href="../google-apis/google-js-api.html">
19
20 <script>
21 (function() {
22
23 /**
24 * Enum of attributes to be passed through to the login API call.
25 * @readonly
26 * @enum {string}
27 */
28 var ProxyLoginAttributes = {
29 'appPackageName': 'apppackagename',
30 'clientId': 'clientid',
31 'cookiePolicy': 'cookiepolicy',
32 'hostedDomain': 'hostedDomain',
33 'openidPrompt': 'prompt',
34 'requestVisibleActions': 'requestvisibleactions'
35 };
36
37 /**
38 * AuthEngine does all interactions with gapi.auth2
39 *
40 * It is tightly coupled with <google-signin-aware> element
41 * The elements configure AuthEngine.
42 * AuthEngine propagates all authentication events to all google-signin-awar e elements
43 *
44 * API used: https://developers.google.com/identity/sign-in/web/reference
45 *
46 */
47 var AuthEngine = {
48
49 /**
50 * oauth2 argument, set by google-signin-aware
51 */
52 _clientId: null,
53
54 get clientId() {
55 return this._clientId;
56 },
57
58 set clientId(val) {
59 if (this._clientId && val && val != this._clientId) {
60 throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId);
61 }
62 if (val && val != this._clientId) {
63 this._clientId = val;
64 this.initAuth2();
65 }
66 },
67
68 /**
69 * oauth2 argument, set by google-signin-aware
70 */
71 _cookiePolicy: 'single_host_origin',
72
73 get cookiePolicy() {
74 return this._cookiePolicy;
75 },
76
77 set cookiePolicy(val) {
78 if (val) {
79 this._cookiePolicy = val;
80 }
81 },
82
83 /**
84 * oauth2 argument, set by google-signin-aware
85 */
86 _appPackageName: '',
87
88 get appPackageName() {
89 return this._appPackageName;
90 },
91
92 set appPackageName(val) {
93 if (this._appPackageName && val && val != this._appPackageName) {
94 throw new Error('appPackageName cannot change. Values do not match. Ne w: ' + val + ' Old: ' + this._appPackageName);
95 }
96 if (val) {
97 this._appPackageName = val;
98 }
99 },
100
101 /**
102 * oauth2 argument, set by google-signin-aware
103 */
104 _requestVisibleActions: '',
105
106 get requestVisibleactions() {
107 return this._requestVisibleActions;
108 },
109
110 set requestVisibleactions(val) {
111 if (this._requestVisibleActions && val && val != this._requestVisibleAct ions) {
112 throw new Error('requestVisibleactions cannot change. Values do not ma tch. New: ' + val + ' Old: ' + this._requestVisibleActions);
113 }
114 if (val)
115 this._requestVisibleActions = val;
116 },
117
118 /**
119 * oauth2 argument, set by google-signin-aware
120 */
121 _hostedDomain: '',
122
123 get hostedDomain() {
124 return this._hostedDomain;
125 },
126
127 set hostedDomain(val) {
128 if (this._hostedDomain && val && val != this._hostedDomain) {
129 throw new Error('hostedDomain cannot change. Values do not match. New: ' + val + ' Old: ' + this._hostedDomain);
130 }
131 if (val)
132 this._hostedDomain = val;
133 },
134
135 /**
136 * oauth2 argument, set by google-signin-aware
137 */
138 _openidPrompt: '',
139
140 get openidPrompt() {
141 return this._openidPrompt;
142 },
143
144 set openidPrompt(val) {
145 if (typeof val !== 'string') {
146 throw new Error(
147 'openidPrompt must be a string. Received ' + typeof val);
148 }
149 if (val) {
150 var values = val.split(' ');
151 values = values.map(function(v) {
152 return v.trim();
153 });
154 values = values.filter(function(v) {
155 return v;
156 });
157 var validValues = {none: 0, login: 0, consent: 0, select_account: 0};
158 values.forEach(function(v) {
159 if (v == 'none' && values.length > 1) {
160 throw new Error(
161 'none cannot be combined with other openidPrompt values');
162 }
163 if (!(v in validValues)) {
164 throw new Error(
165 'invalid openidPrompt value ' + v +
166 '. Valid values: ' + Object.keys(validValues).join(', '));
167 }
168 });
169 }
170 this._openidPrompt = val;
171 },
172
173 /** Is offline access currently enabled in the google-signin-aware element ? */
174 _offline: false,
175
176 get offline() {
177 return this._offline;
178 },
179
180 set offline(val) {
181 this._offline = val;
182 this.updateAdditionalAuth();
183 },
184
185 /** Should we force a re-prompt for offline access? */
186 _offlineAlwaysPrompt: false,
187
188 get offlineAlwaysPrompt() {
189 return this._offlineAlwaysPrompt;
190 },
191
192 set offlineAlwaysPrompt(val) {
193 this._offlineAlwaysPrompt = val;
194 this.updateAdditionalAuth();
195 },
196
197 /** Have we already gotten offline access from Google during this session? */
198 offlineGranted: false,
199
200 /** <google-js-api> */
201 _apiLoader: null,
202
203 /** an array of wanted scopes. oauth2 argument */
204 _requestedScopeArray: [],
205
206 /** _requestedScopeArray as string */
207 get requestedScopes() {
208 return this._requestedScopeArray.join(' ');
209 },
210
211 /** Is auth library initalized? */
212 _initialized: false,
213
214 /** Is user signed in? */
215 _signedIn: false,
216
217 /** Currently granted scopes */
218 _grantedScopeArray: [],
219
220 /** True if additional authorization is required */
221 _needAdditionalAuth: true,
222
223 /** True if have google+ scopes */
224 _hasPlusScopes: false,
225
226 /**
227 * array of <google-signin-aware>
228 * state changes are broadcast to them
229 */
230 signinAwares: [],
231
232 init: function() {
233 this._apiLoader = document.createElement('google-js-api');
234 this._apiLoader.addEventListener('js-api-load', this.loadAuth2.bind(this ));
235 if (Polymer.Element) {
236 document.body.appendChild(this._apiLoader);
237 }
238 },
239
240 loadAuth2: function() {
241 gapi.load('auth2', this.initAuth2.bind(this));
242 },
243
244 initAuth2: function() {
245 if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) {
246 return;
247 }
248 var auth = gapi.auth2.init({
249 'client_id': this.clientId,
250 'cookie_policy': this.cookiePolicy,
251 'scope': this.requestedScopes,
252 'hosted_domain': this.hostedDomain
253 });
254
255 auth['currentUser'].listen(this.handleUserUpdate.bind(this));
256
257 auth.then(
258 function onFulfilled() {
259 // Let the current user listener trigger the changes.
260 },
261 function onRejected(error) {
262 console.error(error);
263 }
264 );
265 },
266
267 handleUserUpdate: function(newPrimaryUser) {
268 // update and broadcast currentUser
269 var isSignedIn = newPrimaryUser.isSignedIn();
270 if (isSignedIn != this._signedIn) {
271 this._signedIn = isSignedIn;
272 for (var i=0; i<this.signinAwares.length; i++) {
273 this.signinAwares[i]._setSignedIn(isSignedIn);
274 }
275 }
276 // update and broadcast initialized property the first time the isSigned In property is set.
277 if(!this._initialized) {
278 for (var i=0; i<this.signinAwares.length; i++) {
279 this.signinAwares[i]._setInitialized(true);
280 }
281 this._initialized = true;
282 }
283
284
285 // update granted scopes
286 this._grantedScopeArray = this.strToScopeArray(
287 newPrimaryUser.getGrantedScopes());
288 // console.log(this._grantedScopeArray);
289 this.updateAdditionalAuth();
290
291 var response = newPrimaryUser.getAuthResponse();
292 for (var i=0; i<this.signinAwares.length; i++) {
293 this.signinAwares[i]._updateScopeStatus(response);
294 }
295 },
296
297 setOfflineCode: function(code) {
298 for (var i=0; i<this.signinAwares.length; i++) {
299 this.signinAwares[i]._updateOfflineCode(code);
300 }
301 },
302
303 /** convert scope string to scope array */
304 strToScopeArray: function(str) {
305 if (!str) {
306 return [];
307 }
308 // remove extra spaces, then split
309 var scopes = str.replace(/\ +/g, ' ').trim().split(' ');
310 for (var i=0; i<scopes.length; i++) {
311 scopes[i] = scopes[i].toLowerCase();
312 // Handle scopes that will be deprecated but are still returned with their old value
313 if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') {
314 scopes[i] = 'profile';
315 }
316 if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') {
317 scopes[i] = 'email';
318 }
319 }
320 // return with duplicates filtered out
321 return scopes.filter( function(value, index, self) {
322 return self.indexOf(value) === index;
323 });
324 },
325
326 /** true if scopes have google+ scopes */
327 isPlusScope: function(scope) {
328 return (scope.indexOf('/auth/games') > -1)
329 || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me' ) < 0);
330 },
331
332 /** true if scopes have been granted */
333 hasGrantedScopes: function(scopeStr) {
334 var scopes = this.strToScopeArray(scopeStr);
335 for (var i=0; i< scopes.length; i++) {
336 if (this._grantedScopeArray.indexOf(scopes[i]) === -1)
337 return false;
338 }
339 return true;
340 },
341
342 /** request additional scopes */
343 requestScopes: function(newScopeStr) {
344 var newScopes = this.strToScopeArray(newScopeStr);
345 var scopesUpdated = false;
346 for (var i=0; i<newScopes.length; i++) {
347 if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) {
348 this._requestedScopeArray.push(newScopes[i]);
349 scopesUpdated = true;
350 }
351 }
352 if (scopesUpdated) {
353 this.updateAdditionalAuth();
354 this.updatePlusScopes();
355 }
356 },
357
358 /** update status of _needAdditionalAuth */
359 updateAdditionalAuth: function() {
360 var needMoreAuth = false;
361 if ((this.offlineAlwaysPrompt || this.offline ) && !this.offlineGranted) {
362 needMoreAuth = true;
363 } else {
364 for (var i=0; i<this._requestedScopeArray.length; i++) {
365 if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) == = -1) {
366 needMoreAuth = true;
367 break;
368 }
369 }
370 }
371 if (this._needAdditionalAuth != needMoreAuth) {
372 this._needAdditionalAuth = needMoreAuth;
373 // broadcast new value
374 for (var i=0; i<this.signinAwares.length; i++) {
375 this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth);
376 }
377 }
378 },
379
380 updatePlusScopes: function() {
381 var hasPlusScopes = false;
382 for (var i = 0; i < this._requestedScopeArray.length; i++) {
383 if (this.isPlusScope(this._requestedScopeArray[i])) {
384 hasPlusScopes = true;
385 break;
386 }
387 }
388 if (this._hasPlusScopes != hasPlusScopes) {
389 this._hasPlusScopes = hasPlusScopes;
390 for (var i=0; i<this.signinAwares.length; i++) {
391 this.signinAwares[i]._setHasPlusScopes(hasPlusScopes);
392 }
393 }
394 },
395 /**
396 * attached <google-signin-aware>
397 * @param {!GoogleSigninAwareElement} aware element to add
398 */
399 attachSigninAware: function(aware) {
400 if (this.signinAwares.indexOf(aware) == -1) {
401 this.signinAwares.push(aware);
402 // Initialize aware properties
403 aware._setNeedAdditionalAuth(this._needAdditionalAuth);
404 aware._setInitialized(this._initialized);
405 aware._setSignedIn(this._signedIn);
406 aware._setHasPlusScopes(this._hasPlusScopes);
407 } else {
408 console.warn('signinAware attached more than once', aware);
409 }
410 },
411
412 detachSigninAware: function(aware) {
413 var index = this.signinAwares.indexOf(aware);
414 if (index != -1) {
415 this.signinAwares.splice(index, 1);
416 } else {
417 console.warn('Trying to detach unattached signin-aware');
418 }
419 },
420
421 /** returns scopes not granted */
422 getMissingScopes: function() {
423 return this._requestedScopeArray.filter( function(scope) {
424 return this._grantedScopeArray.indexOf(scope) === -1;
425 }.bind(this)).join(' ');
426 },
427
428 assertAuthInitialized: function() {
429 if (!this.clientId) {
430 throw new Error("AuthEngine not initialized. clientId has not been con figured.");
431 }
432 if (!('gapi' in window)) {
433 throw new Error("AuthEngine not initialized. gapi has not loaded.");
434 }
435 if (!('auth2' in window.gapi)) {
436 throw new Error("AuthEngine not initialized. auth2 not loaded.");
437 }
438 },
439
440 /** pops up sign-in dialog */
441 signIn: function() {
442 this.assertAuthInitialized();
443 var params = {
444 'scope': this.getMissingScopes()
445 };
446
447 // Proxy specific attributes through to the signIn options.
448 Object.keys(ProxyLoginAttributes).forEach(function(key) {
449 if (this[key] && this[key] !== '') {
450 params[ProxyLoginAttributes[key]] = this[key];
451 }
452 }, this);
453
454 var promise;
455 var user = gapi.auth2.getAuthInstance()['currentUser'].get();
456 if (!(this.offline || this.offlineAlwaysPrompt)) {
457 if (user.getGrantedScopes()) {
458 // additional auth, skip multiple account dialog
459 promise = user.grant(params);
460 } else {
461 // initial signin
462 promise = gapi.auth2.getAuthInstance().signIn(params);
463 }
464 } else {
465 params.redirect_uri = 'postmessage';
466 if (this.offlineAlwaysPrompt) {
467 params.approval_prompt = 'force';
468 }
469
470 // Despite being documented at https://goo.gl/tiO0Bk
471 // It doesn't seem like user.grantOfflineAccess() actually exists in
472 // the current version of the Google Sign-In JS client we're using
473 // through GoogleWebComponents. So in the offline case, we will not
474 // distinguish between a first auth and an additional one.
475 promise = gapi.auth2.getAuthInstance().grantOfflineAccess(params);
476 }
477 promise.then(
478 function onFulfilled(response) {
479 // If login was offline, response contains one string "code"
480 // Otherwise it contains the user object already
481 var newUser;
482 if (response.code) {
483 AuthEngine.offlineGranted = true;
484 newUser = gapi.auth2.getAuthInstance()['currentUser'].get();
485 AuthEngine.setOfflineCode(response.code);
486 } else {
487 newUser = response;
488 }
489
490 var authResponse = newUser.getAuthResponse();
491 // Let the current user listener trigger the changes.
492 },
493 function onRejected(error) {
494 // Access denied is not an error, user hit cancel
495 if ("Access denied." !== error.reason) {
496 this.signinAwares.forEach(function(awareInstance) {
497 awareInstance.errorNotify(error);
498 });
499 }
500 }.bind(this)
501 );
502 },
503
504 /** signs user out */
505 signOut: function() {
506 this.assertAuthInitialized();
507 gapi.auth2.getAuthInstance().signOut().then(
508 function onFulfilled() {
509 // Let the current user listener trigger the changes.
510 },
511 function onRejected(error) {
512 console.error(error);
513 }
514 );
515 }
516 };
517
518 AuthEngine.init();
519
520 /**
521 `google-signin-aware` is used to enable authentication in custom elements by
522 interacting with a google-signin element that needs to be present somewhere
523 on the page.
524
525 The `scopes` attribute allows you to specify which scope permissions are require d
526 (e.g do you want to allow interaction with the Google Drive API).
527
528 The `google-signin-aware-success` event is triggered when a user successfully
529 authenticates. If either `offline` or `offlineAlwaysPrompt` is set to true, succ essful
530 authentication will also trigger the `google-signin-offline-success`event.
531 The `google-signin-aware-signed-out` event is triggered when a user explicitly
532 signs out via the google-signin element.
533
534 You can bind to `isAuthorized` property to monitor authorization state.
535 ##### Example
536
537 <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google -signin-aware>
538
539
540 ##### Example with offline
541 <template id="awareness" is="dom-bind">
542 <google-signin-aware
543 scopes="https://www.googleapis.com/auth/drive"
544 offline
545 on-google-signin-aware-success="handleSignin"
546 on-google-signin-offline-success="handleOffline"></google-signin-aware >
547 <\/template>
548 <script>
549 var aware = document.querySelector('#awareness');
550 aware.handleSignin = function(response) {
551 var user = gapi.auth2.getAuthInstance()['currentUser'].get();
552 console.log('User name: ' + user.getBasicProfile().getName());
553 };
554 aware.handleOffline = function(response) {
555 console.log('Offline code received: ' + response.detail.code);
556 // Here you would POST response.detail.code to your webserver, which can
557 // exchange the authorization code for an access token. More info at:
558 // https://developers.google.com/identity/protocols/OAuth2WebServer
559 };
560 <\/script>
561 */
562 Polymer({
563
564 is: 'google-signin-aware',
565
566 /**
567 * Fired when this scope has been authorized
568 * @param {Object} result Authorization result.
569 * @event google-signin-aware-success
570 */
571
572 /**
573 * Fired when an offline authorization is successful.
574 * @param {{code: string}} detail -
575 * code: The one-time authorization code from Google.
576 * Your application can exchange this for an `access_token` and `r efresh_token`
577 * @event google-signin-offline-success
578 */
579
580 /**
581 * Fired when this scope is not authorized
582 * @event google-signin-aware-signed-out
583 */
584
585 /**
586 * Fired when there is an error during the signin flow.
587 * @param {Object} detail The error object returned from the OAuth 2 flow.
588 * @event google-signin-aware-error
589 */
590
591 /**
592 * This block is needed so the previous @param is not assigned to the next property.
593 */
594
595 properties: {
596 /**
597 * App package name for android over-the-air installs.
598 * See the relevant [docs](https://developers.google.com/+/web/signin/an droid-app-installs)
599 */
600 appPackageName: {
601 type: String,
602 observer: '_appPackageNameChanged'
603 },
604
605 /**
606 * a Google Developers clientId reference
607 */
608 clientId: {
609 type: String,
610 observer: '_clientIdChanged'
611 },
612
613 /**
614 * The cookie policy defines what URIs have access to the session cookie
615 * remembering the user's sign-in state.
616 * See the relevant [docs](https://developers.google.com/+/web/signin/re ference#determining_a_value_for_cookie_policy) for more information.
617 * @default 'single_host_origin'
618 */
619 cookiePolicy: {
620 type: String,
621 observer: '_cookiePolicyChanged'
622 },
623
624 /**
625 * The app activity types you want to write on behalf of the user
626 * (e.g http://schemas.google.com/AddActivity)
627 *
628 */
629 requestVisibleActions: {
630 type: String,
631 observer: '_requestVisibleActionsChanged'
632 },
633
634 /**
635 * The Google Apps domain to which users must belong to sign in.
636 * See the relevant [docs](https://developers.google.com/identity/sign-i n/web/reference) for more information.
637 */
638 hostedDomain: {
639 type: String,
640 observer: '_hostedDomainChanged'
641 },
642
643 /**
644 * Allows for offline `access_token` retrieval during the signin process .
645 * See also `offlineAlwaysPrompt`. You only need to set one of the two; if both
646 * are set, the behavior of `offlineAlwaysPrompt` will override `offline `.
647 */
648 offline: {
649 type: Boolean,
650 value: false,
651 observer: '_offlineChanged'
652 },
653
654 /**
655 * Works the same as `offline` with the addition that it will always
656 * force a re-prompt to the user, guaranteeing that you will get a
657 * refresh_token even if the user has already granted offline access to
658 * this application. You only need to set one of `offline` or
659 * `offlineAlwaysPrompt`, not both.
660 */
661 offlineAlwaysPrompt: {
662 type: Boolean,
663 value: false,
664 observer: '_offlineAlwaysPromptChanged'
665 },
666
667 /**
668 * The scopes to provide access to (e.g https://www.googleapis.com/auth/ drive)
669 * and should be space-delimited.
670 */
671 scopes: {
672 type: String,
673 value: 'profile',
674 observer: '_scopesChanged'
675 },
676
677 /**
678 * Space-delimited, case-sensitive list of strings that
679 * specifies whether the the user is prompted for reauthentication
680 * and/or consent. The defined values are:
681 * none: do not display authentication or consent pages.
682 * This value is mutually exclusive with the rest.
683 * login: always prompt the user for reauthentication.
684 * consent: always show consent screen.
685 * select_account: always show account selection page.
686 * This enables a user who has multiple accounts to select amongst
687 * the multiple accounts that they might have current sessions for.
688 * For more information, see "prompt" parameter description in
689 * https://openid.net/specs/openid-connect-basic-1_0.html#RequestParamet ers
690 */
691 openidPrompt: {
692 type: String,
693 value: '',
694 observer: '_openidPromptChanged'
695 },
696
697 /**
698 * True when the auth library has been initialized, and signedIn propert y value is set from the first api response.
699 */
700 initialized: {
701 type: Boolean,
702 notify: true,
703 readOnly: true
704 },
705
706 /**
707 * True if user is signed in
708 */
709 signedIn: {
710 type: Boolean,
711 notify: true,
712 readOnly: true
713 },
714
715 /**
716 * True if authorizations for *this* element have been granted
717 */
718 isAuthorized: {
719 type: Boolean,
720 notify: true,
721 readOnly: true,
722 value: false
723 },
724
725 /**
726 * True if additional authorizations for *any* element are required
727 */
728 needAdditionalAuth: {
729 type: Boolean,
730 notify: true,
731 readOnly: true
732 },
733
734 /**
735 * True if *any* element has google+ scopes
736 */
737 hasPlusScopes: {
738 type: Boolean,
739 value: false,
740 notify: true,
741 readOnly: true
742 }
743 },
744
745 attached: function() {
746 AuthEngine.attachSigninAware(this);
747 },
748
749 detached: function() {
750 AuthEngine.detachSigninAware(this);
751 },
752
753 /** pops up the authorization dialog */
754 signIn: function() {
755 AuthEngine.signIn();
756 },
757
758 /** signs user out */
759 signOut: function() {
760 AuthEngine.signOut();
761 },
762
763 errorNotify: function(error) {
764 this.fire('google-signin-aware-error', error);
765 },
766
767 _appPackageNameChanged: function(newName, oldName) {
768 AuthEngine.appPackageName = newName;
769 },
770
771 _clientIdChanged: function(newId, oldId) {
772 AuthEngine.clientId = newId;
773 },
774
775 _cookiePolicyChanged: function(newPolicy, oldPolicy) {
776 AuthEngine.cookiePolicy = newPolicy;
777 },
778
779 _requestVisibleActionsChanged: function(newVal, oldVal) {
780 AuthEngine.requestVisibleActions = newVal;
781 },
782
783 _hostedDomainChanged: function(newVal, oldVal) {
784 AuthEngine.hostedDomain = newVal;
785 },
786
787 _offlineChanged: function(newVal, oldVal) {
788 AuthEngine.offline = newVal;
789 },
790
791 _offlineAlwaysPromptChanged: function(newVal, oldVal) {
792 AuthEngine.offlineAlwaysPrompt = newVal;
793 },
794
795 _scopesChanged: function(newVal, oldVal) {
796 AuthEngine.requestScopes(newVal);
797 this._updateScopeStatus(undefined);
798 },
799
800 _openidPromptChanged: function(newVal, oldVal) {
801 AuthEngine.openidPrompt = newVal;
802 },
803
804 _updateScopeStatus: function(user) {
805 var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.sc opes);
806 if (newAuthorized !== this.isAuthorized) {
807 this._setIsAuthorized(newAuthorized);
808 if (newAuthorized) {
809 this.fire('google-signin-aware-success', user);
810 }
811 else {
812 this.fire('google-signin-aware-signed-out', user);
813 }
814 }
815 },
816
817 _updateOfflineCode: function(code) {
818 if (code) {
819 this.fire('google-signin-offline-success', {code: code});
820 }
821 }
822 });
823 })();
824 </script>
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698