Index: lib/src/google-signin/google-signin-aware.html |
diff --git a/lib/src/google-signin/google-signin-aware.html b/lib/src/google-signin/google-signin-aware.html |
index ab8e045288482fe6e58762aa02734feacc5a8911..e28d8be4519eb3bbfebc6fa6c3b2ae9f1da4a0b2 100644 |
--- a/lib/src/google-signin/google-signin-aware.html |
+++ b/lib/src/google-signin/google-signin-aware.html |
@@ -13,7 +13,8 @@ |
'appPackageName': 'apppackagename', |
'clientId': 'clientid', |
'cookiePolicy': 'cookiepolicy', |
- 'requestVisibleActions': 'requestvisibleactions' |
+ 'requestVisibleActions': 'requestvisibleactions', |
+ 'hostedDomain': 'hostedDomain' |
}; |
/** |
@@ -97,6 +98,50 @@ |
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; |
+ }, |
+ |
+ /** 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, |
@@ -142,7 +187,8 @@ |
var auth = gapi.auth2.init({ |
'client_id': this.clientId, |
'cookie_policy': this.cookiePolicy, |
- 'scope': this.requestedScopes |
+ 'scope': this.requestedScopes, |
+ 'hosted_domain': this.hostedDomain |
}); |
auth.currentUser.listen(this.handleUserUpdate.bind(this)); |
@@ -179,6 +225,12 @@ |
} |
}, |
+ 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) { |
@@ -237,10 +289,14 @@ |
/** update status of _needAdditionalAuth */ |
updateAdditionalAuth: function() { |
var needMoreAuth = false; |
- for (var i=0; i<this._requestedScopeArray.length; i++) { |
- if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) === -1) { |
- needMoreAuth = true; |
- break; |
+ 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) { |
@@ -327,15 +383,40 @@ |
var promise; |
var user = gapi.auth2.getAuthInstance().currentUser.get(); |
- if (user.getGrantedScopes()) { |
- // additional auth, skip multiple account dialog |
- promise = user.grant(params); |
+ 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 { |
- // initial signin |
- promise = gapi.auth2.getAuthInstance().signIn(params); |
+ 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 success(newUser) { |
+ function success(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. |
}, |
@@ -375,13 +456,38 @@ The `scopes` attribute allows you to specify which scope permissions are require |
(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. The `google-signin-aware-signed-out` event is triggered |
-when a user explicitely signs out via the google-signin element. |
+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({ |
@@ -393,6 +499,13 @@ You can bind to `isAuthorized` property to monitor authorization state. |
* @event google-signin-aware-success |
*/ |
/** |
+ * Fired when an offline authorization is successful. |
+ * @param {Object} detail |
+ * @param {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 |
*/ |
@@ -434,6 +547,39 @@ You can bind to `isAuthorized` property to monitor authorization state. |
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. |
@@ -517,6 +663,18 @@ You can bind to `isAuthorized` property to monitor authorization state. |
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(); |
@@ -533,6 +691,12 @@ You can bind to `isAuthorized` property to monitor authorization state. |
this.fire('google-signin-aware-signed-out', user); |
} |
} |
+ }, |
+ |
+ _updateOfflineCode: function(code) { |
+ if (code) { |
+ this.fire('google-signin-offline-success', {code: code}); |
+ } |
} |
}); |
})(); |