Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Side by Side Diff: chrome/browser/resources/gaia_auth_host/authenticator.js

Issue 2600683002: Run tools/clang-format-js on some of chrome/browser/resources/ (Closed)
Patch Set: event_handler.js Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <include src="saml_handler.js"> 5 // <include src="saml_handler.js">
6 6
7 /** 7 /**
8 * @fileoverview An UI component to authenciate to Chrome. The component hosts 8 * @fileoverview An UI component to authenciate to Chrome. The component hosts
9 * IdP web pages in a webview. A client who is interested in monitoring 9 * IdP web pages in a webview. A client who is interested in monitoring
10 * authentication events should pass a listener object of type 10 * authentication events should pass a listener object of type
11 * cr.login.GaiaAuthHost.Listener as defined in this file. After initialization, 11 * cr.login.GaiaAuthHost.Listener as defined in this file. After initialization,
12 * call {@code load} to start the authentication flow. 12 * call {@code load} to start the authentication flow.
13 */ 13 */
14 14
15 cr.define('cr.login', function() { 15 cr.define('cr.login', function() {
(...skipping 21 matching lines...) Expand all
37 /** 37 /**
38 * The source URL parameter for the constrained signin flow. 38 * The source URL parameter for the constrained signin flow.
39 */ 39 */
40 var CONSTRAINED_FLOW_SOURCE = 'chrome'; 40 var CONSTRAINED_FLOW_SOURCE = 'chrome';
41 41
42 /** 42 /**
43 * Enum for the authorization mode, must match AuthMode defined in 43 * Enum for the authorization mode, must match AuthMode defined in
44 * chrome/browser/ui/webui/inline_login_ui.cc. 44 * chrome/browser/ui/webui/inline_login_ui.cc.
45 * @enum {number} 45 * @enum {number}
46 */ 46 */
47 var AuthMode = { 47 var AuthMode = {DEFAULT: 0, OFFLINE: 1, DESKTOP: 2};
48 DEFAULT: 0,
49 OFFLINE: 1,
50 DESKTOP: 2
51 };
52 48
53 /** 49 /**
54 * Enum for the authorization type. 50 * Enum for the authorization type.
55 * @enum {number} 51 * @enum {number}
56 */ 52 */
57 var AuthFlow = { 53 var AuthFlow = {DEFAULT: 0, SAML: 1};
58 DEFAULT: 0,
59 SAML: 1
60 };
61 54
62 /** 55 /**
63 * Supported Authenticator params. 56 * Supported Authenticator params.
64 * @type {!Array<string>} 57 * @type {!Array<string>}
65 * @const 58 * @const
66 */ 59 */
67 var SUPPORTED_PARAMS = [ 60 var SUPPORTED_PARAMS = [
68 'gaiaId', // Obfuscated GAIA ID to skip the email prompt page 61 'gaiaId', // Obfuscated GAIA ID to skip the email prompt page
69 // during the re-auth flow. 62 // during the re-auth flow.
70 'gaiaUrl', // Gaia url to use. 63 'gaiaUrl', // Gaia url to use.
71 'gaiaPath', // Gaia path to use without a leading slash. 64 'gaiaPath', // Gaia path to use without a leading slash.
72 'hl', // Language code for the user interface. 65 'hl', // Language code for the user interface.
73 'service', // Name of Gaia service. 66 'service', // Name of Gaia service.
74 'continueUrl', // Continue url to use. 67 'continueUrl', // Continue url to use.
75 'frameUrl', // Initial frame URL to use. If empty defaults to 68 'frameUrl', // Initial frame URL to use. If empty defaults to
76 // gaiaUrl. 69 // gaiaUrl.
77 'constrained', // Whether the extension is loaded in a constrained 70 'constrained', // Whether the extension is loaded in a constrained
78 // window. 71 // window.
79 'clientId', // Chrome client id. 72 'clientId', // Chrome client id.
80 'useEafe', // Whether to use EAFE. 73 'useEafe', // Whether to use EAFE.
81 'needPassword', // Whether the host is interested in getting a password. 74 'needPassword', // Whether the host is interested in getting a password.
82 // If this set to |false|, |confirmPasswordCallback| is 75 // If this set to |false|, |confirmPasswordCallback| is
83 // not called before dispatching |authCopleted|. 76 // not called before dispatching |authCopleted|.
84 // Default is |true|. 77 // Default is |true|.
85 'flow', // One of 'default', 'enterprise', or 'theftprotection'. 78 'flow', // One of 'default', 'enterprise', or 'theftprotection'.
86 'enterpriseDomain', // Domain in which hosting device is (or should be) 79 'enterpriseDomain', // Domain in which hosting device is (or should be)
87 // enrolled. 80 // enrolled.
88 'emailDomain', // Value used to prefill domain for email. 81 'emailDomain', // Value used to prefill domain for email.
89 'chromeType', // Type of Chrome OS device, e.g. "chromebox". 82 'chromeType', // Type of Chrome OS device, e.g. "chromebox".
90 'clientVersion', // Version of the Chrome build. 83 'clientVersion', // Version of the Chrome build.
91 'platformVersion', // Version of the OS build. 84 'platformVersion', // Version of the OS build.
92 'releaseChannel', // Installation channel. 85 'releaseChannel', // Installation channel.
93 'endpointGen', // Current endpoint generation. 86 'endpointGen', // Current endpoint generation.
94 'gapsCookie', // GAPS cookie 87 'gapsCookie', // GAPS cookie
95 88
96 // The email fields allow for the following possibilities: 89 // The email fields allow for the following possibilities:
97 // 90 //
98 // 1/ If 'email' is not supplied, then the email text field is blank and the 91 // 1/ If 'email' is not supplied, then the email text field is blank and the
99 // user must type an email to proceed. 92 // user must type an email to proceed.
100 // 93 //
101 // 2/ If 'email' is supplied, and 'readOnlyEmail' is truthy, then the email 94 // 2/ If 'email' is supplied, and 'readOnlyEmail' is truthy, then the email
102 // is hardcoded and the user cannot change it. The user is asked for 95 // is hardcoded and the user cannot change it. The user is asked for
103 // password. This is useful for re-auth scenarios, where chrome needs the 96 // password. This is useful for re-auth scenarios, where chrome needs the
104 // user to authenticate for a specific account and only that account. 97 // user to authenticate for a specific account and only that account.
(...skipping 13 matching lines...) Expand all
118 * web pages. 111 * web pages.
119 * @constructor 112 * @constructor
120 */ 113 */
121 function Authenticator(webview) { 114 function Authenticator(webview) {
122 this.webview_ = typeof webview == 'string' ? $(webview) : webview; 115 this.webview_ = typeof webview == 'string' ? $(webview) : webview;
123 assert(this.webview_); 116 assert(this.webview_);
124 117
125 this.isLoaded_ = false; 118 this.isLoaded_ = false;
126 this.email_ = null; 119 this.email_ = null;
127 this.password_ = null; 120 this.password_ = null;
128 this.gaiaId_ = null, 121 this.gaiaId_ = null, this.sessionIndex_ = null;
129 this.sessionIndex_ = null;
130 this.chooseWhatToSync_ = false; 122 this.chooseWhatToSync_ = false;
131 this.skipForNow_ = false; 123 this.skipForNow_ = false;
132 this.authFlow = AuthFlow.DEFAULT; 124 this.authFlow = AuthFlow.DEFAULT;
133 this.authDomain = ''; 125 this.authDomain = '';
134 this.videoEnabled = false; 126 this.videoEnabled = false;
135 this.idpOrigin_ = null; 127 this.idpOrigin_ = null;
136 this.continueUrl_ = null; 128 this.continueUrl_ = null;
137 this.continueUrlWithoutParams_ = null; 129 this.continueUrlWithoutParams_ = null;
138 this.initialFrameUrl_ = null; 130 this.initialFrameUrl_ = null;
139 this.reloadUrl_ = null; 131 this.reloadUrl_ = null;
140 this.trusted_ = true; 132 this.trusted_ = true;
141 this.oauthCode_ = null; 133 this.oauthCode_ = null;
142 this.gapsCookie_ = null; 134 this.gapsCookie_ = null;
143 this.gapsCookieSent_ = false; 135 this.gapsCookieSent_ = false;
144 this.newGapsCookie_ = null; 136 this.newGapsCookie_ = null;
145 this.readyFired_ = false; 137 this.readyFired_ = false;
146 138
147 this.useEafe_ = false; 139 this.useEafe_ = false;
148 this.clientId_ = null; 140 this.clientId_ = null;
149 141
150 this.samlHandler_ = new cr.login.SamlHandler(this.webview_); 142 this.samlHandler_ = new cr.login.SamlHandler(this.webview_);
151 this.confirmPasswordCallback = null; 143 this.confirmPasswordCallback = null;
152 this.noPasswordCallback = null; 144 this.noPasswordCallback = null;
153 this.insecureContentBlockedCallback = null; 145 this.insecureContentBlockedCallback = null;
154 this.samlApiUsedCallback = null; 146 this.samlApiUsedCallback = null;
155 this.missingGaiaInfoCallback = null; 147 this.missingGaiaInfoCallback = null;
156 this.needPassword = true; 148 this.needPassword = true;
157 this.samlHandler_.addEventListener( 149 this.samlHandler_.addEventListener(
158 'insecureContentBlocked', 150 'insecureContentBlocked', this.onInsecureContentBlocked_.bind(this));
159 this.onInsecureContentBlocked_.bind(this));
160 this.samlHandler_.addEventListener( 151 this.samlHandler_.addEventListener(
161 'authPageLoaded', 152 'authPageLoaded', this.onAuthPageLoaded_.bind(this));
162 this.onAuthPageLoaded_.bind(this));
163 this.samlHandler_.addEventListener( 153 this.samlHandler_.addEventListener(
164 'videoEnabled', 154 'videoEnabled', this.onVideoEnabled_.bind(this));
165 this.onVideoEnabled_.bind(this));
166 this.samlHandler_.addEventListener( 155 this.samlHandler_.addEventListener(
167 'apiPasswordAdded', 156 'apiPasswordAdded', this.onSamlApiPasswordAdded_.bind(this));
168 this.onSamlApiPasswordAdded_.bind(this));
169 157
170 this.webview_.addEventListener('droplink', this.onDropLink_.bind(this)); 158 this.webview_.addEventListener('droplink', this.onDropLink_.bind(this));
171 this.webview_.addEventListener( 159 this.webview_.addEventListener('newwindow', this.onNewWindow_.bind(this));
172 'newwindow', this.onNewWindow_.bind(this));
173 this.webview_.addEventListener( 160 this.webview_.addEventListener(
174 'contentload', this.onContentLoad_.bind(this)); 161 'contentload', this.onContentLoad_.bind(this));
175 this.webview_.addEventListener( 162 this.webview_.addEventListener('loadabort', this.onLoadAbort_.bind(this));
176 'loadabort', this.onLoadAbort_.bind(this)); 163 this.webview_.addEventListener('loadstop', this.onLoadStop_.bind(this));
177 this.webview_.addEventListener( 164 this.webview_.addEventListener('loadcommit', this.onLoadCommit_.bind(this));
178 'loadstop', this.onLoadStop_.bind(this));
179 this.webview_.addEventListener(
180 'loadcommit', this.onLoadCommit_.bind(this));
181 this.webview_.request.onCompleted.addListener( 165 this.webview_.request.onCompleted.addListener(
182 this.onRequestCompleted_.bind(this), 166 this.onRequestCompleted_.bind(this),
183 {urls: ['<all_urls>'], types: ['main_frame']}, 167 {urls: ['<all_urls>'], types: ['main_frame']}, ['responseHeaders']);
184 ['responseHeaders']);
185 this.webview_.request.onHeadersReceived.addListener( 168 this.webview_.request.onHeadersReceived.addListener(
186 this.onHeadersReceived_.bind(this), 169 this.onHeadersReceived_.bind(this),
187 {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, 170 {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']},
188 ['responseHeaders']); 171 ['responseHeaders']);
189 window.addEventListener( 172 window.addEventListener(
190 'message', this.onMessageFromWebview_.bind(this), false); 173 'message', this.onMessageFromWebview_.bind(this), false);
191 window.addEventListener( 174 window.addEventListener('focus', this.onFocus_.bind(this), false);
192 'focus', this.onFocus_.bind(this), false); 175 window.addEventListener('popstate', this.onPopState_.bind(this), false);
193 window.addEventListener(
194 'popstate', this.onPopState_.bind(this), false);
195 } 176 }
196 177
197 Authenticator.prototype = Object.create(cr.EventTarget.prototype); 178 Authenticator.prototype = Object.create(cr.EventTarget.prototype);
198 179
199 /** 180 /**
200 * Reinitializes authentication parameters so that a failed login attempt 181 * Reinitializes authentication parameters so that a failed login attempt
201 * would not result in an infinite loop. 182 * would not result in an infinite loop.
202 */ 183 */
203 Authenticator.prototype.resetStates = function() { 184 Authenticator.prototype.resetStates = function() {
204 this.isLoaded_ = false; 185 this.isLoaded_ = false;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 this.clientId_ = data.clientId; 228 this.clientId_ = data.clientId;
248 this.gapsCookie_ = data.gapsCookie; 229 this.gapsCookie_ = data.gapsCookie;
249 this.gapsCookieSent_ = false; 230 this.gapsCookieSent_ = false;
250 this.newGapsCookie_ = null; 231 this.newGapsCookie_ = null;
251 this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; 232 this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages;
252 233
253 this.initialFrameUrl_ = this.constructInitialFrameUrl_(data); 234 this.initialFrameUrl_ = this.constructInitialFrameUrl_(data);
254 this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_; 235 this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_;
255 // Don't block insecure content for desktop flow because it lands on 236 // Don't block insecure content for desktop flow because it lands on
256 // http. Otherwise, block insecure content as long as gaia is https. 237 // http. Otherwise, block insecure content as long as gaia is https.
257 this.samlHandler_.blockInsecureContent = authMode != AuthMode.DESKTOP && 238 this.samlHandler_.blockInsecureContent =
258 this.idpOrigin_.startsWith('https://'); 239 authMode != AuthMode.DESKTOP && this.idpOrigin_.startsWith('https://');
259 this.needPassword = !('needPassword' in data) || data.needPassword; 240 this.needPassword = !('needPassword' in data) || data.needPassword;
260 241
261 if (this.isNewGaiaFlow) { 242 if (this.isNewGaiaFlow) {
262 this.webview_.contextMenus.onShow.addListener(function(e) { 243 this.webview_.contextMenus.onShow.addListener(function(e) {
263 e.preventDefault(); 244 e.preventDefault();
264 }); 245 });
265 246
266 if (!this.onBeforeSetHeadersSet_) { 247 if (!this.onBeforeSetHeadersSet_) {
267 this.onBeforeSetHeadersSet_ = true; 248 this.onBeforeSetHeadersSet_ = true;
268 var filterPrefix = this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT; 249 var filterPrefix = this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT;
(...skipping 15 matching lines...) Expand all
284 Authenticator.prototype.reload = function() { 265 Authenticator.prototype.reload = function() {
285 this.resetStates(); 266 this.resetStates();
286 this.webview_.src = this.reloadUrl_; 267 this.webview_.src = this.reloadUrl_;
287 this.isLoaded_ = true; 268 this.isLoaded_ = true;
288 }; 269 };
289 270
290 Authenticator.prototype.constructInitialFrameUrl_ = function(data) { 271 Authenticator.prototype.constructInitialFrameUrl_ = function(data) {
291 if (data.doSamlRedirect) { 272 if (data.doSamlRedirect) {
292 var url = this.idpOrigin_ + SAML_REDIRECTION_PATH; 273 var url = this.idpOrigin_ + SAML_REDIRECTION_PATH;
293 url = appendParam(url, 'domain', data.enterpriseDomain); 274 url = appendParam(url, 'domain', data.enterpriseDomain);
294 url = appendParam(url, 'continue', data.gaiaUrl + 275 url = appendParam(
295 'o/oauth2/programmatic_auth?hl=' + data.hl + 276 url, 'continue', data.gaiaUrl + 'o/oauth2/programmatic_auth?hl=' +
296 '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' + 277 data.hl +
297 'client_id=' + encodeURIComponent(data.clientId) + 278 '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' +
298 '&access_type=offline'); 279 'client_id=' + encodeURIComponent(data.clientId) +
280 '&access_type=offline');
299 281
300 return url; 282 return url;
301 } 283 }
302 284
303 var path = data.gaiaPath; 285 var path = data.gaiaPath;
304 if (!path && this.isNewGaiaFlow) 286 if (!path && this.isNewGaiaFlow)
305 path = EMBEDDED_SETUP_CHROMEOS_ENDPOINT; 287 path = EMBEDDED_SETUP_CHROMEOS_ENDPOINT;
306 if (!path) 288 if (!path)
307 path = IDP_PATH; 289 path = IDP_PATH;
308 var url = this.idpOrigin_ + path; 290 var url = this.idpOrigin_ + path;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 }); 443 });
462 // Removes "" around. 444 // Removes "" around.
463 this.email_ = signinDetails['email'].slice(1, -1); 445 this.email_ = signinDetails['email'].slice(1, -1);
464 this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1); 446 this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1);
465 this.sessionIndex_ = signinDetails['sessionindex']; 447 this.sessionIndex_ = signinDetails['sessionindex'];
466 } else if (headerName == LOCATION_HEADER) { 448 } else if (headerName == LOCATION_HEADER) {
467 // If the "choose what to sync" checkbox was clicked, then the continue 449 // If the "choose what to sync" checkbox was clicked, then the continue
468 // URL will contain a source=3 field. 450 // URL will contain a source=3 field.
469 var location = decodeURIComponent(header.value); 451 var location = decodeURIComponent(header.value);
470 this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/); 452 this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/);
471 } else if ( 453 } else if (this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) {
472 this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) {
473 var headerValue = header.value; 454 var headerValue = header.value;
474 if (headerValue.startsWith(OAUTH_CODE_COOKIE + '=')) { 455 if (headerValue.startsWith(OAUTH_CODE_COOKIE + '=')) {
475 this.oauthCode_ = 456 this.oauthCode_ =
476 headerValue.substring(OAUTH_CODE_COOKIE.length + 1).split(';')[0]; 457 headerValue.substring(OAUTH_CODE_COOKIE.length + 1).split(';')[0];
477 } 458 }
478 if (headerValue.startsWith(GAPS_COOKIE + '=')) { 459 if (headerValue.startsWith(GAPS_COOKIE + '=')) {
479 this.newGapsCookie_ = 460 this.newGapsCookie_ =
480 headerValue.substring(GAPS_COOKIE.length + 1).split(';')[0]; 461 headerValue.substring(GAPS_COOKIE.length + 1).split(';')[0];
481 } 462 }
482 } 463 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 // We should re-send cookie if first request was unsuccessful (i.e. no new 498 // We should re-send cookie if first request was unsuccessful (i.e. no new
518 // GAPS cookie was received). 499 // GAPS cookie was received).
519 if (this.isNewGaiaFlow && this.gapsCookie_ && 500 if (this.isNewGaiaFlow && this.gapsCookie_ &&
520 (!this.gapsCookieSent_ || !this.newGapsCookie_)) { 501 (!this.gapsCookieSent_ || !this.newGapsCookie_)) {
521 var headers = details.requestHeaders; 502 var headers = details.requestHeaders;
522 var found = false; 503 var found = false;
523 var gapsCookie = this.gapsCookie_; 504 var gapsCookie = this.gapsCookie_;
524 505
525 for (var i = 0, l = headers.length; i < l; ++i) { 506 for (var i = 0, l = headers.length; i < l; ++i) {
526 if (headers[i].name == COOKIE_HEADER) { 507 if (headers[i].name == COOKIE_HEADER) {
527 headers[i].value = this.updateCookieValue_(headers[i].value, 508 headers[i].value = this.updateCookieValue_(
528 GAPS_COOKIE, gapsCookie); 509 headers[i].value, GAPS_COOKIE, gapsCookie);
529 found = true; 510 found = true;
530 break; 511 break;
531 } 512 }
532 } 513 }
533 if (!found) { 514 if (!found) {
534 details.requestHeaders.push( 515 details.requestHeaders.push(
535 {name: COOKIE_HEADER, value: GAPS_COOKIE + '=' + gapsCookie}); 516 {name: COOKIE_HEADER, value: GAPS_COOKIE + '=' + gapsCookie});
536 } 517 }
537 this.gapsCookieSent_ = true; 518 this.gapsCookieSent_ = true;
538 } 519 }
539 return { 520 return {requestHeaders: details.requestHeaders};
540 requestHeaders: details.requestHeaders
541 };
542 }; 521 };
543 522
544 /** 523 /**
545 * Returns true if given HTML5 message is received from the webview element. 524 * Returns true if given HTML5 message is received from the webview element.
546 * @param {object} e Payload of the received HTML5 message. 525 * @param {object} e Payload of the received HTML5 message.
547 */ 526 */
548 Authenticator.prototype.isGaiaMessage = function(e) { 527 Authenticator.prototype.isGaiaMessage = function(e) {
549 if (!this.isWebviewEvent_(e)) 528 if (!this.isWebviewEvent_(e))
550 return false; 529 return false;
551 530
552 // The event origin does not have a trailing slash. 531 // The event origin does not have a trailing slash.
553 if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) { 532 if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) {
554 return false; 533 return false;
555 } 534 }
556 535
557 // EAFE passes back auth code via message. 536 // EAFE passes back auth code via message.
558 if (this.useEafe_ && 537 if (this.useEafe_ && typeof e.data == 'object' &&
559 typeof e.data == 'object' &&
560 e.data.hasOwnProperty('authorizationCode')) { 538 e.data.hasOwnProperty('authorizationCode')) {
561 assert(!this.oauthCode_); 539 assert(!this.oauthCode_);
562 this.oauthCode_ = e.data.authorizationCode; 540 this.oauthCode_ = e.data.authorizationCode;
563 this.dispatchEvent( 541 this.dispatchEvent(new CustomEvent(
564 new CustomEvent('authCompleted', 542 'authCompleted',
565 { 543 {detail: {authCodeOnly: true, authCode: this.oauthCode_}}));
566 detail: {
567 authCodeOnly: true,
568 authCode: this.oauthCode_
569 }
570 }));
571 return; 544 return;
572 } 545 }
573 546
574 // Gaia messages must be an object with 'method' property. 547 // Gaia messages must be an object with 'method' property.
575 if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) { 548 if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) {
576 return false; 549 return false;
577 } 550 }
578 return true; 551 return true;
579 }; 552 };
580 553
581 /** 554 /**
582 * Invoked when an HTML5 message is received from the webview element. 555 * Invoked when an HTML5 message is received from the webview element.
583 * @param {object} e Payload of the received HTML5 message. 556 * @param {object} e Payload of the received HTML5 message.
584 * @private 557 * @private
585 */ 558 */
586 Authenticator.prototype.onMessageFromWebview_ = function(e) { 559 Authenticator.prototype.onMessageFromWebview_ = function(e) {
587 if (!this.isGaiaMessage(e)) 560 if (!this.isGaiaMessage(e))
588 return; 561 return;
589 562
590 var msg = e.data; 563 var msg = e.data;
591 if (msg.method == 'attemptLogin') { 564 if (msg.method == 'attemptLogin') {
592 this.email_ = msg.email; 565 this.email_ = msg.email;
593 if (this.authMode == AuthMode.DESKTOP) 566 if (this.authMode == AuthMode.DESKTOP)
594 this.password_ = msg.password; 567 this.password_ = msg.password;
595 568
596 this.chooseWhatToSync_ = msg.chooseWhatToSync; 569 this.chooseWhatToSync_ = msg.chooseWhatToSync;
597 // We need to dispatch only first event, before user enters password. 570 // We need to dispatch only first event, before user enters password.
598 this.dispatchEvent( 571 this.dispatchEvent(new CustomEvent('attemptLogin', {detail: msg.email}));
599 new CustomEvent('attemptLogin', {detail: msg.email}));
600 } else if (msg.method == 'dialogShown') { 572 } else if (msg.method == 'dialogShown') {
601 this.dispatchEvent(new Event('dialogShown')); 573 this.dispatchEvent(new Event('dialogShown'));
602 } else if (msg.method == 'dialogHidden') { 574 } else if (msg.method == 'dialogHidden') {
603 this.dispatchEvent(new Event('dialogHidden')); 575 this.dispatchEvent(new Event('dialogHidden'));
604 } else if (msg.method == 'backButton') { 576 } else if (msg.method == 'backButton') {
605 this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); 577 this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show}));
606 } else if (msg.method == 'showView') { 578 } else if (msg.method == 'showView') {
607 this.dispatchEvent(new Event('showView')); 579 this.dispatchEvent(new Event('showView'));
608 } else if (msg.method == 'identifierEntered') { 580 } else if (msg.method == 'identifierEntered') {
609 this.dispatchEvent(new CustomEvent( 581 this.dispatchEvent(new CustomEvent(
610 'identifierEntered', 582 'identifierEntered',
611 {detail: {accountIdentifier: msg.accountIdentifier}})); 583 {detail: {accountIdentifier: msg.accountIdentifier}}));
612 } else { 584 } else {
613 console.warn('Unrecognized message from GAIA: ' + msg.method); 585 console.warn('Unrecognized message from GAIA: ' + msg.method);
614 } 586 }
615 }; 587 };
616 588
617 /** 589 /**
618 * Invoked by the hosting page to verify the Saml password. 590 * Invoked by the hosting page to verify the Saml password.
619 */ 591 */
620 Authenticator.prototype.verifyConfirmedPassword = function(password) { 592 Authenticator.prototype.verifyConfirmedPassword = function(password) {
621 if (!this.samlHandler_.verifyConfirmedPassword(password)) { 593 if (!this.samlHandler_.verifyConfirmedPassword(password)) {
622 // Invoke confirm password callback asynchronously because the 594 // Invoke confirm password callback asynchronously because the
623 // verification was based on messages and caller (GaiaSigninScreen) 595 // verification was based on messages and caller (GaiaSigninScreen)
624 // does not expect it to be called immediately. 596 // does not expect it to be called immediately.
625 // TODO(xiyuan): Change to synchronous call when iframe based code 597 // TODO(xiyuan): Change to synchronous call when iframe based code
626 // is removed. 598 // is removed.
627 var invokeConfirmPassword = (function() { 599 var invokeConfirmPassword =
628 this.confirmPasswordCallback(this.email_, 600 (function() {
629 this.samlHandler_.scrapedPasswordCount); 601 this.confirmPasswordCallback(
630 }).bind(this); 602 this.email_, this.samlHandler_.scrapedPasswordCount);
603 }).bind(this);
631 window.setTimeout(invokeConfirmPassword, 0); 604 window.setTimeout(invokeConfirmPassword, 0);
632 return; 605 return;
633 } 606 }
634 607
635 this.password_ = password; 608 this.password_ = password;
636 this.onAuthCompleted_(); 609 this.onAuthCompleted_();
637 }; 610 };
638 611
639 /** 612 /**
640 * Check Saml flow and start password confirmation flow if needed. Otherwise, 613 * Check Saml flow and start password confirmation flow if needed. Otherwise,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 // If we scraped exactly one password, we complete the authentication 648 // If we scraped exactly one password, we complete the authentication
676 // right away. 649 // right away.
677 this.password_ = this.samlHandler_.firstScrapedPassword; 650 this.password_ = this.samlHandler_.firstScrapedPassword;
678 this.onAuthCompleted_(); 651 this.onAuthCompleted_();
679 return; 652 return;
680 } 653 }
681 654
682 if (this.confirmPasswordCallback) { 655 if (this.confirmPasswordCallback) {
683 // Confirm scraped password. The flow follows in 656 // Confirm scraped password. The flow follows in
684 // verifyConfirmedPassword. 657 // verifyConfirmedPassword.
685 this.confirmPasswordCallback(this.email_, 658 this.confirmPasswordCallback(
686 this.samlHandler_.scrapedPasswordCount); 659 this.email_, this.samlHandler_.scrapedPasswordCount);
687 return; 660 return;
688 } 661 }
689 } 662 }
690 663
691 this.onAuthCompleted_(); 664 this.onAuthCompleted_();
692 }; 665 };
693 666
694 /** 667 /**
695 * Invoked to complete the authentication using the password the user enters 668 * Invoked to complete the authentication using the password the user enters
696 * manually for non-principals API SAML IdPs that we couldn't scrape their 669 * manually for non-principals API SAML IdPs that we couldn't scrape their
697 * password input. 670 * password input.
698 */ 671 */
699 Authenticator.prototype.completeAuthWithManualPassword = function(password) { 672 Authenticator.prototype.completeAuthWithManualPassword = function(password) {
700 this.password_ = password; 673 this.password_ = password;
701 this.onAuthCompleted_(); 674 this.onAuthCompleted_();
702 }; 675 };
703 676
704 /** 677 /**
705 * Invoked to process authentication completion. 678 * Invoked to process authentication completion.
706 * @private 679 * @private
707 */ 680 */
708 Authenticator.prototype.onAuthCompleted_ = function() { 681 Authenticator.prototype.onAuthCompleted_ = function() {
709 assert(this.skipForNow_ || 682 assert(
710 (this.email_ && this.gaiaId_ && this.sessionIndex_)); 683 this.skipForNow_ ||
684 (this.email_ && this.gaiaId_ && this.sessionIndex_));
711 this.dispatchEvent(new CustomEvent( 685 this.dispatchEvent(new CustomEvent(
712 'authCompleted', 686 'authCompleted',
713 // TODO(rsorokin): get rid of the stub values. 687 // TODO(rsorokin): get rid of the stub values.
714 { 688 {
715 detail: { 689 detail: {
716 email: this.email_ || '', 690 email: this.email_ || '',
717 gaiaId: this.gaiaId_ || '', 691 gaiaId: this.gaiaId_ || '',
718 password: this.password_ || '', 692 password: this.password_ || '',
719 authCode: this.oauthCode_, 693 authCode: this.oauthCode_,
720 usingSAML: this.authFlow == AuthFlow.SAML, 694 usingSAML: this.authFlow == AuthFlow.SAML,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 } else if (currentUrl == BLANK_PAGE_URL) { 797 } else if (currentUrl == BLANK_PAGE_URL) {
824 this.fireReadyEvent_(); 798 this.fireReadyEvent_();
825 } 799 }
826 }; 800 };
827 801
828 /** 802 /**
829 * Invoked when the webview fails loading a page. 803 * Invoked when the webview fails loading a page.
830 * @private 804 * @private
831 */ 805 */
832 Authenticator.prototype.onLoadAbort_ = function(e) { 806 Authenticator.prototype.onLoadAbort_ = function(e) {
833 this.dispatchEvent(new CustomEvent('loadAbort', 807 this.dispatchEvent(
834 {detail: {error: e.reason, src: e.url}})); 808 new CustomEvent('loadAbort', {detail: {error: e.reason, src: e.url}}));
835 }; 809 };
836 810
837 /** 811 /**
838 * Invoked when the webview finishes loading a page. 812 * Invoked when the webview finishes loading a page.
839 * @private 813 * @private
840 */ 814 */
841 Authenticator.prototype.onLoadStop_ = function(e) { 815 Authenticator.prototype.onLoadStop_ = function(e) {
842 // Sends client id to EAFE on every loadstop after a small timeout. This is 816 // Sends client id to EAFE on every loadstop after a small timeout. This is
843 // needed because EAFE sits behind SSO and initialize asynchrounouly 817 // needed because EAFE sits behind SSO and initialize asynchrounouly
844 // and we don't know for sure when it is loaded and ready to listen 818 // and we don't know for sure when it is loaded and ready to listen
845 // for message. The postMessage is guarded by EAFE's origin. 819 // for message. The postMessage is guarded by EAFE's origin.
846 if (this.useEafe_) { 820 if (this.useEafe_) {
847 // An arbitrary small timeout for delivering the initial message. 821 // An arbitrary small timeout for delivering the initial message.
848 var EAFE_INITIAL_MESSAGE_DELAY_IN_MS = 500; 822 var EAFE_INITIAL_MESSAGE_DELAY_IN_MS = 500;
849 window.setTimeout((function() { 823 window.setTimeout(
850 var msg = { 824 (function() {
851 'clientId': this.clientId_ 825 var msg = {'clientId': this.clientId_};
852 }; 826 this.webview_.contentWindow.postMessage(msg, this.idpOrigin_);
853 this.webview_.contentWindow.postMessage(msg, this.idpOrigin_); 827 }).bind(this),
854 }).bind(this), EAFE_INITIAL_MESSAGE_DELAY_IN_MS); 828 EAFE_INITIAL_MESSAGE_DELAY_IN_MS);
855 } 829 }
856 }; 830 };
857 831
858 /** 832 /**
859 * Invoked when the webview navigates withing the current document. 833 * Invoked when the webview navigates withing the current document.
860 * @private 834 * @private
861 */ 835 */
862 Authenticator.prototype.onLoadCommit_ = function(e) { 836 Authenticator.prototype.onLoadCommit_ = function(e) {
863 if (this.oauthCode_) 837 if (this.oauthCode_)
864 this.maybeCompleteAuth_(); 838 this.maybeCompleteAuth_();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 Authenticator.AuthMode = AuthMode; 872 Authenticator.AuthMode = AuthMode;
899 Authenticator.SUPPORTED_PARAMS = SUPPORTED_PARAMS; 873 Authenticator.SUPPORTED_PARAMS = SUPPORTED_PARAMS;
900 874
901 return { 875 return {
902 // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old 876 // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old
903 // iframe-based flow is deprecated. 877 // iframe-based flow is deprecated.
904 GaiaAuthHost: Authenticator, 878 GaiaAuthHost: Authenticator,
905 Authenticator: Authenticator 879 Authenticator: Authenticator
906 }; 880 };
907 }); 881 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698