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 * Authenticator class wraps the communications between Gaia and its host. | 6 * Authenticator class wraps the communications between Gaia and its host. |
7 */ | 7 */ |
8 function Authenticator() { | 8 function Authenticator() {} |
9 } | |
10 | 9 |
11 /** | 10 /** |
12 * Gaia auth extension url origin. | 11 * Gaia auth extension url origin. |
13 * @type {string} | 12 * @type {string} |
14 */ | 13 */ |
15 Authenticator.THIS_EXTENSION_ORIGIN = | 14 Authenticator.THIS_EXTENSION_ORIGIN = |
16 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik'; | 15 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik'; |
17 | 16 |
18 /** | 17 /** |
19 * The lowest version of the credentials passing API supported. | 18 * The lowest version of the credentials passing API supported. |
(...skipping 12 matching lines...) Expand all Loading... |
32 * @type {Array} Array of strings. | 31 * @type {Array} Array of strings. |
33 */ | 32 */ |
34 Authenticator.API_KEY_TYPES = [ | 33 Authenticator.API_KEY_TYPES = [ |
35 'KEY_TYPE_PASSWORD_PLAIN', | 34 'KEY_TYPE_PASSWORD_PLAIN', |
36 ]; | 35 ]; |
37 | 36 |
38 /** | 37 /** |
39 * Allowed origins of the hosting page. | 38 * Allowed origins of the hosting page. |
40 * @type {Array<string>} | 39 * @type {Array<string>} |
41 */ | 40 */ |
42 Authenticator.ALLOWED_PARENT_ORIGINS = [ | 41 Authenticator.ALLOWED_PARENT_ORIGINS = |
43 'chrome://oobe', | 42 ['chrome://oobe', 'chrome://chrome-signin']; |
44 'chrome://chrome-signin' | |
45 ]; | |
46 | 43 |
47 /** | 44 /** |
48 * Singleton getter of Authenticator. | 45 * Singleton getter of Authenticator. |
49 * @return {Object} The singleton instance of Authenticator. | 46 * @return {Object} The singleton instance of Authenticator. |
50 */ | 47 */ |
51 Authenticator.getInstance = function() { | 48 Authenticator.getInstance = function() { |
52 if (!Authenticator.instance_) { | 49 if (!Authenticator.instance_) { |
53 Authenticator.instance_ = new Authenticator(); | 50 Authenticator.instance_ = new Authenticator(); |
54 } | 51 } |
55 return Authenticator.instance_; | 52 return Authenticator.instance_; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 this.initialFrameUrl_ = params.frameUrl || this.constructInitialFrameUrl_(); | 121 this.initialFrameUrl_ = params.frameUrl || this.constructInitialFrameUrl_(); |
125 this.initialFrameUrlWithoutParams_ = stripParams(this.initialFrameUrl_); | 122 this.initialFrameUrlWithoutParams_ = stripParams(this.initialFrameUrl_); |
126 this.needPassword_ = params.needPassword == '1'; | 123 this.needPassword_ = params.needPassword == '1'; |
127 | 124 |
128 // For CrOS 'ServiceLogin' we assume that Gaia is loaded if we recieved | 125 // For CrOS 'ServiceLogin' we assume that Gaia is loaded if we recieved |
129 // 'clearOldAttempts' message. For other scenarios Gaia doesn't send this | 126 // 'clearOldAttempts' message. For other scenarios Gaia doesn't send this |
130 // message so we have to rely on 'load' event. | 127 // message so we have to rely on 'load' event. |
131 // TODO(dzhioev): Do not rely on 'load' event after b/16313327 is fixed. | 128 // TODO(dzhioev): Do not rely on 'load' event after b/16313327 is fixed. |
132 this.assumeLoadedOnLoadEvent_ = | 129 this.assumeLoadedOnLoadEvent_ = |
133 !this.gaiaPath_.startsWith('ServiceLogin') || | 130 !this.gaiaPath_.startsWith('ServiceLogin') || |
134 this.service_ !== 'chromeoslogin' || | 131 this.service_ !== 'chromeoslogin' || this.useEafe_; |
135 this.useEafe_; | |
136 }, | 132 }, |
137 | 133 |
138 isGaiaMessage_: function(msg) { | 134 isGaiaMessage_: function(msg) { |
139 // Not quite right, but good enough. | 135 // Not quite right, but good enough. |
140 return this.gaiaUrl_.startsWith(msg.origin) || | 136 return this.gaiaUrl_.startsWith(msg.origin) || |
141 this.GAIA_URL.startsWith(msg.origin); | 137 this.GAIA_URL.startsWith(msg.origin); |
142 }, | 138 }, |
143 | 139 |
144 isParentMessage_: function(msg) { | 140 isParentMessage_: function(msg) { |
145 return msg.origin == this.parentPage_; | 141 return msg.origin == this.parentPage_; |
146 }, | 142 }, |
147 | 143 |
148 constructInitialFrameUrl_: function() { | 144 constructInitialFrameUrl_: function() { |
149 var url = this.gaiaUrl_ + this.gaiaPath_; | 145 var url = this.gaiaUrl_ + this.gaiaPath_; |
150 | 146 |
151 url = appendParam(url, 'service', this.service_); | 147 url = appendParam(url, 'service', this.service_); |
(...skipping 18 matching lines...) Expand all Loading... |
170 var gaiaFrame = $('gaia-frame'); | 166 var gaiaFrame = $('gaia-frame'); |
171 var handler = function() { | 167 var handler = function() { |
172 gaiaFrame.removeEventListener('load', handler); | 168 gaiaFrame.removeEventListener('load', handler); |
173 if (!this.gaiaLoaded_) { | 169 if (!this.gaiaLoaded_) { |
174 this.gaiaLoaded_ = true; | 170 this.gaiaLoaded_ = true; |
175 this.maybeInitialized_(); | 171 this.maybeInitialized_(); |
176 | 172 |
177 if (this.useEafe_ && this.clientId_) { | 173 if (this.useEafe_ && this.clientId_) { |
178 // Sends initial handshake message to EAFE. Note this fails with | 174 // Sends initial handshake message to EAFE. Note this fails with |
179 // SSO redirect because |gaiaFrame| sits on a different origin. | 175 // SSO redirect because |gaiaFrame| sits on a different origin. |
180 gaiaFrame.contentWindow.postMessage({ | 176 gaiaFrame.contentWindow.postMessage( |
181 clientId: this.clientId_ | 177 {clientId: this.clientId_}, this.gaiaUrl_); |
182 }, this.gaiaUrl_); | |
183 } | 178 } |
184 } | 179 } |
185 }.bind(this); | 180 }.bind(this); |
186 gaiaFrame.addEventListener('load', handler); | 181 gaiaFrame.addEventListener('load', handler); |
187 } | 182 } |
188 }, | 183 }, |
189 | 184 |
190 initSupportChannel_: function() { | 185 initSupportChannel_: function() { |
191 var supportChannel = new Channel(); | 186 var supportChannel = new Channel(); |
192 supportChannel.connect('authMain'); | 187 supportChannel.connect('authMain'); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 }, | 230 }, |
236 | 231 |
237 /** | 232 /** |
238 * Called when one of the initialization stages has finished. If all the | 233 * Called when one of the initialization stages has finished. If all the |
239 * needed parts are initialized, notifies parent about successfull | 234 * needed parts are initialized, notifies parent about successfull |
240 * initialization. | 235 * initialization. |
241 */ | 236 */ |
242 maybeInitialized_: function() { | 237 maybeInitialized_: function() { |
243 if (!this.gaiaLoaded_ || !this.supportChannel_) | 238 if (!this.gaiaLoaded_ || !this.supportChannel_) |
244 return; | 239 return; |
245 var msg = { | 240 var msg = {'method': 'loginUILoaded'}; |
246 'method': 'loginUILoaded' | |
247 }; | |
248 window.parent.postMessage(msg, this.parentPage_); | 241 window.parent.postMessage(msg, this.parentPage_); |
249 }, | 242 }, |
250 | 243 |
251 /** | 244 /** |
252 * Invoked when the background script sends a message to indicate that the | 245 * Invoked when the background script sends a message to indicate that the |
253 * current content does not fit in a constrained window. | 246 * current content does not fit in a constrained window. |
254 * @param {Object=} msg Extra info to send. | 247 * @param {Object=} msg Extra info to send. |
255 */ | 248 */ |
256 switchToFullTab_: function(msg) { | 249 switchToFullTab_: function(msg) { |
257 var parentMsg = { | 250 var parentMsg = {'method': 'switchToFullTab', 'url': msg.url}; |
258 'method': 'switchToFullTab', | |
259 'url': msg.url | |
260 }; | |
261 window.parent.postMessage(parentMsg, this.parentPage_); | 251 window.parent.postMessage(parentMsg, this.parentPage_); |
262 }, | 252 }, |
263 | 253 |
264 /** | 254 /** |
265 * Invoked when the signin flow is complete. | 255 * Invoked when the signin flow is complete. |
266 * @param {Object=} opt_extraMsg Optional extra info to send. | 256 * @param {Object=} opt_extraMsg Optional extra info to send. |
267 */ | 257 */ |
268 completeLogin_: function(opt_extraMsg) { | 258 completeLogin_: function(opt_extraMsg) { |
269 var msg = { | 259 var msg = { |
270 'method': 'completeLogin', | 260 'method': 'completeLogin', |
271 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_, | 261 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_, |
272 'password': this.passwordBytes_ || | 262 'password': |
273 (opt_extraMsg && opt_extraMsg.password), | 263 this.passwordBytes_ || (opt_extraMsg && opt_extraMsg.password), |
274 'usingSAML': this.isSAMLFlow_, | 264 'usingSAML': this.isSAMLFlow_, |
275 'chooseWhatToSync': this.chooseWhatToSync_ || false, | 265 'chooseWhatToSync': this.chooseWhatToSync_ || false, |
276 'skipForNow': (opt_extraMsg && opt_extraMsg.skipForNow) || | 266 'skipForNow': |
277 this.skipForNow_, | 267 (opt_extraMsg && opt_extraMsg.skipForNow) || this.skipForNow_, |
278 'sessionIndex': (opt_extraMsg && opt_extraMsg.sessionIndex) || | 268 'sessionIndex': |
279 this.sessionIndex_, | 269 (opt_extraMsg && opt_extraMsg.sessionIndex) || this.sessionIndex_, |
280 'gaiaId': (opt_extraMsg && opt_extraMsg.gaiaId) || this.gaiaId_ | 270 'gaiaId': (opt_extraMsg && opt_extraMsg.gaiaId) || this.gaiaId_ |
281 }; | 271 }; |
282 window.parent.postMessage(msg, this.parentPage_); | 272 window.parent.postMessage(msg, this.parentPage_); |
283 this.supportChannel_.send({name: 'resetAuth'}); | 273 this.supportChannel_.send({name: 'resetAuth'}); |
284 }, | 274 }, |
285 | 275 |
286 /** | 276 /** |
287 * Invoked when support channel is connected. | 277 * Invoked when support channel is connected. |
288 */ | 278 */ |
289 initSAML_: function() { | 279 initSAML_: function() { |
290 this.isSAMLFlow_ = false; | 280 this.isSAMLFlow_ = false; |
291 | 281 |
292 this.supportChannel_.registerMessage( | 282 this.supportChannel_.registerMessage( |
293 'onAuthPageLoaded', this.onAuthPageLoaded_.bind(this)); | 283 'onAuthPageLoaded', this.onAuthPageLoaded_.bind(this)); |
294 this.supportChannel_.registerMessage( | 284 this.supportChannel_.registerMessage( |
295 'onInsecureContentBlocked', this.onInsecureContentBlocked_.bind(this)); | 285 'onInsecureContentBlocked', this.onInsecureContentBlocked_.bind(this)); |
296 this.supportChannel_.registerMessage( | 286 this.supportChannel_.registerMessage('apiCall', this.onAPICall_.bind(this)); |
297 'apiCall', this.onAPICall_.bind(this)); | 287 this.supportChannel_.send({name: 'setGaiaUrl', gaiaUrl: this.gaiaUrl_}); |
298 this.supportChannel_.send({ | |
299 name: 'setGaiaUrl', | |
300 gaiaUrl: this.gaiaUrl_ | |
301 }); | |
302 if (!this.desktopMode_ && this.gaiaUrl_.startsWith('https://')) { | 288 if (!this.desktopMode_ && this.gaiaUrl_.startsWith('https://')) { |
303 // Abort the login flow when content served over an unencrypted connection | 289 // Abort the login flow when content served over an unencrypted connection |
304 // is detected on Chrome OS. This does not apply to tests that explicitly | 290 // is detected on Chrome OS. This does not apply to tests that explicitly |
305 // set a non-https GAIA URL and want to perform all authentication over | 291 // set a non-https GAIA URL and want to perform all authentication over |
306 // http. | 292 // http. |
307 this.supportChannel_.send({ | 293 this.supportChannel_.send( |
308 name: 'setBlockInsecureContent', | 294 {name: 'setBlockInsecureContent', blockInsecureContent: true}); |
309 blockInsecureContent: true | |
310 }); | |
311 } | 295 } |
312 }, | 296 }, |
313 | 297 |
314 /** | 298 /** |
315 * Invoked when the background page sends 'onHostedPageLoaded' message. | 299 * Invoked when the background page sends 'onHostedPageLoaded' message. |
316 * @param {!Object} msg Details sent with the message. | 300 * @param {!Object} msg Details sent with the message. |
317 */ | 301 */ |
318 onAuthPageLoaded_: function(msg) { | 302 onAuthPageLoaded_: function(msg) { |
319 if (msg.isSAMLPage && !this.isSAMLFlow_) { | 303 if (msg.isSAMLPage && !this.isSAMLFlow_) { |
320 // GAIA redirected to a SAML login page. The credentials provided to this | 304 // GAIA redirected to a SAML login page. The credentials provided to this |
321 // page will determine what user gets logged in. The credentials obtained | 305 // page will determine what user gets logged in. The credentials obtained |
322 // from the GAIA login form are no longer relevant and can be discarded. | 306 // from the GAIA login form are no longer relevant and can be discarded. |
323 this.isSAMLFlow_ = true; | 307 this.isSAMLFlow_ = true; |
324 this.email_ = null; | 308 this.email_ = null; |
325 this.gaiaId_ = null; | 309 this.gaiaId_ = null; |
326 this.passwordBytes_ = null; | 310 this.passwordBytes_ = null; |
327 } | 311 } |
328 | 312 |
329 window.parent.postMessage({ | 313 window.parent.postMessage( |
330 'method': 'authPageLoaded', | 314 { |
331 'isSAML': this.isSAMLFlow_, | 315 'method': 'authPageLoaded', |
332 'domain': extractDomain(msg.url) | 316 'isSAML': this.isSAMLFlow_, |
333 }, this.parentPage_); | 317 'domain': extractDomain(msg.url) |
| 318 }, |
| 319 this.parentPage_); |
334 }, | 320 }, |
335 | 321 |
336 /** | 322 /** |
337 * Invoked when the background page sends an 'onInsecureContentBlocked' | 323 * Invoked when the background page sends an 'onInsecureContentBlocked' |
338 * message. | 324 * message. |
339 * @param {!Object} msg Details sent with the message. | 325 * @param {!Object} msg Details sent with the message. |
340 */ | 326 */ |
341 onInsecureContentBlocked_: function(msg) { | 327 onInsecureContentBlocked_: function(msg) { |
342 window.parent.postMessage({ | 328 window.parent.postMessage( |
343 'method': 'insecureContentBlocked', | 329 {'method': 'insecureContentBlocked', 'url': stripParams(msg.url)}, |
344 'url': stripParams(msg.url) | 330 this.parentPage_); |
345 }, this.parentPage_); | |
346 }, | 331 }, |
347 | 332 |
348 /** | 333 /** |
349 * Invoked when one of the credential passing API methods is called by a SAML | 334 * Invoked when one of the credential passing API methods is called by a SAML |
350 * provider. | 335 * provider. |
351 * @param {!Object} msg Details of the API call. | 336 * @param {!Object} msg Details of the API call. |
352 */ | 337 */ |
353 onAPICall_: function(msg) { | 338 onAPICall_: function(msg) { |
354 var call = msg.call; | 339 var call = msg.call; |
355 if (call.method == 'initialize') { | 340 if (call.method == 'initialize') { |
356 if (!Number.isInteger(call.requestedVersion) || | 341 if (!Number.isInteger(call.requestedVersion) || |
357 call.requestedVersion < Authenticator.MIN_API_VERSION_VERSION) { | 342 call.requestedVersion < Authenticator.MIN_API_VERSION_VERSION) { |
358 this.sendInitializationFailure_(); | 343 this.sendInitializationFailure_(); |
359 return; | 344 return; |
360 } | 345 } |
361 | 346 |
362 this.apiVersion_ = Math.min(call.requestedVersion, | 347 this.apiVersion_ = Math.min( |
363 Authenticator.MAX_API_VERSION_VERSION); | 348 call.requestedVersion, Authenticator.MAX_API_VERSION_VERSION); |
364 this.initialized_ = true; | 349 this.initialized_ = true; |
365 this.sendInitializationSuccess_(); | 350 this.sendInitializationSuccess_(); |
366 return; | 351 return; |
367 } | 352 } |
368 | 353 |
369 if (call.method == 'add') { | 354 if (call.method == 'add') { |
370 if (Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) { | 355 if (Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) { |
371 console.error('Authenticator.onAPICall_: unsupported key type'); | 356 console.error('Authenticator.onAPICall_: unsupported key type'); |
372 return; | 357 return; |
373 } | 358 } |
374 // Not setting |email_| and |gaiaId_| because this API call will | 359 // Not setting |email_| and |gaiaId_| because this API call will |
375 // eventually be followed by onCompleteLogin_() which does set it. | 360 // eventually be followed by onCompleteLogin_() which does set it. |
376 this.apiToken_ = call.token; | 361 this.apiToken_ = call.token; |
377 this.passwordBytes_ = call.passwordBytes; | 362 this.passwordBytes_ = call.passwordBytes; |
378 } else if (call.method == 'confirm') { | 363 } else if (call.method == 'confirm') { |
379 if (call.token != this.apiToken_) | 364 if (call.token != this.apiToken_) |
380 console.error('Authenticator.onAPICall_: token mismatch'); | 365 console.error('Authenticator.onAPICall_: token mismatch'); |
381 } else { | 366 } else { |
382 console.error('Authenticator.onAPICall_: unknown message'); | 367 console.error('Authenticator.onAPICall_: unknown message'); |
383 } | 368 } |
384 }, | 369 }, |
385 | 370 |
386 onGotAuthCode_: function(authCode) { | 371 onGotAuthCode_: function(authCode) { |
387 window.parent.postMessage({ | 372 window.parent.postMessage( |
388 'method': 'completeAuthenticationAuthCodeOnly', | 373 {'method': 'completeAuthenticationAuthCodeOnly', 'authCode': authCode}, |
389 'authCode': authCode | 374 this.parentPage_); |
390 }, this.parentPage_); | |
391 }, | 375 }, |
392 | 376 |
393 sendInitializationSuccess_: function() { | 377 sendInitializationSuccess_: function() { |
394 this.supportChannel_.send({name: 'apiResponse', response: { | 378 this.supportChannel_.send({ |
395 result: 'initialized', | 379 name: 'apiResponse', |
396 version: this.apiVersion_, | 380 response: { |
397 keyTypes: Authenticator.API_KEY_TYPES | 381 result: 'initialized', |
398 }}); | 382 version: this.apiVersion_, |
| 383 keyTypes: Authenticator.API_KEY_TYPES |
| 384 } |
| 385 }); |
399 }, | 386 }, |
400 | 387 |
401 sendInitializationFailure_: function() { | 388 sendInitializationFailure_: function() { |
402 this.supportChannel_.send({ | 389 this.supportChannel_.send( |
403 name: 'apiResponse', | 390 {name: 'apiResponse', response: {result: 'initialization_failed'}}); |
404 response: {result: 'initialization_failed'} | |
405 }); | |
406 }, | 391 }, |
407 | 392 |
408 /** | 393 /** |
409 * Callback invoked for 'completeLogin' message. | 394 * Callback invoked for 'completeLogin' message. |
410 * @param {Object=} msg Message sent from background page. | 395 * @param {Object=} msg Message sent from background page. |
411 */ | 396 */ |
412 onCompleteLogin_: function(msg) { | 397 onCompleteLogin_: function(msg) { |
413 if (!msg.email || !msg.gaiaId || !msg.sessionIndex) { | 398 if (!msg.email || !msg.gaiaId || !msg.sessionIndex) { |
414 // On desktop, if the skipForNow message field is set, send it to handler. | 399 // On desktop, if the skipForNow message field is set, send it to handler. |
415 // This does not require the email, gaiaid or session to be valid. | 400 // This does not require the email, gaiaid or session to be valid. |
416 if (this.desktopMode_ && msg.skipForNow) { | 401 if (this.desktopMode_ && msg.skipForNow) { |
417 this.completeLogin_(msg); | 402 this.completeLogin_(msg); |
418 } else { | 403 } else { |
419 console.error('Missing fields to complete login.'); | 404 console.error('Missing fields to complete login.'); |
420 window.parent.postMessage({method: 'missingGaiaInfo'}, | 405 window.parent.postMessage( |
421 this.parentPage_); | 406 {method: 'missingGaiaInfo'}, this.parentPage_); |
422 return; | 407 return; |
423 } | 408 } |
424 } | 409 } |
425 | 410 |
426 // Skip SAML extra steps for desktop flow and non-SAML flow. | 411 // Skip SAML extra steps for desktop flow and non-SAML flow. |
427 if (!this.isSAMLFlow_ || this.desktopMode_) { | 412 if (!this.isSAMLFlow_ || this.desktopMode_) { |
428 this.completeLogin_(msg); | 413 this.completeLogin_(msg); |
429 return; | 414 return; |
430 } | 415 } |
431 | 416 |
432 this.email_ = msg.email; | 417 this.email_ = msg.email; |
433 this.gaiaId_ = msg.gaiaId; | 418 this.gaiaId_ = msg.gaiaId; |
434 // Password from |msg| is not used because ChromeOS SAML flow | 419 // Password from |msg| is not used because ChromeOS SAML flow |
435 // gets password by asking user to confirm. | 420 // gets password by asking user to confirm. |
436 this.skipForNow_ = msg.skipForNow; | 421 this.skipForNow_ = msg.skipForNow; |
437 this.sessionIndex_ = msg.sessionIndex; | 422 this.sessionIndex_ = msg.sessionIndex; |
438 | 423 |
439 if (this.passwordBytes_) { | 424 if (this.passwordBytes_) { |
440 // If the credentials passing API was used, login is complete. | 425 // If the credentials passing API was used, login is complete. |
441 window.parent.postMessage({method: 'samlApiUsed'}, this.parentPage_); | 426 window.parent.postMessage({method: 'samlApiUsed'}, this.parentPage_); |
442 this.completeLogin_(msg); | 427 this.completeLogin_(msg); |
443 } else if (!this.needPassword_) { | 428 } else if (!this.needPassword_) { |
444 // If the credentials passing API was not used, the password was obtained | 429 // If the credentials passing API was not used, the password was obtained |
445 // by scraping. It must be verified before use. However, the host may not | 430 // by scraping. It must be verified before use. However, the host may not |
446 // be interested in the password at all. In that case, verification is | 431 // be interested in the password at all. In that case, verification is |
447 // unnecessary and login is complete. | 432 // unnecessary and login is complete. |
448 this.completeLogin_(msg); | 433 this.completeLogin_(msg); |
449 } else { | 434 } else { |
450 this.supportChannel_.sendWithCallback( | 435 this.supportChannel_.sendWithCallback( |
451 {name: 'getScrapedPasswords'}, | 436 {name: 'getScrapedPasswords'}, function(passwords) { |
452 function(passwords) { | |
453 if (passwords.length == 0) { | 437 if (passwords.length == 0) { |
454 window.parent.postMessage( | 438 window.parent.postMessage( |
455 {method: 'noPassword', email: this.email_}, | 439 {method: 'noPassword', email: this.email_}, this.parentPage_); |
| 440 } else { |
| 441 window.parent.postMessage( |
| 442 { |
| 443 method: 'confirmPassword', |
| 444 email: this.email_, |
| 445 passwordCount: passwords.length |
| 446 }, |
456 this.parentPage_); | 447 this.parentPage_); |
457 } else { | |
458 window.parent.postMessage({method: 'confirmPassword', | |
459 email: this.email_, | |
460 passwordCount: passwords.length}, | |
461 this.parentPage_); | |
462 } | 448 } |
463 }.bind(this)); | 449 }.bind(this)); |
464 } | 450 } |
465 }, | 451 }, |
466 | 452 |
467 onVerifyConfirmedPassword_: function(password) { | 453 onVerifyConfirmedPassword_: function(password) { |
468 this.supportChannel_.sendWithCallback( | 454 this.supportChannel_.sendWithCallback( |
469 {name: 'getScrapedPasswords'}, | 455 {name: 'getScrapedPasswords'}, function(passwords) { |
470 function(passwords) { | |
471 for (var i = 0; i < passwords.length; ++i) { | 456 for (var i = 0; i < passwords.length; ++i) { |
472 if (passwords[i] == password) { | 457 if (passwords[i] == password) { |
473 this.passwordBytes_ = passwords[i]; | 458 this.passwordBytes_ = passwords[i]; |
474 // SAML login is complete when the user has successfully | 459 // SAML login is complete when the user has successfully |
475 // confirmed the password. | 460 // confirmed the password. |
476 if (this.passwordBytes_ !== null) | 461 if (this.passwordBytes_ !== null) |
477 this.completeLogin_(); | 462 this.completeLogin_(); |
478 return; | 463 return; |
479 } | 464 } |
480 } | 465 } |
481 window.parent.postMessage( | 466 window.parent.postMessage( |
482 {method: 'confirmPassword', email: this.email_}, | 467 {method: 'confirmPassword', email: this.email_}, |
483 this.parentPage_); | 468 this.parentPage_); |
484 }.bind(this)); | 469 }.bind(this)); |
485 }, | 470 }, |
486 | 471 |
487 onMessage: function(e) { | 472 onMessage: function(e) { |
488 var msg = e.data; | 473 var msg = e.data; |
489 | 474 |
490 if (this.useEafe_) { | 475 if (this.useEafe_) { |
491 if (msg == '!_{h:\'gaia-frame\'}' && this.isGaiaMessage_(e)) { | 476 if (msg == '!_{h:\'gaia-frame\'}' && this.isGaiaMessage_(e)) { |
492 // Sends client ID again on the hello message to work around the SSO | 477 // Sends client ID again on the hello message to work around the SSO |
493 // signin issue. | 478 // signin issue. |
494 // TODO(xiyuan): Revisit this when EAFE is integrated or for webview. | 479 // TODO(xiyuan): Revisit this when EAFE is integrated or for webview. |
495 $('gaia-frame').contentWindow.postMessage({ | 480 $('gaia-frame') |
496 clientId: this.clientId_ | 481 .contentWindow.postMessage( |
497 }, this.gaiaUrl_); | 482 {clientId: this.clientId_}, this.gaiaUrl_); |
498 } else if (typeof msg == 'object' && | 483 } else if ( |
499 msg.type == 'authorizationCode' && this.isGaiaMessage_(e)) { | 484 typeof msg == 'object' && msg.type == 'authorizationCode' && |
| 485 this.isGaiaMessage_(e)) { |
500 this.onGotAuthCode_(msg.authorizationCode); | 486 this.onGotAuthCode_(msg.authorizationCode); |
501 } else { | 487 } else { |
502 console.error('Authenticator.onMessage: unknown message' + | 488 console.error( |
503 ', msg=' + JSON.stringify(msg)); | 489 'Authenticator.onMessage: unknown message' + |
| 490 ', msg=' + JSON.stringify(msg)); |
504 } | 491 } |
505 | 492 |
506 return; | 493 return; |
507 } | 494 } |
508 | 495 |
509 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) { | 496 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) { |
510 // At this point GAIA does not yet know the gaiaId, so its not set here. | 497 // At this point GAIA does not yet know the gaiaId, so its not set here. |
511 this.email_ = msg.email; | 498 this.email_ = msg.email; |
512 this.passwordBytes_ = msg.password; | 499 this.passwordBytes_ = msg.password; |
513 this.attemptToken_ = msg.attemptToken; | 500 this.attemptToken_ = msg.attemptToken; |
(...skipping 13 matching lines...) Expand all Loading... |
527 this.sessionIndex_ = false; | 514 this.sessionIndex_ = false; |
528 this.passwordBytes_ = null; | 515 this.passwordBytes_ = null; |
529 this.attemptToken_ = null; | 516 this.attemptToken_ = null; |
530 this.isSAMLFlow_ = false; | 517 this.isSAMLFlow_ = false; |
531 this.skipForNow_ = false; | 518 this.skipForNow_ = false; |
532 this.chooseWhatToSync_ = false; | 519 this.chooseWhatToSync_ = false; |
533 if (this.supportChannel_) { | 520 if (this.supportChannel_) { |
534 this.supportChannel_.send({name: 'resetAuth'}); | 521 this.supportChannel_.send({name: 'resetAuth'}); |
535 // This message is for clearing saml properties in gaia_auth_host and | 522 // This message is for clearing saml properties in gaia_auth_host and |
536 // oobe_screen_oauth_enrollment. | 523 // oobe_screen_oauth_enrollment. |
537 window.parent.postMessage({ | 524 window.parent.postMessage( |
538 'method': 'resetAuthFlow', | 525 { |
539 }, this.parentPage_); | 526 'method': 'resetAuthFlow', |
| 527 }, |
| 528 this.parentPage_); |
540 } | 529 } |
541 } else if (msg.method == 'verifyConfirmedPassword' && | 530 } else if ( |
542 this.isParentMessage_(e)) { | 531 msg.method == 'verifyConfirmedPassword' && this.isParentMessage_(e)) { |
543 this.onVerifyConfirmedPassword_(msg.password); | 532 this.onVerifyConfirmedPassword_(msg.password); |
544 } else if (msg.method == 'redirectToSignin' && | 533 } else if (msg.method == 'redirectToSignin' && this.isParentMessage_(e)) { |
545 this.isParentMessage_(e)) { | |
546 $('gaia-frame').src = this.constructInitialFrameUrl_(); | 534 $('gaia-frame').src = this.constructInitialFrameUrl_(); |
547 } else { | 535 } else { |
548 console.error('Authenticator.onMessage: unknown message + origin!?'); | 536 console.error('Authenticator.onMessage: unknown message + origin!?'); |
549 } | 537 } |
550 } | 538 } |
551 }; | 539 }; |
552 | 540 |
553 Authenticator.getInstance().initialize(); | 541 Authenticator.getInstance().initialize(); |
OLD | NEW |