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',
 | 
					        path: 'sites',
 | 
				
			||||||
        loadChildren: () => import('./pages/sites/sites.page.module').then( m => m.CoreLoginSitesPageModule),
 | 
					        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({
 | 
					@NgModule({
 | 
				
			||||||
 | 
				
			|||||||
@ -264,12 +264,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
 | 
				
			|||||||
     * Forgotten password button clicked.
 | 
					     * Forgotten password button clicked.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    forgottenPassword(): void {
 | 
					    forgottenPassword(): void {
 | 
				
			||||||
        CoreLoginHelper.instance.forgottenPasswordClicked(
 | 
					        CoreLoginHelper.instance.forgottenPasswordClicked(this.siteUrl, this.credForm.value.username, this.siteConfig);
 | 
				
			||||||
            this.navCtrl,
 | 
					 | 
				
			||||||
            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 username Username.
 | 
				
			||||||
     * @param siteConfig Site config.
 | 
					     * @param siteConfig Site config.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    async forgottenPasswordClicked(
 | 
					    async forgottenPasswordClicked(siteUrl: string, username: string, siteConfig?: CoreSitePublicConfigResponse): Promise<void> {
 | 
				
			||||||
        navCtrl: NavController,
 | 
					 | 
				
			||||||
        siteUrl: string,
 | 
					 | 
				
			||||||
        username: string,
 | 
					 | 
				
			||||||
        siteConfig?: CoreSitePublicConfigResponse,
 | 
					 | 
				
			||||||
    ): Promise<void> {
 | 
					 | 
				
			||||||
        if (siteConfig && siteConfig.forgottenpasswordurl) {
 | 
					        if (siteConfig && siteConfig.forgottenpasswordurl) {
 | 
				
			||||||
            // URL set, open it.
 | 
					            // URL set, open it.
 | 
				
			||||||
            CoreUtils.instance.openInApp(siteConfig.forgottenpasswordurl);
 | 
					            CoreUtils.instance.openInApp(siteConfig.forgottenpasswordurl);
 | 
				
			||||||
@ -183,7 +178,7 @@ export class CoreLoginHelperProvider {
 | 
				
			|||||||
            const canReset = await this.canRequestPasswordReset(siteUrl);
 | 
					            const canReset = await this.canRequestPasswordReset(siteUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (canReset) {
 | 
					            if (canReset) {
 | 
				
			||||||
                await navCtrl.navigateForward(['/login/forgottenpassword'], {
 | 
					                await this.navCtrl.navigateForward(['/login/forgottenpassword'], {
 | 
				
			||||||
                    queryParams: {
 | 
					                    queryParams: {
 | 
				
			||||||
                        siteUrl,
 | 
					                        siteUrl,
 | 
				
			||||||
                        username,
 | 
					                        username,
 | 
				
			||||||
@ -445,7 +440,6 @@ export class CoreLoginHelperProvider {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Open a page that doesn't belong to any site.
 | 
					     * Open a page that doesn't belong to any site.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param navCtrl Nav Controller.
 | 
					 | 
				
			||||||
     * @param page Page to open.
 | 
					     * @param page Page to open.
 | 
				
			||||||
     * @param params Params of the page.
 | 
					     * @param params Params of the page.
 | 
				
			||||||
     * @return Promise resolved when done.
 | 
					     * @return Promise resolved when done.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user