From 7e6a46b02867560514c566ef568b42ecdcf6d8c1 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Thu, 3 Oct 2019 15:46:42 +0200 Subject: [PATCH] MOBILE-3093 login: Change password page --- scripts/langindex.json | 7 ++ src/app/app.component.ts | 2 +- src/assets/lang/en.json | 7 ++ src/core/login/lang/en.json | 7 ++ .../change-password/change-password.html | 27 ++++++++ .../change-password/change-password.module.ts | 33 +++++++++ .../pages/change-password/change-password.ts | 69 +++++++++++++++++++ src/core/login/providers/helper.ts | 44 +++++++++++- src/core/mainmenu/pages/more/more.ts | 8 +-- 9 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 src/core/login/pages/change-password/change-password.html create mode 100644 src/core/login/pages/change-password/change-password.module.ts create mode 100644 src/core/login/pages/change-password/change-password.ts diff --git a/scripts/langindex.json b/scripts/langindex.json index fc5464421..6e12a847e 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -1564,6 +1564,12 @@ "core.login.auth_email": "auth_email/pluginname", "core.login.authenticating": "local_moodlemobileapp", "core.login.cancel": "moodle", + "core.login.changepassword": "moodle", + "core.login.changepasswordbutton": "local_moodlemobileapp", + "core.login.changepasswordhelp": "local_moodlemobileapp", + "core.login.changepassowrdinstructions": "local_moodlemobileapp", + "core.login.changepasswordlogoutinstructions": "local_moodlemobileapp", + "core.login.changepasswordreconnectinstructions": "local_moodlemobileapp", "core.login.checksiteversion": "local_moodlemobileapp", "core.login.confirmdeletesite": "local_moodlemobileapp", "core.login.connect": "local_moodlemobileapp", @@ -1585,6 +1591,7 @@ "core.login.errorupdatesite": "local_moodlemobileapp", "core.login.findyoursite": "local_moodlemobileapp", "core.login.firsttime": "moodle", + "core.login.forcepasswordchangenotice": "moodle", "core.login.forgotten": "moodle", "core.login.getanothercaptcha": "auth", "core.login.help": "moodle", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index be27768aa..439ce5867 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -99,7 +99,7 @@ export class MoodleMobileApp implements OnInit { // Listen for passwordchange and usernotfullysetup events to open InAppBrowser. this.eventsProvider.on(CoreEventsProvider.PASSWORD_CHANGE_FORCED, (data) => { - this.loginHelper.openInAppForEdit(data.siteId, '/login/change_password.php', 'core.forcepasswordchangenotice', true); + this.loginHelper.passwordChangeForced(data.siteId); }); this.eventsProvider.on(CoreEventsProvider.USER_NOT_FULLY_SETUP, (data) => { this.loginHelper.openInAppForEdit(data.siteId, '/user/edit.php', 'core.usernotfullysetup'); diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index a82e7ef5a..064ce267d 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -1562,6 +1562,12 @@ "core.login.auth_email": "Email-based self-registration", "core.login.authenticating": "Authenticating", "core.login.cancel": "Cancel", + "core.login.changepassowrdinstructions": "You cannot change your password in the app. Please click the following button to open the site in a web browser to change your password. Take into account you need to close the browser after changing the password as you will not be redirected to the app.", + "core.login.changepassword": "Change password", + "core.login.changepasswordbutton": "Open the change password page", + "core.login.changepasswordhelp": "If you have problems changing your password, please contact your site administrator. \"Site Administrators\" are the people who manages the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.", + "core.login.changepasswordlogoutinstructions": "If you prefer to change site or log out, please click the following button:", + "core.login.changepasswordreconnectinstructions": "Click the following button to reconnect to the site. (Take into account that if you didn't change your password successfully, you would return to the previous screen).", "core.login.checksiteversion": "Check that your site uses Moodle 2.4 or later.", "core.login.confirmdeletesite": "Are you sure you want to delete the site {{sitename}}?", "core.login.connect": "Connect!", @@ -1583,6 +1589,7 @@ "core.login.errorupdatesite": "An error occurred while updating the site's token.", "core.login.findyoursite": "Find your site", "core.login.firsttime": "Is this your first time here?", + "core.login.forcepasswordchangenotice": "You must change your password to proceed.", "core.login.forgotten": "Forgotten your username or password?", "core.login.getanothercaptcha": "Get another CAPTCHA", "core.login.help": "Help", diff --git a/src/core/login/lang/en.json b/src/core/login/lang/en.json index 4328c6d3e..a33582b45 100644 --- a/src/core/login/lang/en.json +++ b/src/core/login/lang/en.json @@ -3,6 +3,12 @@ "authenticating": "Authenticating", "cancel": "Cancel", "checksiteversion": "Check that your site uses Moodle 2.4 or later.", + "changepassword": "Change password", + "changepasswordbutton": "Open the change password page", + "changepasswordhelp": "If you have problems changing your password, please contact your site administrator. \"Site Administrators\" are the people who manages the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.", + "changepassowrdinstructions": "You cannot change your password in the app. Please click the following button to open the site in a web browser to change your password. Take into account you need to close the browser after changing the password as you will not be redirected to the app.", + "changepasswordlogoutinstructions": "If you prefer to change site or log out, please click the following button:", + "changepasswordreconnectinstructions": "Click the following button to reconnect to the site. (Take into account that if you didn't change your password successfully, you would return to the previous screen).", "confirmdeletesite": "Are you sure you want to delete the site {{sitename}}?", "connect": "Connect!", "connecttomoodle": "Connect to Moodle", @@ -23,6 +29,7 @@ "errorupdatesite": "An error occurred while updating the site's token.", "findyoursite": "Find your site", "firsttime": "Is this your first time here?", + "forcepasswordchangenotice": "You must change your password to proceed.", "forgotten": "Forgotten your username or password?", "getanothercaptcha": "Get another CAPTCHA", "help": "Help", diff --git a/src/core/login/pages/change-password/change-password.html b/src/core/login/pages/change-password/change-password.html new file mode 100644 index 000000000..9bbd96064 --- /dev/null +++ b/src/core/login/pages/change-password/change-password.html @@ -0,0 +1,27 @@ + + + {{ 'core.login.changepassword' | translate }} + + + + + + + + +

{{ 'core.login.forcepasswordchangenotice' | translate }}

+

{{ 'core.login.changepassowrdinstructions' | translate }}

+ +
+ +

{{ 'core.login.changepasswordreconnectinstructions' | translate }}

+ +
+ +

{{ 'core.login.changepasswordlogoutinstructions' | translate }}

+ +
+
+
diff --git a/src/core/login/pages/change-password/change-password.module.ts b/src/core/login/pages/change-password/change-password.module.ts new file mode 100644 index 000000000..b505ebe48 --- /dev/null +++ b/src/core/login/pages/change-password/change-password.module.ts @@ -0,0 +1,33 @@ +// (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 { IonicPageModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreLoginChangePasswordPage } from './change-password'; +import { CoreComponentsModule } from '@components/components.module'; +import { CoreDirectivesModule } from '@directives/directives.module'; + +@NgModule({ + declarations: [ + CoreLoginChangePasswordPage + ], + imports: [ + CoreComponentsModule, + CoreDirectivesModule, + IonicPageModule.forChild(CoreLoginChangePasswordPage), + TranslateModule.forChild() + ] +}) +export class CoreLoginChangePasswordPageModule {} diff --git a/src/core/login/pages/change-password/change-password.ts b/src/core/login/pages/change-password/change-password.ts new file mode 100644 index 000000000..ae894cb50 --- /dev/null +++ b/src/core/login/pages/change-password/change-password.ts @@ -0,0 +1,69 @@ +// (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 } from '@angular/core'; +import { IonicPage } from 'ionic-angular'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreLoginHelperProvider } from '../../providers/helper'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; + +/** + * Page that shows instructions to change the password. + */ +@IonicPage({ segment: 'core-login-change-password' }) +@Component({ + selector: 'page-core-change-password', + templateUrl: 'change-password.html', +}) +export class CoreLoginChangePasswordPage { + changingPassword = false; + logoutLabel: string; + + constructor(private translate: TranslateService, private sitesProvider: CoreSitesProvider, + private loginHelper: CoreLoginHelperProvider, private domUtls: CoreDomUtilsProvider) { + this.logoutLabel = this.loginHelper.getLogoutLabel(); + } + + /** + * Show a help modal. + */ + showHelp(): void { + this.domUtls.showAlert(this.translate.instant('core.help'), this.translate.instant('core.login.changepasswordhelp')); + } + + /** + * Open the change password page in a browser. + */ + openChangePasswordPage(): void { + this.loginHelper.openInAppForEdit(this.sitesProvider.getCurrentSiteId(), '/login/change_password.php', undefined, true); + this.changingPassword = true; + } + + /** + * Login the user. + */ + login(): void { + this.loginHelper.goToSiteInitialPage(); + this.changingPassword = false; + } + + /** + * Logout the user. + */ + logout(): void { + this.sitesProvider.logout(); + this.changingPassword = false; + } +} diff --git a/src/core/login/providers/helper.ts b/src/core/login/providers/helper.ts index d08b1ff0c..428acfbb1 100644 --- a/src/core/login/providers/helper.ts +++ b/src/core/login/providers/helper.ts @@ -32,6 +32,7 @@ import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreConfigConstants } from '../../../configconstants'; import { CoreConstants } from '@core/constants'; import { Md5 } from 'ts-md5/dist/md5'; +import { CoreSite } from '@classes/site'; /** * Data related to a SSO authentication. @@ -367,6 +368,19 @@ export class CoreLoginHelperProvider { return errors; } + /** + * Returns the logout label of a site. + * + * @param site Site. If not defined, use current site. + * @return The string key. + */ + getLogoutLabel(site?: CoreSite): string { + site = site || this.sitesProvider.getCurrentSite(); + const config = site.getStoredConfig(); + + return 'core.mainmenu.' + (config && config.tool_mobile_forcelogout == '1' ? 'logout' : 'changesite'); + } + /** * Get the site policy. * @@ -796,7 +810,7 @@ export class CoreLoginHelperProvider { this.utils.openInApp(siteUrl + '/login/forgot_password.php'); } - /* + /** * Function to open in app browser to change password or complete user profile. * * @param siteId The site ID. @@ -804,7 +818,7 @@ export class CoreLoginHelperProvider { * @param alertMessage The key of the message to display before opening the in app browser. * @param invalidateCache Whether to invalidate site's cache (e.g. when the user is forced to change password). */ - openInAppForEdit(siteId: string, path: string, alertMessage: string, invalidateCache?: boolean): void { + openInAppForEdit(siteId: string, path: string, alertMessage?: string, invalidateCache?: boolean): void { if (!siteId || siteId !== this.sitesProvider.getCurrentSiteId()) { // Site that triggered the event is not current site, nothing to do. return; @@ -824,7 +838,9 @@ export class CoreLoginHelperProvider { } // Open change password. - alertMessage = this.translate.instant(alertMessage) + '
' + this.translate.instant('core.redirectingtosite'); + if (alertMessage) { + alertMessage = this.translate.instant(alertMessage) + '
' + this.translate.instant('core.redirectingtosite'); + } currentSite.openInAppWithAutoLogin(siteUrl + path, undefined, alertMessage).then(() => { this.waitingForBrowser = true; }).finally(() => { @@ -833,6 +849,28 @@ export class CoreLoginHelperProvider { } } + /** + * Function that should be called when password change is forced. Reserved for core use. + * + * @param siteId The site ID. + */ + passwordChangeForced(siteId: string): void { + const currentSite = this.sitesProvider.getCurrentSite(); + if (!currentSite || siteId !== currentSite.getId()) { + return; // Site that triggered the event is not current site. + } + + const rootNavCtrl = this.appProvider.getRootNavController(), + activePage = rootNavCtrl.getActive(); + + // If current page is already change password, stop. + if (activePage && activePage.component && activePage.component.name == 'CoreLoginChangePasswordPage') { + return; + } + + rootNavCtrl.setRoot('CoreLoginChangePasswordPage', {siteId}); + } + /** * Prepare the app to perform SSO login. * diff --git a/src/core/mainmenu/pages/more/more.ts b/src/core/mainmenu/pages/more/more.ts index 257fb27c7..6d4bcb649 100644 --- a/src/core/mainmenu/pages/more/more.ts +++ b/src/core/mainmenu/pages/more/more.ts @@ -18,6 +18,7 @@ import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreMainMenuDelegate, CoreMainMenuHandlerData } from '../../providers/delegate'; import { CoreMainMenuProvider, CoreMainMenuCustomItem } from '../../providers/mainmenu'; +import { CoreLoginHelperProvider } from '@core/login/providers/helper'; /** * Page that displays the list of main menu options that aren't in the tabs. @@ -46,7 +47,7 @@ export class CoreMainMenuMorePage implements OnDestroy { constructor(private menuDelegate: CoreMainMenuDelegate, private sitesProvider: CoreSitesProvider, private navCtrl: NavController, private mainMenuProvider: CoreMainMenuProvider, - eventsProvider: CoreEventsProvider) { + eventsProvider: CoreEventsProvider, private loginHelper: CoreLoginHelperProvider) { this.langObserver = eventsProvider.on(CoreEventsProvider.LANGUAGE_CHANGED, this.loadSiteInfo.bind(this)); this.updateSiteObserver = eventsProvider.on(CoreEventsProvider.SITE_UPDATED, this.loadSiteInfo.bind(this), @@ -104,13 +105,12 @@ export class CoreMainMenuMorePage implements OnDestroy { * Load the site info required by the view. */ protected loadSiteInfo(): void { - const currentSite = this.sitesProvider.getCurrentSite(), - config = currentSite.getStoredConfig(); + const currentSite = this.sitesProvider.getCurrentSite(); this.siteInfo = currentSite.getInfo(); this.siteName = currentSite.getSiteName(); this.siteUrl = currentSite.getURL(); - this.logoutLabel = 'core.mainmenu.' + (config && config.tool_mobile_forcelogout == '1' ? 'logout' : 'changesite'); + this.logoutLabel = this.loginHelper.getLogoutLabel(currentSite); this.showWeb = !currentSite.isFeatureDisabled('CoreMainMenuDelegate_website'); this.showHelp = !currentSite.isFeatureDisabled('CoreMainMenuDelegate_help');