| 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 |