| OLD | NEW |
| (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> |
| OLD | NEW |