MOBILE-4469 login: Support isFeatureDisabled in all site classes

main
Dani Palou 2023-11-13 08:19:23 +01:00
parent a724a946d2
commit a3898d7515
19 changed files with 263 additions and 134 deletions

View File

@ -108,14 +108,18 @@ export class CoreCandidateSite extends CoreUnauthenticatedSite {
* *
* @param siteUrl Site URL. * @param siteUrl Site URL.
* @param token Site's WS token. * @param token Site's WS token.
* @param privateToken Private token. * @param otherData Other data.
*/ */
constructor(siteUrl: string, token: string, privateToken?: string) { constructor(
super(siteUrl); siteUrl: string,
token: string,
otherData: CoreCandidateSiteOptionalData = {},
) {
super(siteUrl, otherData.publicConfig);
this.token = token;
this.privateToken = privateToken;
this.logger = CoreLogger.getInstance('CoreCandidateSite'); this.logger = CoreLogger.getInstance('CoreCandidateSite');
this.token = token;
this.privateToken = otherData.privateToken;
} }
/** /**
@ -700,7 +704,7 @@ export class CoreCandidateSite extends CoreUnauthenticatedSite {
this.saveToCache(method, data, error, preSets); this.saveToCache(method, data, error, preSets);
throw new CoreWSError(error); throw new CoreWSError(error);
} else if (preSets.emergencyCache !== undefined && !preSets.emergencyCache) { } else if (preSets.emergencyCache === false) {
this.logger.debug(`WS call '${method}' failed. Emergency cache is forbidden, rejecting.`); this.logger.debug(`WS call '${method}' failed. Emergency cache is forbidden, rejecting.`);
throw new CoreWSError(error); throw new CoreWSError(error);
@ -1273,6 +1277,11 @@ export class CoreCandidateSite extends CoreUnauthenticatedSite {
* @inheritdoc * @inheritdoc
*/ */
async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise<CoreSitePublicConfigResponse> { async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise<CoreSitePublicConfigResponse> {
const ignoreCache = CoreSitesReadingStrategy.ONLY_NETWORK || CoreSitesReadingStrategy.PREFER_NETWORK;
if (!ignoreCache && this.publicConfig) {
return this.publicConfig;
};
const method = 'tool_mobile_get_public_config'; const method = 'tool_mobile_get_public_config';
const cacheId = this.getCacheId(method, {}); const cacheId = this.getCacheId(method, {});
const cachePreSets: CoreSiteWSPreSets = { const cachePreSets: CoreSiteWSPreSets = {
@ -1321,12 +1330,15 @@ export class CoreCandidateSite extends CoreUnauthenticatedSite {
try { try {
const config = await this.requestPublicConfig(); const config = await this.requestPublicConfig();
if (cachePreSets.saveToCache) { this.saveToCache(method, {}, config, cachePreSets);
this.saveToCache(method, {}, config, cachePreSets); this.setPublicConfig(config);
}
return config; return config;
} catch (error) { } catch (error) {
if (cachePreSets.emergencyCache === false) {
throw error;
}
cachePreSets.omitExpires = true; cachePreSets.omitExpires = true;
cachePreSets.getFromCache = true; cachePreSets.getFromCache = true;
@ -1340,7 +1352,10 @@ export class CoreCandidateSite extends CoreUnauthenticatedSite {
} }
}).then((response) => { }).then((response) => {
// The app doesn't store exceptions for this call, it's safe to assume type CoreSitePublicConfigResponse. // The app doesn't store exceptions for this call, it's safe to assume type CoreSitePublicConfigResponse.
subject.next(<CoreSitePublicConfigResponse> response); response = <CoreSitePublicConfigResponse> response;
this.setPublicConfig(response);
subject.next(response);
subject.complete(); subject.complete();
return; return;
@ -1581,6 +1596,14 @@ export function chainRequests<T, O extends ObservableInput<any>>(
); );
} }
/**
* Optional data to create a candidate site.
*/
export type CoreCandidateSiteOptionalData = {
privateToken?: string;
publicConfig?: CoreSitePublicConfigResponse;
};
/** /**
* PreSets accepted by the WS call. * PreSets accepted by the WS call.
*/ */

View File

@ -51,7 +51,7 @@ import { map } from 'rxjs/operators';
import { firstValueFrom } from '../../utils/rxjs'; import { firstValueFrom } from '../../utils/rxjs';
import { CoreFilepool } from '@services/filepool'; import { CoreFilepool } from '@services/filepool';
import { CoreSiteInfo } from './unauthenticated-site'; import { CoreSiteInfo } from './unauthenticated-site';
import { CoreCandidateSite, CoreSiteWSPreSets, WSObservable } from './candidate-site'; import { CoreCandidateSite, CoreCandidateSiteOptionalData, CoreSiteWSPreSets, WSObservable } from './candidate-site';
/** /**
* Class that represents a site (combination of site + user). * Class that represents a site (combination of site + user).
@ -78,25 +78,19 @@ export class CoreSite extends CoreCandidateSite {
* @param id Site ID. * @param id Site ID.
* @param siteUrl Site URL. * @param siteUrl Site URL.
* @param token Site's WS token. * @param token Site's WS token.
* @param infos Site info. * @param otherData Other data.
* @param privateToken Private token.
* @param config Site public config.
* @param loggedOut Whether user is logged out.
*/ */
constructor( constructor(
id: string, id: string,
siteUrl: string, siteUrl: string,
token: string, token: string,
infos?: CoreSiteInfo, otherData: CoreSiteOptionalData = {},
privateToken?: string,
config?: CoreSiteConfig,
loggedOut?: boolean,
) { ) {
super(siteUrl, token, privateToken); super(siteUrl, token, otherData);
this.id = id; this.id = id;
this.config = config; this.config = otherData.config;
this.loggedOut = loggedOut; this.loggedOut = otherData.loggedOut;
this.logger = CoreLogger.getInstance('CoreSite'); this.logger = CoreLogger.getInstance('CoreSite');
this.cacheTable = asyncInstance(() => CoreSites.getSiteTable(WS_CACHE_TABLE, { this.cacheTable = asyncInstance(() => CoreSites.getSiteTable(WS_CACHE_TABLE, {
@ -118,7 +112,7 @@ export class CoreSite extends CoreCandidateSite {
config: { cachingStrategy: CoreDatabaseCachingStrategy.Eager }, config: { cachingStrategy: CoreDatabaseCachingStrategy.Eager },
primaryKeyColumns: ['component', 'id'], primaryKeyColumns: ['component', 'id'],
})); }));
this.setInfo(infos); this.setInfo(otherData.info);
this.calculateOfflineDisabled(); this.calculateOfflineDisabled();
this.db = CoreDB.getDB('Site-' + this.id); this.db = CoreDB.getDB('Site-' + this.id);
@ -678,20 +672,10 @@ export class CoreSite extends CoreCandidateSite {
} }
/** /**
* Check if a certain feature is disabled in the site. * @inheritdoc
*
* @param name Name of the feature to check.
* @returns Whether it's disabled.
*/ */
isFeatureDisabled(name: string): boolean { protected getDisabledFeatures(): string | undefined {
const disabledFeatures = this.getStoredConfig('tool_mobile_disabledfeatures'); return this.config ? this.getStoredConfig('tool_mobile_disabledfeatures') : super.getDisabledFeatures();
if (!disabledFeatures) {
return false;
}
const regEx = new RegExp('(,|^)' + CoreTextUtils.escapeForRegex(name) + '(,|$)', 'g');
return !!disabledFeatures.match(regEx);
} }
/** /**
@ -923,6 +907,15 @@ export class CoreSite extends CoreCandidateSite {
} }
/**
* Optional data to create a site.
*/
export type CoreSiteOptionalData = CoreCandidateSiteOptionalData & {
info?: CoreSiteInfo;
config?: CoreSiteConfig;
loggedOut?: boolean;
};
/** /**
* Result of WS tool_mobile_get_config. * Result of WS tool_mobile_get_config.
*/ */

View File

@ -28,13 +28,19 @@ export class CoreUnauthenticatedSite {
siteUrl: string; siteUrl: string;
protected publicConfig?: CoreSitePublicConfigResponse;
/** /**
* Create a site. * Create a site.
* *
* @param siteUrl Site URL. * @param siteUrl Site URL.
* @param publicConfig Site public config.
*/ */
constructor(siteUrl: string) { constructor(siteUrl: string, publicConfig?: CoreSitePublicConfigResponse) {
this.siteUrl = CoreUrlUtils.removeUrlParams(siteUrl); // Make sure the URL doesn't have params. this.siteUrl = CoreUrlUtils.removeUrlParams(siteUrl); // Make sure the URL doesn't have params.
if (publicConfig) {
this.setPublicConfig(publicConfig);
}
} }
/** /**
@ -75,7 +81,7 @@ export class CoreUnauthenticatedSite {
return CoreConstants.CONFIG.appname; return CoreConstants.CONFIG.appname;
} }
const siteName = this.getInfo()?.sitename; const siteName = this.getInfo()?.sitename || this.publicConfig?.sitename;
if (siteName) { if (siteName) {
return siteName; return siteName;
} }
@ -108,6 +114,7 @@ export class CoreUnauthenticatedSite {
* @returns Logo URL. * @returns Logo URL.
*/ */
getLogoUrl(config?: CoreSitePublicConfigResponse): string | undefined { getLogoUrl(config?: CoreSitePublicConfigResponse): string | undefined {
config = config ?? this.publicConfig;
if (!config || this.forcesLocalLogo()) { if (!config || this.forcesLocalLogo()) {
return 'assets/img/login_logo.png'; return 'assets/img/login_logo.png';
} }
@ -151,11 +158,40 @@ export class CoreUnauthenticatedSite {
* @returns Promise resolved with public config. Rejected with an object if error, see CoreWSProvider.callAjax. * @returns Promise resolved with public config. Rejected with an object if error, see CoreWSProvider.callAjax.
*/ */
async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise<CoreSitePublicConfigResponse> { async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise<CoreSitePublicConfigResponse> {
const ignoreCache = options.readingStrategy === CoreSitesReadingStrategy.ONLY_NETWORK ||
options.readingStrategy === CoreSitesReadingStrategy.PREFER_NETWORK;
if (!ignoreCache && this.publicConfig) {
return this.publicConfig;
};
if (options.readingStrategy === CoreSitesReadingStrategy.ONLY_CACHE) { if (options.readingStrategy === CoreSitesReadingStrategy.ONLY_CACHE) {
throw new CoreError('Cache not available to read public config'); throw new CoreError('Cache not available to read public config');
} }
return this.requestPublicConfig(); try {
const config = await this.requestPublicConfig();
this.setPublicConfig(config);
return config;
} catch (error) {
if (options.readingStrategy === CoreSitesReadingStrategy.ONLY_NETWORK || !this.publicConfig) {
throw error;
}
return this.publicConfig;
}
}
/**
* Set public config.
*
* @param publicConfig Public config.
*/
setPublicConfig(publicConfig: CoreSitePublicConfigResponse): void {
publicConfig.tool_mobile_disabledfeatures =
CoreTextUtils.treatDisabledFeatures(publicConfig.tool_mobile_disabledfeatures ?? '');
this.publicConfig = publicConfig;
} }
/** /**
@ -262,6 +298,32 @@ export class CoreUnauthenticatedSite {
return !CoreConstants.CONFIG.hideInformativeLinks && !this.isDemoModeSite(); return !CoreConstants.CONFIG.hideInformativeLinks && !this.isDemoModeSite();
} }
/**
* Check if a certain feature is disabled in the site.
*
* @param name Name of the feature to check.
* @returns Whether it's disabled.
*/
isFeatureDisabled(name: string): boolean {
const disabledFeatures = this.getDisabledFeatures();
if (!disabledFeatures) {
return false;
}
const regEx = new RegExp('(,|^)' + CoreTextUtils.escapeForRegex(name) + '(,|$)', 'g');
return !!disabledFeatures.match(regEx);
}
/**
* Get disabled features string.
*
* @returns Disabled features.
*/
protected getDisabledFeatures(): string | undefined {
return this.publicConfig?.tool_mobile_disabledfeatures;
}
} }
/** /**

View File

@ -17,6 +17,7 @@ import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes
import { CoreLoginHelper, CoreLoginMethod } from '@features/login/services/login-helper'; import { CoreLoginHelper, CoreLoginMethod } from '@features/login/services/login-helper';
import { CoreRedirectPayload } from '@services/navigator'; import { CoreRedirectPayload } from '@services/navigator';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreSitesFactory } from '@services/sites-factory';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
@Component({ @Component({
@ -53,11 +54,11 @@ export class CoreLoginMethodsComponent implements OnInit {
if (this.siteConfig) { if (this.siteConfig) {
this.isBrowserSSO = CoreLoginHelper.isSSOLoginNeeded(this.siteConfig.typeoflogin); this.isBrowserSSO = CoreLoginHelper.isSSOLoginNeeded(this.siteConfig.typeoflogin);
// Identity providers won't be shown if login on browser.
if (!this.isBrowserSSO) { if (!this.isBrowserSSO) {
// Identity providers won't be shown if login on browser. this.identityProviders = await CoreLoginHelper.getValidIdentityProvidersForSite(
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig); CoreSitesFactory.makeUnauthenticatedSite(this.siteUrl, this.siteConfig),
);
this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
} }
if (this.reconnect) { if (this.reconnect) {

View File

@ -20,7 +20,7 @@
</ion-header> </ion-header>
<ion-content class="ion-padding limited-width"> <ion-content class="ion-padding limited-width">
<core-loading [hideUntil]="pageLoaded"> <core-loading [hideUntil]="pageLoaded">
<ng-container *ngIf="!siteCheckError && site"> <ng-container *ngIf="!siteCheckError && site && credForm">
<div class="ion-text-wrap ion-text-center core-login-info-box"> <div class="ion-text-wrap ion-text-center core-login-info-box">
<div class="core-login-site"> <div class="core-login-site">
<div class="core-login-site-logo" *ngIf="logoUrl"> <div class="core-login-site-logo" *ngIf="logoUrl">

View File

@ -21,7 +21,7 @@ import { CoreApp } from '@services/app';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
import { CoreSiteCheckResponse, CoreSites } from '@services/sites'; import { CoreSiteCheckResponse, CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CoreLoginHelper, CoreLoginHelperProvider } from '@features/login/services/login-helper';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreSitePublicConfigResponse, CoreUnauthenticatedSite } from '@classes/sites/unauthenticated-site'; import { CoreSitePublicConfigResponse, CoreUnauthenticatedSite } from '@classes/sites/unauthenticated-site';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
@ -86,12 +86,12 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
this.siteConfig = this.siteCheck.config; this.siteConfig = this.siteCheck.config;
} }
this.site = CoreSitesFactory.makeUnauthenticatedSite(siteUrl); this.site = CoreSitesFactory.makeUnauthenticatedSite(siteUrl, this.siteConfig);
this.logoUrl = this.site.getLogoUrl(this.siteConfig); this.logoUrl = this.site.getLogoUrl(this.siteConfig);
this.urlToOpen = CoreNavigator.getRouteParam('urlToOpen'); this.urlToOpen = CoreNavigator.getRouteParam('urlToOpen');
this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.siteConfig); this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.site, this.siteConfig);
this.displaySiteUrl = this.site.shouldDisplayInformativeLinks(); this.displaySiteUrl = this.site.shouldDisplayInformativeLinks();
this.siteName = (await this.site.getSiteName()) || CoreNavigator.getRouteParam('siteName'); this.siteName = await this.site.getSiteName();
} catch (error) { } catch (error) {
CoreDomUtils.showErrorModal(error); CoreDomUtils.showErrorModal(error);
@ -158,11 +158,12 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
try { try {
if (!this.siteCheck) { if (!this.siteCheck) {
this.siteCheck = await CoreSites.checkSite(this.site.siteUrl, protocol); this.siteCheck = await CoreSites.checkSite(this.site.siteUrl, protocol);
this.siteCheck.config && this.site.setPublicConfig(this.siteCheck.config);
} }
this.site.setURL(this.siteCheck.siteUrl); this.site.setURL(this.siteCheck.siteUrl);
this.siteConfig = this.siteCheck.config; this.siteConfig = this.siteCheck.config;
this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.siteConfig); this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.site, this.siteConfig);
await this.treatSiteConfig(); await this.treatSiteConfig();
@ -198,10 +199,9 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype); this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype);
} }
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);
this.canSignup = this.siteConfig.registerauth == 'email' && this.canSignup = this.siteConfig.registerauth == 'email' &&
!CoreLoginHelper.isEmailSignupDisabled(this.siteConfig, disabledFeatures); !this.site.isFeatureDisabled(CoreLoginHelperProvider.EMAIL_SIGNUP_FEATURE_NAME);
this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig, disabledFeatures); this.showForgottenPassword = !this.site.isFeatureDisabled(CoreLoginHelperProvider.FORGOTTEN_PASSWORD_FEATURE_NAME);
this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML( this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML(
!!this.supportConfig?.canContactSupport(), !!this.supportConfig?.canContactSupport(),
this.showForgottenPassword, this.showForgottenPassword,

View File

@ -77,7 +77,7 @@
</form> </form>
<!-- Signup form. --> <!-- Signup form. -->
<form *ngIf="!ageDigitalConsentVerification" [formGroup]="signupForm" (ngSubmit)="create($event)" #signupFormEl> <form *ngIf="!ageDigitalConsentVerification && site" [formGroup]="signupForm" (ngSubmit)="create($event)" #signupFormEl>
<ion-item class="ion-text-wrap ion-text-center"> <ion-item class="ion-text-wrap ion-text-center">
<ion-label> <ion-label>

View File

@ -15,7 +15,6 @@
import { Component, ViewChild, ElementRef, OnInit, ChangeDetectorRef } from '@angular/core'; import { Component, ViewChild, ElementRef, OnInit, ChangeDetectorRef } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreCountry, CoreUtils } from '@services/utils/utils'; import { CoreCountry, CoreUtils } from '@services/utils/utils';
@ -28,6 +27,7 @@ import {
AuthEmailSignupProfileFieldsCategory, AuthEmailSignupProfileFieldsCategory,
AuthEmailSignupSettings, AuthEmailSignupSettings,
CoreLoginHelper, CoreLoginHelper,
CoreLoginHelperProvider,
} from '@features/login/services/login-helper'; } from '@features/login/services/login-helper';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreForms } from '@singletons/form'; import { CoreForms } from '@singletons/form';
@ -163,7 +163,7 @@ export class CoreLoginEmailSignupPage implements OnInit {
protected async fetchData(): Promise<void> { protected async fetchData(): Promise<void> {
try { try {
// Get site config. // Get site config.
this.siteConfig = await CoreSites.getSitePublicConfig(this.site.getURL()); this.siteConfig = await this.site.getPublicConfig();
this.signupUrl = CorePath.concatenatePaths(this.siteConfig.httpswwwroot, 'login/signup.php'); this.signupUrl = CorePath.concatenatePaths(this.siteConfig.httpswwwroot, 'login/signup.php');
const configValid = await this.treatSiteConfig(); const configValid = await this.treatSiteConfig();
@ -238,7 +238,10 @@ export class CoreLoginEmailSignupPage implements OnInit {
* @returns True if success. * @returns True if success.
*/ */
protected async treatSiteConfig(): Promise<boolean> { protected async treatSiteConfig(): Promise<boolean> {
if (this.siteConfig?.registerauth == 'email' && !CoreLoginHelper.isEmailSignupDisabled(this.siteConfig)) { if (
this.siteConfig?.registerauth == 'email' &&
!this.site.isFeatureDisabled(CoreLoginHelperProvider.EMAIL_SIGNUP_FEATURE_NAME)
) {
this.siteName = await this.site.getSiteName(); this.siteName = await this.site.getSiteName();
this.authInstructions = this.siteConfig.authinstructions; this.authInstructions = this.siteConfig.authinstructions;

View File

@ -21,9 +21,10 @@ import { Translate } from '@singletons';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreForms } from '@singletons/form'; import { CoreForms } from '@singletons/form';
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { CoreSitePublicConfigResponse } from '@classes/sites/unauthenticated-site'; import { CoreSitePublicConfigResponse, CoreUnauthenticatedSite } from '@classes/sites/unauthenticated-site';
import { CoreUserSupportConfig } from '@features/user/classes/support/support-config'; import { CoreUserSupportConfig } from '@features/user/classes/support/support-config';
import { CoreUserGuestSupportConfig } from '@features/user/classes/support/guest-support-config'; import { CoreUserGuestSupportConfig } from '@features/user/classes/support/guest-support-config';
import { CoreSitesFactory } from '@services/sites-factory';
/** /**
* Page to recover a forgotten password. * Page to recover a forgotten password.
@ -37,7 +38,7 @@ export class CoreLoginForgottenPasswordPage implements OnInit {
@ViewChild('resetPasswordForm') formElement?: ElementRef; @ViewChild('resetPasswordForm') formElement?: ElementRef;
myForm!: FormGroup; myForm!: FormGroup;
siteUrl!: string; site!: CoreUnauthenticatedSite;
autoFocus!: boolean; autoFocus!: boolean;
supportConfig?: CoreUserSupportConfig; supportConfig?: CoreUserSupportConfig;
canContactSupport?: boolean; canContactSupport?: boolean;
@ -59,14 +60,14 @@ export class CoreLoginForgottenPasswordPage implements OnInit {
const siteConfig = CoreNavigator.getRouteParam<CoreSitePublicConfigResponse>('siteConfig'); const siteConfig = CoreNavigator.getRouteParam<CoreSitePublicConfigResponse>('siteConfig');
this.siteUrl = siteUrl; this.site = CoreSitesFactory.makeUnauthenticatedSite(siteUrl, siteConfig);
this.autoFocus = CorePlatform.is('tablet'); this.autoFocus = CorePlatform.is('tablet');
this.myForm = this.formBuilder.group({ this.myForm = this.formBuilder.group({
field: ['username', Validators.required], field: ['username', Validators.required],
value: [CoreNavigator.getRouteParam<string>('username') || '', Validators.required], value: [CoreNavigator.getRouteParam<string>('username') || '', Validators.required],
}); });
this.supportConfig = siteConfig && new CoreUserGuestSupportConfig(siteConfig); this.supportConfig = siteConfig && new CoreUserGuestSupportConfig(this.site, siteConfig);
this.canContactSupport = this.supportConfig?.canContactSupport(); this.canContactSupport = this.supportConfig?.canContactSupport();
this.wasPasswordResetRequestedRecently = await CoreLoginHelper.wasPasswordResetRequestedRecently(siteUrl); this.wasPasswordResetRequestedRecently = await CoreLoginHelper.wasPasswordResetRequestedRecently(siteUrl);
} }
@ -94,7 +95,7 @@ export class CoreLoginForgottenPasswordPage implements OnInit {
try { try {
const response = await CoreLoginHelper.requestPasswordReset( const response = await CoreLoginHelper.requestPasswordReset(
this.siteUrl, this.site.getURL(),
isMail ? '' : value, isMail ? '' : value,
isMail ? value : '', isMail ? value : '',
); );
@ -115,7 +116,7 @@ export class CoreLoginForgottenPasswordPage implements OnInit {
await CoreDomUtils.showAlert(Translate.instant('core.success'), response.notice); await CoreDomUtils.showAlert(Translate.instant('core.success'), response.notice);
await CoreNavigator.back(); await CoreNavigator.back();
await CoreLoginHelper.passwordResetRequested(this.siteUrl); await CoreLoginHelper.passwordResetRequested(this.site.getURL());
} }
} catch (error) { } catch (error) {
CoreDomUtils.showErrorModal(error); CoreDomUtils.showErrorModal(error);

View File

@ -20,7 +20,7 @@ import { CoreNetwork } from '@services/network';
import { CoreSiteBasicInfo, CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSiteBasicInfo, CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CoreLoginHelper, CoreLoginHelperProvider } from '@features/login/services/login-helper';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
@ -171,7 +171,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
return; return;
} }
this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig); this.showForgottenPassword = !this.site.isFeatureDisabled(CoreLoginHelperProvider.FORGOTTEN_PASSWORD_FEATURE_NAME);
this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML( this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML(
!!this.supportConfig?.canContactSupport(), !!this.supportConfig?.canContactSupport(),
this.showForgottenPassword, this.showForgottenPassword,

View File

@ -120,7 +120,7 @@
<!-- Template site selector. --> <!-- Template site selector. -->
<ng-template #sitelisting let-site="site"> <ng-template #sitelisting let-site="site">
<ion-item button (click)="connect(site.url, $event, site)" [ngClass]="site.className" [attr.aria-label]="site.name" [detail]="true"> <ion-item button (click)="connect(site.url, $event)" [ngClass]="site.className" [attr.aria-label]="site.name" [detail]="true">
<ion-thumbnail *ngIf="siteFinderSettings.displayimage" slot="start"> <ion-thumbnail *ngIf="siteFinderSettings.displayimage" slot="start">
<img [src]="site.imageurl" *ngIf="site.imageurl" onError="this.src='assets/icon/icon.png'" alt="" role="presentation"> <img [src]="site.imageurl" *ngIf="site.imageurl" onError="this.src='assets/icon/icon.png'" alt="" role="presentation">
<img src="assets/icon/icon.png" *ngIf="!site.imageurl" class="core-login-default-icon" alt="" role="presentation"> <img src="assets/icon/icon.png" *ngIf="!site.imageurl" class="core-login-default-icon" alt="" role="presentation">

View File

@ -278,10 +278,9 @@ export class CoreLoginSitePage implements OnInit {
* *
* @param url The URL to connect to. * @param url The URL to connect to.
* @param e Event (if any). * @param e Event (if any).
* @param foundSite The site clicked, if any, from the found sites list.
* @returns Promise resolved when done. * @returns Promise resolved when done.
*/ */
async connect(url: string, e?: Event, foundSite?: CoreLoginSiteInfoExtended): Promise<void> { async connect(url: string, e?: Event): Promise<void> {
e?.preventDefault(); e?.preventDefault();
e?.stopPropagation(); e?.stopPropagation();
@ -341,7 +340,7 @@ export class CoreLoginSitePage implements OnInit {
} }
} }
await this.login(checkResult, foundSite); await this.login(checkResult);
modal.dismiss(); modal.dismiss();
} }
@ -381,23 +380,17 @@ export class CoreLoginSitePage implements OnInit {
* Process login to a site. * Process login to a site.
* *
* @param siteCheck Response obtained from the site check request. * @param siteCheck Response obtained from the site check request.
* @param foundSite The site clicked, if any, from the found sites list.
* *
* @returns Promise resolved after logging in. * @returns Promise resolved after logging in.
*/ */
protected async login(siteCheck: CoreSiteCheckResponse, foundSite?: CoreLoginSiteInfoExtended): Promise<void> { protected async login(siteCheck: CoreSiteCheckResponse): Promise<void> {
try { try {
await CoreSites.checkApplication(siteCheck.config); await CoreSites.checkApplication(siteCheck.config);
CoreForms.triggerFormSubmittedEvent(this.formElement, true); CoreForms.triggerFormSubmittedEvent(this.formElement, true);
const pageParams = { siteCheck };
if (foundSite && !this.fixedSites) {
pageParams['siteName'] = foundSite.name;
}
CoreNavigator.navigate('/login/credentials', { CoreNavigator.navigate('/login/credentials', {
params: pageParams, params: { siteCheck },
}); });
} catch { } catch {
// Ignore errors. // Ignore errors.

View File

@ -45,6 +45,7 @@ import {
CoreSiteIdentityProvider, CoreSiteIdentityProvider,
CoreSitePublicConfigResponse, CoreSitePublicConfigResponse,
CoreSiteQRCodeType, CoreSiteQRCodeType,
CoreUnauthenticatedSite,
TypeOfLogin, TypeOfLogin,
} from '@classes/sites/unauthenticated-site'; } from '@classes/sites/unauthenticated-site';
@ -62,6 +63,10 @@ export class CoreLoginHelperProvider {
static readonly FAQ_QRCODE_INFO_DONE = 'qrcode_info_done'; static readonly FAQ_QRCODE_INFO_DONE = 'qrcode_info_done';
static readonly FAQ_URL_IMAGE_HTML = '<img src="assets/img/login/faq_url.png" role="presentation" alt="">'; static readonly FAQ_URL_IMAGE_HTML = '<img src="assets/img/login/faq_url.png" role="presentation" alt="">';
static readonly FAQ_QRCODE_IMAGE_HTML = '<img src="assets/img/login/faq_qrcode.png" role="presentation" alt="">'; static readonly FAQ_QRCODE_IMAGE_HTML = '<img src="assets/img/login/faq_qrcode.png" role="presentation" alt="">';
static readonly EMAIL_SIGNUP_FEATURE_NAME = 'CoreLoginEmailSignup';
static readonly FORGOTTEN_PASSWORD_FEATURE_NAME = 'NoDelegate_ForgottenPassword';
static readonly IDENTITY_PROVIDERS_FEATURE_NAME = 'NoDelegate_IdentityProviders';
static readonly IDENTITY_PROVIDER_FEATURE_NAME_PREFIX = 'NoDelegate_IdentityProvider_';
protected logger: CoreLogger; protected logger: CoreLogger;
protected sessionExpiredCheckingSite: Record<string, boolean> = {}; protected sessionExpiredCheckingSite: Record<string, boolean> = {};
@ -238,6 +243,7 @@ export class CoreLoginHelperProvider {
* *
* @param config Site public config. * @param config Site public config.
* @returns Disabled features. * @returns Disabled features.
* @deprecated since 4.4. No longer needed.
*/ */
getDisabledFeatures(config?: CoreSitePublicConfigResponse): string { getDisabledFeatures(config?: CoreSitePublicConfigResponse): string {
const disabledFeatures = config?.tool_mobile_disabledfeatures; const disabledFeatures = config?.tool_mobile_disabledfeatures;
@ -307,7 +313,7 @@ export class CoreLoginHelperProvider {
* *
* @param config Site public config. * @param config Site public config.
* @returns Logo URL. * @returns Logo URL.
* @deprecated since 4.2. Please use getLogoUrl in a site instance. * @deprecated since 4.4. Please use getLogoUrl in a site instance.
*/ */
getLogoUrl(config: CoreSitePublicConfigResponse): string | undefined { getLogoUrl(config: CoreSitePublicConfigResponse): string | undefined {
return !CoreConstants.CONFIG.forceLoginLogo && config ? (config.logourl || config.compactlogourl) : undefined; return !CoreConstants.CONFIG.forceLoginLogo && config ? (config.logourl || config.compactlogourl) : undefined;
@ -404,14 +410,56 @@ export class CoreLoginHelperProvider {
* Get the valid identity providers from a site config. * Get the valid identity providers from a site config.
* *
* @param siteConfig Site's public config. * @param siteConfig Site's public config.
* @param disabledFeatures List of disabled features already treated. If not provided it will be calculated.
* @returns Valid identity providers. * @returns Valid identity providers.
* @deprecated since 4.4. Please use getValidIdentityProvidersForSite instead.
*/ */
getValidIdentityProviders(siteConfig?: CoreSitePublicConfigResponse, disabledFeatures?: string): CoreSiteIdentityProvider[] { getValidIdentityProviders(siteConfig?: CoreSitePublicConfigResponse): CoreSiteIdentityProvider[] {
if (!siteConfig) { if (!siteConfig) {
return []; return [];
} }
if (this.isFeatureDisabled('NoDelegate_IdentityProviders', siteConfig, disabledFeatures)) { // eslint-disable-next-line deprecation/deprecation
if (this.isFeatureDisabled(CoreLoginHelperProvider.IDENTITY_PROVIDERS_FEATURE_NAME, siteConfig)) {
// Identity providers are disabled, return an empty list.
return [];
}
const validProviders: CoreSiteIdentityProvider[] = [];
const httpUrl = CorePath.concatenatePaths(siteConfig.wwwroot, 'auth/oauth2/');
const httpsUrl = CorePath.concatenatePaths(siteConfig.httpswwwroot, 'auth/oauth2/');
if (siteConfig.identityproviders && siteConfig.identityproviders.length) {
siteConfig.identityproviders.forEach((provider) => {
const urlParams = CoreUrlUtils.extractUrlParams(provider.url);
if (
provider.url &&
(provider.url.indexOf(httpsUrl) != -1 || provider.url.indexOf(httpUrl) != -1) &&
!this.isFeatureDisabled( // eslint-disable-line deprecation/deprecation
CoreLoginHelperProvider.IDENTITY_PROVIDER_FEATURE_NAME_PREFIX + urlParams.id,
siteConfig,
)
) {
validProviders.push(provider);
}
});
}
return validProviders;
}
/**
* Get the valid identity providers from a site config.
*
* @param site Site instance.
* @returns Valid identity providers.
*/
async getValidIdentityProvidersForSite(site: CoreUnauthenticatedSite): Promise<CoreSiteIdentityProvider[]> {
const siteConfig = await CoreUtils.ignoreErrors(site.getPublicConfig());
if (!siteConfig) {
return [];
}
if (site.isFeatureDisabled(CoreLoginHelperProvider.IDENTITY_PROVIDERS_FEATURE_NAME)) {
// Identity providers are disabled, return an empty list. // Identity providers are disabled, return an empty list.
return []; return [];
} }
@ -425,7 +473,7 @@ export class CoreLoginHelperProvider {
const urlParams = CoreUrlUtils.extractUrlParams(provider.url); const urlParams = CoreUrlUtils.extractUrlParams(provider.url);
if (provider.url && (provider.url.indexOf(httpsUrl) != -1 || provider.url.indexOf(httpUrl) != -1) && if (provider.url && (provider.url.indexOf(httpsUrl) != -1 || provider.url.indexOf(httpUrl) != -1) &&
!this.isFeatureDisabled('NoDelegate_IdentityProvider_' + urlParams.id, siteConfig, disabledFeatures)) { !site.isFeatureDisabled(CoreLoginHelperProvider.IDENTITY_PROVIDER_FEATURE_NAME_PREFIX + urlParams.id)) {
validProviders.push(provider); validProviders.push(provider);
} }
}); });
@ -518,11 +566,12 @@ export class CoreLoginHelperProvider {
* Given a site public config, check if email signup is disabled. * Given a site public config, check if email signup is disabled.
* *
* @param config Site public config. * @param config Site public config.
* @param disabledFeatures List of disabled features already treated. If not provided it will be calculated.
* @returns Whether email signup is disabled. * @returns Whether email signup is disabled.
* @deprecated since 4.4. Please use isFeatureDisabled in a site instance.
*/ */
isEmailSignupDisabled(config?: CoreSitePublicConfigResponse, disabledFeatures?: string): boolean { isEmailSignupDisabled(config?: CoreSitePublicConfigResponse): boolean {
return this.isFeatureDisabled('CoreLoginEmailSignup', config, disabledFeatures); // eslint-disable-next-line deprecation/deprecation
return this.isFeatureDisabled(CoreLoginHelperProvider.EMAIL_SIGNUP_FEATURE_NAME, config);
} }
/** /**
@ -530,17 +579,12 @@ export class CoreLoginHelperProvider {
* *
* @param feature Feature to check. * @param feature Feature to check.
* @param config Site public config. * @param config Site public config.
* @param disabledFeatures List of disabled features already treated. If not provided it will be calculated.
* @returns Whether email signup is disabled. * @returns Whether email signup is disabled.
* @deprecated since 4.4. Please use isFeatureDisabled in a site instance.
*/ */
isFeatureDisabled(feature: string, config?: CoreSitePublicConfigResponse, disabledFeatures?: string): boolean { isFeatureDisabled(feature: string, config?: CoreSitePublicConfigResponse): boolean {
if (disabledFeatures === undefined) { // eslint-disable-next-line deprecation/deprecation
disabledFeatures = this.getDisabledFeatures(config); return this.isFeatureDisabled(feature, config);
}
const regEx = new RegExp('(,|^)' + feature + '(,|$)', 'g');
return !!disabledFeatures.match(regEx);
} }
/** /**
@ -568,11 +612,12 @@ export class CoreLoginHelperProvider {
* Given a site public config, check if forgotten password is disabled. * Given a site public config, check if forgotten password is disabled.
* *
* @param config Site public config. * @param config Site public config.
* @param disabledFeatures List of disabled features already treated. If not provided it will be calculated.
* @returns Whether it's disabled. * @returns Whether it's disabled.
* @deprecated since 4.4. Please use isFeatureDisabled in a site instance.
*/ */
isForgottenPasswordDisabled(config?: CoreSitePublicConfigResponse, disabledFeatures?: string): boolean { isForgottenPasswordDisabled(config?: CoreSitePublicConfigResponse): boolean {
return this.isFeatureDisabled('NoDelegate_ForgottenPassword', config, disabledFeatures); // eslint-disable-next-line deprecation/deprecation
return this.isFeatureDisabled(CoreLoginHelperProvider.FORGOTTEN_PASSWORD_FEATURE_NAME, config);
} }
/** /**

View File

@ -842,7 +842,7 @@ export class CorePushNotificationsProvider {
result.siteid, result.siteid,
result.siteurl, result.siteurl,
result.token, result.token,
CoreTextUtils.parseJSON<CoreSiteInfo | null>(result.info, null) || undefined, { info: CoreTextUtils.parseJSON<CoreSiteInfo | null>(result.info, null) || undefined },
); );
await this.unregisterDeviceOnMoodle(tmpSite); await this.unregisterDeviceOnMoodle(tmpSite);

View File

@ -16,6 +16,7 @@ import { CoreSite } from '@classes/sites/site';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUserSupportConfig } from './support-config'; import { CoreUserSupportConfig } from './support-config';
import { CoreSiteConfigSupportAvailability } from '@classes/sites/unauthenticated-site'; import { CoreSiteConfigSupportAvailability } from '@classes/sites/unauthenticated-site';
import { CoreCandidateSite } from '@classes/sites/candidate-site';
/** /**
* Support config for an authenticated user. * Support config for an authenticated user.
@ -31,9 +32,9 @@ export class CoreUserAuthenticatedSupportConfig extends CoreUserSupportConfig {
return new CoreUserAuthenticatedSupportConfig(CoreSites.getRequiredCurrentSite()); return new CoreUserAuthenticatedSupportConfig(CoreSites.getRequiredCurrentSite());
} }
private site: CoreSite; private site: CoreSite | CoreCandidateSite;
constructor(site: CoreSite) { constructor(site: CoreSite | CoreCandidateSite) {
super(); super();
this.site = site; this.site = site;
@ -48,7 +49,7 @@ export class CoreUserAuthenticatedSupportConfig extends CoreUserSupportConfig {
} }
if (this.site.isVersionGreaterEqualThan('4.1')) { if (this.site.isVersionGreaterEqualThan('4.1')) {
if (!this.site.config || !('supportavailability' in this.site.config)) { if (!('config' in this.site) || !this.site.config || !('supportavailability' in this.site.config)) {
return false; return false;
} }
@ -78,8 +79,10 @@ export class CoreUserAuthenticatedSupportConfig extends CoreUserSupportConfig {
* @inheritdoc * @inheritdoc
*/ */
protected buildSupportPageUrl(): string { protected buildSupportPageUrl(): string {
return this.site.config?.supportpage?.trim() const config = 'config' in this.site ? this.site.config : undefined;
|| `${this.site.config?.httpswwwroot ?? this.site.config?.wwwroot ?? this.site.siteUrl}/user/contactsitesupport.php`;
return config?.supportpage?.trim()
|| `${config?.httpswwwroot ?? config?.wwwroot ?? this.site.siteUrl}/user/contactsitesupport.php`;
} }
} }

View File

@ -12,12 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CoreSiteConfigSupportAvailability, CoreSitePublicConfigResponse } from '@classes/sites/unauthenticated-site'; import {
import { CoreLoginHelper } from '@features/login/services/login-helper'; CoreSiteConfigSupportAvailability,
CoreSitePublicConfigResponse,
CoreUnauthenticatedSite,
} from '@classes/sites/unauthenticated-site';
import { CoreUserNullSupportConfig } from '@features/user/classes/support/null-support-config'; import { CoreUserNullSupportConfig } from '@features/user/classes/support/null-support-config';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreUserSupportConfig } from './support-config'; import { CoreUserSupportConfig } from './support-config';
import { CoreSitesFactory } from '@services/sites-factory';
/** /**
* Support config for a guest user. * Support config for a guest user.
@ -37,14 +41,16 @@ export class CoreUserGuestSupportConfig extends CoreUserSupportConfig {
return new CoreUserNullSupportConfig(); return new CoreUserNullSupportConfig();
} }
return new CoreUserGuestSupportConfig(siteConfig); return new CoreUserGuestSupportConfig(CoreSitesFactory.makeUnauthenticatedSite(siteUrl, siteConfig), siteConfig);
} }
private site: CoreUnauthenticatedSite;
private config: CoreSitePublicConfigResponse; private config: CoreSitePublicConfigResponse;
constructor(config: CoreSitePublicConfigResponse) { constructor(site: CoreUnauthenticatedSite, config: CoreSitePublicConfigResponse) {
super(); super();
this.site = site;
this.config = config; this.config = config;
} }
@ -52,7 +58,7 @@ export class CoreUserGuestSupportConfig extends CoreUserSupportConfig {
* @inheritdoc * @inheritdoc
*/ */
canContactSupport(): boolean { canContactSupport(): boolean {
if (CoreLoginHelper.isFeatureDisabled('NoDelegate_CoreUserSupport', this.config)) { if (this.site.isFeatureDisabled('NoDelegate_CoreUserSupport')) {
return false; return false;
} }

View File

@ -13,10 +13,10 @@
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCandidateSite } from '@classes/sites/candidate-site'; import { CoreCandidateSite, CoreCandidateSiteOptionalData } from '@classes/sites/candidate-site';
import { CoreSite, CoreSiteConfig } from '@classes/sites/site'; import { CoreSite, CoreSiteOptionalData } from '@classes/sites/site';
import { CoreUnauthenticatedSite, CoreSiteInfo } from '@classes/sites/unauthenticated-site'; import { CoreUnauthenticatedSite, CoreSitePublicConfigResponse } from '@classes/sites/unauthenticated-site';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
/* /*
@ -31,22 +31,16 @@ export class CoreSitesFactoryService {
* @param id Site ID. * @param id Site ID.
* @param siteUrl Site URL. * @param siteUrl Site URL.
* @param token Site's WS token. * @param token Site's WS token.
* @param info Site info. * @param otherData Other data.
* @param privateToken Private token.
* @param config Site public config.
* @param loggedOut Whether user is logged out.
* @returns Site instance. * @returns Site instance.
*/ */
makeSite( makeSite(
id: string, id: string,
siteUrl: string, siteUrl: string,
token: string, token: string,
info?: CoreSiteInfo, otherData: CoreSiteOptionalData = {},
privateToken?: string,
config?: CoreSiteConfig,
loggedOut?: boolean,
): CoreSite { ): CoreSite {
return new CoreSite(id, siteUrl, token, info, privateToken, config, loggedOut); return new CoreSite(id, siteUrl, token, otherData);
} }
/** /**
@ -54,21 +48,22 @@ export class CoreSitesFactoryService {
* *
* @param siteUrl Site URL. * @param siteUrl Site URL.
* @param token Site's WS token. * @param token Site's WS token.
* @param privateToken Private token. * @param options Other options.
* @returns Candidate site instance. * @returns Candidate site instance.
*/ */
makeCandidateSite(siteUrl: string, token: string, privateToken?: string): CoreCandidateSite { makeCandidateSite(siteUrl: string, token: string, options: CoreCandidateSiteOptionalData = {}): CoreCandidateSite {
return new CoreCandidateSite(siteUrl, token, privateToken); return new CoreCandidateSite(siteUrl, token, options);
} }
/** /**
* Create an unauthenticated site instance. * Create an unauthenticated site instance.
* *
* @param siteUrl Site URL. * @param siteUrl Site URL.
* @param publicConfig Site public config.
* @returns Unauthenticated site instance. * @returns Unauthenticated site instance.
*/ */
makeUnauthenticatedSite(siteUrl: string): CoreUnauthenticatedSite { makeUnauthenticatedSite(siteUrl: string, publicConfig?: CoreSitePublicConfigResponse): CoreUnauthenticatedSite {
return new CoreUnauthenticatedSite(siteUrl); return new CoreUnauthenticatedSite(siteUrl, publicConfig);
} }
} }

View File

@ -305,7 +305,7 @@ export class CoreSitesProvider {
// Check that the user can authenticate. // Check that the user can authenticate.
if (!config.enablewebservices) { if (!config.enablewebservices) {
throw this.createCannotConnectLoginError(config.httpswwwroot || config.wwwroot, { throw this.createCannotConnectLoginError(config.httpswwwroot || config.wwwroot, {
supportConfig: new CoreUserGuestSupportConfig(config), supportConfig: new CoreUserGuestSupportConfig(temporarySite, config),
errorcode: 'webservicesnotenabled', errorcode: 'webservicesnotenabled',
errorDetails: Translate.instant('core.login.webservicesnotenabled'), errorDetails: Translate.instant('core.login.webservicesnotenabled'),
critical: true, critical: true,
@ -314,7 +314,7 @@ export class CoreSitesProvider {
if (!config.enablemobilewebservice) { if (!config.enablemobilewebservice) {
throw this.createCannotConnectLoginError(config.httpswwwroot || config.wwwroot, { throw this.createCannotConnectLoginError(config.httpswwwroot || config.wwwroot, {
supportConfig: new CoreUserGuestSupportConfig(config), supportConfig: new CoreUserGuestSupportConfig(temporarySite, config),
errorcode: 'mobileservicesnotenabled', errorcode: 'mobileservicesnotenabled',
errorDetails: Translate.instant('core.login.mobileservicesnotenabled'), errorDetails: Translate.instant('core.login.mobileservicesnotenabled'),
critical: true, critical: true,
@ -515,7 +515,7 @@ export class CoreSitesProvider {
} }
// Create a "candidate" site to fetch the site info. // Create a "candidate" site to fetch the site info.
const candidateSite = CoreSitesFactory.makeCandidateSite(siteUrl, token, privateToken); const candidateSite = CoreSitesFactory.makeCandidateSite(siteUrl, token, { privateToken });
let isNewSite = true; let isNewSite = true;
try { try {
@ -544,7 +544,7 @@ export class CoreSitesProvider {
} else { } else {
// New site, set site ID and info. // New site, set site ID and info.
isNewSite = true; isNewSite = true;
site = CoreSitesFactory.makeSite(siteId, siteUrl, token, info, privateToken); site = CoreSitesFactory.makeSite(siteId, siteUrl, token, { info, privateToken });
site.setOAuthId(oauthId); site.setOAuthId(oauthId);
// Create database tables before login and before any WS call. // Create database tables before login and before any WS call.
@ -1172,10 +1172,12 @@ export class CoreSitesProvider {
entry.id, entry.id,
entry.siteUrl, entry.siteUrl,
entry.token, entry.token,
info, {
entry.privateToken, info,
config, privateToken: entry.privateToken,
entry.loggedOut == 1, config,
loggedOut: entry.loggedOut == 1,
},
); );
site.setOAuthId(entry.oauthId || undefined); site.setOAuthId(entry.oauthId || undefined);
@ -1246,8 +1248,10 @@ export class CoreSitesProvider {
await Promise.all(sites.map(async (site) => { await Promise.all(sites.map(async (site) => {
if (!ids || ids.indexOf(site.id) > -1) { if (!ids || ids.indexOf(site.id) > -1) {
const siteName = await CoreSitesFactory.makeUnauthenticatedSite(site.siteUrl).getSiteName();
const siteInfo = site.info ? <CoreSiteInfo> CoreTextUtils.parseJSON(site.info) : undefined; const siteInfo = site.info ? <CoreSiteInfo> CoreTextUtils.parseJSON(site.info) : undefined;
const siteInstance = CoreSitesFactory.makeSite(site.id, site.siteUrl, site.token, { info: siteInfo });
const siteName = await siteInstance.getSiteName();
const basicInfo: CoreSiteBasicInfo = { const basicInfo: CoreSiteBasicInfo = {
id: site.id, id: site.id,

View File

@ -27,7 +27,7 @@ export class CoreSiteStub extends CoreSite {
protected wsStubs: Record<string, unknown> = {}; protected wsStubs: Record<string, unknown> = {};
constructor (fixture: CoreSiteFixture) { constructor (fixture: CoreSiteFixture) {
super(fixture.id, fixture.info.siteurl, '', fixture.info); super(fixture.id, fixture.info.siteurl, '', { info: fixture.info });
this.stubWSResponse<CoreSiteConfigResponse>('tool_mobile_get_config', { this.stubWSResponse<CoreSiteConfigResponse>('tool_mobile_get_config', {
settings: [], settings: [],