Skip to content

Commit

Permalink
Merge pull request #3790 from crazyserver/MOBILE-4201
Browse files Browse the repository at this point in the history
Mobile 4201
  • Loading branch information
dpalou authored Sep 21, 2023
2 parents e526189 + 8f7e153 commit 3dd5acc
Show file tree
Hide file tree
Showing 16 changed files with 72 additions and 38 deletions.
2 changes: 1 addition & 1 deletion local_moodleappbehat/tests/behat/behat_app.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ public function login(string $username) {

// Note there are two 'Log in' texts visible (the title and the button) so we have to use
// a 'near' value here.
$this->i_press_in_the_app('"Log in" near "Forgotten"');
$this->i_press_in_the_app('"Log in" "ion-button"');

// Wait until the main page appears.
$this->spin(
Expand Down
2 changes: 1 addition & 1 deletion scripts/langindex.json
Original file line number Diff line number Diff line change
Expand Up @@ -2074,7 +2074,7 @@
"core.login.findyoursite": "local_moodlemobileapp",
"core.login.firsttime": "moodle",
"core.login.forcepasswordchangenotice": "moodle",
"core.login.forgotten": "moodle",
"core.login.forgotaccount": "moodle",
"core.login.help": "moodle",
"core.login.instructions": "auth",
"core.login.invalidaccount": "local_moodlemobileapp",
Expand Down
11 changes: 10 additions & 1 deletion src/core/classes/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2771,7 +2771,7 @@ export type CoreSitePublicConfigResponse = {
maintenancemessage: string; // Maintenance message.
logourl?: string; // The site logo URL.
compactlogourl?: string; // The site compact logo URL.
typeoflogin: number; // The type of login. 1 for app, 2 for browser, 3 for embedded.
typeoflogin: TypeOfLogin; // The type of login. 1 for app, 2 for browser, 3 for embedded.
launchurl?: string; // SSO login launch URL.
mobilecssurl?: string; // Mobile custom CSS theme.
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down Expand Up @@ -2869,3 +2869,12 @@ enum OngoingRequestType {
STANDARD = 0,
UPDATE_IN_BACKGROUND = 1,
}

/**
* The type of login. 1 for app, 2 for browser, 3 for embedded.
*/
export enum TypeOfLogin {
APP = 1,
BROWSER = 2, // SSO in browser window is required.
EMBEDDED = 3, // SSO in embedded browser is required.
}
6 changes: 6 additions & 0 deletions src/core/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,13 @@ export class CoreConstants {
static readonly WS_PREFIX = 'local_mobile_'; // @deprecated since app 4.0.

// Login constants.
/**
* @deprecated since 4.3 Use TypeOfLogin.BROWSER instead.
*/
static readonly LOGIN_SSO_CODE = 2; // SSO in browser window is required.
/**
* @deprecated since 4.3 Use TypeOfLogin.EMBEDDED instead.
*/
static readonly LOGIN_SSO_INAPP_CODE = 3; // SSO in embedded browser is required.
static readonly LOGIN_LAUNCH_DATA = 'CoreLoginLaunchData';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class CoreLoginMethodsComponent implements OnInit {
@Input() siteConfig?: CoreSitePublicConfigResponse;
@Input() redirectData?: CoreRedirectPayload;

isBrowserSSO = false;
showScanQR = false;
loginMethods: CoreLoginMethod[] = [];
identityProviders: CoreSiteIdentityProvider[] = [];
Expand All @@ -50,9 +51,14 @@ export class CoreLoginMethodsComponent implements OnInit {
}

if (this.siteConfig) {
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);
this.isBrowserSSO = CoreLoginHelper.isSSOLoginNeeded(this.siteConfig.typeoflogin);

this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
if (!this.isBrowserSSO) {
// Identity providers won't be shown if login on browser.
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);

this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
}

if (this.reconnect) {
this.showScanQR = CoreLoginHelper.displayQRInSiteScreen();
Expand Down
4 changes: 2 additions & 2 deletions src/core/features/login/lang.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"exceededpasswordresetattemptssupportsubject": "I can't reset my password",
"faqcannotfindmysiteanswer": "If you tried searching by URL address and still can't find your Moodle site, please get in touch with the person who takes care of Moodle in your school or learning organisation.",
"faqcannotfindmysitequestion": "I can't find my site by URL address.",
"faqcantloginanswer": "<p>Once you've connected to your Moodle site, you should be able to log in with your usual username and password.</p><br><p>If you forgot your username or password, select the option <strong>Forgotten your username or password?</strong>. If you still have trouble logging in or can't see any options for retrieving your username or password, please get in touch with the person who takes care of Moodle in your school or learning organisation.</p>",
"faqcantloginanswer": "<p>Once you've connected to your Moodle site, you should be able to log in with your usual username and password.</p><br><p>If you forgot your username or password, select the option <strong>Lost password?</strong>. If you still have trouble logging in or can't see any options for retrieving your username or password, please get in touch with the person who takes care of Moodle in your school or learning organisation.</p>",
"faqcantloginquestion": "I can't log in.",
"faqmore": "Check out <a href=\"https://docs.moodle.org/en/Moodle_app_FAQ#toc\" target=\"_blank\">our FAQ</a> for more answers.",
"faqsetupsiteanswer": "Visit {{$link}} to check out the different options you have to create your own Moodle site.",
Expand All @@ -52,7 +52,7 @@
"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?",
"forgotaccount": "Lost password?",
"help": "Help",
"instructions": "Instructions",
"invalidaccount": "Please check your login details and try again.",
Expand Down
12 changes: 6 additions & 6 deletions src/core/features/login/pages/credentials/credentials.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ <h2 *ngIf="siteName" class="ion-margin-top ion-no-padding core-sitename">
<!-- Forgotten password option. -->
<ion-button *ngIf="showForgottenPassword" expand="block" fill="clear"
class="core-login-forgotten-password core-button-as-link ion-text-wrap" (click)="forgottenPassword()">
{{ 'core.login.forgotten' | translate }}
{{ 'core.login.forgotaccount' | translate }}
</ion-button>
</form>

Expand All @@ -86,7 +86,7 @@ <h2 *ngIf="siteName" class="ion-margin-top ion-no-padding core-sitename">
<core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [siteUrl]="siteUrl"></core-login-methods>
</div>

<div class="core-login-sign-up" *ngIf="canSignup || authInstructions">
<div class="core-login-sign-up" *ngIf="!isBrowserSSO && (canSignup || authInstructions)">
<h2>{{ 'core.login.firsttime' | translate }}</h2>

<ion-item class="ion-text-wrap ion-no-padding core-login-instructions">
Expand All @@ -95,12 +95,12 @@ <h2>{{ 'core.login.firsttime' | translate }}</h2>
</ion-label>
</ion-item>


<ion-button *ngIf="canSignup" expand="block" class="ion-margin ion-text-wrap" fill="outline" (click)="openEmailSignup()">
{{ 'core.login.startsignup' | translate }}
</ion-button>
</div>
<ion-button *ngIf="canSignup" expand="block" class="ion-margin ion-text-wrap" fill="outline" (click)="openEmailSignup()">
{{ 'core.login.startsignup' | translate }}
</ion-button>
</ng-container>

<core-empty-box *ngIf="siteCheckError" icon="fas-circle-exclamation" [message]="siteCheckError">
<ion-button expand="block" (click)="checkSite()" fill="outline">
{{ 'core.tryagain' | translate }}
Expand Down
4 changes: 4 additions & 0 deletions src/core/features/login/pages/credentials/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {

await this.checkSite();

if (this.isBrowserSSO && CoreLoginHelper.shouldSkipCredentialsScreenOnSSO()) {
this.openBrowserSSO();
}

if (CorePlatform.isIOS() && !this.isBrowserSSO) {
// Make iOS auto-fill work. The field that isn't focused doesn't get updated, do it manually.
// Debounce it to prevent triggering this function too often when the user is typing.
Expand Down
2 changes: 1 addition & 1 deletion src/core/features/login/pages/reconnect/reconnect.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ <h1>{{ 'core.login.reconnect' | translate }}</h1>
<!-- Forgotten password option. -->
<ion-button *ngIf="showForgottenPassword" expand="block" fill="clear"
class="core-login-forgotten-password core-button-as-link ion-text-wrap" (click)="forgottenPassword()">
{{ 'core.login.forgotten' | translate }}
{{ 'core.login.forgotaccount' | translate }}
</ion-button>
</form>

Expand Down
36 changes: 22 additions & 14 deletions src/core/features/login/services/login-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlParams, CoreUrlUtils } from '@services/utils/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreConstants } from '@/core/constants';
import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse, CoreSiteQRCodeType } from '@classes/site';
import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse, CoreSiteQRCodeType, TypeOfLogin } from '@classes/site';
import { CoreError } from '@classes/errors/error';
import { CoreWSError } from '@classes/errors/wserror';
import { DomSanitizer, makeSingleton, Translate } from '@singletons';
Expand Down Expand Up @@ -139,7 +139,7 @@ export class CoreLoginHelperProvider {
* Open a browser to perform SSO login.
*
* @param siteUrl URL of the site where the SSO login will be performed.
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
* @param typeOfLogin TypeOfLogin.BROWSER or TypeOfLogin.EMBEDDED.
* @param service The service to use. If not defined, core service will be used.
* @param launchUrl The URL to open for SSO. If not defined, default tool mobile launch URL will be used.
* @param redirectData Data of the path/url to open once authenticated. If not defined, site initial page.
Expand All @@ -148,7 +148,7 @@ export class CoreLoginHelperProvider {
*/
async confirmAndOpenBrowserForSSOLogin(
siteUrl: string,
typeOfLogin: number,
typeOfLogin: TypeOfLogin,
service?: string,
launchUrl?: string,
redirectData?: CoreRedirectPayload,
Expand Down Expand Up @@ -601,8 +601,8 @@ export class CoreLoginHelperProvider {
* @param code Code to check.
* @returns True if embedded browser, false othwerise.
*/
isSSOEmbeddedBrowser(code: number): boolean {
return code == CoreConstants.LOGIN_SSO_INAPP_CODE;
isSSOEmbeddedBrowser(code: TypeOfLogin): boolean {
return code == TypeOfLogin.EMBEDDED;
}

/**
Expand All @@ -611,8 +611,8 @@ export class CoreLoginHelperProvider {
* @param code Code to check.
* @returns True if SSO login is needed, false othwerise.
*/
isSSOLoginNeeded(code: number): boolean {
return code == CoreConstants.LOGIN_SSO_CODE || code == CoreConstants.LOGIN_SSO_INAPP_CODE;
isSSOLoginNeeded(code: TypeOfLogin): boolean {
return code == TypeOfLogin.BROWSER || code == TypeOfLogin.EMBEDDED;
}

/**
Expand Down Expand Up @@ -656,14 +656,14 @@ export class CoreLoginHelperProvider {
* Open a browser to perform SSO login.
*
* @param siteUrl URL of the site where the SSO login will be performed.
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
* @param typeOfLogin TypeOfLogin.BROWSER or TypeOfLogin.EMBEDDED.
* @param service The service to use. If not defined, core service will be used.
* @param launchUrl The URL to open for SSO. If not defined, default tool mobile launch URL will be used.
* @param redirectData Data of the path/url to open once authenticated. If not defined, site initial page.
*/
openBrowserForSSOLogin(
siteUrl: string,
typeOfLogin: number,
typeOfLogin: TypeOfLogin,
service?: string,
launchUrl?: string,
redirectData?: CoreRedirectPayload,
Expand Down Expand Up @@ -901,13 +901,21 @@ export class CoreLoginHelperProvider {
/**
* Check if a confirm should be shown to open a SSO authentication.
*
* @param typeOfLogin CoreConstants.LOGIN_SSO_CODE or CoreConstants.LOGIN_SSO_INAPP_CODE.
* @param typeOfLogin TypeOfLogin.BROWSER or TypeOfLogin.EMBEDDED.
* @returns True if confirm modal should be shown, false otherwise.
* @deprecated since 4.3 Not used anymore.
* @deprecated since 4.3 Not used anymore. See shouldSkipCredentialsScreenOnSSO.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
shouldShowSSOConfirm(typeOfLogin: number): boolean {
return false;
shouldShowSSOConfirm(typeOfLogin: TypeOfLogin): boolean {
return !this.isSSOEmbeddedBrowser(typeOfLogin) && !this.shouldSkipCredentialsScreenOnSSO();
}

/**
* Check if we can skip credentials page.
*
* @returns If true, the browser should be opened without the user prompt.
*/
shouldSkipCredentialsScreenOnSSO(): boolean {
return String(CoreConstants.CONFIG.skipssoconfirmation) === 'true';
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/core/features/login/tests/behat/basic-usage-400.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ Feature: Test basic usage of login in app

Scenario: Forgot password
When I enter the app
And I press "Forgotten your username or password?" in the app
And I press "Lost password?" in the app
And I set the field "Enter either username or email address" to "student1"
And I press "Search" in the app
Then I should find "Success" in the app

When I press "OK" in the app
And I press "Forgotten your username or password?" in the app
And I press "Lost password?" in the app
Then I should find "Contact support" in the app
4 changes: 2 additions & 2 deletions src/core/features/login/tests/behat/basic_usage-311.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ Feature: Test basic usage of login in app

Scenario: Forgot password
When I enter the app
And I press "Forgotten your username or password?" in the app
And I press "Lost password?" in the app
And I set the field "Enter either username or email address" to "student1"
And I press "Search" in the app
Then I should find "Success" in the app

When I press "OK" in the app
And I press "Forgotten your username or password?" in the app
And I press "Lost password?" in the app
Then I should not find "Contact support" in the app
6 changes: 3 additions & 3 deletions src/core/features/login/tests/behat/basic_usage.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Feature: Test basic usage of login in app
When I set the following fields to these values in the app:
| Username | student1 |
| Password | student1 |
And I press "Log in" near "Forgotten your username or password?" in the app
And I press "Log in" near "Lost password?" in the app
Then I should find "Acceptance test site" in the app
And the UI should match the snapshot
But I should not find "Log in" in the app
Expand Down Expand Up @@ -143,11 +143,11 @@ Feature: Test basic usage of login in app
Given the following config values are set as admin:
| supportavailability | 2 |
When I enter the app
And I press "Forgotten your username or password?" in the app
And I press "Lost password?" in the app
And I set the field "Enter either username or email address" to "student1"
And I press "Search" in the app
Then I should find "Success" in the app

When I press "OK" in the app
And I press "Forgotten your username or password?" in the app
And I press "Lost password?" in the app
Then I should find "Contact support" in the app
6 changes: 3 additions & 3 deletions src/core/features/login/tests/behat/signup.feature
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ Feature: Test signup in app
And I set the following fields to these values in the app:
| Username | u1 |
| Password | pu1 |
And I press "Log in" near "Forgotten your username or password?" in the app
And I press "Log in" near "Lost password?" in the app
Then I should find "You need to confirm your account" in the app

When I open a browser tab with url "$WWWROOT"
And I confirm email for "u1"
And I close the browser tab opened by the app
And I press "Close" in the app
And I press "Log in" near "Forgotten your username or password?" in the app
And I press "Log in" near "Lost password?" in the app
Then I should find "Acceptance test site" in the app
But I should not find "You need to confirm your account" in the app

Expand Down Expand Up @@ -173,7 +173,7 @@ Feature: Test signup in app
And I set the following fields to these values in the app:
| Username | u1 |
| Password | pu1 |
And I press "Log in" near "Forgotten your username or password?" in the app
And I press "Log in" near "Lost password?" in the app
And I press the user menu button in the app
And I press "User Test" in the app
Then I should find "No" near "Are you a developer?" in the app
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/types/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface EnvironmentConfig {
multisitesdisplay: CoreLoginSiteSelectorListMethod;
sitefindersettings: Partial<CoreLoginSiteFinderSettings>;
onlyallowlistedsites: boolean;
skipssoconfirmation: boolean;
forcedefaultlanguage: boolean;
privacypolicy: string;
notificoncolor: string;
Expand Down

0 comments on commit 3dd5acc

Please sign in to comment.