OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * OAuth2 class that handles retrieval/storage of an OAuth2 token. | 7 * OAuth2 class that handles retrieval/storage of an OAuth2 token. |
8 * | 8 * |
9 * Uses a content script to trampoline the OAuth redirect page back into the | 9 * Uses a content script to trampoline the OAuth redirect page back into the |
10 * extension context. This works around the lack of native support for | 10 * extension context. This works around the lack of native support for |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 * @return {{token: string, expiration: number}} The current access token, or | 141 * @return {{token: string, expiration: number}} The current access token, or |
142 * an invalid token if not authenticated. | 142 * an invalid token if not authenticated. |
143 */ | 143 */ |
144 remoting.OAuth2.prototype.getAccessTokenInternal_ = function() { | 144 remoting.OAuth2.prototype.getAccessTokenInternal_ = function() { |
145 if (!window.localStorage.getItem(this.KEY_ACCESS_TOKEN_)) { | 145 if (!window.localStorage.getItem(this.KEY_ACCESS_TOKEN_)) { |
146 // Always be able to return structured data. | 146 // Always be able to return structured data. |
147 this.setAccessToken('', 0); | 147 this.setAccessToken('', 0); |
148 } | 148 } |
149 var accessToken = window.localStorage.getItem(this.KEY_ACCESS_TOKEN_); | 149 var accessToken = window.localStorage.getItem(this.KEY_ACCESS_TOKEN_); |
150 if (typeof accessToken == 'string') { | 150 if (typeof accessToken == 'string') { |
151 var result = JSON.parse(accessToken); | 151 var result = jsonParseSafe(accessToken); |
152 if ('token' in result && 'expiration' in result) { | 152 if (result && 'token' in result && 'expiration' in result) { |
153 return /** @type {{token: string, expiration: number}} */ result; | 153 return /** @type {{token: string, expiration: number}} */ result; |
154 } | 154 } |
155 } | 155 } |
156 console.log('Invalid access token stored.'); | 156 console.log('Invalid access token stored.'); |
157 return {'token': '', 'expiration': 0}; | 157 return {'token': '', 'expiration': 0}; |
158 }; | 158 }; |
159 | 159 |
160 /** | 160 /** |
161 * Returns true if the access token is expired, or otherwise invalid. | 161 * Returns true if the access token is expired, or otherwise invalid. |
162 * | 162 * |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 199 |
200 /** | 200 /** |
201 * Update state based on token response from the OAuth2 /token endpoint. | 201 * Update state based on token response from the OAuth2 /token endpoint. |
202 * | 202 * |
203 * @private | 203 * @private |
204 * @param {XMLHttpRequest} xhr The XHR object for this request. | 204 * @param {XMLHttpRequest} xhr The XHR object for this request. |
205 * @return {void} Nothing. | 205 * @return {void} Nothing. |
206 */ | 206 */ |
207 remoting.OAuth2.prototype.processTokenResponse_ = function(xhr) { | 207 remoting.OAuth2.prototype.processTokenResponse_ = function(xhr) { |
208 if (xhr.status == 200) { | 208 if (xhr.status == 200) { |
209 var tokens = JSON.parse(xhr.responseText); | 209 var tokens = jsonParseSafe(xhr.responseText); |
210 if ('refresh_token' in tokens) { | 210 if (tokens) { |
211 this.setRefreshToken(tokens['refresh_token']); | 211 if ('refresh_token' in tokens) { |
| 212 this.setRefreshToken(tokens['refresh_token']); |
| 213 } |
| 214 |
| 215 // Offset by 120 seconds so that we can guarantee that the token |
| 216 // we return will be valid for at least 2 minutes. |
| 217 // If the access token is to be useful, this object must make some |
| 218 // guarantee as to how long the token will be valid for. |
| 219 // The choice of 2 minutes is arbitrary, but that length of time |
| 220 // is part of the contract satisfied by callWithToken(). |
| 221 // Offset by a further 30 seconds to account for RTT issues. |
| 222 this.setAccessToken(tokens['access_token'], |
| 223 (tokens['expires_in'] - (120 + 30)) * 1000 + Date.now()); |
| 224 } else { |
| 225 console.error('Invalid "token" response from server.'); |
212 } | 226 } |
213 | |
214 // Offset by 120 seconds so that we can guarantee that the token | |
215 // we return will be valid for at least 2 minutes. | |
216 // If the access token is to be useful, this object must make some | |
217 // guarantee as to how long the token will be valid for. | |
218 // The choice of 2 minutes is arbitrary, but that length of time | |
219 // is part of the contract satisfied by callWithToken(). | |
220 // Offset by a further 30 seconds to account for RTT issues. | |
221 this.setAccessToken(tokens['access_token'], | |
222 (tokens['expires_in'] - (120 + 30)) * 1000 + Date.now()); | |
223 } else { | 227 } else { |
224 console.log('Failed to get tokens. Status: ' + xhr.status + | 228 console.error('Failed to get tokens. Status: ' + xhr.status + |
225 ' response: ' + xhr.responseText); | 229 ' response: ' + xhr.responseText); |
226 } | 230 } |
227 }; | 231 }; |
228 | 232 |
229 /** | 233 /** |
230 * Asynchronously retrieves a new access token from the server. | 234 * Asynchronously retrieves a new access token from the server. |
231 * | 235 * |
232 * Will throw if !isAuthenticated(). | 236 * Will throw if !isAuthenticated(). |
233 * | 237 * |
234 * @param {function(XMLHttpRequest): void} onDone Callback to invoke on | 238 * @param {function(XMLHttpRequest): void} onDone Callback to invoke on |
235 * completion. | 239 * completion. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 * @return {?string} The email address, if it has been cached by a previous call | 405 * @return {?string} The email address, if it has been cached by a previous call |
402 * to getEmail, otherwise null. | 406 * to getEmail, otherwise null. |
403 */ | 407 */ |
404 remoting.OAuth2.prototype.getCachedEmail = function() { | 408 remoting.OAuth2.prototype.getCachedEmail = function() { |
405 var value = window.localStorage.getItem(this.KEY_EMAIL_); | 409 var value = window.localStorage.getItem(this.KEY_EMAIL_); |
406 if (typeof value == 'string') { | 410 if (typeof value == 'string') { |
407 return value; | 411 return value; |
408 } | 412 } |
409 return null; | 413 return null; |
410 }; | 414 }; |
OLD | NEW |