278 lines
9.4 KiB
TypeScript

// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component, ViewChild, ElementRef } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreEventsProvider } from '@providers/events';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreLoginHelperProvider } from '../../providers/helper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CoreConfigConstants } from '../../../../configconstants';
/**
* Page to enter the user credentials.
*/
@IonicPage({ segment: 'core-login-credentials' })
@Component({
selector: 'page-core-login-credentials',
templateUrl: 'credentials.html',
})
export class CoreLoginCredentialsPage {
@ViewChild('credentialsForm') formElement: ElementRef;
credForm: FormGroup;
siteUrl: string;
siteChecked = false;
siteName: string;
logoUrl: string;
authInstructions: string;
canSignup: boolean;
identityProviders: any[];
pageLoaded = false;
isBrowserSSO = false;
isFixedUrlSet = false;
showForgottenPassword = true;
protected siteConfig;
protected eventThrown = false;
protected viewLeft = false;
protected siteId: string;
protected urlToOpen: string;
constructor(private navCtrl: NavController,
navParams: NavParams,
fb: FormBuilder,
private appProvider: CoreAppProvider,
private sitesProvider: CoreSitesProvider,
private loginHelper: CoreLoginHelperProvider,
private domUtils: CoreDomUtilsProvider,
private translate: TranslateService,
private eventsProvider: CoreEventsProvider) {
this.siteUrl = navParams.get('siteUrl');
this.siteConfig = navParams.get('siteConfig');
this.urlToOpen = navParams.get('urlToOpen');
this.credForm = fb.group({
username: [navParams.get('username') || '', Validators.required],
password: ['', Validators.required]
});
}
/**
* View loaded.
*/
ionViewDidLoad(): void {
this.treatSiteConfig();
this.isFixedUrlSet = this.loginHelper.isFixedUrlSet();
if (this.isFixedUrlSet) {
// Fixed URL, we need to check if it uses browser SSO login.
this.checkSite(this.siteUrl);
} else {
this.siteChecked = true;
this.pageLoaded = true;
}
}
/**
* View enter.
*/
ionViewDidEnter(): void {
this.viewLeft = false;
}
/**
* View left.
*/
ionViewDidLeave(): void {
this.viewLeft = true;
this.eventsProvider.trigger(CoreEventsProvider.LOGIN_SITE_UNCHECKED, { config: this.siteConfig }, this.siteId);
}
/**
* Check if a site uses local_mobile, requires SSO login, etc.
* This should be used only if a fixed URL is set, otherwise this check is already performed in CoreLoginSitePage.
*
* @param siteUrl Site URL to check.
* @return Promise resolved when done.
*/
protected checkSite(siteUrl: string): Promise<any> {
this.pageLoaded = false;
// If the site is configured with http:// protocol we force that one, otherwise we use default mode.
const protocol = siteUrl.indexOf('http://') === 0 ? 'http://' : undefined;
return this.sitesProvider.checkSite(siteUrl, protocol).then((result) => {
this.siteChecked = true;
this.siteUrl = result.siteUrl;
this.siteConfig = result.config;
this.treatSiteConfig();
if (result && result.warning) {
this.domUtils.showErrorModal(result.warning, true, 4000);
}
if (this.loginHelper.isSSOLoginNeeded(result.code)) {
// SSO. User needs to authenticate in a browser.
this.isBrowserSSO = true;
// Check that there's no SSO authentication ongoing and the view hasn't changed.
if (!this.appProvider.isSSOAuthenticationOngoing() && !this.viewLeft) {
this.loginHelper.confirmAndOpenBrowserForSSOLogin(
result.siteUrl, result.code, result.service, result.config && result.config.launchurl);
}
} else {
this.isBrowserSSO = false;
}
}).catch((error) => {
this.domUtils.showErrorModal(error);
}).finally(() => {
this.pageLoaded = true;
});
}
/**
* Treat the site configuration (if it exists).
*/
protected treatSiteConfig(): void {
if (this.siteConfig) {
this.siteName = CoreConfigConstants.sitename ? CoreConfigConstants.sitename : this.siteConfig.sitename;
this.logoUrl = this.loginHelper.getLogoUrl(this.siteConfig);
this.authInstructions = this.siteConfig.authinstructions || this.translate.instant('core.login.loginsteps');
const disabledFeatures = this.loginHelper.getDisabledFeatures(this.siteConfig);
this.identityProviders = this.loginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
this.canSignup = this.siteConfig.registerauth == 'email' &&
!this.loginHelper.isEmailSignupDisabled(this.siteConfig, disabledFeatures);
this.showForgottenPassword = !this.loginHelper.isForgottenPasswordDisabled(this.siteConfig, disabledFeatures);
if (!this.eventThrown && !this.viewLeft) {
this.eventThrown = true;
this.eventsProvider.trigger(CoreEventsProvider.LOGIN_SITE_CHECKED, { config: this.siteConfig });
}
} else {
this.siteName = null;
this.logoUrl = null;
this.authInstructions = null;
this.canSignup = false;
this.identityProviders = [];
}
}
/**
* Tries to authenticate the user.
*
* @param e Event.
*/
login(e?: Event): void {
if (e) {
e.preventDefault();
e.stopPropagation();
}
this.appProvider.closeKeyboard();
// Get input data.
const siteUrl = this.siteUrl,
username = this.credForm.value.username,
password = this.credForm.value.password;
if (!this.siteChecked || this.isBrowserSSO) {
// Site wasn't checked (it failed) or a previous check determined it was SSO. Let's check again.
this.checkSite(siteUrl).then(() => {
if (!this.isBrowserSSO) {
// Site doesn't use browser SSO, throw app's login again.
return this.login();
}
});
return;
}
if (!username) {
this.domUtils.showErrorModal('core.login.usernamerequired', true);
return;
}
if (!password) {
this.domUtils.showErrorModal('core.login.passwordrequired', true);
return;
}
if (!this.appProvider.isOnline()) {
this.domUtils.showErrorModal('core.networkerrormsg', true);
return;
}
const modal = this.domUtils.showModalLoading();
// Start the authentication process.
this.sitesProvider.getUserToken(siteUrl, username, password).then((data) => {
return this.sitesProvider.newSite(data.siteUrl, data.token, data.privateToken).then((id) => {
// Reset fields so the data is not in the view anymore.
this.credForm.controls['username'].reset();
this.credForm.controls['password'].reset();
this.siteId = id;
return this.loginHelper.goToSiteInitialPage(undefined, undefined, undefined, undefined, this.urlToOpen);
});
}).catch((error) => {
this.loginHelper.treatUserTokenError(siteUrl, error, username, password);
if (error.loggedout) {
this.navCtrl.setRoot('CoreLoginSitesPage');
}
}).finally(() => {
modal.dismiss();
this.domUtils.triggerFormSubmittedEvent(this.formElement, true);
});
}
/**
* Forgotten password button clicked.
*/
forgottenPassword(): void {
this.loginHelper.forgottenPasswordClicked(this.navCtrl, this.siteUrl, this.credForm.value.username, this.siteConfig);
}
/**
* An OAuth button was clicked.
*
* @param provider The provider that was clicked.
*/
oauthClicked(provider: any): void {
if (!this.loginHelper.openBrowserForOAuthLogin(this.siteUrl, provider, this.siteConfig.launchurl)) {
this.domUtils.showErrorModal('Invalid data.');
}
}
/**
* Signup button was clicked.
*/
signup(): void {
this.navCtrl.push('CoreLoginEmailSignupPage', { siteUrl: this.siteUrl });
}
}