diff options
Diffstat (limited to 'chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js')
-rw-r--r-- | chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js | 399 |
1 files changed, 351 insertions, 48 deletions
diff --git a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index ff044033a19..388a8a55750 100644 --- a/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chromium/chrome/browser/resources/chromeos/login/screen_gaia_signin.js @@ -6,25 +6,33 @@ * @fileoverview Oobe signin screen implementation. */ -<include src="../../gaia_auth_host/gaia_auth_host.js"> - login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { // Gaia loading time after which error message must be displayed and // lazy portal check should be fired. /** @const */ var GAIA_LOADING_PORTAL_SUSSPECT_TIME_SEC = 7; + // GAIA animation guard timer. Started when GAIA page is loaded + // (Authenticator 'ready' event) and is intended to guard against edge cases + // when 'showView' message is not generated/received. + /** @const */ var GAIA_ANIMATION_GUARD_MILLISEC = 300; + // Maximum Gaia loading time in seconds. /** @const */ var MAX_GAIA_LOADING_TIME_SEC = 60; /** @const */ var HELP_TOPIC_ENTERPRISE_REPORTING = 2535613; + // The help topic regarding user not being in the whitelist. + /** @const */ var HELP_CANT_ACCESS_ACCOUNT = 188036; + return { EXTERNAL_API: [ 'loadAuthExtension', 'updateAuthExtension', 'doReload', + 'onWebviewError', 'onFrameError', - 'updateCancelButtonState' + 'updateCancelButtonState', + 'showWhitelistCheckFailedError', ], /** @@ -49,6 +57,12 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { isLocal_: false, /** + * Whether new Gaia flow is active. + * @type {boolean} + */ + isNewGaiaFlow: false, + + /** * Email of the user, which is logging in using offline mode. * @type {string} */ @@ -69,6 +83,22 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { loadingTimer_: undefined, /** + * Timer id of a guard timer that is fired in case 'showView' message + * is not received from GAIA. + * @type {number} + * @private + */ + loadAnimationGuardTimer_: undefined, + + /** + * Whether we've processed 'showView' message - either from GAIA or from + * guard timer. + * @type {boolean} + * @private + */ + showViewProcessed_: undefined, + + /** * Whether user can cancel Gaia screen. * @type {boolean} * @private @@ -88,11 +118,40 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { */ samlPasswordConfirmAttempt_: 0, + /** + * Whether we should show webview based signin. + * @type {boolean} + * @private + */ + isWebviewSignin: false, + /** @override */ decorate: function() { - this.gaiaAuthHost_ = new cr.login.GaiaAuthHost($('signin-frame')); + this.isWebviewSignin = loadTimeData.getValue('isWebviewSignin'); + if (this.isWebviewSignin) { + // Replace iframe with webview. + var webview = this.ownerDocument.createElement('webview'); + webview.id = 'signin-frame'; + webview.name = 'signin-frame'; + webview.hidden = true; + $('signin-frame').parentNode.replaceChild(webview, $('signin-frame')); + this.gaiaAuthHost_ = new cr.login.GaiaAuthHost(webview); + + $('offline-gaia').addEventListener('authCompleted', + this.onAuthCompletedMessage_.bind(this)); + } else { + this.gaiaAuthHost_ = new cr.login.GaiaAuthHost($('signin-frame')); + } this.gaiaAuthHost_.addEventListener( 'ready', this.onAuthReady_.bind(this)); + this.gaiaAuthHost_.addEventListener( + 'dialogShown', this.onDialogShown_.bind(this)); + this.gaiaAuthHost_.addEventListener( + 'dialogHidden', this.onDialogHidden_.bind(this)); + this.gaiaAuthHost_.addEventListener( + 'backButton', this.onBackButton_.bind(this)); + this.gaiaAuthHost_.addEventListener( + 'showView', this.onShowView_.bind(this)); this.gaiaAuthHost_.confirmPasswordCallback = this.onAuthConfirmPassword_.bind(this); this.gaiaAuthHost_.noPasswordCallback = @@ -103,14 +162,38 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { this.missingGaiaInfo_.bind(this); this.gaiaAuthHost_.samlApiUsedCallback = this.samlApiUsed_.bind(this); + this.gaiaAuthHost_.addEventListener('authDomainChange', + this.onAuthDomainChange_.bind(this)); this.gaiaAuthHost_.addEventListener('authFlowChange', this.onAuthFlowChange_.bind(this)); + this.gaiaAuthHost_.addEventListener('authCompleted', + this.onAuthCompletedMessage_.bind(this)); + this.gaiaAuthHost_.addEventListener('loadAbort', + this.onLoadAbortMessage_.bind(this)); $('enterprise-info-hint-link').addEventListener('click', function(e) { chrome.send('launchHelpApp', [HELP_TOPIC_ENTERPRISE_REPORTING]); e.preventDefault(); }); + $('back-button-item').addEventListener('click', function(e) { + $('back-button-item').hidden = true; + $('signin-frame').back(); + e.preventDefault(); + }); + + $('close-button-item').addEventListener('click', function(e) { + this.cancel(); + e.preventDefault(); + }.bind(this)); + + $('gaia-whitelist-error').addEventListener('buttonclick', function() { + this.showWhitelistCheckFailedError(false); + }.bind(this)); + + $('gaia-whitelist-error').addEventListener('linkclick', function() { + chrome.send('launchHelpApp', [HELP_CANT_ACCESS_ACCOUNT]); + }); this.updateLocalizedContent(); }, @@ -137,6 +220,10 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { */ set isLocal(value) { this.isLocal_ = value; + if (this.isNewGaiaFlow) { + $('signin-frame').hidden = this.isLocal_; + $('offline-gaia').hidden = !this.isLocal_; + } chrome.send('updateOfflineLogin', [value]); }, @@ -147,10 +234,18 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { */ showLoadingUI_: function(show) { $('gaia-loading').hidden = !show; - this.gaiaAuthHost_.frame.hidden = show; + if (this.isNewGaiaFlow && this.isLocal) { + $('offline-gaia').hidden = show; + } else { + $('signin-frame').hidden = show; + } $('signin-right').hidden = show; $('enterprise-info-container').hidden = show; $('gaia-signin-divider').hidden = show; + this.classList.toggle('loading', show); + $('signin-frame').classList.remove('show'); + if (!show) + this.classList.remove('auth-completed'); }, /** @@ -161,7 +256,7 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { if (this != Oobe.getInstance().currentScreen) return; chrome.send('showLoadingTimeoutError'); - this.loadingTimer_ = window.setTimeout( + this.loadingTimer_ = setTimeout( this.onLoadingTimeOut_.bind(this), (MAX_GAIA_LOADING_TIME_SEC - GAIA_LOADING_PORTAL_SUSSPECT_TIME_SEC) * 1000); @@ -182,7 +277,7 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { */ clearLoadingTimer_: function() { if (this.loadingTimer_) { - window.clearTimeout(this.loadingTimer_); + clearTimeout(this.loadingTimer_); this.loadingTimer_ = undefined; } }, @@ -193,12 +288,43 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { */ startLoadingTimer_: function() { this.clearLoadingTimer_(); - this.loadingTimer_ = window.setTimeout( + this.loadingTimer_ = setTimeout( this.onLoadingSuspiciouslyLong_.bind(this), GAIA_LOADING_PORTAL_SUSSPECT_TIME_SEC * 1000); }, /** + * Handler for GAIA animation guard timer. + * @private + */ + onLoadAnimationGuardTimer_: function() { + this.loadAnimationGuardTimer_ = undefined; + this.onShowView_(); + }, + + /** + * Clears GAIA animation guard timer. + * @private + */ + clearLoadAnimationGuardTimer_: function() { + if (this.loadAnimationGuardTimer_) { + clearTimeout(this.loadAnimationGuardTimer_); + this.loadAnimationGuardTimer_ = undefined; + } + }, + + /** + * Sets up GAIA animation guard timer. + * @private + */ + startLoadAnimationGuardTimer_: function() { + this.clearLoadAnimationGuardTimer_(); + this.loadAnimationGuardTimer_ = setTimeout( + this.onLoadAnimationGuardTimer_.bind(this), + GAIA_ANIMATION_GUARD_MILLISEC); + }, + + /** * Whether Gaia is loading. * @type {boolean} */ @@ -228,12 +354,25 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { window.requestAnimationFrame(function() { chrome.send('loginVisible', ['gaia-loading']); }); + $('back-button-item').disabled = false; + $('back-button-item').hidden = true; + $('close-button-item').disabled = false; + this.classList.toggle('loading', this.loading); // Button header is always visible when sign in is presented. // Header is hidden once GAIA reports on successful sign in. Oobe.getInstance().headerHidden = false; }, + onAfterShow: function(data) { + if (!this.loading && this.isWebviewSignin) { + if (this.isLocal) + $('offline-gaia').focus(); + else + $('signin-frame').focus(); + } + }, + /** * Event handler that is invoked just before the screen is hidden. */ @@ -248,11 +387,12 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { * @private */ loadAuthExtension: function(data) { + this.isNewGaiaFlow = data.useNewGaiaFlow; this.isLocal = data.isLocal; this.email = ''; // Reset SAML - this.classList.toggle('saml', false); + this.classList.toggle('full-width', false); this.samlPasswordConfirmAttempt_ = 0; this.updateAuthExtension(data); @@ -267,8 +407,22 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { if (data.localizedStrings) params.localizedStrings = data.localizedStrings; - if (data.useEmbedded) - params.gaiaPath = 'EmbeddedSignIn'; + if (this.isNewGaiaFlow) { + $('inner-container').classList.add('new-gaia-flow'); + $('progress-dots').hidden = true; + params.chromeType = data.chromeType; + params.isNewGaiaFlowChromeOS = true; + } + + if (data.gaiaEndpoint) + params.gaiaPath = data.gaiaEndpoint; + + $('login-header-bar').newGaiaFlow = this.isNewGaiaFlow; + + // Screen size could have been changed because of 'new-gaia-flow' or + // 'full-width' classes. + if (Oobe.getInstance().currentScreen === this) + Oobe.getInstance().updateScreenSize(this); if (data.forceReload || JSON.stringify(this.gaiaAuthParams_) != JSON.stringify(params)) { @@ -277,16 +431,19 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { var authMode = cr.login.GaiaAuthHost.AuthMode.DEFAULT; if (data.useOffline) authMode = cr.login.GaiaAuthHost.AuthMode.OFFLINE; - else if (data.useEmbedded) - authMode = cr.login.GaiaAuthHost.AuthMode.DESKTOP; - this.gaiaAuthHost_.load(authMode, - params, - this.onAuthCompleted_.bind(this)); this.gaiaAuthParams_ = params; - this.loading = true; this.startLoadingTimer_(); + + if (this.isLocal && this.isNewGaiaFlow) { + this.loadOffline(params); + this.onAuthReady_(); + } else { + this.gaiaAuthHost_.load(authMode, + params, + this.onAuthCompleted_.bind(this)); + } } else if (this.loading && this.error_) { // An error has occurred, so trying to reload. this.doReload(); @@ -308,16 +465,22 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { reasonLabel.hidden = true; } - $('createAccount').hidden = !data.createAccount; - $('guestSignin').hidden = !data.guestSignin; - $('createSupervisedUserPane').hidden = !data.supervisedUsersEnabled; - - $('createSupervisedUserLinkPlaceholder').hidden = - !data.supervisedUsersCanCreate; - $('createSupervisedUserNoManagerText').hidden = - data.supervisedUsersCanCreate; - $('createSupervisedUserNoManagerText').textContent = - data.supervisedUsersRestrictionReason; + if (this.isNewGaiaFlow) { + $('login-header-bar').showCreateSupervisedButton = + data.supervisedUsersCanCreate; + $('login-header-bar').showGuestButton = data.guestSignin; + } else { + $('createAccount').hidden = !data.createAccount; + $('guestSignin').hidden = !data.guestSignin; + $('createSupervisedUserPane').hidden = !data.supervisedUsersEnabled; + + $('createSupervisedUserLinkPlaceholder').hidden = + !data.supervisedUsersCanCreate; + $('createSupervisedUserNoManagerText').hidden = + data.supervisedUsersCanCreate; + $('createSupervisedUserNoManagerText').textContent = + data.supervisedUsersRestrictionReason; + } var isEnrollingConsumerManagement = data.isEnrollingConsumerManagement; $('consumerManagementEnrollment').hidden = !isEnrollingConsumerManagement; @@ -334,6 +497,7 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { $('createSupervisedUserPane').hidden && $('consumerManagementEnrollment').hidden; this.classList.toggle('no-right-panel', noRightPanel); + this.classList.toggle('full-width', false); if (Oobe.getInstance().currentScreen === this) Oobe.getInstance().updateScreenSize(this); }, @@ -343,8 +507,11 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { * user pods can be displayed. */ updateCancelButtonState: function() { - this.cancelAllowed_ = this.isShowUsers_ && $('pod-row').pods.length; + this.cancelAllowed_ = this.isLocal || + (this.isShowUsers_ && $('pod-row').pods.length); $('login-header-bar').allowCancel = this.cancelAllowed_; + if (this.isNewGaiaFlow) + $('close-button-item').hidden = !this.cancelAllowed_; }, /** @@ -356,24 +523,30 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { }, /** - * Invoked when the authFlow property is changed no the gaia host. + * Invoked when the authDomain property is changed on the GAIA host. + */ + onAuthDomainChange_: function() { + $('saml-notice-message').textContent = loadTimeData.getStringF( + 'samlNotice', + this.gaiaAuthHost_.authDomain); + }, + + /** + * Invoked when the authFlow property is changed on the GAIA host. * @param {Event} e Property change event. */ onAuthFlowChange_: function(e) { var isSAML = this.isSAML(); - if (isSAML) { - $('saml-notice-message').textContent = loadTimeData.getStringF( - 'samlNotice', - this.gaiaAuthHost_.authDomain); - } - - this.classList.toggle('saml', isSAML); + this.classList.toggle('no-right-panel', isSAML); + this.classList.toggle('full-width', isSAML); $('saml-notice-container').hidden = !isSAML; if (Oobe.getInstance().currentScreen === this) { Oobe.getInstance().updateScreenSize(this); $('login-header-bar').allowCancel = isSAML || this.cancelAllowed_; + if (this.isNewGaiaFlow) + $('close-button-item').hidden = !(isSAML || this.cancelAllowed_); } }, @@ -382,9 +555,67 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { * @private */ onAuthReady_: function() { - this.loading = false; + showViewProcessed_ = false; + if (this.isNewGaiaFlow) + this.startLoadAnimationGuardTimer_(); + this.clearLoadingTimer_(); + this.loading = false; + + if (!this.isNewGaiaFlow) + this.onLoginUIVisible_(); + + // Warm up the user images screen. + Oobe.getInstance().preloadScreen({id: SCREEN_USER_IMAGE_PICKER}); + }, + + /** + * Invoked when the auth host emits 'dialogShown' event. + * @private + */ + onDialogShown_: function() { + $('back-button-item').disabled = true; + $('close-button-item').disabled = true; + }, + + /** + * Invoked when the auth host emits 'dialogHidden' event. + * @private + */ + onDialogHidden_: function() { + $('back-button-item').disabled = false; + $('close-button-item').disabled = false; + }, + + /** + * Invoked when the auth host emits 'backButton' event. + * @private + */ + onBackButton_: function(e) { + $('back-button-item').hidden = !e.detail; + $('login-header-bar').updateUI_(); + }, + /** + * Invoked when the auth host emits 'showView' event or when corresponding + * guard time fires. + * @private + */ + onShowView_: function(e) { + if (showViewProcessed_) + return; + + showViewProcessed_ = true; + this.clearLoadAnimationGuardTimer_(); + $('signin-frame').classList.add('show'); + this.onLoginUIVisible_(); + }, + + /** + * Called when UI is shown. + * @private + */ + onLoginUIVisible_: function() { // Show deferred error bubble. if (this.errorBubble_) { this.showErrorBubble(this.errorBubble_[0], this.errorBubble_[1]); @@ -393,19 +624,17 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { chrome.send('loginWebuiReady'); chrome.send('loginVisible', ['gaia-signin']); - - // Warm up the user images screen. - Oobe.getInstance().preloadScreen({id: SCREEN_USER_IMAGE_PICKER}); }, /** * Invoked when the user has successfully authenticated via SAML, the * principals API was not used and the auth host needs the user to confirm * the scraped password. + * @param {string} email The authenticated user's e-mail. * @param {number} passwordCount The number of passwords that were scraped. * @private */ - onAuthConfirmPassword_: function(passwordCount) { + onAuthConfirmPassword_: function(email, passwordCount) { this.loading = true; Oobe.getInstance().headerHidden = false; @@ -414,6 +643,7 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { if (this.samlPasswordConfirmAttempt_ < 2) { login.ConfirmPasswordScreen.show( + email, this.samlPasswordConfirmAttempt_, this.onConfirmPasswordCollected_.bind(this)); } else { @@ -491,15 +721,22 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { if (credentials.useOffline) { this.email = credentials.email; chrome.send('authenticateUser', - [credentials.gaiaId, - credentials.email, + [credentials.email, credentials.password]); } else if (credentials.authCode) { - chrome.send('completeAuthentication', - [credentials.gaiaId, - credentials.email, - credentials.password, - credentials.authCode]); + if (credentials.hasOwnProperty('authCodeOnly') && + credentials.authCodeOnly) { + chrome.send('completeAuthenticationAuthCodeOnly', + [credentials.authCode]); + } else { + chrome.send('completeAuthentication', [ + credentials.gaiaId, + credentials.email, + credentials.password, + credentials.authCode, + credentials.usingSAML + ]); + } } else { chrome.send('completeLogin', [credentials.gaiaId, @@ -509,6 +746,7 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { } this.loading = true; + this.classList.add('auth-completed'); // Now that we're in logged in state header should be hidden. Oobe.getInstance().headerHidden = true; // Clear any error messages that were shown before login. @@ -516,6 +754,24 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { }, /** + * Invoked when onAuthCompleted message received. + * @param {!Object} e Payload of the received HTML5 message. + * @private + */ + onAuthCompletedMessage_: function(e) { + this.onAuthCompleted_(e.detail); + }, + + /** + * Invoked when onLoadAbort message received. + * @param {!Object} e Payload of the received HTML5 message. + * @private + */ + onLoadAbortMessage_: function(e) { + this.onWebviewError(e.detail); + }, + + /** * Clears input fields and switches to input mode. * @param {boolean} takeFocus True to take focus. * @param {boolean} forceOnline Whether online sign-in should be forced. @@ -624,6 +880,7 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { $('pod-row').loadLastWallpaper(); Oobe.showScreen({id: SCREEN_ACCOUNT_PICKER}); + this.classList.remove('whitelist-error'); Oobe.resetSigninUI(true); }, @@ -637,5 +894,51 @@ login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { this.error_ = error; chrome.send('frameLoadingCompleted', [this.error_]); }, + + /** + * Handler for webview error handling. + * @param {!Object} data Additional information about error event like: + * {string} error Error code such as "ERR_INTERNET_DISCONNECTED". + * {string} url The URL that failed to load. + */ + onWebviewError: function(data) { + chrome.send('webviewLoadAborted', [data.error]); + }, + + /** + * Sets welcome and enterpriseinfo strings for offline gaia. + * Also sets callback and sends message whether we already have email and + * should switch to the password screen with error. + */ + loadOffline: function(params) { + var offlineLogin = $('offline-gaia'); + var strings = params.localizedStrings; + if ('stringEnterpriseInfo' in strings) + offlineLogin.enterpriseInfo = strings['stringEnterpriseInfo']; + if ('emailDomain' in params) + offlineLogin.emailDomain = '@' + params['emailDomain']; + offlineLogin.setEmail(params.email); + }, + + /** + * Show/Hide error when user is not in whitelist. When UI is hidden + * GAIA is reloaded. + * @param {boolean} show Show/hide error UI. + * @param {!Object} opt_data Optional additional information. + */ + showWhitelistCheckFailedError: function(show, opt_data) { + if (show) { + var isManaged = opt_data && opt_data.enterpriseManaged; + $('gaia-whitelist-error').textContent = + loadTimeData.getValue(isManaged ? 'whitelistErrorEnterprise' : + 'whitelistErrorConsumer'); + } + + this.classList.toggle('whitelist-error', show); + this.loading = !show; + + if (!show) + Oobe.showSigninUI(); + } }; }); |