diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/chrome/browser/resources/gaia_auth_host | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/gaia_auth_host')
4 files changed, 327 insertions, 341 deletions
diff --git a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js index 381a7df1565..2c3f836f88e 100644 --- a/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chromium/chrome/browser/resources/gaia_auth_host/authenticator.js @@ -10,6 +10,8 @@ * authentication events should pass a listener object of type * cr.login.GaiaAuthHost.Listener as defined in this file. After initialization, * call {@code load} to start the authentication flow. + * + * See go/cros-auth-design for details on Google API. */ cr.define('cr.login', function() { @@ -31,6 +33,7 @@ cr.define('cr.login', function() { var GAPS_COOKIE = 'GAPS'; var SERVICE_ID = 'chromeoslogin'; var EMBEDDED_SETUP_CHROMEOS_ENDPOINT = 'embedded/setup/chromeos'; + var EMBEDDED_SETUP_CHROMEOS_ENDPOINT_V2 = 'embedded/setup/v2/chromeos'; var SAML_REDIRECTION_PATH = 'samlredirect'; var BLANK_PAGE_URL = 'about:blank'; @@ -44,20 +47,13 @@ cr.define('cr.login', function() { * chrome/browser/ui/webui/inline_login_ui.cc. * @enum {number} */ - var AuthMode = { - DEFAULT: 0, - OFFLINE: 1, - DESKTOP: 2 - }; + var AuthMode = {DEFAULT: 0, OFFLINE: 1, DESKTOP: 2}; /** * Enum for the authorization type. * @enum {number} */ - var AuthFlow = { - DEFAULT: 0, - SAML: 1 - }; + var AuthFlow = {DEFAULT: 0, SAML: 1}; /** * Supported Authenticator params. @@ -83,15 +79,19 @@ cr.define('cr.login', function() { // not called before dispatching |authCopleted|. // Default is |true|. 'flow', // One of 'default', 'enterprise', or 'theftprotection'. - 'enterpriseDomain', // Domain in which hosting device is (or should be) - // enrolled. - 'emailDomain', // Value used to prefill domain for email. - 'chromeType', // Type of Chrome OS device, e.g. "chromebox". - 'clientVersion', // Version of the Chrome build. - 'platformVersion', // Version of the OS build. - 'releaseChannel', // Installation channel. - 'endpointGen', // Current endpoint generation. - 'gapsCookie', // GAPS cookie + 'enterpriseEnrollmentDomain', // Domain in which hosting device is (or + // should be) enrolled. + 'emailDomain', // Value used to prefill domain for email. + 'chromeType', // Type of Chrome OS device, e.g. "chromebox". + 'clientVersion', // Version of the Chrome build. + 'platformVersion', // Version of the OS build. + 'releaseChannel', // Installation channel. + 'endpointGen', // Current endpoint generation. + 'gapsCookie', // GAPS cookie + 'chromeOSApiVersion', // GAIA Chrome OS API version + 'menuGuestMode', // Enables "Guest mode" menu item + 'menuKeyboardOptions', // Enables "Keyboard options" menu item + 'menuEnterpriseEnrollment', // Enables "Enterprise enrollment" menu item. // The email fields allow for the following possibilities: // @@ -126,8 +126,7 @@ cr.define('cr.login', function() { this.isLoaded_ = false; this.email_ = null; this.password_ = null; - this.gaiaId_ = null, - this.sessionIndex_ = null; + this.gaiaId_ = null, this.sessionIndex_ = null; this.chooseWhatToSync_ = false; this.skipForNow_ = false; this.authFlow = AuthFlow.DEFAULT; @@ -156,43 +155,32 @@ cr.define('cr.login', function() { this.missingGaiaInfoCallback = null; this.needPassword = true; this.samlHandler_.addEventListener( - 'insecureContentBlocked', - this.onInsecureContentBlocked_.bind(this)); + 'insecureContentBlocked', this.onInsecureContentBlocked_.bind(this)); this.samlHandler_.addEventListener( - 'authPageLoaded', - this.onAuthPageLoaded_.bind(this)); + 'authPageLoaded', this.onAuthPageLoaded_.bind(this)); this.samlHandler_.addEventListener( - 'videoEnabled', - this.onVideoEnabled_.bind(this)); + 'videoEnabled', this.onVideoEnabled_.bind(this)); this.samlHandler_.addEventListener( - 'apiPasswordAdded', - this.onSamlApiPasswordAdded_.bind(this)); + 'apiPasswordAdded', this.onSamlApiPasswordAdded_.bind(this)); this.webview_.addEventListener('droplink', this.onDropLink_.bind(this)); - this.webview_.addEventListener( - 'newwindow', this.onNewWindow_.bind(this)); + this.webview_.addEventListener('newwindow', this.onNewWindow_.bind(this)); this.webview_.addEventListener( 'contentload', this.onContentLoad_.bind(this)); - this.webview_.addEventListener( - 'loadabort', this.onLoadAbort_.bind(this)); - this.webview_.addEventListener( - 'loadstop', this.onLoadStop_.bind(this)); - this.webview_.addEventListener( - 'loadcommit', this.onLoadCommit_.bind(this)); + this.webview_.addEventListener('loadabort', this.onLoadAbort_.bind(this)); + this.webview_.addEventListener('loadstop', this.onLoadStop_.bind(this)); + this.webview_.addEventListener('loadcommit', this.onLoadCommit_.bind(this)); this.webview_.request.onCompleted.addListener( this.onRequestCompleted_.bind(this), - {urls: ['<all_urls>'], types: ['main_frame']}, - ['responseHeaders']); + {urls: ['<all_urls>'], types: ['main_frame']}, ['responseHeaders']); this.webview_.request.onHeadersReceived.addListener( this.onHeadersReceived_.bind(this), {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, ['responseHeaders']); window.addEventListener( 'message', this.onMessageFromWebview_.bind(this), false); - window.addEventListener( - 'focus', this.onFocus_.bind(this), false); - window.addEventListener( - 'popstate', this.onPopState_.bind(this), false); + window.addEventListener('focus', this.onFocus_.bind(this), false); + window.addEventListener('popstate', this.onPopState_.bind(this), false); } Authenticator.prototype = Object.create(cr.EventTarget.prototype); @@ -250,13 +238,14 @@ cr.define('cr.login', function() { this.gapsCookieSent_ = false; this.newGapsCookie_ = null; this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; + this.chromeOSApiVersion_ = data.chromeOSApiVersion; this.initialFrameUrl_ = this.constructInitialFrameUrl_(data); this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_; // Don't block insecure content for desktop flow because it lands on // http. Otherwise, block insecure content as long as gaia is https. - this.samlHandler_.blockInsecureContent = authMode != AuthMode.DESKTOP && - this.idpOrigin_.startsWith('https://'); + this.samlHandler_.blockInsecureContent = + authMode != AuthMode.DESKTOP && this.idpOrigin_.startsWith('https://'); this.needPassword = !('needPassword' in data) || data.needPassword; if (this.isNewGaiaFlow) { @@ -266,7 +255,7 @@ cr.define('cr.login', function() { if (!this.onBeforeSetHeadersSet_) { this.onBeforeSetHeadersSet_ = true; - var filterPrefix = this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT; + var filterPrefix = this.constructChromeOSAPIUrl_(); // This depends on gaiaUrl parameter, that is why it is here. this.webview_.request.onBeforeSendHeaders.addListener( this.onBeforeSendHeaders_.bind(this), @@ -279,6 +268,13 @@ cr.define('cr.login', function() { this.isLoaded_ = true; }; + Authenticator.prototype.constructChromeOSAPIUrl_ = function() { + if (this.chromeOSApiVersion_ && this.chromeOSApiVersion_ == 2) + return this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT_V2; + + return this.idpOrigin_ + EMBEDDED_SETUP_CHROMEOS_ENDPOINT; + }; + /** * Reloads the authenticator component. */ @@ -291,30 +287,33 @@ cr.define('cr.login', function() { Authenticator.prototype.constructInitialFrameUrl_ = function(data) { if (data.doSamlRedirect) { var url = this.idpOrigin_ + SAML_REDIRECTION_PATH; - url = appendParam(url, 'domain', data.enterpriseDomain); - url = appendParam(url, 'continue', data.gaiaUrl + - 'o/oauth2/programmatic_auth?hl=' + data.hl + - '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' + - 'client_id=' + encodeURIComponent(data.clientId) + - '&access_type=offline'); + url = appendParam(url, 'domain', data.enterpriseEnrollmentDomain); + url = appendParam( + url, 'continue', + data.gaiaUrl + 'o/oauth2/programmatic_auth?hl=' + data.hl + + '&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin&' + + 'client_id=' + encodeURIComponent(data.clientId) + + '&access_type=offline'); return url; } - var path = data.gaiaPath; - if (!path && this.isNewGaiaFlow) - path = EMBEDDED_SETUP_CHROMEOS_ENDPOINT; - if (!path) - path = IDP_PATH; - var url = this.idpOrigin_ + path; + var url; + if (data.gaiaPath) + url = this.idpOrigin_ + data.gaiaPath; + else if (this.isNewGaiaFlow) + url = this.constructChromeOSAPIUrl_(); + else + url = this.idpOrigin_ + IDP_PATH; if (this.isNewGaiaFlow) { if (data.chromeType) url = appendParam(url, 'chrometype', data.chromeType); if (data.clientId) url = appendParam(url, 'client_id', data.clientId); - if (data.enterpriseDomain) - url = appendParam(url, 'manageddomain', data.enterpriseDomain); + if (data.enterpriseEnrollmentDomain) + url = + appendParam(url, 'manageddomain', data.enterpriseEnrollmentDomain); if (data.clientVersion) url = appendParam(url, 'client_version', data.clientVersion); if (data.platformVersion) @@ -323,6 +322,17 @@ cr.define('cr.login', function() { url = appendParam(url, 'release_channel', data.releaseChannel); if (data.endpointGen) url = appendParam(url, 'endpoint_gen', data.endpointGen); + if (data.chromeOSApiVersion == 2) { + var mi = ''; + if (data.menuGuestMode) + mi += 'gm,'; + if (data.menuKeyboardOptions) + mi += 'ko,'; + if (data.menuEnterpriseEnrollment) + mi += 'ee,'; + if (mi.length) + url = appendParam(url, 'mi', mi); + } } else { url = appendParam(url, 'continue', this.continueUrl_); url = appendParam(url, 'service', data.service || SERVICE_ID); @@ -404,11 +414,11 @@ cr.define('cr.login', function() { }; /** - * Manually updates the history. Invoked upon completion of a webview - * navigation. - * @param {string} url Request URL. - * @private - */ + * Manually updates the history. Invoked upon completion of a webview + * navigation. + * @param {string} url Request URL. + * @private + */ Authenticator.prototype.updateHistoryState_ = function(url) { if (history.state && history.state.url != url) history.pushState({url: url}, ''); @@ -469,8 +479,7 @@ cr.define('cr.login', function() { // URL will contain a source=3 field. var location = decodeURIComponent(header.value); this.chooseWhatToSync_ = !!location.match(/(\?|&)source=3($|&)/); - } else if ( - this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) { + } else if (this.isNewGaiaFlow && headerName == SET_COOKIE_HEADER) { var headerValue = header.value; if (headerValue.startsWith(OAUTH_CODE_COOKIE + '=')) { this.oauthCode_ = @@ -525,8 +534,8 @@ cr.define('cr.login', function() { for (var i = 0, l = headers.length; i < l; ++i) { if (headers[i].name == COOKIE_HEADER) { - headers[i].value = this.updateCookieValue_(headers[i].value, - GAPS_COOKIE, gapsCookie); + headers[i].value = this.updateCookieValue_( + headers[i].value, GAPS_COOKIE, gapsCookie); found = true; break; } @@ -537,9 +546,7 @@ cr.define('cr.login', function() { } this.gapsCookieSent_ = true; } - return { - requestHeaders: details.requestHeaders - }; + return {requestHeaders: details.requestHeaders}; }; /** @@ -556,19 +563,13 @@ cr.define('cr.login', function() { } // EAFE passes back auth code via message. - if (this.useEafe_ && - typeof e.data == 'object' && + if (this.useEafe_ && typeof e.data == 'object' && e.data.hasOwnProperty('authorizationCode')) { assert(!this.oauthCode_); this.oauthCode_ = e.data.authorizationCode; - this.dispatchEvent( - new CustomEvent('authCompleted', - { - detail: { - authCodeOnly: true, - authCode: this.oauthCode_ - } - })); + this.dispatchEvent(new CustomEvent( + 'authCompleted', + {detail: {authCodeOnly: true, authCode: this.oauthCode_}})); return; } @@ -596,8 +597,7 @@ cr.define('cr.login', function() { this.chooseWhatToSync_ = msg.chooseWhatToSync; // We need to dispatch only first event, before user enters password. - this.dispatchEvent( - new CustomEvent('attemptLogin', {detail: msg.email})); + this.dispatchEvent(new CustomEvent('attemptLogin', {detail: msg.email})); } else if (msg.method == 'dialogShown') { this.dispatchEvent(new Event('dialogShown')); } else if (msg.method == 'dialogHidden') { @@ -606,6 +606,9 @@ cr.define('cr.login', function() { this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); } else if (msg.method == 'showView') { this.dispatchEvent(new Event('showView')); + } else if (msg.method == 'menuItemClicked') { + this.dispatchEvent( + new CustomEvent('menuItemClicked', {detail: msg.item})); } else if (msg.method == 'identifierEntered') { this.dispatchEvent(new CustomEvent( 'identifierEntered', @@ -625,10 +628,11 @@ cr.define('cr.login', function() { // does not expect it to be called immediately. // TODO(xiyuan): Change to synchronous call when iframe based code // is removed. - var invokeConfirmPassword = (function() { - this.confirmPasswordCallback(this.email_, - this.samlHandler_.scrapedPasswordCount); - }).bind(this); + var invokeConfirmPassword = + (function() { + this.confirmPasswordCallback( + this.email_, this.samlHandler_.scrapedPasswordCount); + }).bind(this); window.setTimeout(invokeConfirmPassword, 0); return; } @@ -683,8 +687,8 @@ cr.define('cr.login', function() { if (this.confirmPasswordCallback) { // Confirm scraped password. The flow follows in // verifyConfirmedPassword. - this.confirmPasswordCallback(this.email_, - this.samlHandler_.scrapedPasswordCount); + this.confirmPasswordCallback( + this.email_, this.samlHandler_.scrapedPasswordCount); return; } } @@ -707,8 +711,9 @@ cr.define('cr.login', function() { * @private */ Authenticator.prototype.onAuthCompleted_ = function() { - assert(this.skipForNow_ || - (this.email_ && this.gaiaId_ && this.sessionIndex_)); + assert( + this.skipForNow_ || + (this.email_ && this.gaiaId_ && this.sessionIndex_)); this.dispatchEvent(new CustomEvent( 'authCompleted', // TODO(rsorokin): get rid of the stub values. @@ -831,8 +836,8 @@ cr.define('cr.login', function() { * @private */ Authenticator.prototype.onLoadAbort_ = function(e) { - this.dispatchEvent(new CustomEvent('loadAbort', - {detail: {error: e.reason, src: e.url}})); + this.dispatchEvent( + new CustomEvent('loadAbort', {detail: {error: e.reason, src: e.url}})); }; /** @@ -847,12 +852,12 @@ cr.define('cr.login', function() { if (this.useEafe_) { // An arbitrary small timeout for delivering the initial message. var EAFE_INITIAL_MESSAGE_DELAY_IN_MS = 500; - window.setTimeout((function() { - var msg = { - 'clientId': this.clientId_ - }; - this.webview_.contentWindow.postMessage(msg, this.idpOrigin_); - }).bind(this), EAFE_INITIAL_MESSAGE_DELAY_IN_MS); + window.setTimeout( + (function() { + var msg = {'clientId': this.clientId_}; + this.webview_.contentWindow.postMessage(msg, this.idpOrigin_); + }).bind(this), + EAFE_INITIAL_MESSAGE_DELAY_IN_MS); } }; diff --git a/chromium/chrome/browser/resources/gaia_auth_host/post_message_channel.js b/chromium/chrome/browser/resources/gaia_auth_host/post_message_channel.js index b20300dccaa..1239a89cbe1 100644 --- a/chromium/chrome/browser/resources/gaia_auth_host/post_message_channel.js +++ b/chromium/chrome/browser/resources/gaia_auth_host/post_message_channel.js @@ -16,10 +16,7 @@ var PostMessageChannel = (function() { * Allowed origins of the hosting page. * @type {Array<string>} */ - var ALLOWED_ORIGINS = [ - 'chrome://oobe', - 'chrome://chrome-signin' - ]; + var ALLOWED_ORIGINS = ['chrome://oobe', 'chrome://chrome-signin']; /** @const */ var PORT_MESSAGE = 'post-message-port-message'; @@ -149,7 +146,9 @@ var PostMessageChannel = (function() { * @private */ getProxyPortForwardHandler_: function(proxyPort) { - return function(msg) { proxyPort.postMessage(msg); }; + return function(msg) { + proxyPort.postMessage(msg); + }; }, /** @@ -161,8 +160,8 @@ var PostMessageChannel = (function() { */ createProxyPort: function( channelId, channelName, targetWindow, targetOrigin) { - var port = this.createPort( - channelId, channelName, targetWindow, targetOrigin); + var port = + this.createPort(channelId, channelName, targetWindow, targetOrigin); port.onMessage.addListener(this.getProxyPortForwardHandler_(port)); return port; }, @@ -213,8 +212,7 @@ var PostMessageChannel = (function() { * Window 'message' handler. */ onMessage_: function(e) { - if (typeof e.data != 'object' || - !e.data.hasOwnProperty('type')) { + if (typeof e.data != 'object' || !e.data.hasOwnProperty('type')) { return; } @@ -233,8 +231,8 @@ var PostMessageChannel = (function() { var channelName = e.data.channelName; if (this.isDaemon) { - var port = this.createPort( - channelId, channelName, e.source, e.origin); + var port = + this.createPort(channelId, channelName, e.source, e.origin); this.onConnect.dispatch(port); } else { this.createProxyPort(channelId, channelName, e.source, e.origin); @@ -248,14 +246,14 @@ var PostMessageChannel = (function() { this.upperOrigin = e.origin; for (var i = 0; i < this.deferredUpperWindowMessages_.length; ++i) { - this.upperWindow.postMessage(this.deferredUpperWindowMessages_[i], - this.upperOrigin); + this.upperWindow.postMessage( + this.deferredUpperWindowMessages_[i], this.upperOrigin); } this.deferredUpperWindowMessages_ = []; for (var i = 0; i < this.deferredUpperWindowPorts_.length; ++i) { - this.deferredUpperWindowPorts_[i].setTarget(this.upperWindow, - this.upperOrigin); + this.deferredUpperWindowPorts_[i].setTarget( + this.upperWindow, this.upperOrigin); } this.deferredUpperWindowPorts_ = []; } @@ -306,11 +304,9 @@ var PostMessageChannel = (function() { return; } - this.targetWindow.postMessage({ - type: PORT_MESSAGE, - channelId: this.channelId, - payload: msg - }, this.targetOrigin); + this.targetWindow.postMessage( + {type: PORT_MESSAGE, channelId: this.channelId, payload: msg}, + this.targetOrigin); }, handleWindowMessage: function(e) { @@ -342,9 +338,7 @@ var PostMessageChannel = (function() { * @param {DOMWindow} webViewContentWindow Content window of the webview. */ PostMessageChannel.init = function(webViewContentWindow) { - webViewContentWindow.postMessage({ - type: CHANNEL_INIT_MESSAGE - }, '*'); + webViewContentWindow.postMessage({type: CHANNEL_INIT_MESSAGE}, '*'); }; /** diff --git a/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js b/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js index 48b195b410a..9212e584129 100644 --- a/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js +++ b/chromium/chrome/browser/resources/gaia_auth_host/saml_handler.js @@ -143,17 +143,14 @@ cr.define('cr.login', function() { this.webview_.addEventListener( 'contentload', this.onContentLoad_.bind(this)); - this.webview_.addEventListener( - 'loadabort', this.onLoadAbort_.bind(this)); - this.webview_.addEventListener( - 'loadcommit', this.onLoadCommit_.bind(this)); + this.webview_.addEventListener('loadabort', this.onLoadAbort_.bind(this)); + this.webview_.addEventListener('loadcommit', this.onLoadCommit_.bind(this)); this.webview_.addEventListener( 'permissionrequest', this.onPermissionRequest_.bind(this)); this.webview_.request.onBeforeRequest.addListener( this.onInsecureRequest.bind(this), - {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']}, - ['blocking']); + {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']}, ['blocking']); this.webview_.request.onHeadersReceived.addListener( this.onHeadersReceived_.bind(this), {urls: ['<all_urls>'], types: ['main_frame', 'xmlhttprequest']}, @@ -162,9 +159,7 @@ cr.define('cr.login', function() { this.webview_.addContentScripts([{ name: 'samlInjected', matches: ['http://*/*', 'https://*/*'], - js: { - code: injectedJs - }, + js: {code: injectedJs}, all_frames: true, run_at: 'document_start' }]); @@ -290,8 +285,8 @@ cr.define('cr.login', function() { if (!this.blockInsecureContent) return {}; var strippedUrl = stripParams(details.url); - this.dispatchEvent(new CustomEvent('insecureContentBlocked', - {detail: {url: strippedUrl}})); + this.dispatchEvent(new CustomEvent( + 'insecureContentBlocked', {detail: {url: strippedUrl}})); return {cancel: true}; }, @@ -318,8 +313,8 @@ cr.define('cr.login', function() { // requests will be coming from the IdP. Append a cookie to the // current |headers| that marks the point at which the redirect // occurred. - headers.push({name: 'Set-Cookie', - value: 'google-accounts-saml-start=now'}); + headers.push( + {name: 'Set-Cookie', value: 'google-accounts-saml-start=now'}); return {responseHeaders: headers}; } else if (action == 'end') { this.pendingIsSamlPage_ = false; @@ -344,8 +339,8 @@ cr.define('cr.login', function() { // ignored by Chrome in cookie headers, causing the modified headers // to actually set the original cookies. var otherHeaders = []; - var cookies = [{name: 'Set-Cookie', - value: 'google-accounts-saml-end=now'}]; + var cookies = + [{name: 'Set-Cookie', value: 'google-accounts-saml-end=now'}]; for (var j = 0; j < headers.length; ++j) { if (headers[j].name.toLowerCase().startsWith('set-cookie')) { var header = headers[j]; @@ -373,8 +368,7 @@ cr.define('cr.login', function() { var channel = Channel.create(); channel.init(port); - channel.registerMessage( - 'apiCall', this.onAPICall_.bind(this, channel)); + channel.registerMessage('apiCall', this.onAPICall_.bind(this, channel)); channel.registerMessage( 'updatePassword', this.onUpdatePassword_.bind(this, channel)); channel.registerMessage( @@ -384,20 +378,21 @@ cr.define('cr.login', function() { }, sendInitializationSuccess_: function(channel) { - channel.send({name: 'apiResponse', response: { - result: 'initialized', - version: this.apiVersion_, - keyTypes: API_KEY_TYPES - }}); - }, - - sendInitializationFailure_: function(channel) { channel.send({ name: 'apiResponse', - response: {result: 'initialization_failed'} + response: { + result: 'initialized', + version: this.apiVersion_, + keyTypes: API_KEY_TYPES + } }); }, + sendInitializationFailure_: function(channel) { + channel.send( + {name: 'apiResponse', response: {result: 'initialization_failed'}}); + }, + /** * Handlers for channel messages. * @param {Channel} channel A channel to send back response. @@ -413,8 +408,8 @@ cr.define('cr.login', function() { return; } - this.apiVersion_ = Math.min(call.requestedVersion, - MAX_API_VERSION_VERSION); + this.apiVersion_ = + Math.min(call.requestedVersion, MAX_API_VERSION_VERSION); this.apiInitialized_ = true; this.sendInitializationSuccess_(channel); return; @@ -446,11 +441,13 @@ cr.define('cr.login', function() { onPageLoaded_: function(channel, msg) { this.authDomain = extractDomain(msg.url); - this.dispatchEvent(new CustomEvent( - 'authPageLoaded', - {detail: {url: url, - isSAMLPage: this.isSamlPage_, - domain: this.authDomain}})); + this.dispatchEvent(new CustomEvent('authPageLoaded', { + detail: { + url: url, + isSAMLPage: this.isSamlPage_, + domain: this.authDomain + } + })); }, onPermissionRequest_: function(permissionEvent) { @@ -467,7 +464,5 @@ cr.define('cr.login', function() { }, }; - return { - SamlHandler: SamlHandler - }; + return {SamlHandler: SamlHandler}; }); diff --git a/chromium/chrome/browser/resources/gaia_auth_host/saml_injected.js b/chromium/chrome/browser/resources/gaia_auth_host/saml_injected.js index f79c6264929..ed1468e66a7 100644 --- a/chromium/chrome/browser/resources/gaia_auth_host/saml_injected.js +++ b/chromium/chrome/browser/resources/gaia_auth_host/saml_injected.js @@ -15,204 +15,196 @@ */ (function() { - function APICallForwarder() { - } +function APICallForwarder() {} + +/** + * The credential passing API is used by sending messages to the SAML page's + * |window| object. This class forwards API calls from the SAML page to a + * background script and API responses from the background script to the SAML + * page. Communication with the background script occurs via a |Channel|. + */ +APICallForwarder.prototype = { + // Channel to which API calls are forwarded. + channel_: null, /** - * The credential passing API is used by sending messages to the SAML page's - * |window| object. This class forwards API calls from the SAML page to a - * background script and API responses from the background script to the SAML - * page. Communication with the background script occurs via a |Channel|. + * Initialize the API call forwarder. + * @param {!Object} channel Channel to which API calls should be forwarded. */ - APICallForwarder.prototype = { - // Channel to which API calls are forwarded. - channel_: null, - - /** - * Initialize the API call forwarder. - * @param {!Object} channel Channel to which API calls should be forwarded. - */ - init: function(channel) { - this.channel_ = channel; - this.channel_.registerMessage('apiResponse', - this.onAPIResponse_.bind(this)); - - window.addEventListener('message', this.onMessage_.bind(this)); - }, - - onMessage_: function(event) { - if (event.source != window || - typeof event.data != 'object' || - !event.data.hasOwnProperty('type') || - event.data.type != 'gaia_saml_api') { - return; - } - // Forward API calls to the background script. - this.channel_.send({name: 'apiCall', call: event.data.call}); - }, - - onAPIResponse_: function(msg) { - // Forward API responses to the SAML page. - window.postMessage({type: 'gaia_saml_api_reply', response: msg.response}, - '/'); + init: function(channel) { + this.channel_ = channel; + this.channel_.registerMessage( + 'apiResponse', this.onAPIResponse_.bind(this)); + + window.addEventListener('message', this.onMessage_.bind(this)); + }, + + onMessage_: function(event) { + if (event.source != window || typeof event.data != 'object' || + !event.data.hasOwnProperty('type') || + event.data.type != 'gaia_saml_api') { + return; } - }; + // Forward API calls to the background script. + this.channel_.send({name: 'apiCall', call: event.data.call}); + }, + + onAPIResponse_: function(msg) { + // Forward API responses to the SAML page. + window.postMessage( + {type: 'gaia_saml_api_reply', response: msg.response}, '/'); + } +}; + +/** + * A class to scrape password from type=password input elements under a given + * docRoot and send them back via a Channel. + */ +function PasswordInputScraper() {} + +PasswordInputScraper.prototype = { + // URL of the page. + pageURL_: null, + + // Channel to send back changed password. + channel_: null, + + // An array to hold password fields. + passwordFields_: null, + + // An array to hold cached password values. + passwordValues_: null, + + // A MutationObserver to watch for dynamic password field creation. + passwordFieldsObserver: null, /** - * A class to scrape password from type=password input elements under a given - * docRoot and send them back via a Channel. + * Initialize the scraper with given channel and docRoot. Note that the + * scanning for password fields happens inside the function and does not + * handle DOM tree changes after the call returns. + * @param {!Object} channel The channel to send back password. + * @param {!string} pageURL URL of the page. + * @param {!HTMLElement} docRoot The root element of the DOM tree that + * contains the password fields of interest. */ - function PasswordInputScraper() { - } - - PasswordInputScraper.prototype = { - // URL of the page. - pageURL_: null, - - // Channel to send back changed password. - channel_: null, - - // An array to hold password fields. - passwordFields_: null, - - // An array to hold cached password values. - passwordValues_: null, - - // A MutationObserver to watch for dynamic password field creation. - passwordFieldsObserver: null, - - /** - * Initialize the scraper with given channel and docRoot. Note that the - * scanning for password fields happens inside the function and does not - * handle DOM tree changes after the call returns. - * @param {!Object} channel The channel to send back password. - * @param {!string} pageURL URL of the page. - * @param {!HTMLElement} docRoot The root element of the DOM tree that - * contains the password fields of interest. - */ - init: function(channel, pageURL, docRoot) { - this.pageURL_ = pageURL; - this.channel_ = channel; - - this.passwordFields_ = []; - this.passwordValues_ = []; - - this.findAndTrackChildren(docRoot); - - this.passwordFieldsObserver = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - Array.prototype.forEach.call( - mutation.addedNodes, - function(addedNode) { - if (addedNode.nodeType != Node.ELEMENT_NODE) - return; - - if (addedNode.matches('input[type=password]')) { - this.trackPasswordField(addedNode); - } else { - this.findAndTrackChildren(addedNode); - } - }.bind(this)); + init: function(channel, pageURL, docRoot) { + this.pageURL_ = pageURL; + this.channel_ = channel; + + this.passwordFields_ = []; + this.passwordValues_ = []; + + this.findAndTrackChildren(docRoot); + + this.passwordFieldsObserver = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) { + if (addedNode.nodeType != Node.ELEMENT_NODE) + return; + + if (addedNode.matches('input[type=password]')) { + this.trackPasswordField(addedNode); + } else { + this.findAndTrackChildren(addedNode); + } }.bind(this)); }.bind(this)); - this.passwordFieldsObserver.observe(docRoot, - {subtree: true, childList: true}); - }, - - /** - * Find and track password fields that are descendants of the given element. - * @param {!HTMLElement} element The parent element to search from. - */ - findAndTrackChildren: function(element) { - Array.prototype.forEach.call( - element.querySelectorAll('input[type=password]'), function(field) { - this.trackPasswordField(field); - }.bind(this)); - }, - - /** - * Start tracking value changes of the given password field if it is - * not being tracked yet. - * @param {!HTMLInputElement} passworField The password field to track. - */ - trackPasswordField: function(passwordField) { - var existing = this.passwordFields_.filter(function(element) { - return element === passwordField; - }); - if (existing.length != 0) - return; + }.bind(this)); + this.passwordFieldsObserver.observe( + docRoot, {subtree: true, childList: true}); + }, - var index = this.passwordFields_.length; - var fieldId = passwordField.id || passwordField.name || ''; - passwordField.addEventListener( - 'input', this.onPasswordChanged_.bind(this, index, fieldId)); - this.passwordFields_.push(passwordField); - this.passwordValues_.push(passwordField.value); - }, - - /** - * Check if the password field at |index| has changed. If so, sends back - * the updated value. - */ - maybeSendUpdatedPassword: function(index, fieldId) { - var newValue = this.passwordFields_[index].value; - if (newValue == this.passwordValues_[index]) - return; + /** + * Find and track password fields that are descendants of the given element. + * @param {!HTMLElement} element The parent element to search from. + */ + findAndTrackChildren: function(element) { + Array.prototype.forEach.call( + element.querySelectorAll('input[type=password]'), function(field) { + this.trackPasswordField(field); + }.bind(this)); + }, - this.passwordValues_[index] = newValue; - - // Use an invalid char for URL as delimiter to concatenate page url, - // password field index and id to construct a unique ID for the password - // field. - var passwordId = this.pageURL_.split('#')[0].split('?')[0] + - '|' + index + '|' + fieldId; - this.channel_.send({ - name: 'updatePassword', - id: passwordId, - password: newValue - }); - }, - - /** - * Handles 'change' event in the scraped password fields. - * @param {number} index The index of the password fields in - * |passwordFields_|. - * @param {string} fieldId The id or name of the password field or blank. - */ - onPasswordChanged_: function(index, fieldId) { - this.maybeSendUpdatedPassword(index, fieldId); - } - }; + /** + * Start tracking value changes of the given password field if it is + * not being tracked yet. + * @param {!HTMLInputElement} passworField The password field to track. + */ + trackPasswordField: function(passwordField) { + var existing = this.passwordFields_.filter(function(element) { + return element === passwordField; + }); + if (existing.length != 0) + return; - function onGetSAMLFlag(channel, isSAMLPage) { - if (!isSAMLPage) + var index = this.passwordFields_.length; + var fieldId = passwordField.id || passwordField.name || ''; + passwordField.addEventListener( + 'input', this.onPasswordChanged_.bind(this, index, fieldId)); + this.passwordFields_.push(passwordField); + this.passwordValues_.push(passwordField.value); + }, + + /** + * Check if the password field at |index| has changed. If so, sends back + * the updated value. + */ + maybeSendUpdatedPassword: function(index, fieldId) { + var newValue = this.passwordFields_[index].value; + if (newValue == this.passwordValues_[index]) return; - var pageURL = window.location.href; - - channel.send({name: 'pageLoaded', url: pageURL}); - - var initPasswordScraper = function() { - var passwordScraper = new PasswordInputScraper(); - passwordScraper.init(channel, pageURL, document.documentElement); - }; - - if (document.readyState == 'loading') { - window.addEventListener('readystatechange', function listener(event) { - if (document.readyState == 'loading') - return; - initPasswordScraper(); - window.removeEventListener(event.type, listener, true); - }, true); - } else { + + this.passwordValues_[index] = newValue; + + // Use an invalid char for URL as delimiter to concatenate page url, + // password field index and id to construct a unique ID for the password + // field. + var passwordId = + this.pageURL_.split('#')[0].split('?')[0] + '|' + index + '|' + fieldId; + this.channel_.send( + {name: 'updatePassword', id: passwordId, password: newValue}); + }, + + /** + * Handles 'change' event in the scraped password fields. + * @param {number} index The index of the password fields in + * |passwordFields_|. + * @param {string} fieldId The id or name of the password field or blank. + */ + onPasswordChanged_: function(index, fieldId) { + this.maybeSendUpdatedPassword(index, fieldId); + } +}; + +function onGetSAMLFlag(channel, isSAMLPage) { + if (!isSAMLPage) + return; + var pageURL = window.location.href; + + channel.send({name: 'pageLoaded', url: pageURL}); + + var initPasswordScraper = function() { + var passwordScraper = new PasswordInputScraper(); + passwordScraper.init(channel, pageURL, document.documentElement); + }; + + if (document.readyState == 'loading') { + window.addEventListener('readystatechange', function listener(event) { + if (document.readyState == 'loading') + return; initPasswordScraper(); - } + window.removeEventListener(event.type, listener, true); + }, true); + } else { + initPasswordScraper(); } +} - var channel = Channel.create(); - channel.connect('injected'); - channel.sendWithCallback({name: 'getSAMLFlag'}, - onGetSAMLFlag.bind(undefined, channel)); +var channel = Channel.create(); +channel.connect('injected'); +channel.sendWithCallback( + {name: 'getSAMLFlag'}, onGetSAMLFlag.bind(undefined, channel)); - var apiCallForwarder = new APICallForwarder(); - apiCallForwarder.init(channel); +var apiCallForwarder = new APICallForwarder(); +apiCallForwarder.init(channel); })(); |