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

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: hackhackhack Created 3 years, 11 months 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'.
dschuyler 2017/01/06 02:16:33 Could the formatter align the comments in all of S
Dan Beam 2017/01/06 02:36:50 maybe it could but there's style rules that discou
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 14 matching lines...) Expand all
119 * web pages. 112 * web pages.
120 * @constructor 113 * @constructor
121 */ 114 */
122 function Authenticator(webview) { 115 function Authenticator(webview) {
123 this.webview_ = typeof webview == 'string' ? $(webview) : webview; 116 this.webview_ = typeof webview == 'string' ? $(webview) : webview;
124 assert(this.webview_); 117 assert(this.webview_);
125 118
126 this.isLoaded_ = false; 119 this.isLoaded_ = false;
127 this.email_ = null; 120 this.email_ = null;
128 this.password_ = null; 121 this.password_ = null;
129 this.gaiaId_ = null, 122 this.gaiaId_ = null, this.sessionIndex_ = null;
dschuyler 2017/01/06 02:16:33 This looks like a typo in the original file. s/,/
Dan Beam 2017/01/06 02:36:50 yes, it is
130 this.sessionIndex_ = null;
131 this.chooseWhatToSync_ = false; 123 this.chooseWhatToSync_ = false;
132 this.skipForNow_ = false; 124 this.skipForNow_ = false;
133 this.authFlow = AuthFlow.DEFAULT; 125 this.authFlow = AuthFlow.DEFAULT;
134 this.authDomain = ''; 126 this.authDomain = '';
135 this.videoEnabled = false; 127 this.videoEnabled = false;
136 this.idpOrigin_ = null; 128 this.idpOrigin_ = null;
137 this.continueUrl_ = null; 129 this.continueUrl_ = null;
138 this.continueUrlWithoutParams_ = null; 130 this.continueUrlWithoutParams_ = null;
139 this.initialFrameUrl_ = null; 131 this.initialFrameUrl_ = null;
140 this.reloadUrl_ = null; 132 this.reloadUrl_ = null;
141 this.trusted_ = true; 133 this.trusted_ = true;
142 this.oauthCode_ = null; 134 this.oauthCode_ = null;
143 this.gapsCookie_ = null; 135 this.gapsCookie_ = null;
144 this.gapsCookieSent_ = false; 136 this.gapsCookieSent_ = false;
145 this.newGapsCookie_ = null; 137 this.newGapsCookie_ = null;
146 this.readyFired_ = false; 138 this.readyFired_ = false;
147 139
148 this.useEafe_ = false; 140 this.useEafe_ = false;
149 this.clientId_ = null; 141 this.clientId_ = null;
150 142
151 this.samlHandler_ = new cr.login.SamlHandler(this.webview_); 143 this.samlHandler_ = new cr.login.SamlHandler(this.webview_);
152 this.confirmPasswordCallback = null; 144 this.confirmPasswordCallback = null;
153 this.noPasswordCallback = null; 145 this.noPasswordCallback = null;
154 this.insecureContentBlockedCallback = null; 146 this.insecureContentBlockedCallback = null;
155 this.samlApiUsedCallback = null; 147 this.samlApiUsedCallback = null;
156 this.missingGaiaInfoCallback = null; 148 this.missingGaiaInfoCallback = null;
157 this.needPassword = true; 149 this.needPassword = true;
158 this.samlHandler_.addEventListener( 150 this.samlHandler_.addEventListener(
159 'insecureContentBlocked', 151 'insecureContentBlocked', this.onInsecureContentBlocked_.bind(this));
160 this.onInsecureContentBlocked_.bind(this));
161 this.samlHandler_.addEventListener( 152 this.samlHandler_.addEventListener(
162 'authPageLoaded', 153 'authPageLoaded', this.onAuthPageLoaded_.bind(this));
163 this.onAuthPageLoaded_.bind(this));
164 this.samlHandler_.addEventListener( 154 this.samlHandler_.addEventListener(
165 'videoEnabled', 155 'videoEnabled', this.onVideoEnabled_.bind(this));
166 this.onVideoEnabled_.bind(this));
167 this.samlHandler_.addEventListener( 156 this.samlHandler_.addEventListener(
168 'apiPasswordAdded', 157 'apiPasswordAdded', this.onSamlApiPasswordAdded_.bind(this));
169 this.onSamlApiPasswordAdded_.bind(this));
170 158
171 this.webview_.addEventListener('droplink', this.onDropLink_.bind(this)); 159 this.webview_.addEventListener('droplink', this.onDropLink_.bind(this));
172 this.webview_.addEventListener( 160 this.webview_.addEventListener('newwindow', this.onNewWindow_.bind(this));
173 'newwindow', this.onNewWindow_.bind(this));
174 this.webview_.addEventListener( 161 this.webview_.addEventListener(
175 'contentload', this.onContentLoad_.bind(this)); 162 'contentload', this.onContentLoad_.bind(this));
176 this.webview_.addEventListener( 163 this.webview_.addEventListener('loadabort', this.onLoadAbort_.bind(this));
177 'loadabort', this.onLoadAbort_.bind(this)); 164 this.webview_.addEventListener('loadstop', this.onLoadStop_.bind(this));
178 this.webview_.addEventListener( 165 this.webview_.addEventListener('loadcommit', this.onLoadCommit_.bind(this));
179 'loadstop', this.onLoadStop_.bind(this));
180 this.webview_.addEventListener(
181 'loadcommit', this.onLoadCommit_.bind(this));
182 this.webview_.request.onCompleted.addListener( 166 this.webview_.request.onCompleted.addListener(
183 this.onRequestCompleted_.bind(this), 167 this.onRequestCompleted_.bind(this),
184 {urls: ['<all_urls>'], types: ['main_frame']}, 168 {urls: ['<all_urls>'], types: ['main_frame']}, ['responseHeaders']);
185 ['responseHeaders']);
186 this.webview_.request.onHeadersReceived.addListener( 169 this.webview_.request.onHeadersReceived.addListener(
187 this.onHeadersReceived_.bind(this), 170 this.onHeadersReceived_.bind(this),
188 {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, 171 {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']},
189 ['responseHeaders']); 172 ['responseHeaders']);
190 window.addEventListener( 173 window.addEventListener(
191 'message', this.onMessageFromWebview_.bind(this), false); 174 'message', this.onMessageFromWebview_.bind(this), false);
192 window.addEventListener( 175 window.addEventListener('focus', this.onFocus_.bind(this), false);
193 'focus', this.onFocus_.bind(this), false); 176 window.addEventListener('popstate', this.onPopState_.bind(this), false);
194 window.addEventListener(
195 'popstate', this.onPopState_.bind(this), false);
196 } 177 }
197 178
198 Authenticator.prototype = Object.create(cr.EventTarget.prototype); 179 Authenticator.prototype = Object.create(cr.EventTarget.prototype);
199 180
200 /** 181 /**
201 * Reinitializes authentication parameters so that a failed login attempt 182 * Reinitializes authentication parameters so that a failed login attempt
202 * would not result in an infinite loop. 183 * would not result in an infinite loop.
203 */ 184 */
204 Authenticator.prototype.resetStates = function() { 185 Authenticator.prototype.resetStates = function() {
205 this.isLoaded_ = false; 186 this.isLoaded_ = false;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 this.clientId_ = data.clientId; 229 this.clientId_ = data.clientId;
249 this.gapsCookie_ = data.gapsCookie; 230 this.gapsCookie_ = data.gapsCookie;
250 this.gapsCookieSent_ = false; 231 this.gapsCookieSent_ = false;
251 this.newGapsCookie_ = null; 232 this.newGapsCookie_ = null;
252 this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; 233 this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages;
253 234
254 this.initialFrameUrl_ = this.constructInitialFrameUrl_(data); 235 this.initialFrameUrl_ = this.constructInitialFrameUrl_(data);
255 this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_; 236 this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_;
256 // Don't block insecure content for desktop flow because it lands on 237 // Don't block insecure content for desktop flow because it lands on
257 // http. Otherwise, block insecure content as long as gaia is https. 238 // http. Otherwise, block insecure content as long as gaia is https.
258 this.samlHandler_.blockInsecureContent = authMode != AuthMode.DESKTOP && 239 this.samlHandler_.blockInsecureContent =
259 this.idpOrigin_.startsWith('https://'); 240 authMode != AuthMode.DESKTOP && this.idpOrigin_.startsWith('https://');
260 this.needPassword = !('needPassword' in data) || data.needPassword; 241 this.needPassword = !('needPassword' in data) || data.needPassword;
261 242
262 if (this.isNewGaiaFlow) { 243 if (this.isNewGaiaFlow) {
263 this.webview_.contextMenus.onShow.addListener(function(e) { 244 this.webview_.contextMenus.onShow.addListener(function(e) {
264 e.preventDefault(); 245 e.preventDefault();
265 }); 246 });
266 247
267 if (!this.onBeforeSetHeadersSet_) { 248 if (!this.onBeforeSetHeadersSet_) {
268 this.onBeforeSetHeadersSet_ = true; 249 this.onBeforeSetHeadersSet_ = true;
269 var filterPrefix = this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT; 250 var filterPrefix = this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT;
(...skipping 15 matching lines...) Expand all
285 Authenticator.prototype.reload = function() { 266 Authenticator.prototype.reload = function() {
286 this.resetStates(); 267 this.resetStates();
287 this.webview_.src = this.reloadUrl_; 268 this.webview_.src = this.reloadUrl_;
288 this.isLoaded_ = true; 269 this.isLoaded_ = true;
289 }; 270 };
290 271
291 Authenticator.prototype.constructInitialFrameUrl_ = function(data) { 272 Authenticator.prototype.constructInitialFrameUrl_ = function(data) {
292 if (data.doSamlRedirect) { 273 if (data.doSamlRedirect) {
293 var url = this.idpOrigin_ + SAML_REDIRECTION_PATH; 274 var url = this.idpOrigin_ + SAML_REDIRECTION_PATH;
294 url = appendParam(url, 'domain', data.enterpriseDomain); 275 url = appendParam(url, 'domain', data.enterpriseDomain);
295 url = appendParam(url, 'continue', data.gaiaUrl + 276 url = appendParam(
296 'o/oauth2/programmatic_auth?hl=' + data.hl + 277 url, 'continue', data.gaiaUrl + 'o/oauth2/programmatic_auth?hl=' +
297 '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' + 278 data.hl +
298 'client_id=' + encodeURIComponent(data.clientId) + 279 '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' +
299 '&access_type=offline'); 280 'client_id=' + encodeURIComponent(data.clientId) +
281 '&access_type=offline');
300 282
301 return url; 283 return url;
302 } 284 }
303 285
304 var path = data.gaiaPath; 286 var path = data.gaiaPath;
305 if (!path && this.isNewGaiaFlow) 287 if (!path && this.isNewGaiaFlow)
306 path = EMBEDDED_SETUP_CHROMEOS_ENDPOINT; 288 path = EMBEDDED_SETUP_CHROMEOS_ENDPOINT;
307 if (!path) 289 if (!path)
308 path = IDP_PATH; 290 path = IDP_PATH;
309 var url = this.idpOrigin_ + path; 291 var url = this.idpOrigin_ + path;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 }); 444 });
463 // Removes "" around. 445 // Removes "" around.
464 this.email_ = signinDetails['email'].slice(1, -1); 446 this.email_ = signinDetails['email'].slice(1, -1);
465 this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1); 447 this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1);
466 this.sessionIndex_ = signinDetails['sessionindex']; 448 this.sessionIndex_ = signinDetails['sessionindex'];
467 } else if (headerName == LOCATION_HEADER) { 449 } else if (headerName == LOCATION_HEADER) {
468 // If the "choose what to sync" checkbox was clicked, then the continue 450 // If the "choose what to sync" checkbox was clicked, then the continue
469 // URL will contain a source=3 field. 451 // URL will contain a source=3 field.
470 var location = decodeURIComponent(header.value); 452 var location = decodeURIComponent(header.value);
471 this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/); 453 this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/);
472 } else if ( 454 } else if (this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) {
473 this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) {
474 var headerValue = header.value; 455 var headerValue = header.value;
475 if (headerValue.startsWith(OAUTH_CODE_COOKIE + '=')) { 456 if (headerValue.startsWith(OAUTH_CODE_COOKIE + '=')) {
476 this.oauthCode_ = 457 this.oauthCode_ =
477 headerValue.substring(OAUTH_CODE_COOKIE.length + 1).split(';')[0]; 458 headerValue.substring(OAUTH_CODE_COOKIE.length + 1).split(';')[0];
478 } 459 }
479 if (headerValue.startsWith(GAPS_COOKIE + '=')) { 460 if (headerValue.startsWith(GAPS_COOKIE + '=')) {
480 this.newGapsCookie_ = 461 this.newGapsCookie_ =
481 headerValue.substring(GAPS_COOKIE.length + 1).split(';')[0]; 462 headerValue.substring(GAPS_COOKIE.length + 1).split(';')[0];
482 } 463 }
483 } 464 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 // We should re-send cookie if first request was unsuccessful (i.e. no new 499 // We should re-send cookie if first request was unsuccessful (i.e. no new
519 // GAPS cookie was received). 500 // GAPS cookie was received).
520 if (this.isNewGaiaFlow && this.gapsCookie_ && 501 if (this.isNewGaiaFlow && this.gapsCookie_ &&
521 (!this.gapsCookieSent_ || !this.newGapsCookie_)) { 502 (!this.gapsCookieSent_ || !this.newGapsCookie_)) {
522 var headers = details.requestHeaders; 503 var headers = details.requestHeaders;
523 var found = false; 504 var found = false;
524 var gapsCookie = this.gapsCookie_; 505 var gapsCookie = this.gapsCookie_;
525 506
526 for (var i = 0, l = headers.length; i < l; ++i) { 507 for (var i = 0, l = headers.length; i < l; ++i) {
527 if (headers[i].name == COOKIE_HEADER) { 508 if (headers[i].name == COOKIE_HEADER) {
528 headers[i].value = this.updateCookieValue_(headers[i].value, 509 headers[i].value = this.updateCookieValue_(
529 GAPS_COOKIE, gapsCookie); 510 headers[i].value, GAPS_COOKIE, gapsCookie);
530 found = true; 511 found = true;
531 break; 512 break;
532 } 513 }
533 } 514 }
534 if (!found) { 515 if (!found) {
535 details.requestHeaders.push( 516 details.requestHeaders.push(
536 {name: COOKIE_HEADER, value: GAPS_COOKIE + '=' + gapsCookie}); 517 {name: COOKIE_HEADER, value: GAPS_COOKIE + '=' + gapsCookie});
537 } 518 }
538 this.gapsCookieSent_ = true; 519 this.gapsCookieSent_ = true;
539 } 520 }
540 return { 521 return {requestHeaders: details.requestHeaders};
541 requestHeaders: details.requestHeaders
542 };
543 }; 522 };
544 523
545 /** 524 /**
546 * Returns true if given HTML5 message is received from the webview element. 525 * Returns true if given HTML5 message is received from the webview element.
547 * @param {object} e Payload of the received HTML5 message. 526 * @param {object} e Payload of the received HTML5 message.
548 */ 527 */
549 Authenticator.prototype.isGaiaMessage = function(e) { 528 Authenticator.prototype.isGaiaMessage = function(e) {
550 if (!this.isWebviewEvent_(e)) 529 if (!this.isWebviewEvent_(e))
551 return false; 530 return false;
552 531
553 // The event origin does not have a trailing slash. 532 // The event origin does not have a trailing slash.
554 if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) { 533 if (e.origin != this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) {
555 return false; 534 return false;
556 } 535 }
557 536
558 // EAFE passes back auth code via message. 537 // EAFE passes back auth code via message.
559 if (this.useEafe_ && 538 if (this.useEafe_ && typeof e.data == 'object' &&
560 typeof e.data == 'object' &&
561 e.data.hasOwnProperty('authorizationCode')) { 539 e.data.hasOwnProperty('authorizationCode')) {
562 assert(!this.oauthCode_); 540 assert(!this.oauthCode_);
563 this.oauthCode_ = e.data.authorizationCode; 541 this.oauthCode_ = e.data.authorizationCode;
564 this.dispatchEvent( 542 this.dispatchEvent(new CustomEvent(
565 new CustomEvent('authCompleted', 543 'authCompleted',
566 { 544 {detail: {authCodeOnly: true, authCode: this.oauthCode_}}));
567 detail: {
568 authCodeOnly: true,
569 authCode: this.oauthCode_
570 }
571 }));
572 return; 545 return;
573 } 546 }
574 547
575 // Gaia messages must be an object with 'method' property. 548 // Gaia messages must be an object with 'method' property.
576 if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) { 549 if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) {
577 return false; 550 return false;
578 } 551 }
579 return true; 552 return true;
580 }; 553 };
581 554
582 /** 555 /**
583 * Invoked when an HTML5 message is received from the webview element. 556 * Invoked when an HTML5 message is received from the webview element.
584 * @param {object} e Payload of the received HTML5 message. 557 * @param {object} e Payload of the received HTML5 message.
585 * @private 558 * @private
586 */ 559 */
587 Authenticator.prototype.onMessageFromWebview_ = function(e) { 560 Authenticator.prototype.onMessageFromWebview_ = function(e) {
588 if (!this.isGaiaMessage(e)) 561 if (!this.isGaiaMessage(e))
589 return; 562 return;
590 563
591 var msg = e.data; 564 var msg = e.data;
592 if (msg.method == 'attemptLogin') { 565 if (msg.method == 'attemptLogin') {
593 this.email_ = msg.email; 566 this.email_ = msg.email;
594 if (this.authMode == AuthMode.DESKTOP) 567 if (this.authMode == AuthMode.DESKTOP)
595 this.password_ = msg.password; 568 this.password_ = msg.password;
596 569
597 this.chooseWhatToSync_ = msg.chooseWhatToSync; 570 this.chooseWhatToSync_ = msg.chooseWhatToSync;
598 // We need to dispatch only first event, before user enters password. 571 // We need to dispatch only first event, before user enters password.
599 this.dispatchEvent( 572 this.dispatchEvent(new CustomEvent('attemptLogin', {detail: msg.email}));
600 new CustomEvent('attemptLogin', {detail: msg.email}));
601 } else if (msg.method == 'dialogShown') { 573 } else if (msg.method == 'dialogShown') {
602 this.dispatchEvent(new Event('dialogShown')); 574 this.dispatchEvent(new Event('dialogShown'));
603 } else if (msg.method == 'dialogHidden') { 575 } else if (msg.method == 'dialogHidden') {
604 this.dispatchEvent(new Event('dialogHidden')); 576 this.dispatchEvent(new Event('dialogHidden'));
605 } else if (msg.method == 'backButton') { 577 } else if (msg.method == 'backButton') {
606 this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); 578 this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show}));
607 } else if (msg.method == 'showView') { 579 } else if (msg.method == 'showView') {
608 this.dispatchEvent(new Event('showView')); 580 this.dispatchEvent(new Event('showView'));
609 } else if (msg.method == 'identifierEntered') { 581 } else if (msg.method == 'identifierEntered') {
610 this.dispatchEvent(new CustomEvent( 582 this.dispatchEvent(new CustomEvent(
611 'identifierEntered', 583 'identifierEntered',
612 {detail: {accountIdentifier: msg.accountIdentifier}})); 584 {detail: {accountIdentifier: msg.accountIdentifier}}));
613 } else { 585 } else {
614 console.warn('Unrecognized message from GAIA: ' + msg.method); 586 console.warn('Unrecognized message from GAIA: ' + msg.method);
615 } 587 }
616 }; 588 };
617 589
618 /** 590 /**
619 * Invoked by the hosting page to verify the Saml password. 591 * Invoked by the hosting page to verify the Saml password.
620 */ 592 */
621 Authenticator.prototype.verifyConfirmedPassword = function(password) { 593 Authenticator.prototype.verifyConfirmedPassword = function(password) {
622 if (!this.samlHandler_.verifyConfirmedPassword(password)) { 594 if (!this.samlHandler_.verifyConfirmedPassword(password)) {
623 // Invoke confirm password callback asynchronously because the 595 // Invoke confirm password callback asynchronously because the
624 // verification was based on messages and caller (GaiaSigninScreen) 596 // verification was based on messages and caller (GaiaSigninScreen)
625 // does not expect it to be called immediately. 597 // does not expect it to be called immediately.
626 // TODO(xiyuan): Change to synchronous call when iframe based code 598 // TODO(xiyuan): Change to synchronous call when iframe based code
627 // is removed. 599 // is removed.
628 var invokeConfirmPassword = (function() { 600 var invokeConfirmPassword =
629 this.confirmPasswordCallback(this.email_, 601 (function() {
630 this.samlHandler_.scrapedPasswordCount); 602 this.confirmPasswordCallback(
631 }).bind(this); 603 this.email_, this.samlHandler_.scrapedPasswordCount);
604 }).bind(this);
632 window.setTimeout(invokeConfirmPassword, 0); 605 window.setTimeout(invokeConfirmPassword, 0);
633 return; 606 return;
634 } 607 }
635 608
636 this.password_ = password; 609 this.password_ = password;
637 this.onAuthCompleted_(); 610 this.onAuthCompleted_();
638 }; 611 };
639 612
640 /** 613 /**
641 * Check Saml flow and start password confirmation flow if needed. Otherwise, 614 * Check Saml flow and start password confirmation flow if needed. Otherwise,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 // If we scraped exactly one password, we complete the authentication 649 // If we scraped exactly one password, we complete the authentication
677 // right away. 650 // right away.
678 this.password_ = this.samlHandler_.firstScrapedPassword; 651 this.password_ = this.samlHandler_.firstScrapedPassword;
679 this.onAuthCompleted_(); 652 this.onAuthCompleted_();
680 return; 653 return;
681 } 654 }
682 655
683 if (this.confirmPasswordCallback) { 656 if (this.confirmPasswordCallback) {
684 // Confirm scraped password. The flow follows in 657 // Confirm scraped password. The flow follows in
685 // verifyConfirmedPassword. 658 // verifyConfirmedPassword.
686 this.confirmPasswordCallback(this.email_, 659 this.confirmPasswordCallback(
687 this.samlHandler_.scrapedPasswordCount); 660 this.email_, this.samlHandler_.scrapedPasswordCount);
688 return; 661 return;
689 } 662 }
690 } 663 }
691 664
692 this.onAuthCompleted_(); 665 this.onAuthCompleted_();
693 }; 666 };
694 667
695 /** 668 /**
696 * Invoked to complete the authentication using the password the user enters 669 * Invoked to complete the authentication using the password the user enters
697 * manually for non-principals API SAML IdPs that we couldn't scrape their 670 * manually for non-principals API SAML IdPs that we couldn't scrape their
698 * password input. 671 * password input.
699 */ 672 */
700 Authenticator.prototype.completeAuthWithManualPassword = function(password) { 673 Authenticator.prototype.completeAuthWithManualPassword = function(password) {
701 this.password_ = password; 674 this.password_ = password;
702 this.onAuthCompleted_(); 675 this.onAuthCompleted_();
703 }; 676 };
704 677
705 /** 678 /**
706 * Invoked to process authentication completion. 679 * Invoked to process authentication completion.
707 * @private 680 * @private
708 */ 681 */
709 Authenticator.prototype.onAuthCompleted_ = function() { 682 Authenticator.prototype.onAuthCompleted_ = function() {
710 assert(this.skipForNow_ || 683 assert(
711 (this.email_ && this.gaiaId_ && this.sessionIndex_)); 684 this.skipForNow_ ||
685 (this.email_ && this.gaiaId_ && this.sessionIndex_));
712 this.dispatchEvent(new CustomEvent( 686 this.dispatchEvent(new CustomEvent(
713 'authCompleted', 687 'authCompleted',
714 // TODO(rsorokin): get rid of the stub values. 688 // TODO(rsorokin): get rid of the stub values.
715 { 689 {
716 detail: { 690 detail: {
717 email: this.email_ || '', 691 email: this.email_ || '',
718 gaiaId: this.gaiaId_ || '', 692 gaiaId: this.gaiaId_ || '',
719 password: this.password_ || '', 693 password: this.password_ || '',
720 authCode: this.oauthCode_, 694 authCode: this.oauthCode_,
721 usingSAML: this.authFlow == AuthFlow.SAML, 695 usingSAML: this.authFlow == AuthFlow.SAML,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 } else if (currentUrl == BLANK_PAGE_URL) { 798 } else if (currentUrl == BLANK_PAGE_URL) {
825 this.fireReadyEvent_(); 799 this.fireReadyEvent_();
826 } 800 }
827 }; 801 };
828 802
829 /** 803 /**
830 * Invoked when the webview fails loading a page. 804 * Invoked when the webview fails loading a page.
831 * @private 805 * @private
832 */ 806 */
833 Authenticator.prototype.onLoadAbort_ = function(e) { 807 Authenticator.prototype.onLoadAbort_ = function(e) {
834 this.dispatchEvent(new CustomEvent('loadAbort', 808 this.dispatchEvent(
835 {detail: {error: e.reason, src: e.url}})); 809 new CustomEvent('loadAbort', {detail: {error: e.reason, src: e.url}}));
836 }; 810 };
837 811
838 /** 812 /**
839 * Invoked when the webview finishes loading a page. 813 * Invoked when the webview finishes loading a page.
840 * @private 814 * @private
841 */ 815 */
842 Authenticator.prototype.onLoadStop_ = function(e) { 816 Authenticator.prototype.onLoadStop_ = function(e) {
843 // Sends client id to EAFE on every loadstop after a small timeout. This is 817 // Sends client id to EAFE on every loadstop after a small timeout. This is
844 // needed because EAFE sits behind SSO and initialize asynchrounouly 818 // needed because EAFE sits behind SSO and initialize asynchrounouly
845 // and we don't know for sure when it is loaded and ready to listen 819 // and we don't know for sure when it is loaded and ready to listen
846 // for message. The postMessage is guarded by EAFE's origin. 820 // for message. The postMessage is guarded by EAFE's origin.
847 if (this.useEafe_) { 821 if (this.useEafe_) {
848 // An arbitrary small timeout for delivering the initial message. 822 // An arbitrary small timeout for delivering the initial message.
849 var EAFE_INITIAL_MESSAGE_DELAY_IN_MS = 500; 823 var EAFE_INITIAL_MESSAGE_DELAY_IN_MS = 500;
850 window.setTimeout((function() { 824 window.setTimeout(
851 var msg = { 825 (function() {
852 'clientId': this.clientId_ 826 var msg = {'clientId': this.clientId_};
853 }; 827 this.webview_.contentWindow.postMessage(msg, this.idpOrigin_);
854 this.webview_.contentWindow.postMessage(msg, this.idpOrigin_); 828 }).bind(this),
855 }).bind(this), EAFE_INITIAL_MESSAGE_DELAY_IN_MS); 829 EAFE_INITIAL_MESSAGE_DELAY_IN_MS);
856 } 830 }
857 }; 831 };
858 832
859 /** 833 /**
860 * Invoked when the webview navigates withing the current document. 834 * Invoked when the webview navigates withing the current document.
861 * @private 835 * @private
862 */ 836 */
863 Authenticator.prototype.onLoadCommit_ = function(e) { 837 Authenticator.prototype.onLoadCommit_ = function(e) {
864 if (this.oauthCode_) 838 if (this.oauthCode_)
865 this.maybeCompleteAuth_(); 839 this.maybeCompleteAuth_();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 Authenticator.AuthMode = AuthMode; 873 Authenticator.AuthMode = AuthMode;
900 Authenticator.SUPPORTED_PARAMS = SUPPORTED_PARAMS; 874 Authenticator.SUPPORTED_PARAMS = SUPPORTED_PARAMS;
901 875
902 return { 876 return {
903 // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old 877 // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old
904 // iframe-based flow is deprecated. 878 // iframe-based flow is deprecated.
905 GaiaAuthHost: Authenticator, 879 GaiaAuthHost: Authenticator,
906 Authenticator: Authenticator 880 Authenticator: Authenticator
907 }; 881 };
908 }); 882 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698