Chromium Code Reviews| Index: appengine/config_service/ui/common/third_party/google-signin/google-signin-aware.html |
| diff --git a/appengine/config_service/ui/common/third_party/google-signin/google-signin-aware.html b/appengine/config_service/ui/common/third_party/google-signin/google-signin-aware.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4368b2951ff1de04b15fd5ca85c604ff5b85e284 |
| --- /dev/null |
| +++ b/appengine/config_service/ui/common/third_party/google-signin/google-signin-aware.html |
| @@ -0,0 +1,828 @@ |
| +<!-- |
| +Copyright 2014 Google Inc |
|
Sergey Berezin
2017/06/28 19:53:02
As discussed offline, let's commit the original ve
cwpayton
2017/06/29 22:28:15
Done.
|
| + |
| +Licensed under the Apache License, Version 2.0 (the "License"); |
| +you may not use this file except in compliance with the License. |
| +You may obtain a copy of the License at |
| + |
| + https://www.apache.org/licenses/LICENSE-2.0 |
| + |
| +Unless required by applicable law or agreed to in writing, software |
| +distributed under the License is distributed on an "AS IS" BASIS, |
| +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| +See the License for the specific language governing permissions and |
| +limitations under the License. |
| +--> |
| + |
| +<link rel="import" href="../../../bower_components/polymer/polymer.html"> |
| +<link rel="import" href="../../../bower_components/google-apis/google-js-api.html"> |
|
Sergey Berezin
2017/06/28 19:53:02
This is probably fine for the our vendored copy, b
cwpayton
2017/06/29 22:28:15
Acknowledged.
|
| + |
| +<script> |
| + (function() { |
| + |
| + /** |
| + * Enum of attributes to be passed through to the login API call. |
| + * @readonly |
| + * @enum {string} |
| + */ |
| + var ProxyLoginAttributes = { |
| + 'appPackageName': 'apppackagename', |
| + 'clientId': 'clientid', |
| + 'cookiePolicy': 'cookiepolicy', |
| + 'hostedDomain': 'hostedDomain', |
| + 'openidPrompt': 'prompt', |
| + 'requestVisibleActions': 'requestvisibleactions' |
| + }; |
| + |
| + /** |
| + * AuthEngine does all interactions with gapi.auth2 |
| + * |
| + * It is tightly coupled with <google-signin-aware> element |
| + * The elements configure AuthEngine. |
| + * AuthEngine propagates all authentication events to all google-signin-aware elements |
| + * |
| + * API used: https://developers.google.com/identity/sign-in/web/reference |
| + * |
| + */ |
| + var AuthEngine = { |
| + |
| + /** |
| + * oauth2 argument, set by google-signin-aware |
| + */ |
| + _clientId: null, |
| + |
| + get clientId() { |
| + return this._clientId; |
| + }, |
| + |
| + set clientId(val) { |
| + if (this._clientId && val && val != this._clientId) { |
| + throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId); |
| + } |
| + if (val && val != this._clientId) { |
| + this._clientId = val; |
| + this.initAuth2(); |
| + } |
| + }, |
| + |
| + /** |
| + * oauth2 argument, set by google-signin-aware |
| + */ |
| + _cookiePolicy: 'single_host_origin', |
| + |
| + get cookiePolicy() { |
| + return this._cookiePolicy; |
| + }, |
| + |
| + set cookiePolicy(val) { |
| + if (val) { |
| + this._cookiePolicy = val; |
| + } |
| + }, |
| + |
| + /** |
| + * oauth2 argument, set by google-signin-aware |
| + */ |
| + _appPackageName: '', |
| + |
| + get appPackageName() { |
| + return this._appPackageName; |
| + }, |
| + |
| + set appPackageName(val) { |
| + if (this._appPackageName && val && val != this._appPackageName) { |
| + throw new Error('appPackageName cannot change. Values do not match. New: ' + val + ' Old: ' + this._appPackageName); |
| + } |
| + if (val) { |
| + this._appPackageName = val; |
| + } |
| + }, |
| + |
| + /** |
| + * oauth2 argument, set by google-signin-aware |
| + */ |
| + _requestVisibleActions: '', |
| + |
| + get requestVisibleactions() { |
| + return this._requestVisibleActions; |
| + }, |
| + |
| + set requestVisibleactions(val) { |
| + if (this._requestVisibleActions && val && val != this._requestVisibleActions) { |
| + throw new Error('requestVisibleactions cannot change. Values do not match. New: ' + val + ' Old: ' + this._requestVisibleActions); |
| + } |
| + if (val) |
| + this._requestVisibleActions = val; |
| + }, |
| + |
| + /** |
| + * oauth2 argument, set by google-signin-aware |
| + */ |
| + _hostedDomain: '', |
| + |
| + get hostedDomain() { |
| + return this._hostedDomain; |
| + }, |
| + |
| + set hostedDomain(val) { |
| + if (this._hostedDomain && val && val != this._hostedDomain) { |
| + throw new Error('hostedDomain cannot change. Values do not match. New: ' + val + ' Old: ' + this._hostedDomain); |
| + } |
| + if (val) |
| + this._hostedDomain = val; |
| + }, |
| + |
| + /** |
| + * oauth2 argument, set by google-signin-aware |
| + */ |
| + _openidPrompt: '', |
| + |
| + get openidPrompt() { |
| + return this._openidPrompt; |
| + }, |
| + |
| + set openidPrompt(val) { |
| + if (typeof val !== 'string') { |
| + throw new Error( |
| + 'openidPrompt must be a string. Received ' + typeof val); |
| + } |
| + if (val) { |
| + var values = val.split(' '); |
| + values = values.map(function(v) { |
| + return v.trim(); |
| + }); |
| + values = values.filter(function(v) { |
| + return v; |
| + }); |
| + var validValues = {none: 0, login: 0, consent: 0, select_account: 0}; |
| + values.forEach(function(v) { |
| + if (v == 'none' && values.length > 1) { |
| + throw new Error( |
| + 'none cannot be combined with other openidPrompt values'); |
| + } |
| + if (!(v in validValues)) { |
| + throw new Error( |
| + 'invalid openidPrompt value ' + v + |
| + '. Valid values: ' + Object.keys(validValues).join(', ')); |
| + } |
| + }); |
| + } |
| + this._openidPrompt = val; |
| + }, |
| + |
| + /** Is offline access currently enabled in the google-signin-aware element? */ |
| + _offline: false, |
| + |
| + get offline() { |
| + return this._offline; |
| + }, |
| + |
| + set offline(val) { |
| + this._offline = val; |
| + this.updateAdditionalAuth(); |
| + }, |
| + |
| + /** Should we force a re-prompt for offline access? */ |
| + _offlineAlwaysPrompt: false, |
| + |
| + get offlineAlwaysPrompt() { |
| + return this._offlineAlwaysPrompt; |
| + }, |
| + |
| + set offlineAlwaysPrompt(val) { |
| + this._offlineAlwaysPrompt = val; |
| + this.updateAdditionalAuth(); |
| + }, |
| + |
| + /** Have we already gotten offline access from Google during this session? */ |
| + offlineGranted: false, |
| + |
| + /** <google-js-api> */ |
| + _apiLoader: null, |
| + |
| + /** an array of wanted scopes. oauth2 argument */ |
| + _requestedScopeArray: [], |
| + |
| + /** _requestedScopeArray as string */ |
| + get requestedScopes() { |
| + return this._requestedScopeArray.join(' '); |
| + }, |
| + |
| + /** Is auth library initalized? */ |
| + _initialized: false, |
| + |
| + /** Is user signed in? */ |
| + _signedIn: false, |
| + |
| + /** Currently granted scopes */ |
| + _grantedScopeArray: [], |
| + |
| + /** True if additional authorization is required */ |
| + _needAdditionalAuth: true, |
| + |
| + /** True if have google+ scopes */ |
| + _hasPlusScopes: false, |
| + |
| + /** |
| + * array of <google-signin-aware> |
| + * state changes are broadcast to them |
| + */ |
| + signinAwares: [], |
| + |
| + init: function() { |
| + var that = this; |
| + document.addEventListener('DOMContentLoaded', function() { |
| + that._apiLoader = document.createElement('google-js-api'); |
| + that._apiLoader.addEventListener('js-api-load', that.loadAuth2.bind(that)); |
| + if (Polymer.Element) { |
| + document.body.appendChild(that._apiLoader); |
| + } |
| + }) |
| + }, |
| + |
| + loadAuth2: function() { |
| + var that = this; |
|
Sergey Berezin
2017/06/28 19:53:02
Is this renaming necessary? There is no function c
Sergey Berezin
2017/06/29 23:52:53
What about this line?
cwpayton
2017/06/30 00:12:48
This line is in here because of the way the "this"
|
| + gapi.load('auth2', that.initAuth2.bind(that)); |
| + }, |
| + |
| + initAuth2: function() { |
| + if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) { |
| + return; |
| + } |
| + var auth = gapi.auth2.init({ |
| + 'client_id': this.clientId, |
| + 'cookie_policy': this.cookiePolicy, |
| + 'scope': this.requestedScopes, |
| + 'hosted_domain': this.hostedDomain |
| + }); |
| + |
| + auth['currentUser'].listen(this.handleUserUpdate.bind(this)); |
| + |
| + auth.then( |
| + function onFulfilled() { |
| + // Let the current user listener trigger the changes. |
| + }, |
| + function onRejected(error) { |
| + console.error(error); |
| + } |
| + ); |
| + }, |
| + |
| + handleUserUpdate: function(newPrimaryUser) { |
| + // update and broadcast currentUser |
| + var isSignedIn = newPrimaryUser.isSignedIn(); |
| + if (isSignedIn != this._signedIn) { |
| + this._signedIn = isSignedIn; |
| + for (var i=0; i<this.signinAwares.length; i++) { |
| + this.signinAwares[i]._setSignedIn(isSignedIn); |
| + } |
| + } |
| + // update and broadcast initialized property the first time the isSignedIn property is set. |
| + if(!this._initialized) { |
| + for (var i=0; i<this.signinAwares.length; i++) { |
| + this.signinAwares[i]._setInitialized(true); |
| + } |
| + this._initialized = true; |
| + } |
| + |
| + |
| + // update granted scopes |
| + this._grantedScopeArray = this.strToScopeArray( |
| + newPrimaryUser.getGrantedScopes()); |
| + // console.log(this._grantedScopeArray); |
| + this.updateAdditionalAuth(); |
| + |
| + var response = newPrimaryUser.getAuthResponse(); |
| + for (var i=0; i<this.signinAwares.length; i++) { |
| + this.signinAwares[i]._updateScopeStatus(response); |
| + } |
| + }, |
| + |
| + setOfflineCode: function(code) { |
| + for (var i=0; i<this.signinAwares.length; i++) { |
| + this.signinAwares[i]._updateOfflineCode(code); |
| + } |
| + }, |
| + |
| + /** convert scope string to scope array */ |
| + strToScopeArray: function(str) { |
| + if (!str) { |
| + return []; |
| + } |
| + // remove extra spaces, then split |
| + var scopes = str.replace(/\ +/g, ' ').trim().split(' '); |
| + for (var i=0; i<scopes.length; i++) { |
| + scopes[i] = scopes[i].toLowerCase(); |
| + // Handle scopes that will be deprecated but are still returned with their old value |
| + if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') { |
| + scopes[i] = 'profile'; |
| + } |
| + if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') { |
| + scopes[i] = 'email'; |
| + } |
| + } |
| + // return with duplicates filtered out |
| + return scopes.filter( function(value, index, self) { |
| + return self.indexOf(value) === index; |
| + }); |
| + }, |
| + |
| + /** true if scopes have google+ scopes */ |
| + isPlusScope: function(scope) { |
| + return (scope.indexOf('/auth/games') > -1) |
| + || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me') < 0); |
| + }, |
| + |
| + /** true if scopes have been granted */ |
| + hasGrantedScopes: function(scopeStr) { |
| + var scopes = this.strToScopeArray(scopeStr); |
| + for (var i=0; i< scopes.length; i++) { |
| + if (this._grantedScopeArray.indexOf(scopes[i]) === -1) |
| + return false; |
| + } |
| + return true; |
| + }, |
| + |
| + /** request additional scopes */ |
| + requestScopes: function(newScopeStr) { |
| + var newScopes = this.strToScopeArray(newScopeStr); |
| + var scopesUpdated = false; |
| + for (var i=0; i<newScopes.length; i++) { |
| + if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) { |
| + this._requestedScopeArray.push(newScopes[i]); |
| + scopesUpdated = true; |
| + } |
| + } |
| + if (scopesUpdated) { |
| + this.updateAdditionalAuth(); |
| + this.updatePlusScopes(); |
| + } |
| + }, |
| + |
| + /** update status of _needAdditionalAuth */ |
| + updateAdditionalAuth: function() { |
| + var needMoreAuth = false; |
| + if ((this.offlineAlwaysPrompt || this.offline ) && !this.offlineGranted) { |
| + needMoreAuth = true; |
| + } else { |
| + for (var i=0; i<this._requestedScopeArray.length; i++) { |
| + if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) === -1) { |
| + needMoreAuth = true; |
| + break; |
| + } |
| + } |
| + } |
| + if (this._needAdditionalAuth != needMoreAuth) { |
| + this._needAdditionalAuth = needMoreAuth; |
| + // broadcast new value |
| + for (var i=0; i<this.signinAwares.length; i++) { |
| + this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth); |
| + } |
| + } |
| + }, |
| + |
| + updatePlusScopes: function() { |
| + var hasPlusScopes = false; |
| + for (var i = 0; i < this._requestedScopeArray.length; i++) { |
| + if (this.isPlusScope(this._requestedScopeArray[i])) { |
| + hasPlusScopes = true; |
| + break; |
| + } |
| + } |
| + if (this._hasPlusScopes != hasPlusScopes) { |
| + this._hasPlusScopes = hasPlusScopes; |
| + for (var i=0; i<this.signinAwares.length; i++) { |
| + this.signinAwares[i]._setHasPlusScopes(hasPlusScopes); |
| + } |
| + } |
| + }, |
| + /** |
| + * attached <google-signin-aware> |
| + * @param {!GoogleSigninAwareElement} aware element to add |
| + */ |
| + attachSigninAware: function(aware) { |
| + if (this.signinAwares.indexOf(aware) == -1) { |
| + this.signinAwares.push(aware); |
| + // Initialize aware properties |
| + aware._setNeedAdditionalAuth(this._needAdditionalAuth); |
| + aware._setInitialized(this._initialized); |
| + aware._setSignedIn(this._signedIn); |
| + aware._setHasPlusScopes(this._hasPlusScopes); |
| + } else { |
| + console.warn('signinAware attached more than once', aware); |
| + } |
| + }, |
| + |
| + detachSigninAware: function(aware) { |
| + var index = this.signinAwares.indexOf(aware); |
| + if (index != -1) { |
| + this.signinAwares.splice(index, 1); |
| + } else { |
| + console.warn('Trying to detach unattached signin-aware'); |
| + } |
| + }, |
| + |
| + /** returns scopes not granted */ |
| + getMissingScopes: function() { |
| + return this._requestedScopeArray.filter( function(scope) { |
| + return this._grantedScopeArray.indexOf(scope) === -1; |
| + }.bind(this)).join(' '); |
| + }, |
| + |
| + assertAuthInitialized: function() { |
| + if (!this.clientId) { |
| + throw new Error("AuthEngine not initialized. clientId has not been configured."); |
| + } |
| + if (!('gapi' in window)) { |
| + throw new Error("AuthEngine not initialized. gapi has not loaded."); |
| + } |
| + if (!('auth2' in window.gapi)) { |
| + throw new Error("AuthEngine not initialized. auth2 not loaded."); |
| + } |
| + }, |
| + |
| + /** pops up sign-in dialog */ |
| + signIn: function() { |
| + this.assertAuthInitialized(); |
| + var params = { |
| + 'scope': this.getMissingScopes() |
| + }; |
| + |
| + // Proxy specific attributes through to the signIn options. |
| + Object.keys(ProxyLoginAttributes).forEach(function(key) { |
| + if (this[key] && this[key] !== '') { |
| + params[ProxyLoginAttributes[key]] = this[key]; |
| + } |
| + }, this); |
| + |
| + var promise; |
| + var user = gapi.auth2.getAuthInstance()['currentUser'].get(); |
| + if (!(this.offline || this.offlineAlwaysPrompt)) { |
| + if (user.getGrantedScopes()) { |
| + // additional auth, skip multiple account dialog |
| + promise = user.grant(params); |
| + } else { |
| + // initial signin |
| + promise = gapi.auth2.getAuthInstance().signIn(params); |
| + } |
| + } else { |
| + params.redirect_uri = 'postmessage'; |
| + if (this.offlineAlwaysPrompt) { |
| + params.approval_prompt = 'force'; |
| + } |
| + |
| + // Despite being documented at https://goo.gl/tiO0Bk |
| + // It doesn't seem like user.grantOfflineAccess() actually exists in |
| + // the current version of the Google Sign-In JS client we're using |
| + // through GoogleWebComponents. So in the offline case, we will not |
| + // distinguish between a first auth and an additional one. |
| + promise = gapi.auth2.getAuthInstance().grantOfflineAccess(params); |
| + } |
| + promise.then( |
| + function onFulfilled(response) { |
| + // If login was offline, response contains one string "code" |
| + // Otherwise it contains the user object already |
| + var newUser; |
| + if (response.code) { |
| + AuthEngine.offlineGranted = true; |
| + newUser = gapi.auth2.getAuthInstance()['currentUser'].get(); |
| + AuthEngine.setOfflineCode(response.code); |
| + } else { |
| + newUser = response; |
| + } |
| + |
| + var authResponse = newUser.getAuthResponse(); |
| + // Let the current user listener trigger the changes. |
| + }, |
| + function onRejected(error) { |
| + // Access denied is not an error, user hit cancel |
| + if ("Access denied." !== error.reason) { |
| + this.signinAwares.forEach(function(awareInstance) { |
| + awareInstance.errorNotify(error); |
| + }); |
| + } |
| + }.bind(this) |
| + ); |
| + }, |
| + |
| + /** signs user out */ |
| + signOut: function() { |
| + this.assertAuthInitialized(); |
| + gapi.auth2.getAuthInstance().signOut().then( |
| + function onFulfilled() { |
| + // Let the current user listener trigger the changes. |
| + }, |
| + function onRejected(error) { |
| + console.error(error); |
| + } |
| + ); |
| + } |
| + }; |
| + |
| + AuthEngine.init(); |
| + |
| +/** |
| +`google-signin-aware` is used to enable authentication in custom elements by |
| +interacting with a google-signin element that needs to be present somewhere |
| +on the page. |
| + |
| +The `scopes` attribute allows you to specify which scope permissions are required |
| +(e.g do you want to allow interaction with the Google Drive API). |
| + |
| +The `google-signin-aware-success` event is triggered when a user successfully |
| +authenticates. If either `offline` or `offlineAlwaysPrompt` is set to true, successful |
| +authentication will also trigger the `google-signin-offline-success`event. |
| +The `google-signin-aware-signed-out` event is triggered when a user explicitly |
| +signs out via the google-signin element. |
| + |
| +You can bind to `isAuthorized` property to monitor authorization state. |
| +##### Example |
| + |
| + <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google-signin-aware> |
| + |
| + |
| +##### Example with offline |
| + <template id="awareness" is="dom-bind"> |
| + <google-signin-aware |
| + scopes="https://www.googleapis.com/auth/drive" |
| + offline |
| + on-google-signin-aware-success="handleSignin" |
| + on-google-signin-offline-success="handleOffline"></google-signin-aware> |
| + <\/template> |
| + <script> |
| + var aware = document.querySelector('#awareness'); |
| + aware.handleSignin = function(response) { |
| + var user = gapi.auth2.getAuthInstance()['currentUser'].get(); |
| + console.log('User name: ' + user.getBasicProfile().getName()); |
| + }; |
| + aware.handleOffline = function(response) { |
| + console.log('Offline code received: ' + response.detail.code); |
| + // Here you would POST response.detail.code to your webserver, which can |
| + // exchange the authorization code for an access token. More info at: |
| + // https://developers.google.com/identity/protocols/OAuth2WebServer |
| + }; |
| + <\/script> |
| +*/ |
| + Polymer({ |
| + |
| + is: 'google-signin-aware', |
| + |
| + /** |
| + * Fired when this scope has been authorized |
| + * @param {Object} result Authorization result. |
| + * @event google-signin-aware-success |
| + */ |
| + |
| + /** |
| + * Fired when an offline authorization is successful. |
| + * @param {{code: string}} detail - |
| + * code: The one-time authorization code from Google. |
| + * Your application can exchange this for an `access_token` and `refresh_token` |
| + * @event google-signin-offline-success |
| + */ |
| + |
| + /** |
| + * Fired when this scope is not authorized |
| + * @event google-signin-aware-signed-out |
| + */ |
| + |
| + /** |
| + * Fired when there is an error during the signin flow. |
| + * @param {Object} detail The error object returned from the OAuth 2 flow. |
| + * @event google-signin-aware-error |
| + */ |
| + |
| + /** |
| + * This block is needed so the previous @param is not assigned to the next property. |
| + */ |
| + |
| + properties: { |
| + /** |
| + * App package name for android over-the-air installs. |
| + * See the relevant [docs](https://developers.google.com/+/web/signin/android-app-installs) |
| + */ |
| + appPackageName: { |
| + type: String, |
| + observer: '_appPackageNameChanged' |
| + }, |
| + |
| + /** |
| + * a Google Developers clientId reference |
| + */ |
| + clientId: { |
| + type: String, |
| + observer: '_clientIdChanged' |
| + }, |
| + |
| + /** |
| + * The cookie policy defines what URIs have access to the session cookie |
| + * remembering the user's sign-in state. |
| + * See the relevant [docs](https://developers.google.com/+/web/signin/reference#determining_a_value_for_cookie_policy) for more information. |
| + * @default 'single_host_origin' |
| + */ |
| + cookiePolicy: { |
| + type: String, |
| + observer: '_cookiePolicyChanged' |
| + }, |
| + |
| + /** |
| + * The app activity types you want to write on behalf of the user |
| + * (e.g http://schemas.google.com/AddActivity) |
| + * |
| + */ |
| + requestVisibleActions: { |
| + type: String, |
| + observer: '_requestVisibleActionsChanged' |
| + }, |
| + |
| + /** |
| + * The Google Apps domain to which users must belong to sign in. |
| + * See the relevant [docs](https://developers.google.com/identity/sign-in/web/reference) for more information. |
| + */ |
| + hostedDomain: { |
| + type: String, |
| + observer: '_hostedDomainChanged' |
| + }, |
| + |
| + /** |
| + * Allows for offline `access_token` retrieval during the signin process. |
| + * See also `offlineAlwaysPrompt`. You only need to set one of the two; if both |
| + * are set, the behavior of `offlineAlwaysPrompt` will override `offline`. |
| + */ |
| + offline: { |
| + type: Boolean, |
| + value: false, |
| + observer: '_offlineChanged' |
| + }, |
| + |
| + /** |
| + * Works the same as `offline` with the addition that it will always |
| + * force a re-prompt to the user, guaranteeing that you will get a |
| + * refresh_token even if the user has already granted offline access to |
| + * this application. You only need to set one of `offline` or |
| + * `offlineAlwaysPrompt`, not both. |
| + */ |
| + offlineAlwaysPrompt: { |
| + type: Boolean, |
| + value: false, |
| + observer: '_offlineAlwaysPromptChanged' |
| + }, |
| + |
| + /** |
| + * The scopes to provide access to (e.g https://www.googleapis.com/auth/drive) |
| + * and should be space-delimited. |
| + */ |
| + scopes: { |
| + type: String, |
| + value: 'profile', |
| + observer: '_scopesChanged' |
| + }, |
| + |
| + /** |
| + * Space-delimited, case-sensitive list of strings that |
| + * specifies whether the the user is prompted for reauthentication |
| + * and/or consent. The defined values are: |
| + * none: do not display authentication or consent pages. |
| + * This value is mutually exclusive with the rest. |
| + * login: always prompt the user for reauthentication. |
| + * consent: always show consent screen. |
| + * select_account: always show account selection page. |
| + * This enables a user who has multiple accounts to select amongst |
| + * the multiple accounts that they might have current sessions for. |
| + * For more information, see "prompt" parameter description in |
| + * https://openid.net/specs/openid-connect-basic-1_0.html#RequestParameters |
| + */ |
| + openidPrompt: { |
| + type: String, |
| + value: '', |
| + observer: '_openidPromptChanged' |
| + }, |
| + |
| + /** |
| + * True when the auth library has been initialized, and signedIn property value is set from the first api response. |
| + */ |
| + initialized: { |
| + type: Boolean, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * True if user is signed in |
| + */ |
| + signedIn: { |
| + type: Boolean, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * True if authorizations for *this* element have been granted |
| + */ |
| + isAuthorized: { |
| + type: Boolean, |
| + notify: true, |
| + readOnly: true, |
| + value: false |
| + }, |
| + |
| + /** |
| + * True if additional authorizations for *any* element are required |
| + */ |
| + needAdditionalAuth: { |
| + type: Boolean, |
| + notify: true, |
| + readOnly: true |
| + }, |
| + |
| + /** |
| + * True if *any* element has google+ scopes |
| + */ |
| + hasPlusScopes: { |
| + type: Boolean, |
| + value: false, |
| + notify: true, |
| + readOnly: true |
| + } |
| + }, |
| + |
| + attached: function() { |
| + AuthEngine.attachSigninAware(this); |
| + }, |
| + |
| + detached: function() { |
| + AuthEngine.detachSigninAware(this); |
| + }, |
| + |
| + /** pops up the authorization dialog */ |
| + signIn: function() { |
| + AuthEngine.signIn(); |
| + }, |
| + |
| + /** signs user out */ |
| + signOut: function() { |
| + AuthEngine.signOut(); |
| + }, |
| + |
| + errorNotify: function(error) { |
| + this.fire('google-signin-aware-error', error); |
| + }, |
| + |
| + _appPackageNameChanged: function(newName, oldName) { |
| + AuthEngine.appPackageName = newName; |
| + }, |
| + |
| + _clientIdChanged: function(newId, oldId) { |
| + AuthEngine.clientId = newId; |
| + }, |
| + |
| + _cookiePolicyChanged: function(newPolicy, oldPolicy) { |
| + AuthEngine.cookiePolicy = newPolicy; |
| + }, |
| + |
| + _requestVisibleActionsChanged: function(newVal, oldVal) { |
| + AuthEngine.requestVisibleActions = newVal; |
| + }, |
| + |
| + _hostedDomainChanged: function(newVal, oldVal) { |
| + AuthEngine.hostedDomain = newVal; |
| + }, |
| + |
| + _offlineChanged: function(newVal, oldVal) { |
| + AuthEngine.offline = newVal; |
| + }, |
| + |
| + _offlineAlwaysPromptChanged: function(newVal, oldVal) { |
| + AuthEngine.offlineAlwaysPrompt = newVal; |
| + }, |
| + |
| + _scopesChanged: function(newVal, oldVal) { |
| + AuthEngine.requestScopes(newVal); |
| + this._updateScopeStatus(undefined); |
| + }, |
| + |
| + _openidPromptChanged: function(newVal, oldVal) { |
| + AuthEngine.openidPrompt = newVal; |
| + }, |
| + |
| + _updateScopeStatus: function(user) { |
| + var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.scopes); |
| + if (newAuthorized !== this.isAuthorized) { |
| + this._setIsAuthorized(newAuthorized); |
| + if (newAuthorized) { |
| + this.fire('google-signin-aware-success', user); |
| + } |
| + else { |
| + this.fire('google-signin-aware-signed-out', user); |
| + } |
| + } |
| + }, |
| + |
| + _updateOfflineCode: function(code) { |
| + if (code) { |
| + this.fire('google-signin-offline-success', {code: code}); |
| + } |
| + } |
| + }); |
| + })(); |
| +</script> |