From 357fda719a590679331015dbfb4b269e7ddcd1f9 Mon Sep 17 00:00:00 2001
From: Albert Gasset
Date: Mon, 5 Aug 2024 15:36:00 +0200
Subject: [PATCH] MOBILE-4631 login: Hide the login form in the app when is
hidden in LMS
---
.../classes/sites/unauthenticated-site.ts | 1 +
.../login-methods/login-methods.html | 3 +-
.../components/login-methods/login-methods.ts | 1 +
src/core/features/login/constants.ts | 2 +
.../login/pages/credentials/credentials.html | 5 +-
.../login/pages/credentials/credentials.ts | 17 ++++-
.../login/pages/reconnect/reconnect.html | 5 +-
.../login/pages/reconnect/reconnect.ts | 13 +++-
.../features/login/services/login-helper.ts | 18 ++++++
.../tests/behat/showloginform_setting.feature | 60 ++++++++++++++++++
...wloginform-setting-in-the-app-login_10.png | Bin 0 -> 20542 bytes
...inform-setting-in-the-app-reconnect_10.png | Bin 0 -> 18200 bytes
src/core/features/settings/pages/dev/dev.html | 5 ++
src/core/features/settings/pages/dev/dev.ts | 19 +++++-
14 files changed, 139 insertions(+), 10 deletions(-)
create mode 100644 src/core/features/login/tests/behat/showloginform_setting.feature
create mode 100644 src/core/features/login/tests/behat/snapshots/test-showloginform-setting-in-the-app-login_10.png
create mode 100644 src/core/features/login/tests/behat/snapshots/test-showloginform-setting-in-the-app-reconnect_10.png
diff --git a/src/core/classes/sites/unauthenticated-site.ts b/src/core/classes/sites/unauthenticated-site.ts
index 68ef3f975..3d4a5e3fa 100644
--- a/src/core/classes/sites/unauthenticated-site.ts
+++ b/src/core/classes/sites/unauthenticated-site.ts
@@ -464,6 +464,7 @@ export type CoreSitePublicConfigResponse = {
tool_mobile_setuplink?: string; // App download page.
tool_mobile_qrcodetype?: CoreSiteQRCodeType; // eslint-disable-line @typescript-eslint/naming-convention
warnings?: CoreWSExternalWarning[];
+ showloginform?: number; // @since 4.5. Display default login form.
};
/**
diff --git a/src/core/features/login/components/login-methods/login-methods.html b/src/core/features/login/components/login-methods/login-methods.html
index 9a405ae15..be93e7972 100644
--- a/src/core/features/login/components/login-methods/login-methods.html
+++ b/src/core/features/login/components/login-methods/login-methods.html
@@ -1,4 +1,5 @@
-
+
{{ 'core.login.or' | translate }}
diff --git a/src/core/features/login/components/login-methods/login-methods.ts b/src/core/features/login/components/login-methods/login-methods.ts
index 88ac5a23e..f4c24f255 100644
--- a/src/core/features/login/components/login-methods/login-methods.ts
+++ b/src/core/features/login/components/login-methods/login-methods.ts
@@ -32,6 +32,7 @@ export class CoreLoginMethodsComponent implements OnInit {
@Input() siteUrl = '';
@Input() siteConfig?: CoreSitePublicConfigResponse;
@Input() redirectData?: CoreRedirectPayload;
+ @Input() showLoginForm = true;
isBrowserSSO = false;
showScanQR = false;
diff --git a/src/core/features/login/constants.ts b/src/core/features/login/constants.ts
index b83fbe9d6..2cb7ac285 100644
--- a/src/core/features/login/constants.ts
+++ b/src/core/features/login/constants.ts
@@ -21,6 +21,8 @@ export const EMAIL_SIGNUP_FEATURE_NAME = 'CoreLoginEmailSignup';
export const FORGOTTEN_PASSWORD_FEATURE_NAME = 'NoDelegate_ForgottenPassword';
export const IDENTITY_PROVIDERS_FEATURE_NAME = 'NoDelegate_IdentityProviders';
export const IDENTITY_PROVIDER_FEATURE_NAME_PREFIX = 'NoDelegate_IdentityProvider_';
+export const ALWAYS_SHOW_LOGIN_FORM = 'always_show_login_form';
+export const ALWAYS_SHOW_LOGIN_FORM_CHANGED = 'always_show_login_form_changed';
// Event indicating that a user left the app because it wasn't supported by a site.
export const APP_UNSUPPORTED_CHURN = 'app_unsupported_churn';
diff --git a/src/core/features/login/pages/credentials/credentials.html b/src/core/features/login/pages/credentials/credentials.html
index caacc02d9..c6d71047b 100644
--- a/src/core/features/login/pages/credentials/credentials.html
+++ b/src/core/features/login/pages/credentials/credentials.html
@@ -43,7 +43,8 @@
-
diff --git a/src/core/features/login/pages/credentials/credentials.ts b/src/core/features/login/pages/credentials/credentials.ts
index aad90fa57..8c8ccaa14 100644
--- a/src/core/features/login/pages/credentials/credentials.ts
+++ b/src/core/features/login/pages/credentials/credentials.ts
@@ -24,7 +24,7 @@ import { CoreDomUtils } from '@services/utils/dom';
import { CoreLoginHelper } from '@features/login/services/login-helper';
import { Translate } from '@singletons';
import { CoreSitePublicConfigResponse, CoreUnauthenticatedSite } from '@classes/sites/unauthenticated-site';
-import { CoreEvents } from '@singletons/events';
+import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreNavigator } from '@services/navigator';
import { CoreForms } from '@singletons/form';
import { CoreUserSupport } from '@features/user/services/support';
@@ -33,7 +33,11 @@ import { CoreUserGuestSupportConfig } from '@features/user/classes/support/guest
import { SafeHtml } from '@angular/platform-browser';
import { CorePlatform } from '@services/platform';
import { CoreSitesFactory } from '@services/sites-factory';
-import { EMAIL_SIGNUP_FEATURE_NAME, FORGOTTEN_PASSWORD_FEATURE_NAME } from '@features/login/constants';
+import {
+ ALWAYS_SHOW_LOGIN_FORM_CHANGED,
+ EMAIL_SIGNUP_FEATURE_NAME,
+ FORGOTTEN_PASSWORD_FEATURE_NAME,
+} from '@features/login/constants';
import { CoreCustomURLSchemes } from '@services/urlschemes';
import { CoreSiteError } from '@classes/errors/siteerror';
import { CoreKeyboard } from '@singletons/keyboard';
@@ -66,6 +70,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
siteConfig?: CoreSitePublicConfigResponse;
siteCheckError = '';
displaySiteUrl = false;
+ showLoginForm = true;
protected siteCheck?: CoreSiteCheckResponse;
protected eventThrown = false;
@@ -73,6 +78,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
protected siteId?: string;
protected urlToOpen?: string;
protected valueChangeSubscription?: Subscription;
+ protected alwaysShowLoginFormObserver?: CoreEventObserver;
constructor(
protected fb: FormBuilder,
@@ -137,6 +143,10 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
}
});
}
+
+ this.alwaysShowLoginFormObserver = CoreEvents.on(ALWAYS_SHOW_LOGIN_FORM_CHANGED, async () => {
+ this.showLoginForm = await CoreLoginHelper.shouldShowLoginForm(this.siteConfig);
+ });
}
/**
@@ -191,6 +201,8 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
* Treat the site configuration (if it exists).
*/
protected async treatSiteConfig(): Promise {
+ this.showLoginForm = await CoreLoginHelper.shouldShowLoginForm(this.siteConfig);
+
if (!this.siteConfig) {
this.authInstructions = undefined;
this.canSignup = false;
@@ -365,6 +377,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
this.siteId,
);
this.valueChangeSubscription?.unsubscribe();
+ this.alwaysShowLoginFormObserver?.off();
}
}
diff --git a/src/core/features/login/pages/reconnect/reconnect.html b/src/core/features/login/pages/reconnect/reconnect.html
index 3c529966e..2a5c92b3a 100644
--- a/src/core/features/login/pages/reconnect/reconnect.html
+++ b/src/core/features/login/pages/reconnect/reconnect.html
@@ -59,7 +59,8 @@
-
diff --git a/src/core/features/login/pages/reconnect/reconnect.ts b/src/core/features/login/pages/reconnect/reconnect.ts
index 642831241..181ef2f13 100644
--- a/src/core/features/login/pages/reconnect/reconnect.ts
+++ b/src/core/features/login/pages/reconnect/reconnect.ts
@@ -21,7 +21,7 @@ import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { CoreLoginHelper } from '@features/login/services/login-helper';
import { CoreSite } from '@classes/sites/site';
-import { CoreEvents } from '@singletons/events';
+import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreError } from '@classes/errors/error';
import { CoreNavigator, CoreRedirectPayload } from '@services/navigator';
import { CoreForms } from '@singletons/form';
@@ -31,7 +31,7 @@ import { CoreUserAuthenticatedSupportConfig } from '@features/user/classes/suppo
import { Translate } from '@singletons';
import { SafeHtml } from '@angular/platform-browser';
import { CoreSitePublicConfigResponse } from '@classes/sites/unauthenticated-site';
-import { FORGOTTEN_PASSWORD_FEATURE_NAME } from '@features/login/constants';
+import { ALWAYS_SHOW_LOGIN_FORM_CHANGED, FORGOTTEN_PASSWORD_FEATURE_NAME } from '@features/login/constants';
import { CoreKeyboard } from '@singletons/keyboard';
/**
@@ -63,11 +63,13 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
exceededAttemptsHTML?: SafeHtml | string | null;
siteConfig?: CoreSitePublicConfigResponse;
redirectData?: CoreRedirectPayload;
+ showLoginForm = true;
protected viewLeft = false;
protected eventThrown = false;
protected loginSuccessful = false;
protected username = '';
+ protected alwaysShowLoginFormObserver?: CoreEventObserver;
constructor(
protected fb: FormBuilder,
@@ -126,6 +128,10 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
await this.checkSiteConfig();
+ this.alwaysShowLoginFormObserver = CoreEvents.on(ALWAYS_SHOW_LOGIN_FORM_CHANGED, async () => {
+ this.showLoginForm = await CoreLoginHelper.shouldShowLoginForm(this.siteConfig);
+ });
+
this.showLoading = false;
} catch (error) {
CoreDomUtils.showErrorModal(error);
@@ -147,6 +153,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
},
this.siteId,
);
+ this.alwaysShowLoginFormObserver?.off();
}
/**
@@ -168,6 +175,8 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
readingStrategy: CoreSitesReadingStrategy.PREFER_NETWORK,
}));
+ this.showLoginForm = await CoreLoginHelper.shouldShowLoginForm(this.siteConfig);
+
if (!this.siteConfig) {
return;
}
diff --git a/src/core/features/login/services/login-helper.ts b/src/core/features/login/services/login-helper.ts
index 856d729ca..8a92e8108 100644
--- a/src/core/features/login/services/login-helper.ts
+++ b/src/core/features/login/services/login-helper.ts
@@ -47,6 +47,8 @@ import {
TypeOfLogin,
} from '@classes/sites/unauthenticated-site';
import {
+ ALWAYS_SHOW_LOGIN_FORM,
+ ALWAYS_SHOW_LOGIN_FORM_CHANGED,
APP_UNSUPPORTED_CHURN,
EMAIL_SIGNUP_FEATURE_NAME,
FAQ_QRCODE_IMAGE_HTML,
@@ -924,6 +926,21 @@ export class CoreLoginHelperProvider {
}
}
+ /**
+ * Check if the default login form should be displayed.
+ *
+ * @param config Site public config.
+ * @returns True if the login form should be displayed.
+ */
+ async shouldShowLoginForm(config?: CoreSitePublicConfigResponse): Promise {
+ // Only hide the form if the setting exists and is set to 0.
+ if (config?.showloginform === 0) {
+ return Boolean(await CoreConfig.get(ALWAYS_SHOW_LOGIN_FORM, 0));
+ }
+
+ return true;
+ }
+
/**
* Check if a confirm should be shown to open a SSO authentication.
*
@@ -1692,6 +1709,7 @@ declare module '@singletons/events' {
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/
export interface CoreEventsData {
+ [ALWAYS_SHOW_LOGIN_FORM_CHANGED]: { value: number };
[APP_UNSUPPORTED_CHURN]: { siteUrl: string; debug?: CoreSiteErrorDebug };
}
diff --git a/src/core/features/login/tests/behat/showloginform_setting.feature b/src/core/features/login/tests/behat/showloginform_setting.feature
new file mode 100644
index 000000000..56a02a978
--- /dev/null
+++ b/src/core/features/login/tests/behat/showloginform_setting.feature
@@ -0,0 +1,60 @@
+@core_login @app @javascript @lms_from4.5
+Feature: Test showloginform setting in the app
+
+ Background:
+ Given the Moodle site is compatible with this feature
+ And the following config values are set as admin:
+ | showloginform | 0 |
+ And the following "users" exist:
+ | username | firstname | lastname |
+ | student | david | student |
+
+ Scenario: Login
+ When I launch the app
+ And I set the field "Your site" to "$WWWROOT" in the app
+ And I press "Connect to your site" in the app
+ Then the header should be "Log in" in the app
+ And I should not find "Log in" "ion-button" in the app
+ And I replace "/.*/" within ".core-siteurl" with "https://campus.example.edu"
+ And the UI should match the snapshot
+
+ Scenario: Reconnect
+ When I entered the app as "student"
+ And I log out in the app
+ And I press "david student" in the app
+ Then the header should be "Reconnect" in the app
+ And I should not find "Log in" "ion-button" in the app
+ And I replace "/.*/" within ".core-siteurl" with "https://campus.example.edu"
+ And the UI should match the snapshot
+
+ Scenario: Login with forced developer option
+ When I launch the app
+ And I set the field "Your site" to "$WWWROOT" in the app
+ And I press "Connect to your site" in the app
+ And I press "App settings" in the app
+ And I press "About" in the app
+ And I press "Moodle Mobile" in the app
+ And I press "Developer options" in the app
+ And I press "Always show login form" in the app
+ And I press the back button in the app
+ And I press the back button in the app
+ And I press the back button in the app
+ And I press the back button in the app
+ Then the header should be "Log in" in the app
+ And I should find "Log in" "ion-button" in the app
+
+ Scenario: Reconnect with forced developer option
+ When I entered the app as "student"
+ And I log out in the app
+ And I press "App settings" in the app
+ And I press "About" in the app
+ And I press "Moodle Mobile" in the app
+ And I press "Developer options" in the app
+ And I press "Always show login form" in the app
+ And I press the back button in the app
+ And I press the back button in the app
+ And I press the back button in the app
+ And I press the back button in the app
+ And I press "david student" in the app
+ Then the header should be "Reconnect" in the app
+ And I should find "Log in" "ion-button" in the app
diff --git a/src/core/features/login/tests/behat/snapshots/test-showloginform-setting-in-the-app-login_10.png b/src/core/features/login/tests/behat/snapshots/test-showloginform-setting-in-the-app-login_10.png
new file mode 100644
index 0000000000000000000000000000000000000000..c31717c6490cd2d717d469534ab3ab01cbcf0c04
GIT binary patch
literal 20542
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 staging sites {{stagingSitesCount}}
+
+
+ Always show login form
+
+
diff --git a/src/core/features/settings/pages/dev/dev.ts b/src/core/features/settings/pages/dev/dev.ts
index 8b2888399..7c9464ffd 100644
--- a/src/core/features/settings/pages/dev/dev.ts
+++ b/src/core/features/settings/pages/dev/dev.ts
@@ -14,12 +14,18 @@
import { CoreConstants } from '@/core/constants';
import { Component, OnInit } from '@angular/core';
-import { FAQ_QRCODE_INFO_DONE, ONBOARDING_DONE } from '@features/login/constants';
+import {
+ ALWAYS_SHOW_LOGIN_FORM,
+ ALWAYS_SHOW_LOGIN_FORM_CHANGED,
+ FAQ_QRCODE_INFO_DONE,
+ ONBOARDING_DONE,
+} from '@features/login/constants';
import { CoreSettingsHelper } from '@features/settings/services/settings-helper';
import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins';
import { CoreUserTours } from '@features/usertours/services/user-tours';
import { CoreCacheManager } from '@services/cache-manager';
import { CoreConfig } from '@services/config';
+import { CoreEvents } from '@singletons/events';
import { CoreFile } from '@services/file';
import { CoreNavigator } from '@services/navigator';
import { CorePlatform } from '@services/platform';
@@ -40,6 +46,7 @@ export class CoreSettingsDevPage implements OnInit {
rtl = false;
forceSafeAreaMargins = false;
direction = 'ltr';
+ alwaysShowLoginForm = false;
remoteStyles = true;
remoteStylesCount = 0;
@@ -70,6 +77,7 @@ export class CoreSettingsDevPage implements OnInit {
this.enableStagingSites = await CoreSettingsHelper.hasEnabledStagingSites();
this.previousEnableStagingSites = this.enableStagingSites;
}
+ this.alwaysShowLoginForm = Boolean(await CoreConfig.get(ALWAYS_SHOW_LOGIN_FORM, 0));
if (!this.siteId) {
return;
@@ -125,6 +133,15 @@ export class CoreSettingsDevPage implements OnInit {
document.documentElement.classList.toggle('force-safe-area-margins', this.forceSafeAreaMargins);
}
+ /**
+ * Called when always show login form is enabled or disabled.
+ */
+ async alwaysShowLoginFormChanged(): Promise {
+ const value = Number(this.alwaysShowLoginForm);
+ await CoreConfig.set(ALWAYS_SHOW_LOGIN_FORM, value);
+ CoreEvents.trigger(ALWAYS_SHOW_LOGIN_FORM_CHANGED, { value });
+ }
+
/**
* Called when remote styles is enabled or disabled.
*/