forked from CIT/Vmeda.Online
		
	MOBILE-3565 login: Implement forgotten password page
This commit is contained in:
		
							parent
							
								
									d66c744ab8
								
							
						
					
					
						commit
						996f1c6ae3
					
				@ -37,6 +37,11 @@ const routes: Routes = [
 | 
			
		||||
        path: 'sites',
 | 
			
		||||
        loadChildren: () => import('./pages/sites/sites.page.module').then( m => m.CoreLoginSitesPageModule),
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path: 'forgottenpassword',
 | 
			
		||||
        loadChildren: () => import('./pages/forgotten-password/forgotten-password.module')
 | 
			
		||||
            .then( m => m.CoreLoginForgottenPasswordPageModule),
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
 | 
			
		||||
@ -264,12 +264,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
 | 
			
		||||
     * Forgotten password button clicked.
 | 
			
		||||
     */
 | 
			
		||||
    forgottenPassword(): void {
 | 
			
		||||
        CoreLoginHelper.instance.forgottenPasswordClicked(
 | 
			
		||||
            this.navCtrl,
 | 
			
		||||
            this.siteUrl,
 | 
			
		||||
            this.credForm.value.username,
 | 
			
		||||
            this.siteConfig,
 | 
			
		||||
        );
 | 
			
		||||
        CoreLoginHelper.instance.forgottenPasswordClicked(this.siteUrl, this.credForm.value.username, this.siteConfig);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,41 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
 | 
			
		||||
        <ion-title>{{ 'core.login.passwordforgotten' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
</ion-header>
 | 
			
		||||
<ion-content>
 | 
			
		||||
    <ion-list lines="none">
 | 
			
		||||
        <ion-item class="ion-text-wrap">
 | 
			
		||||
            {{ 'core.login.passwordforgotteninstructions2' | translate }}
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-list>
 | 
			
		||||
    <ion-card>
 | 
			
		||||
        <form ion-list [formGroup]="myForm" (ngSubmit)="resetPassword($event)" #resetPasswordForm>
 | 
			
		||||
            <ion-item-divider class="ion-text-wrap">
 | 
			
		||||
                {{ 'core.login.searchby' | translate }}
 | 
			
		||||
            </ion-item-divider>
 | 
			
		||||
            <ion-radio-group formControlName="field">
 | 
			
		||||
                <ion-item>
 | 
			
		||||
                    <ion-label>{{ 'core.login.username' | translate }}</ion-label>
 | 
			
		||||
                    <ion-radio slot="start" value="username"></ion-radio>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
                <ion-item>
 | 
			
		||||
                    <ion-label>{{ 'core.user.email' | translate }}</ion-label>
 | 
			
		||||
                    <ion-radio slot="start" value="email"></ion-radio>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
            </ion-radio-group>
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-input type="text" name="value" placeholder="{{ 'core.login.usernameoremail' | translate }}"
 | 
			
		||||
                    formControlName="value" autocapitalize="none" autocorrect="off" [core-auto-focus]="autoFocus">
 | 
			
		||||
                </ion-input>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
            <ion-button type="submit" class="ion-margin" expand="block" [disabled]="!myForm.valid">
 | 
			
		||||
                {{ 'core.courses.search' | translate }}
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </form>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
</ion-content>
 | 
			
		||||
@ -0,0 +1,47 @@
 | 
			
		||||
// (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 { NgModule } from '@angular/core';
 | 
			
		||||
import { CommonModule } from '@angular/common';
 | 
			
		||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { IonicModule } from '@ionic/angular';
 | 
			
		||||
import { TranslateModule } from '@ngx-translate/core';
 | 
			
		||||
 | 
			
		||||
import { CoreDirectivesModule } from '@directives/directives.module';
 | 
			
		||||
import { CoreLoginForgottenPasswordPage } from './forgotten-password.page';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path: '',
 | 
			
		||||
        component: CoreLoginForgottenPasswordPage,
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports: [
 | 
			
		||||
        RouterModule.forChild(routes),
 | 
			
		||||
        CommonModule,
 | 
			
		||||
        IonicModule,
 | 
			
		||||
        TranslateModule.forChild(),
 | 
			
		||||
        FormsModule,
 | 
			
		||||
        ReactiveFormsModule,
 | 
			
		||||
        CoreDirectivesModule,
 | 
			
		||||
    ],
 | 
			
		||||
    declarations: [
 | 
			
		||||
        CoreLoginForgottenPasswordPage,
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [RouterModule],
 | 
			
		||||
})
 | 
			
		||||
export class CoreLoginForgottenPasswordPageModule {}
 | 
			
		||||
@ -0,0 +1,120 @@
 | 
			
		||||
// (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, OnInit } from '@angular/core';
 | 
			
		||||
import { ActivatedRoute } from '@angular/router';
 | 
			
		||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 | 
			
		||||
import { NavController } from '@ionic/angular';
 | 
			
		||||
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreLoginHelper } from '@core/login/services/helper';
 | 
			
		||||
import { Translate, Platform } from '@singletons/core.singletons';
 | 
			
		||||
import { CoreWSExternalWarning } from '@services/ws';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Page to recover a forgotten password.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'page-core-login-forgotten-password',
 | 
			
		||||
    templateUrl: 'forgotten-password.html',
 | 
			
		||||
})
 | 
			
		||||
export class CoreLoginForgottenPasswordPage implements OnInit {
 | 
			
		||||
 | 
			
		||||
    @ViewChild('resetPasswordForm') formElement?: ElementRef;
 | 
			
		||||
 | 
			
		||||
    myForm!: FormGroup;
 | 
			
		||||
    siteUrl!: string;
 | 
			
		||||
    autoFocus!: boolean;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        protected navCtrl: NavController,
 | 
			
		||||
        protected formBuilder: FormBuilder,
 | 
			
		||||
        protected route: ActivatedRoute,
 | 
			
		||||
    ) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize the component.
 | 
			
		||||
     */
 | 
			
		||||
    ngOnInit(): void {
 | 
			
		||||
        const params = this.route.snapshot.queryParams;
 | 
			
		||||
 | 
			
		||||
        this.siteUrl = params['siteUrl'];
 | 
			
		||||
        this.autoFocus = Platform.instance.is('tablet');
 | 
			
		||||
        this.myForm = this.formBuilder.group({
 | 
			
		||||
            field: ['username', Validators.required],
 | 
			
		||||
            value: [params['username'] || '', Validators.required],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Request to reset the password.
 | 
			
		||||
     *
 | 
			
		||||
     * @param e Event.
 | 
			
		||||
     */
 | 
			
		||||
    async resetPassword(e: Event): Promise<void> {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        const field = this.myForm.value.field;
 | 
			
		||||
        const value = this.myForm.value.value;
 | 
			
		||||
 | 
			
		||||
        if (!value) {
 | 
			
		||||
            CoreDomUtils.instance.showErrorModal('core.login.usernameoremail', true);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const modal = await CoreDomUtils.instance.showModalLoading('core.sending', true);
 | 
			
		||||
        const isMail = field == 'email';
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            const response = await CoreLoginHelper.instance.requestPasswordReset(
 | 
			
		||||
                this.siteUrl,
 | 
			
		||||
                isMail ? '' : value,
 | 
			
		||||
                isMail ? value : '',
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (response.status == 'dataerror') {
 | 
			
		||||
                // Error in the data sent.
 | 
			
		||||
                this.showError(isMail, response.warnings!);
 | 
			
		||||
            } else if (response.status == 'emailpasswordconfirmnotsent' || response.status == 'emailpasswordconfirmnoemail') {
 | 
			
		||||
                // Error, not found.
 | 
			
		||||
                CoreDomUtils.instance.showErrorModal(response.notice);
 | 
			
		||||
            } else {
 | 
			
		||||
                // Success.
 | 
			
		||||
                CoreDomUtils.instance.triggerFormSubmittedEvent(this.formElement, true);
 | 
			
		||||
 | 
			
		||||
                CoreDomUtils.instance.showAlert(Translate.instance.instant('core.success'), response.notice);
 | 
			
		||||
                this.navCtrl.pop();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            CoreDomUtils.instance.showErrorModal(error);
 | 
			
		||||
        } finally {
 | 
			
		||||
            modal.dismiss();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Show an error from the warnings.
 | 
			
		||||
    protected showError(isMail: boolean, warnings: CoreWSExternalWarning[]): void {
 | 
			
		||||
        for (let i = 0; i < warnings.length; i++) {
 | 
			
		||||
            const warning = warnings[i];
 | 
			
		||||
            if ((warning.item == 'email' && isMail) || (warning.item == 'username' && !isMail)) {
 | 
			
		||||
                CoreDomUtils.instance.showErrorModal(warning.message);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -163,12 +163,7 @@ export class CoreLoginHelperProvider {
 | 
			
		||||
     * @param username Username.
 | 
			
		||||
     * @param siteConfig Site config.
 | 
			
		||||
     */
 | 
			
		||||
    async forgottenPasswordClicked(
 | 
			
		||||
        navCtrl: NavController,
 | 
			
		||||
        siteUrl: string,
 | 
			
		||||
        username: string,
 | 
			
		||||
        siteConfig?: CoreSitePublicConfigResponse,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
    async forgottenPasswordClicked(siteUrl: string, username: string, siteConfig?: CoreSitePublicConfigResponse): Promise<void> {
 | 
			
		||||
        if (siteConfig && siteConfig.forgottenpasswordurl) {
 | 
			
		||||
            // URL set, open it.
 | 
			
		||||
            CoreUtils.instance.openInApp(siteConfig.forgottenpasswordurl);
 | 
			
		||||
@ -183,7 +178,7 @@ export class CoreLoginHelperProvider {
 | 
			
		||||
            const canReset = await this.canRequestPasswordReset(siteUrl);
 | 
			
		||||
 | 
			
		||||
            if (canReset) {
 | 
			
		||||
                await navCtrl.navigateForward(['/login/forgottenpassword'], {
 | 
			
		||||
                await this.navCtrl.navigateForward(['/login/forgottenpassword'], {
 | 
			
		||||
                    queryParams: {
 | 
			
		||||
                        siteUrl,
 | 
			
		||||
                        username,
 | 
			
		||||
@ -445,7 +440,6 @@ export class CoreLoginHelperProvider {
 | 
			
		||||
    /**
 | 
			
		||||
     * Open a page that doesn't belong to any site.
 | 
			
		||||
     *
 | 
			
		||||
     * @param navCtrl Nav Controller.
 | 
			
		||||
     * @param page Page to open.
 | 
			
		||||
     * @param params Params of the page.
 | 
			
		||||
     * @return Promise resolved when done.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user