| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Authenticator class wraps the communications between Gaia and its host. | |
| 7 */ | |
| 8 function Authenticator() { | |
| 9 } | |
| 10 | |
| 11 /** | |
| 12 * Gaia auth extension url origin. | |
| 13 * @type {string} | |
| 14 */ | |
| 15 Authenticator.THIS_EXTENSION_ORIGIN = | |
| 16 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik'; | |
| 17 | |
| 18 /** | |
| 19 * The lowest version of the credentials passing API supported. | |
| 20 * @type {number} | |
| 21 */ | |
| 22 Authenticator.MIN_API_VERSION_VERSION = 1; | |
| 23 | |
| 24 /** | |
| 25 * The highest version of the credentials passing API supported. | |
| 26 * @type {number} | |
| 27 */ | |
| 28 Authenticator.MAX_API_VERSION_VERSION = 1; | |
| 29 | |
| 30 /** | |
| 31 * The key types supported by the credentials passing API. | |
| 32 * @type {Array} Array of strings. | |
| 33 */ | |
| 34 Authenticator.API_KEY_TYPES = [ | |
| 35 'KEY_TYPE_PASSWORD_PLAIN', | |
| 36 ]; | |
| 37 | |
| 38 /** | |
| 39 * Allowed origins of the hosting page. | |
| 40 * @type {Array<string>} | |
| 41 */ | |
| 42 Authenticator.ALLOWED_PARENT_ORIGINS = [ | |
| 43 'chrome://oobe', | |
| 44 'chrome://chrome-signin' | |
| 45 ]; | |
| 46 | |
| 47 /** | |
| 48 * Singleton getter of Authenticator. | |
| 49 * @return {Object} The singleton instance of Authenticator. | |
| 50 */ | |
| 51 Authenticator.getInstance = function() { | |
| 52 if (!Authenticator.instance_) { | |
| 53 Authenticator.instance_ = new Authenticator(); | |
| 54 } | |
| 55 return Authenticator.instance_; | |
| 56 }; | |
| 57 | |
| 58 Authenticator.prototype = { | |
| 59 email_: null, | |
| 60 gaiaId_: null, | |
| 61 | |
| 62 // Depending on the key type chosen, this will contain the plain text password | |
| 63 // or a credential derived from it along with the information required to | |
| 64 // repeat the derivation, such as a salt. The information will be encoded so | |
| 65 // that it contains printable ASCII characters only. The exact encoding is TBD | |
| 66 // when support for key types other than plain text password is added. | |
| 67 passwordBytes_: null, | |
| 68 | |
| 69 needPassword_: false, | |
| 70 chooseWhatToSync_: false, | |
| 71 skipForNow_: false, | |
| 72 sessionIndex_: null, | |
| 73 attemptToken_: null, | |
| 74 | |
| 75 // Input params from extension initialization URL. | |
| 76 inputLang_: undefined, | |
| 77 intputEmail_: undefined, | |
| 78 | |
| 79 isSAMLFlow_: false, | |
| 80 gaiaLoaded_: false, | |
| 81 supportChannel_: null, | |
| 82 | |
| 83 useEafe_: false, | |
| 84 clientId_: '', | |
| 85 | |
| 86 GAIA_URL: 'https://accounts.google.com/', | |
| 87 GAIA_PAGE_PATH: 'ServiceLogin?skipvpage=true&sarp=1&rm=hide', | |
| 88 SERVICE_ID: 'chromeoslogin', | |
| 89 CONTINUE_URL: Authenticator.THIS_EXTENSION_ORIGIN + '/success.html', | |
| 90 CONSTRAINED_FLOW_SOURCE: 'chrome', | |
| 91 | |
| 92 initialize: function() { | |
| 93 var handleInitializeMessage = function(e) { | |
| 94 if (Authenticator.ALLOWED_PARENT_ORIGINS.indexOf(e.origin) == -1) { | |
| 95 console.error('Unexpected parent message, origin=' + e.origin); | |
| 96 return; | |
| 97 } | |
| 98 window.removeEventListener('message', handleInitializeMessage); | |
| 99 | |
| 100 var params = e.data; | |
| 101 params.parentPage = e.origin; | |
| 102 this.initializeFromParent_(params); | |
| 103 this.onPageLoad_(); | |
| 104 }.bind(this); | |
| 105 | |
| 106 document.addEventListener('DOMContentLoaded', function() { | |
| 107 window.addEventListener('message', handleInitializeMessage); | |
| 108 window.parent.postMessage({'method': 'loginUIDOMContentLoaded'}, '*'); | |
| 109 }); | |
| 110 }, | |
| 111 | |
| 112 initializeFromParent_: function(params) { | |
| 113 this.parentPage_ = params.parentPage; | |
| 114 this.gaiaUrl_ = params.gaiaUrl || this.GAIA_URL; | |
| 115 this.gaiaPath_ = params.gaiaPath || this.GAIA_PAGE_PATH; | |
| 116 this.inputLang_ = params.hl; | |
| 117 this.inputEmail_ = params.email; | |
| 118 this.service_ = params.service || this.SERVICE_ID; | |
| 119 this.continueUrl_ = params.continueUrl || this.CONTINUE_URL; | |
| 120 this.desktopMode_ = params.desktopMode == '1'; | |
| 121 this.isConstrainedWindow_ = params.constrained == '1'; | |
| 122 this.useEafe_ = params.useEafe || false; | |
| 123 this.clientId_ = params.clientId || ''; | |
| 124 this.initialFrameUrl_ = params.frameUrl || this.constructInitialFrameUrl_(); | |
| 125 this.initialFrameUrlWithoutParams_ = stripParams(this.initialFrameUrl_); | |
| 126 this.needPassword_ = params.needPassword == '1'; | |
| 127 | |
| 128 // For CrOS 'ServiceLogin' we assume that Gaia is loaded if we recieved | |
| 129 // 'clearOldAttempts' message. For other scenarios Gaia doesn't send this | |
| 130 // message so we have to rely on 'load' event. | |
| 131 // TODO(dzhioev): Do not rely on 'load' event after b/16313327 is fixed. | |
| 132 this.assumeLoadedOnLoadEvent_ = | |
| 133 !this.gaiaPath_.startsWith('ServiceLogin') || | |
| 134 this.service_ !== 'chromeoslogin' || | |
| 135 this.useEafe_; | |
| 136 }, | |
| 137 | |
| 138 isGaiaMessage_: function(msg) { | |
| 139 // Not quite right, but good enough. | |
| 140 return this.gaiaUrl_.startsWith(msg.origin) || | |
| 141 this.GAIA_URL.startsWith(msg.origin); | |
| 142 }, | |
| 143 | |
| 144 isParentMessage_: function(msg) { | |
| 145 return msg.origin == this.parentPage_; | |
| 146 }, | |
| 147 | |
| 148 constructInitialFrameUrl_: function() { | |
| 149 var url = this.gaiaUrl_ + this.gaiaPath_; | |
| 150 | |
| 151 url = appendParam(url, 'service', this.service_); | |
| 152 // Easy bootstrap use auth_code message as success signal instead of | |
| 153 // continue URL. | |
| 154 if (!this.useEafe_) | |
| 155 url = appendParam(url, 'continue', this.continueUrl_); | |
| 156 if (this.inputLang_) | |
| 157 url = appendParam(url, 'hl', this.inputLang_); | |
| 158 if (this.inputEmail_) | |
| 159 url = appendParam(url, 'Email', this.inputEmail_); | |
| 160 if (this.isConstrainedWindow_) | |
| 161 url = appendParam(url, 'source', this.CONSTRAINED_FLOW_SOURCE); | |
| 162 return url; | |
| 163 }, | |
| 164 | |
| 165 onPageLoad_: function() { | |
| 166 window.addEventListener('message', this.onMessage.bind(this), false); | |
| 167 this.initSupportChannel_(); | |
| 168 | |
| 169 if (this.assumeLoadedOnLoadEvent_) { | |
| 170 var gaiaFrame = $('gaia-frame'); | |
| 171 var handler = function() { | |
| 172 gaiaFrame.removeEventListener('load', handler); | |
| 173 if (!this.gaiaLoaded_) { | |
| 174 this.gaiaLoaded_ = true; | |
| 175 this.maybeInitialized_(); | |
| 176 | |
| 177 if (this.useEafe_ && this.clientId_) { | |
| 178 // Sends initial handshake message to EAFE. Note this fails with | |
| 179 // SSO redirect because |gaiaFrame| sits on a different origin. | |
| 180 gaiaFrame.contentWindow.postMessage({ | |
| 181 clientId: this.clientId_ | |
| 182 }, this.gaiaUrl_); | |
| 183 } | |
| 184 } | |
| 185 }.bind(this); | |
| 186 gaiaFrame.addEventListener('load', handler); | |
| 187 } | |
| 188 }, | |
| 189 | |
| 190 initSupportChannel_: function() { | |
| 191 var supportChannel = new Channel(); | |
| 192 supportChannel.connect('authMain'); | |
| 193 | |
| 194 supportChannel.registerMessage('channelConnected', function() { | |
| 195 // Load the gaia frame after the background page indicates that it is | |
| 196 // ready, so that the webRequest handlers are all setup first. | |
| 197 var gaiaFrame = $('gaia-frame'); | |
| 198 gaiaFrame.src = this.initialFrameUrl_; | |
| 199 | |
| 200 if (this.supportChannel_) { | |
| 201 console.error('Support channel is already initialized.'); | |
| 202 return; | |
| 203 } | |
| 204 this.supportChannel_ = supportChannel; | |
| 205 | |
| 206 if (this.desktopMode_) { | |
| 207 this.supportChannel_.send({ | |
| 208 name: 'initDesktopFlow', | |
| 209 gaiaUrl: this.gaiaUrl_, | |
| 210 continueUrl: stripParams(this.continueUrl_), | |
| 211 isConstrainedWindow: this.isConstrainedWindow_, | |
| 212 initialFrameUrlWithoutParams: this.initialFrameUrlWithoutParams_ | |
| 213 }); | |
| 214 | |
| 215 this.supportChannel_.registerMessage( | |
| 216 'switchToFullTab', this.switchToFullTab_.bind(this)); | |
| 217 } | |
| 218 this.supportChannel_.registerMessage( | |
| 219 'completeLogin', this.onCompleteLogin_.bind(this)); | |
| 220 this.initSAML_(); | |
| 221 this.supportChannel_.send({name: 'resetAuth'}); | |
| 222 this.maybeInitialized_(); | |
| 223 }.bind(this)); | |
| 224 | |
| 225 window.setTimeout(function() { | |
| 226 if (!this.supportChannel_) { | |
| 227 // Give up previous channel and bind its 'channelConnected' to a no-op. | |
| 228 supportChannel.registerMessage('channelConnected', function() {}); | |
| 229 | |
| 230 // Re-initialize the channel if it is not connected properly, e.g. | |
| 231 // connect may be called before background script started running. | |
| 232 this.initSupportChannel_(); | |
| 233 } | |
| 234 }.bind(this), 200); | |
| 235 }, | |
| 236 | |
| 237 /** | |
| 238 * Called when one of the initialization stages has finished. If all the | |
| 239 * needed parts are initialized, notifies parent about successfull | |
| 240 * initialization. | |
| 241 */ | |
| 242 maybeInitialized_: function() { | |
| 243 if (!this.gaiaLoaded_ || !this.supportChannel_) | |
| 244 return; | |
| 245 var msg = { | |
| 246 'method': 'loginUILoaded' | |
| 247 }; | |
| 248 window.parent.postMessage(msg, this.parentPage_); | |
| 249 }, | |
| 250 | |
| 251 /** | |
| 252 * Invoked when the background script sends a message to indicate that the | |
| 253 * current content does not fit in a constrained window. | |
| 254 * @param {Object=} msg Extra info to send. | |
| 255 */ | |
| 256 switchToFullTab_: function(msg) { | |
| 257 var parentMsg = { | |
| 258 'method': 'switchToFullTab', | |
| 259 'url': msg.url | |
| 260 }; | |
| 261 window.parent.postMessage(parentMsg, this.parentPage_); | |
| 262 }, | |
| 263 | |
| 264 /** | |
| 265 * Invoked when the signin flow is complete. | |
| 266 * @param {Object=} opt_extraMsg Optional extra info to send. | |
| 267 */ | |
| 268 completeLogin_: function(opt_extraMsg) { | |
| 269 var msg = { | |
| 270 'method': 'completeLogin', | |
| 271 'email': (opt_extraMsg && opt_extraMsg.email) || this.email_, | |
| 272 'password': this.passwordBytes_ || | |
| 273 (opt_extraMsg && opt_extraMsg.password), | |
| 274 'usingSAML': this.isSAMLFlow_, | |
| 275 'chooseWhatToSync': this.chooseWhatToSync_ || false, | |
| 276 'skipForNow': (opt_extraMsg && opt_extraMsg.skipForNow) || | |
| 277 this.skipForNow_, | |
| 278 'sessionIndex': (opt_extraMsg && opt_extraMsg.sessionIndex) || | |
| 279 this.sessionIndex_, | |
| 280 'gaiaId': (opt_extraMsg && opt_extraMsg.gaiaId) || this.gaiaId_ | |
| 281 }; | |
| 282 window.parent.postMessage(msg, this.parentPage_); | |
| 283 this.supportChannel_.send({name: 'resetAuth'}); | |
| 284 }, | |
| 285 | |
| 286 /** | |
| 287 * Invoked when support channel is connected. | |
| 288 */ | |
| 289 initSAML_: function() { | |
| 290 this.isSAMLFlow_ = false; | |
| 291 | |
| 292 this.supportChannel_.registerMessage( | |
| 293 'onAuthPageLoaded', this.onAuthPageLoaded_.bind(this)); | |
| 294 this.supportChannel_.registerMessage( | |
| 295 'onInsecureContentBlocked', this.onInsecureContentBlocked_.bind(this)); | |
| 296 this.supportChannel_.registerMessage( | |
| 297 'apiCall', this.onAPICall_.bind(this)); | |
| 298 this.supportChannel_.send({ | |
| 299 name: 'setGaiaUrl', | |
| 300 gaiaUrl: this.gaiaUrl_ | |
| 301 }); | |
| 302 if (!this.desktopMode_ && this.gaiaUrl_.startsWith('https://')) { | |
| 303 // 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 | |
| 305 // set a non-https GAIA URL and want to perform all authentication over | |
| 306 // http. | |
| 307 this.supportChannel_.send({ | |
| 308 name: 'setBlockInsecureContent', | |
| 309 blockInsecureContent: true | |
| 310 }); | |
| 311 } | |
| 312 }, | |
| 313 | |
| 314 /** | |
| 315 * Invoked when the background page sends 'onHostedPageLoaded' message. | |
| 316 * @param {!Object} msg Details sent with the message. | |
| 317 */ | |
| 318 onAuthPageLoaded_: function(msg) { | |
| 319 if (msg.isSAMLPage && !this.isSAMLFlow_) { | |
| 320 // GAIA redirected to a SAML login page. The credentials provided to this | |
| 321 // 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. | |
| 323 this.isSAMLFlow_ = true; | |
| 324 this.email_ = null; | |
| 325 this.gaiaId_ = null; | |
| 326 this.passwordBytes_ = null; | |
| 327 } | |
| 328 | |
| 329 window.parent.postMessage({ | |
| 330 'method': 'authPageLoaded', | |
| 331 'isSAML': this.isSAMLFlow_, | |
| 332 'domain': extractDomain(msg.url) | |
| 333 }, this.parentPage_); | |
| 334 }, | |
| 335 | |
| 336 /** | |
| 337 * Invoked when the background page sends an 'onInsecureContentBlocked' | |
| 338 * message. | |
| 339 * @param {!Object} msg Details sent with the message. | |
| 340 */ | |
| 341 onInsecureContentBlocked_: function(msg) { | |
| 342 window.parent.postMessage({ | |
| 343 'method': 'insecureContentBlocked', | |
| 344 'url': stripParams(msg.url) | |
| 345 }, this.parentPage_); | |
| 346 }, | |
| 347 | |
| 348 /** | |
| 349 * Invoked when one of the credential passing API methods is called by a SAML | |
| 350 * provider. | |
| 351 * @param {!Object} msg Details of the API call. | |
| 352 */ | |
| 353 onAPICall_: function(msg) { | |
| 354 var call = msg.call; | |
| 355 if (call.method == 'initialize') { | |
| 356 if (!Number.isInteger(call.requestedVersion) || | |
| 357 call.requestedVersion < Authenticator.MIN_API_VERSION_VERSION) { | |
| 358 this.sendInitializationFailure_(); | |
| 359 return; | |
| 360 } | |
| 361 | |
| 362 this.apiVersion_ = Math.min(call.requestedVersion, | |
| 363 Authenticator.MAX_API_VERSION_VERSION); | |
| 364 this.initialized_ = true; | |
| 365 this.sendInitializationSuccess_(); | |
| 366 return; | |
| 367 } | |
| 368 | |
| 369 if (call.method == 'add') { | |
| 370 if (Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) { | |
| 371 console.error('Authenticator.onAPICall_: unsupported key type'); | |
| 372 return; | |
| 373 } | |
| 374 // Not setting |email_| and |gaiaId_| because this API call will | |
| 375 // eventually be followed by onCompleteLogin_() which does set it. | |
| 376 this.apiToken_ = call.token; | |
| 377 this.passwordBytes_ = call.passwordBytes; | |
| 378 } else if (call.method == 'confirm') { | |
| 379 if (call.token != this.apiToken_) | |
| 380 console.error('Authenticator.onAPICall_: token mismatch'); | |
| 381 } else { | |
| 382 console.error('Authenticator.onAPICall_: unknown message'); | |
| 383 } | |
| 384 }, | |
| 385 | |
| 386 onGotAuthCode_: function(authCode) { | |
| 387 window.parent.postMessage({ | |
| 388 'method': 'completeAuthenticationAuthCodeOnly', | |
| 389 'authCode': authCode | |
| 390 }, this.parentPage_); | |
| 391 }, | |
| 392 | |
| 393 sendInitializationSuccess_: function() { | |
| 394 this.supportChannel_.send({name: 'apiResponse', response: { | |
| 395 result: 'initialized', | |
| 396 version: this.apiVersion_, | |
| 397 keyTypes: Authenticator.API_KEY_TYPES | |
| 398 }}); | |
| 399 }, | |
| 400 | |
| 401 sendInitializationFailure_: function() { | |
| 402 this.supportChannel_.send({ | |
| 403 name: 'apiResponse', | |
| 404 response: {result: 'initialization_failed'} | |
| 405 }); | |
| 406 }, | |
| 407 | |
| 408 /** | |
| 409 * Callback invoked for 'completeLogin' message. | |
| 410 * @param {Object=} msg Message sent from background page. | |
| 411 */ | |
| 412 onCompleteLogin_: function(msg) { | |
| 413 if (!msg.email || !msg.gaiaId || !msg.sessionIndex) { | |
| 414 // 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. | |
| 416 if (this.desktopMode_ && msg.skipForNow) { | |
| 417 this.completeLogin_(msg); | |
| 418 } else { | |
| 419 console.error('Missing fields to complete login.'); | |
| 420 window.parent.postMessage({method: 'missingGaiaInfo'}, | |
| 421 this.parentPage_); | |
| 422 return; | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 // Skip SAML extra steps for desktop flow and non-SAML flow. | |
| 427 if (!this.isSAMLFlow_ || this.desktopMode_) { | |
| 428 this.completeLogin_(msg); | |
| 429 return; | |
| 430 } | |
| 431 | |
| 432 this.email_ = msg.email; | |
| 433 this.gaiaId_ = msg.gaiaId; | |
| 434 // Password from |msg| is not used because ChromeOS SAML flow | |
| 435 // gets password by asking user to confirm. | |
| 436 this.skipForNow_ = msg.skipForNow; | |
| 437 this.sessionIndex_ = msg.sessionIndex; | |
| 438 | |
| 439 if (this.passwordBytes_) { | |
| 440 // If the credentials passing API was used, login is complete. | |
| 441 window.parent.postMessage({method: 'samlApiUsed'}, this.parentPage_); | |
| 442 this.completeLogin_(msg); | |
| 443 } else if (!this.needPassword_) { | |
| 444 // 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 | |
| 446 // be interested in the password at all. In that case, verification is | |
| 447 // unnecessary and login is complete. | |
| 448 this.completeLogin_(msg); | |
| 449 } else { | |
| 450 this.supportChannel_.sendWithCallback( | |
| 451 {name: 'getScrapedPasswords'}, | |
| 452 function(passwords) { | |
| 453 if (passwords.length == 0) { | |
| 454 window.parent.postMessage( | |
| 455 {method: 'noPassword', email: this.email_}, | |
| 456 this.parentPage_); | |
| 457 } else { | |
| 458 window.parent.postMessage({method: 'confirmPassword', | |
| 459 email: this.email_, | |
| 460 passwordCount: passwords.length}, | |
| 461 this.parentPage_); | |
| 462 } | |
| 463 }.bind(this)); | |
| 464 } | |
| 465 }, | |
| 466 | |
| 467 onVerifyConfirmedPassword_: function(password) { | |
| 468 this.supportChannel_.sendWithCallback( | |
| 469 {name: 'getScrapedPasswords'}, | |
| 470 function(passwords) { | |
| 471 for (var i = 0; i < passwords.length; ++i) { | |
| 472 if (passwords[i] == password) { | |
| 473 this.passwordBytes_ = passwords[i]; | |
| 474 // SAML login is complete when the user has successfully | |
| 475 // confirmed the password. | |
| 476 if (this.passwordBytes_ !== null) | |
| 477 this.completeLogin_(); | |
| 478 return; | |
| 479 } | |
| 480 } | |
| 481 window.parent.postMessage( | |
| 482 {method: 'confirmPassword', email: this.email_}, | |
| 483 this.parentPage_); | |
| 484 }.bind(this)); | |
| 485 }, | |
| 486 | |
| 487 onMessage: function(e) { | |
| 488 var msg = e.data; | |
| 489 | |
| 490 if (this.useEafe_) { | |
| 491 if (msg == '!_{h:\'gaia-frame\'}' && this.isGaiaMessage_(e)) { | |
| 492 // Sends client ID again on the hello message to work around the SSO | |
| 493 // signin issue. | |
| 494 // TODO(xiyuan): Revisit this when EAFE is integrated or for webview. | |
| 495 $('gaia-frame').contentWindow.postMessage({ | |
| 496 clientId: this.clientId_ | |
| 497 }, this.gaiaUrl_); | |
| 498 } else if (typeof msg == 'object' && | |
| 499 msg.type == 'authorizationCode' && this.isGaiaMessage_(e)) { | |
| 500 this.onGotAuthCode_(msg.authorizationCode); | |
| 501 } else { | |
| 502 console.error('Authenticator.onMessage: unknown message' + | |
| 503 ', msg=' + JSON.stringify(msg)); | |
| 504 } | |
| 505 | |
| 506 return; | |
| 507 } | |
| 508 | |
| 509 if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) { | |
| 510 // At this point GAIA does not yet know the gaiaId, so its not set here. | |
| 511 this.email_ = msg.email; | |
| 512 this.passwordBytes_ = msg.password; | |
| 513 this.attemptToken_ = msg.attemptToken; | |
| 514 this.chooseWhatToSync_ = msg.chooseWhatToSync; | |
| 515 this.isSAMLFlow_ = false; | |
| 516 if (this.supportChannel_) | |
| 517 this.supportChannel_.send({name: 'startAuth'}); | |
| 518 else | |
| 519 console.error('Support channel is not initialized.'); | |
| 520 } else if (msg.method == 'clearOldAttempts' && this.isGaiaMessage_(e)) { | |
| 521 if (!this.gaiaLoaded_) { | |
| 522 this.gaiaLoaded_ = true; | |
| 523 this.maybeInitialized_(); | |
| 524 } | |
| 525 this.email_ = null; | |
| 526 this.gaiaId_ = null; | |
| 527 this.sessionIndex_ = false; | |
| 528 this.passwordBytes_ = null; | |
| 529 this.attemptToken_ = null; | |
| 530 this.isSAMLFlow_ = false; | |
| 531 this.skipForNow_ = false; | |
| 532 this.chooseWhatToSync_ = false; | |
| 533 if (this.supportChannel_) { | |
| 534 this.supportChannel_.send({name: 'resetAuth'}); | |
| 535 // This message is for clearing saml properties in gaia_auth_host and | |
| 536 // oobe_screen_oauth_enrollment. | |
| 537 window.parent.postMessage({ | |
| 538 'method': 'resetAuthFlow', | |
| 539 }, this.parentPage_); | |
| 540 } | |
| 541 } else if (msg.method == 'verifyConfirmedPassword' && | |
| 542 this.isParentMessage_(e)) { | |
| 543 this.onVerifyConfirmedPassword_(msg.password); | |
| 544 } else if (msg.method == 'redirectToSignin' && | |
| 545 this.isParentMessage_(e)) { | |
| 546 $('gaia-frame').src = this.constructInitialFrameUrl_(); | |
| 547 } else { | |
| 548 console.error('Authenticator.onMessage: unknown message + origin!?'); | |
| 549 } | |
| 550 } | |
| 551 }; | |
| 552 | |
| 553 Authenticator.getInstance().initialize(); | |
| OLD | NEW |