forked from EVOgeek/Vmeda.Online
		
	
						commit
						f519d56ea7
					
				
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -6454,7 +6454,7 @@ | ||||
|       "integrity": "sha512-EYC5eQFVkoYXq39l7tYKE6lEjHJ04mvTmKXxGL7quHLdFPfJMNzru/UYpn92AOfpl3PQaZmou78C7EgmFOwFQQ==" | ||||
|     }, | ||||
|     "cordova-plugin-wkuserscript": { | ||||
|       "version": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git#6413f4bb3c2565f353e690b5c1450b69ad9e860e", | ||||
|       "version": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git#aa77d0f98a3fb106f2e798e5adf5882f01a2c947", | ||||
|       "from": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git" | ||||
|     }, | ||||
|     "cordova-plugin-wkwebview-cookies": { | ||||
|  | ||||
| @ -16,7 +16,8 @@ import { Component, OnInit } from '@angular/core'; | ||||
| import { NavController } from '@ionic/angular'; | ||||
| 
 | ||||
| import { CoreLangProvider } from '@services/lang'; | ||||
| import { CoreEvents } from '@singletons/events'; | ||||
| import { CoreLoginHelperProvider } from '@core/login/services/helper'; | ||||
| import { CoreEvents, CoreEventSessionExpiredData } from '@singletons/events'; | ||||
| 
 | ||||
| @Component({ | ||||
|     selector: 'app-root', | ||||
| @ -28,6 +29,7 @@ export class AppComponent implements OnInit { | ||||
|     constructor( | ||||
|         protected langProvider: CoreLangProvider, | ||||
|         protected navCtrl: NavController, | ||||
|         protected loginHelper: CoreLoginHelperProvider, | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
| @ -46,6 +48,11 @@ export class AppComponent implements OnInit { | ||||
|             // @todo
 | ||||
|             // this.removeVersionClass();
 | ||||
|         }); | ||||
| 
 | ||||
|         // Listen for session expired events.
 | ||||
|         CoreEvents.on(CoreEvents.SESSION_EXPIRED, (data: CoreEventSessionExpiredData) => { | ||||
|             this.loginHelper.sessionExpired(data); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -2,12 +2,12 @@ | ||||
|     <ng-container *ngIf="control && control.dirty && !control.valid"> | ||||
|         <ng-container *ngFor="let error of errorKeys"> | ||||
|             <div *ngIf="control.hasError(error)" class="core-input-error"> | ||||
|                 <span *ngIf="errorMessages[error]">{{errorMessages[error]}}</span> | ||||
|                 <span *ngIf="!errorMessages[error] && error == 'max' && control.errors.max"> | ||||
|                     {{ 'core.login.invalidvaluemax' | translate:{$a: control.errors.max.max} }} | ||||
|                 <span *ngIf="errorMessages && errorMessages[error]">{{errorMessages[error]}}</span> | ||||
|                 <span *ngIf="(!errorMessages || !errorMessages[error]) && error == 'max' && control.errors?.max"> | ||||
|                     {{ 'core.login.invalidvaluemax' | translate:{$a: control.errors!.max.max} }} | ||||
|                 </span> | ||||
|                 <span *ngIf="!errorMessages[error] && error == 'min' && control.errors.min"> | ||||
|                     {{ 'core.login.invalidvaluemin' | translate:{$a: control.errors.min.min} }} | ||||
|                 <span *ngIf="(!errorMessages || !errorMessages[error]) && error == 'min' && control.errors?.min"> | ||||
|                     {{ 'core.login.invalidvaluemin' | translate:{$a: control.errors!.min.min} }} | ||||
|                 </span> | ||||
|             </div> | ||||
|         </ng-container> | ||||
|  | ||||
| @ -39,21 +39,25 @@ const routes: Routes = [ | ||||
|     }, | ||||
|     { | ||||
|         path: 'forgottenpassword', | ||||
|         loadChildren: () => import('./pages/forgotten-password/forgotten-password.module') | ||||
|         loadChildren: () => import('./pages/forgotten-password/forgotten-password.page.module') | ||||
|             .then( m => m.CoreLoginForgottenPasswordPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'changepassword', | ||||
|         loadChildren: () => import('./pages/change-password/change-password.module') | ||||
|         loadChildren: () => import('./pages/change-password/change-password.page.module') | ||||
|             .then( m => m.CoreLoginChangePasswordPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'sitepolicy', | ||||
|         loadChildren: () => import('./pages/site-policy/site-policy.module').then( m => m.CoreLoginSitePolicyPageModule), | ||||
|         loadChildren: () => import('./pages/site-policy/site-policy.page.module').then( m => m.CoreLoginSitePolicyPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'emailsignup', | ||||
|         loadChildren: () => import('./pages/email-signup/email-signup.module').then( m => m.CoreLoginEmailSignupPageModule), | ||||
|         loadChildren: () => import('./pages/email-signup/email-signup.page.module').then( m => m.CoreLoginEmailSignupPageModule), | ||||
|     }, | ||||
|     { | ||||
|         path: 'reconnect', | ||||
|         loadChildren: () => import('./pages/reconnect/reconnect.page.module').then( m => m.CoreLoginReconnectPageModule), | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
|  | ||||
| @ -13,7 +13,7 @@ | ||||
|     } | ||||
| 
 | ||||
|     .core-sitename { | ||||
|         font-size: 1.8rem; | ||||
|         font-size: 1.2rem; | ||||
|     } | ||||
| 
 | ||||
|     .core-login-site-logo { | ||||
|  | ||||
| @ -28,7 +28,7 @@ import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes | ||||
| import { CoreEvents } from '@singletons/events'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays a "splash screen" while the app is being initialized. | ||||
|  * Page to enter the user credentials. | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'page-core-login-credentials', | ||||
| @ -161,7 +161,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { | ||||
|      */ | ||||
|     protected treatSiteConfig(): void { | ||||
|         if (this.siteConfig) { | ||||
|             this.siteName = CoreConstants.CONFIG.sitename ?? this.siteConfig.sitename; | ||||
|             this.siteName = CoreConstants.CONFIG.sitename ? CoreConstants.CONFIG.sitename : this.siteConfig.sitename; | ||||
|             this.logoUrl = CoreLoginHelper.instance.getLogoUrl(this.siteConfig); | ||||
|             this.authInstructions = this.siteConfig.authinstructions || Translate.instance.instant('core.login.loginsteps'); | ||||
| 
 | ||||
|  | ||||
| @ -148,7 +148,7 @@ | ||||
|                 <ion-input type="text" name="nameField" placeholder="{{ 'core.user.' + nameField | translate }}" | ||||
|                     formControlName="{{nameField}}" autocorrect="off"> | ||||
|                 </ion-input> | ||||
|                 <core-input-errors [control]="signupForm.controls[nameField]" [errorMessages]="namefieldsErrors[nameField]"> | ||||
|                 <core-input-errors [control]="signupForm.controls[nameField]" [errorMessages]="namefieldsErrors![nameField]"> | ||||
|                 </core-input-errors> | ||||
|             </ion-item> | ||||
|             <ion-item class="ion-text-wrap"> | ||||
|  | ||||
| @ -337,7 +337,7 @@ export class CoreLoginEmailSignupPage implements OnInit { | ||||
|     /** | ||||
|      * Show authentication instructions. | ||||
|      */ | ||||
|     protected showAuthInstructions(): void { | ||||
|     showAuthInstructions(): void { | ||||
|         CoreTextUtils.instance.viewText(Translate.instance.instant('core.login.instructions'), this.authInstructions!); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										90
									
								
								src/app/core/login/pages/reconnect/reconnect.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/app/core/login/pages/reconnect/reconnect.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
| <ion-header> | ||||
|     <ion-toolbar> | ||||
|         <ion-buttons slot="start"> | ||||
|             <ion-back-button></ion-back-button> | ||||
|         </ion-buttons> | ||||
| 
 | ||||
|         <ion-title>{{ 'core.login.reconnect' | translate }}</ion-title> | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <div class="ion-text-wrap ion-text-center ion-margin-bottom" [ngClass]="{'item-avatar-center': showSiteAvatar}"> | ||||
|         <ng-container *ngIf="showSiteAvatar"> | ||||
|             <ion-avatar> | ||||
|                 <!-- Show user avatar. --> | ||||
|                 <img [src]="userAvatar" class="avatar" core-external-content [siteId]="siteId" role="presentation" | ||||
|                     alt="{{ 'core.pictureof' | translate:{$a: userFullName} }}" onError="this.src='assets/img/user-avatar.png'"> | ||||
|             </ion-avatar> | ||||
|         </ng-container> | ||||
| 
 | ||||
|         <div class="core-login-site-logo" *ngIf="!showSiteAvatar"> | ||||
|             <!-- Show site logo or a default image. --> | ||||
|             <img *ngIf="logoUrl" [src]="logoUrl" role="presentation" onError="this.src='assets/img/login_logo.png'"> | ||||
|             <img *ngIf="!logoUrl" src="assets/img/login_logo.png" role="presentation"> | ||||
|         </div> | ||||
| 
 | ||||
|         <h6 *ngIf="siteName" class="ion-padding core-sitename"> | ||||
|             <core-format-text [text]="siteName" [filter]="false"></core-format-text> | ||||
|         </h6> | ||||
|         <p class="core-siteurl">{{siteUrl}}</p> | ||||
| 
 | ||||
|         <ion-item *ngIf="!isLoggedOut" class="ion-text-center core-login-reconnect-warning" lines="none"> | ||||
|             <ion-label color="danger"> | ||||
|                 <ion-icon name="fas-exclamation-circle" slot="start"></ion-icon> | ||||
|                 {{ 'core.login.reconnectdescription' | translate }} | ||||
|             </ion-label> | ||||
|         </ion-item> | ||||
|     </div> | ||||
|     <form ion-list *ngIf="!isOAuth" [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #reconnectForm> | ||||
|         <ion-item class="ion-text-wrap core-username"> | ||||
|             <ion-label> | ||||
|                 <p>{{username}}</p> | ||||
|             </ion-label> | ||||
|         </ion-item> | ||||
|         <ion-item class="ion-margin-bottom"> | ||||
|             <core-show-password [name]="'password'"> | ||||
|                 <ion-input class="core-ioninput-password" name="password" type="password" | ||||
|                     placeholder="{{ 'core.login.password' | translate }}" formControlName="password" [clearOnEdit]="false"> | ||||
|                 </ion-input> | ||||
|             </core-show-password> | ||||
|         </ion-item> | ||||
|         <ion-grid class="ion-padding"> | ||||
|             <ion-row> | ||||
|                 <ion-col> | ||||
|                     <ion-button expand="block" color="light" (click)="cancel($event)">{{ 'core.login.cancel' | translate }}</ion-button> | ||||
|                 </ion-col> | ||||
|                 <ion-col> | ||||
|                     <ion-button type="submit" expand="block" [disabled]="!credForm.valid">{{ 'core.login.loginbutton' | translate }}</ion-button> | ||||
|                 </ion-col> | ||||
|             </ion-row> | ||||
|         </ion-grid> | ||||
|     </form> | ||||
| 
 | ||||
|     <!-- Forgotten password option. --> | ||||
|     <ion-list lines="none" *ngIf="showForgottenPassword && !isOAuth" class="core-login-forgotten-password ion-no-padding"> | ||||
|         <ion-item button class="ion-text-center ion-text-wrap" (click)="forgottenPassword()" detail="false"> | ||||
|             <ion-label> | ||||
|                 {{ 'core.login.forgotten' | translate }} | ||||
|             </ion-label> | ||||
|         </ion-item> | ||||
|     </ion-list> | ||||
| 
 | ||||
|     <!-- Identity providers. --> | ||||
|     <ion-list *ngIf="identityProviders && identityProviders.length" class="ion-padding-top core-login-identity-providers"> | ||||
|         <ion-item class="ion-text-wrap" lines="none"> | ||||
|             <ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label> | ||||
|         </ion-item> | ||||
|         <ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon" | ||||
|             (click)="oauthClicked(provider)" title="{{provider.name}}"> | ||||
|             <img [src]="provider.iconurl" alt="" width="32" height="32" slot="start"> | ||||
|             <ion-label>{{provider.name}}</ion-label> | ||||
|         </ion-item> | ||||
|     </ion-list> | ||||
| 
 | ||||
|     <!-- If OAuth, display cancel button since the form isn't displayed. --> | ||||
|     <ion-list *ngIf="isOAuth"> | ||||
|         <ion-button expand="block" class="ion-margin" color="light" (click)="cancel($event)"> | ||||
|             {{ 'core.login.cancel' | translate }} | ||||
|         </ion-button> | ||||
|     </ion-list> | ||||
| </ion-content> | ||||
							
								
								
									
										50
									
								
								src/app/core/login/pages/reconnect/reconnect.page.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/app/core/login/pages/reconnect/reconnect.page.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| // (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 { CoreComponentsModule } from '@components/components.module'; | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| 
 | ||||
| import { CoreLoginReconnectPage } from './reconnect.page'; | ||||
| 
 | ||||
| const routes: Routes = [ | ||||
|     { | ||||
|         path: '', | ||||
|         component: CoreLoginReconnectPage, | ||||
|     }, | ||||
| ]; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         RouterModule.forChild(routes), | ||||
|         CommonModule, | ||||
|         IonicModule, | ||||
|         TranslateModule.forChild(), | ||||
|         FormsModule, | ||||
|         ReactiveFormsModule, | ||||
|         CoreComponentsModule, | ||||
|         CoreDirectivesModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreLoginReconnectPage, | ||||
|     ], | ||||
|     exports: [RouterModule], | ||||
| }) | ||||
| export class CoreLoginReconnectPageModule {} | ||||
							
								
								
									
										245
									
								
								src/app/core/login/pages/reconnect/reconnect.page.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								src/app/core/login/pages/reconnect/reconnect.page.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,245 @@ | ||||
| // (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, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core'; | ||||
| import { ActivatedRoute, Params } from '@angular/router'; | ||||
| import { FormBuilder, FormGroup, Validators } from '@angular/forms'; | ||||
| import { NavController } from '@ionic/angular'; | ||||
| 
 | ||||
| import { CoreApp } from '@services/app'; | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| import { CoreUtils } from '@services/utils/utils'; | ||||
| import { CoreLoginHelper } from '@core/login/services/helper'; | ||||
| import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site'; | ||||
| import { CoreEvents } from '@singletons/events'; | ||||
| import { CoreError } from '@classes/errors/error'; | ||||
| 
 | ||||
| /** | ||||
|  * Page to enter the user password to reconnect to a site. | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'page-core-login-reconnect', | ||||
|     templateUrl: 'reconnect.html', | ||||
|     styleUrls: ['../../login.scss'], | ||||
| }) | ||||
| export class CoreLoginReconnectPage implements OnInit, OnDestroy { | ||||
| 
 | ||||
|     @ViewChild('reconnectForm') formElement?: ElementRef; | ||||
| 
 | ||||
|     credForm: FormGroup; | ||||
|     siteUrl!: string; | ||||
|     username!: string; | ||||
|     userFullName!: string; | ||||
|     userAvatar?: string; | ||||
|     siteName!: string; | ||||
|     logoUrl?: string; | ||||
|     identityProviders?: CoreSiteIdentityProvider[]; | ||||
|     showForgottenPassword = true; | ||||
|     showSiteAvatar = false; | ||||
|     isOAuth = false; | ||||
|     isLoggedOut: boolean; | ||||
|     siteId!: string; | ||||
| 
 | ||||
|     protected page?: string; | ||||
|     protected pageParams?: Params; | ||||
|     protected siteConfig?: CoreSitePublicConfigResponse; | ||||
|     protected viewLeft = false; | ||||
|     protected eventThrown = false; | ||||
| 
 | ||||
|     constructor( | ||||
|         protected navCtrl: NavController, | ||||
|         protected fb: FormBuilder, | ||||
|         protected route: ActivatedRoute, | ||||
|     ) { | ||||
| 
 | ||||
|         const currentSite = CoreSites.instance.getCurrentSite(); | ||||
| 
 | ||||
|         this.isLoggedOut = !!currentSite?.isLoggedOut(); | ||||
|         this.credForm = fb.group({ | ||||
|             password: ['', Validators.required], | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Initialize the component. | ||||
|      */ | ||||
|     async ngOnInit(): Promise<void> { | ||||
|         const params = this.route.snapshot.queryParams; | ||||
| 
 | ||||
|         this.siteId = params['siteId']; | ||||
|         this.page = params['pageName']; | ||||
|         this.pageParams = params['pageParams']; | ||||
| 
 | ||||
|         try { | ||||
|             const site = await CoreSites.instance.getSite(this.siteId); | ||||
| 
 | ||||
|             if (!site.infos) { | ||||
|                 throw new CoreError('Invalid site'); | ||||
|             } | ||||
| 
 | ||||
|             this.username = site.infos.username; | ||||
|             this.userFullName = site.infos.fullname; | ||||
|             this.userAvatar = site.infos.userpictureurl; | ||||
|             this.siteUrl = site.infos.siteurl; | ||||
|             this.siteName = site.getSiteName(); | ||||
| 
 | ||||
|             // If login was OAuth we should only reach this page if the OAuth method ID has changed.
 | ||||
|             this.isOAuth = site.isOAuth(); | ||||
| 
 | ||||
|             // Show logo instead of avatar if it's a fixed site.
 | ||||
|             this.showSiteAvatar = !!this.userAvatar && !CoreLoginHelper.instance.getFixedSites(); | ||||
| 
 | ||||
|             const config = await CoreUtils.instance.ignoreErrors(site.getPublicConfig()); | ||||
| 
 | ||||
|             if (!config) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             this.siteConfig = config; | ||||
| 
 | ||||
|             await CoreSites.instance.checkRequiredMinimumVersion(config); | ||||
| 
 | ||||
|             // Check logoURL if user avatar is not set.
 | ||||
|             if (this.userAvatar.startsWith(this.siteUrl + '/theme/image.php')) { | ||||
|                 this.showSiteAvatar = false; | ||||
|             } | ||||
|             this.logoUrl = CoreLoginHelper.instance.getLogoUrl(config); | ||||
| 
 | ||||
|             this.getDataFromConfig(this.siteConfig); | ||||
|         } catch (error) { | ||||
|             // Just leave the view.
 | ||||
|             this.cancel(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Component destroyed. | ||||
|      */ | ||||
|     ngOnDestroy(): void { | ||||
|         this.viewLeft = true; | ||||
|         CoreEvents.trigger(CoreEvents.LOGIN_SITE_UNCHECKED, { config: this.siteConfig }, this.siteId); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get some data (like identity providers) from the site config. | ||||
|      * | ||||
|      * @param config Config to use. | ||||
|      */ | ||||
|     protected getDataFromConfig(config: CoreSitePublicConfigResponse): void { | ||||
|         const disabledFeatures = CoreLoginHelper.instance.getDisabledFeatures(config); | ||||
| 
 | ||||
|         this.identityProviders = CoreLoginHelper.instance.getValidIdentityProviders(config, disabledFeatures); | ||||
|         this.showForgottenPassword = !CoreLoginHelper.instance.isForgottenPasswordDisabled(config); | ||||
| 
 | ||||
|         if (!this.eventThrown && !this.viewLeft) { | ||||
|             this.eventThrown = true; | ||||
|             CoreEvents.trigger(CoreEvents.LOGIN_SITE_CHECKED, { config: config }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Cancel reconnect. | ||||
|      * | ||||
|      * @param e Event. | ||||
|      */ | ||||
|     cancel(e?: Event): void { | ||||
|         if (e) { | ||||
|             e.preventDefault(); | ||||
|             e.stopPropagation(); | ||||
|         } | ||||
| 
 | ||||
|         CoreSites.instance.logout(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Tries to authenticate the user. | ||||
|      * | ||||
|      * @param e Event. | ||||
|      */ | ||||
|     async login(e: Event): Promise<void> { | ||||
|         e.preventDefault(); | ||||
|         e.stopPropagation(); | ||||
| 
 | ||||
|         CoreApp.instance.closeKeyboard(); | ||||
| 
 | ||||
|         // Get input data.
 | ||||
|         const password = this.credForm.value.password; | ||||
| 
 | ||||
|         if (!password) { | ||||
|             CoreDomUtils.instance.showErrorModal('core.login.passwordrequired', true); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (!CoreApp.instance.isOnline()) { | ||||
|             CoreDomUtils.instance.showErrorModal('core.networkerrormsg', true); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const modal = await CoreDomUtils.instance.showModalLoading(); | ||||
| 
 | ||||
|         try { | ||||
|             // Start the authentication process.
 | ||||
|             const data = await CoreSites.instance.getUserToken(this.siteUrl, this.username, password); | ||||
| 
 | ||||
|             await CoreSites.instance.updateSiteToken(this.siteUrl, this.username, data.token, data.privateToken); | ||||
| 
 | ||||
|             CoreDomUtils.instance.triggerFormSubmittedEvent(this.formElement, true); | ||||
| 
 | ||||
|             // Update site info too.
 | ||||
|             await CoreSites.instance.updateSiteInfoByUrl(this.siteUrl, this.username); | ||||
| 
 | ||||
|             // Reset fields so the data is not in the view anymore.
 | ||||
|             this.credForm.controls['password'].reset(); | ||||
| 
 | ||||
|             // Go to the site initial page.
 | ||||
|             await CoreLoginHelper.instance.goToSiteInitialPage({ | ||||
|                 redirectPage: this.page, | ||||
|                 redirectParams: this.pageParams, | ||||
|             }); | ||||
|         } catch (error) { | ||||
|             CoreLoginHelper.instance.treatUserTokenError(this.siteUrl, error, this.username, password); | ||||
| 
 | ||||
|             if (error.loggedout) { | ||||
|                 this.cancel(); | ||||
|             } else if (error.errorcode == 'forcepasswordchangenotice') { | ||||
|                 // Reset password field.
 | ||||
|                 this.credForm.controls.password.reset(); | ||||
|             } | ||||
|         } finally { | ||||
|             modal.dismiss(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Forgotten password button clicked. | ||||
|      */ | ||||
|     forgottenPassword(): void { | ||||
|         CoreLoginHelper.instance.forgottenPasswordClicked(this.siteUrl, this.username, this.siteConfig); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * An OAuth button was clicked. | ||||
|      * | ||||
|      * @param provider The provider that was clicked. | ||||
|      */ | ||||
|     oauthClicked(provider: CoreSiteIdentityProvider): void { | ||||
|         if (!CoreLoginHelper.instance.openBrowserForOAuthLogin(this.siteUrl, provider, this.siteConfig?.launchurl)) { | ||||
|             CoreDomUtils.instance.showErrorModal('Invalid data.'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -35,6 +35,7 @@ import { makeSingleton, Translate } from '@singletons/core.singletons'; | ||||
| import { CoreLogger } from '@singletons/logger'; | ||||
| import { CoreUrl } from '@singletons/url'; | ||||
| import { NavigationOptions } from '@ionic/angular/providers/nav-controller'; | ||||
| import { CoreObject } from '@/app/singletons/object'; | ||||
| 
 | ||||
| /** | ||||
|  * Helper provider that provides some common features regarding authentication. | ||||
| @ -126,7 +127,7 @@ export class CoreLoginHelperProvider { | ||||
|         const currentSite = CoreSites.instance.getCurrentSite(); | ||||
|         const currentPage = CoreApp.instance.getCurrentPage(); | ||||
| 
 | ||||
|         if (!CoreApp.instance.isSSOAuthenticationOngoing() && currentSite?.isLoggedOut() && currentPage == 'login/reconnect') { | ||||
|         if (!CoreApp.instance.isSSOAuthenticationOngoing() && currentSite?.isLoggedOut() && currentPage == '/login/reconnect') { | ||||
|             // User must reauthenticate but he closed the InAppBrowser without doing so, logout him.
 | ||||
|             CoreSites.instance.logout(); | ||||
|         } | ||||
| @ -1106,14 +1107,11 @@ export class CoreLoginHelperProvider { | ||||
|                     this.isOpeningReconnect = true; | ||||
| 
 | ||||
|                     await CoreUtils.instance.ignoreErrors(this.navCtrl.navigateRoot('/login/reconnect', { | ||||
|                         queryParams: { | ||||
|                             infoSiteUrl: info.siteurl, | ||||
|                             siteUrl: result.siteUrl, | ||||
|                             siteId: siteId, | ||||
|                         queryParams: CoreObject.removeUndefined({ | ||||
|                             siteId, | ||||
|                             pageName: data.pageName, | ||||
|                             pageParams: data.params, | ||||
|                             siteConfig: result.config, | ||||
|                         }, | ||||
|                         }), | ||||
|                     })); | ||||
| 
 | ||||
|                     this.isOpeningReconnect = false; | ||||
|  | ||||
| @ -20,6 +20,7 @@ import { TranslateModule } from '@ngx-translate/core'; | ||||
| 
 | ||||
| import { CoreComponentsModule } from '@components/components.module'; | ||||
| import { CoreDirectivesModule } from '@directives/directives.module'; | ||||
| import { CorePipesModule } from '@pipes/pipes.module'; | ||||
| 
 | ||||
| import { CoreSettingsDeviceInfoPage } from './deviceinfo.page'; | ||||
| 
 | ||||
| @ -38,6 +39,7 @@ const routes: Routes = [ | ||||
|         TranslateModule.forChild(), | ||||
|         CoreComponentsModule, | ||||
|         CoreDirectivesModule, | ||||
|         CorePipesModule, | ||||
|     ], | ||||
|     declarations: [ | ||||
|         CoreSettingsDeviceInfoPage, | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { NavController } from '@ionic/angular'; | ||||
| import { WKUserScriptWindow, WKUserScriptInjectionTime } from 'cordova-plugin-wkuserscript'; | ||||
| import { WKUserScriptWindow } from 'cordova-plugin-wkuserscript'; | ||||
| import { WKWebViewCookiesWindow } from 'cordova-plugin-wkwebview-cookies'; | ||||
| 
 | ||||
| import { CoreApp } from '@services/app'; | ||||
| @ -470,7 +470,7 @@ export class CoreIframeUtilsProvider { | ||||
|         userScriptWindow.WKUserScript?.addScript({ | ||||
|             id: 'CoreIframeUtilsRecaptchaScript', | ||||
|             file: recaptchaPath, | ||||
|             injectionTime: WKUserScriptInjectionTime.END, | ||||
|             injectionTime: userScriptWindow.WKUserScript?.InjectionTime.END, | ||||
|         }); | ||||
| 
 | ||||
|         // Handle post messages received by iframes.
 | ||||
|  | ||||
							
								
								
									
										35
									
								
								src/app/singletons/object.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/app/singletons/object.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| // (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.
 | ||||
| 
 | ||||
| /** | ||||
|  * Singleton with helper functions for objects. | ||||
|  */ | ||||
| export class CoreObject { | ||||
| 
 | ||||
|     /** | ||||
|      * Delete all keys from an object whose value are null or undefined. | ||||
|      * | ||||
|      * @param object Object to modify. | ||||
|      */ | ||||
|     static removeUndefined<T>(object: T): T { | ||||
|         for (const name in object) { | ||||
|             if (object[name] === undefined) { | ||||
|                 delete object[name]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return object; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user