MOBILE-4459 core: Support demo mode

main
Dani Palou 2023-11-01 12:08:24 +01:00
parent 38303aadf5
commit d27d3ddec3
17 changed files with 119 additions and 30 deletions

View File

@ -296,14 +296,18 @@ export class CoreSite {
* @returns Site name.
*/
async getSiteName(): Promise<string> {
if (this.isDemoModeSite()) {
return CoreConstants.CONFIG.appname;
}
if (this.infos?.sitename) {
return this.infos?.sitename;
}
// Fallback.
const isSigleFixedSite = await CoreLoginHelper.isSingleFixedSite();
const isSingleFixedSite = await CoreLoginHelper.isSingleFixedSite();
if (isSigleFixedSite) {
if (isSingleFixedSite) {
const sites = await CoreLoginHelper.getAvailableSites();
return sites[0].name;
@ -2459,6 +2463,17 @@ export class CoreSite {
});
}
/**
* Check if the site is a demo mode site.
*
* @returns Whether the site is a demo mode site.
*/
isDemoModeSite(): boolean {
const demoSiteData = CoreLoginHelper.getDemoModeSiteInfo();
return this.containsUrl(demoSiteData?.url);
}
}
/**

View File

@ -27,7 +27,7 @@
<p>
<core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text>
</p>
<p>{{site.siteUrl}}</p>
<p *ngIf="!site.isDemoModeSite">{{site.siteUrl}}</p>
</ion-label>
</ion-item>
</ion-list>

View File

@ -28,8 +28,10 @@
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
[siteId]="accountsList.currentSite.id"></core-format-text>
</h2>
<p><a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">{{
accountsList.currentSite.siteUrlWithoutProtocol }}</a>
<p *ngIf="!accountsList.currentSite.isDemoModeSite">
<a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">
{{ accountsList.currentSite.siteUrlWithoutProtocol }}
</a>
</p>
</ion-label>
</ion-item-divider>
@ -53,7 +55,9 @@
<h2>
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</h2>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
<p *ngIf="!sites[0].isDemoModeSite">
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
</p>
</ion-label>
</ion-item-divider>

View File

@ -32,7 +32,7 @@
<h2 *ngIf="siteName" class="ion-margin-top ion-no-padding core-sitename">
<core-format-text [text]="siteName" [filter]="false"></core-format-text>
</h2>
<p class="core-siteurl">{{siteUrl}}</p>
<p class="core-siteurl" *ngIf="!isDemoModeSite">{{siteUrl}}</p>
</div>
<core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && loginAttempts >= 3"

View File

@ -61,6 +61,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
exceededAttemptsHTML?: SafeHtml | string | null;
siteConfig?: CoreSitePublicConfigResponse;
siteCheckError = '';
isDemoModeSite = false;
protected siteCheck?: CoreSiteCheckResponse;
protected eventThrown = false;
@ -89,8 +90,11 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
this.siteConfig = this.siteCheck.config;
}
this.siteName = CoreNavigator.getRouteParam('siteName');
this.logoUrl = !CoreConstants.CONFIG.forceLoginLogo && CoreNavigator.getRouteParam('logoUrl') || undefined;
this.isDemoModeSite = CoreLoginHelper.isDemoModeSite(this.siteUrl);
this.siteName = this.isDemoModeSite ? CoreConstants.CONFIG.appname : CoreNavigator.getRouteParam('siteName');
this.logoUrl = !CoreConstants.CONFIG.forceLoginLogo && !this.isDemoModeSite ?
CoreNavigator.getRouteParam('logoUrl') :
undefined;
this.urlToOpen = CoreNavigator.getRouteParam('urlToOpen');
this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.siteConfig);
} catch (error) {
@ -191,9 +195,13 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
return;
}
this.siteName = this.siteConfig.sitename;
this.logoUrl = CoreLoginHelper.getLogoUrl(this.siteConfig);
this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype);
if (this.isDemoModeSite) {
this.showScanQR = false;
} else {
this.siteName = this.siteConfig.sitename;
this.logoUrl = CoreLoginHelper.getLogoUrl(this.siteConfig);
this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype);
}
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);
this.canSignup = this.siteConfig.registerauth == 'email' &&

View File

@ -82,7 +82,7 @@
<ion-item class="ion-text-wrap ion-text-center">
<ion-label>
<!-- If no sitename show big siteurl. -->
<p *ngIf="!siteName" class="ion-padding item-heading">{{siteUrl}}</p>
<p *ngIf="!siteName && !isDemoModeSite" class="ion-padding item-heading">{{siteUrl}}</p>
<!-- If sitename, show big sitename and small siteurl. -->
<p *ngIf="siteName" class="ion-padding item-heading">
<core-format-text [text]="siteName" [filter]="false"></core-format-text>

View File

@ -34,6 +34,7 @@ import { CoreForms } from '@singletons/form';
import { CoreRecaptchaComponent } from '@components/recaptcha/recaptcha';
import { CorePath } from '@singletons/path';
import { CoreDom } from '@singletons/dom';
import { CoreConstants } from '@/core/constants';
/**
* Page to signup using email.
@ -51,6 +52,7 @@ export class CoreLoginEmailSignupPage implements OnInit {
signupForm: FormGroup;
siteUrl!: string;
isDemoModeSite = false;
siteConfig?: CoreSitePublicConfigResponse;
siteName?: string;
authInstructions = '';
@ -127,6 +129,7 @@ export class CoreLoginEmailSignupPage implements OnInit {
}
this.siteUrl = siteUrl;
this.isDemoModeSite = CoreLoginHelper.isDemoModeSite(this.siteUrl);
// Fetch the data.
this.fetchData().finally(() => {
@ -235,7 +238,7 @@ export class CoreLoginEmailSignupPage implements OnInit {
*/
protected treatSiteConfig(): boolean {
if (this.siteConfig?.registerauth == 'email' && !CoreLoginHelper.isEmailSignupDisabled(this.siteConfig)) {
this.siteName = this.siteConfig.sitename;
this.siteName = this.isDemoModeSite ? CoreConstants.CONFIG.appname : this.siteConfig.sitename;
this.authInstructions = this.siteConfig.authinstructions;
this.ageDigitalConsentVerification = this.siteConfig.agedigitalconsentverification;
this.supportName = this.siteConfig.supportname;

View File

@ -40,7 +40,7 @@
<p *ngIf="siteInfo?.siteName" class="ion-no-margin ion-no-padding core-sitename">
<core-format-text [text]="siteInfo?.siteName" [filter]="false"></core-format-text>
</p>
<p class="core-siteurl">{{siteUrl}}</p>
<p class="core-siteurl" *ngIf="!isDemoModeSite">{{siteUrl}}</p>
</div>
<div class="core-login-user">

View File

@ -46,6 +46,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
credForm: FormGroup;
siteUrl!: string;
isDemoModeSite = false;
logoUrl?: string;
showForgottenPassword = true;
showUserAvatar = false;
@ -101,6 +102,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
}
this.siteUrl = site.getURL();
this.isDemoModeSite = site.isDemoModeSite();
this.siteInfo = {
id: this.siteId,
@ -112,6 +114,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
siteName: await site.getSiteName(),
userpictureurl: site.infos.userpictureurl,
loggedOut: true, // Not used.
isDemoModeSite: this.isDemoModeSite,
};
this.username = site.infos.username;
@ -185,7 +188,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
await CoreSites.checkApplication(this.siteConfig);
this.logoUrl = CoreLoginHelper.getLogoUrl(this.siteConfig);
this.logoUrl = this.isDemoModeSite ? undefined : CoreLoginHelper.getLogoUrl(this.siteConfig);
}
/**

View File

@ -28,7 +28,9 @@
<h2>
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</h2>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
<p *ngIf="!sites[0].isDemoModeSite">
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
</p>
</ion-label>
</ion-item-divider>

View File

@ -374,14 +374,23 @@ export class CoreLoginHelperProvider {
}
/**
* Get Available sites (includes staging sites if are enabled).
* Get Available sites (includes staging sites if are enabled). It doesn't include demo mode site.
*
* @returns Available sites.
*/
async getAvailableSites(): Promise<CoreLoginSiteInfo[]> {
const hasEnabledStagingSites = await CoreSettingsHelper.hasEnabledStagingSites();
return hasEnabledStagingSites ? CoreConstants.CONFIG.sites : CoreConstants.CONFIG.sites.filter(site => !site.staging);
return CoreConstants.CONFIG.sites.filter(site => (!site.staging || hasEnabledStagingSites) && !site.demoMode);
}
/**
* Get demo mode site info. This function doesn't check if demo mode is enabled.
*
* @returns Demo mode site info, undefined if no demo mode site.
*/
getDemoModeSiteInfo(): CoreLoginSiteInfo | undefined {
return CoreConstants.CONFIG.sites.find(site => site.demoMode);
}
/**
@ -453,6 +462,14 @@ export class CoreLoginHelperProvider {
* @returns Path and params.
*/
async getAddSiteRouteInfo(showKeyboard?: boolean): Promise<[string, Params]> {
if (CoreConstants.CONFIG.demoMode) {
const demoModeSite = this.getDemoModeSiteInfo();
if (demoModeSite) {
return ['/login/credentials', { siteUrl: demoModeSite.url }];
}
}
const sites = await this.getAvailableSites();
if (sites.length === 1) {
@ -583,7 +600,10 @@ export class CoreLoginHelperProvider {
const sites = await this.getAvailableSites();
if (sites.length) {
return sites.some((site) => CoreUrl.sameDomainAndPath(siteUrl, site.url));
const demoModeSite = this.getDemoModeSiteInfo();
return sites.some((site) => CoreUrl.sameDomainAndPath(siteUrl, site.url)) ||
(!!demoModeSite && CoreUrl.sameDomainAndPath(siteUrl, demoModeSite.url));
} else if (CoreConstants.CONFIG.multisitesdisplay == 'sitefinder' && CoreConstants.CONFIG.onlyallowlistedsites &&
checkSiteFinder) {
// Call the sites finder to validate the site.
@ -1497,6 +1517,23 @@ export class CoreLoginHelperProvider {
return CoreTextUtils.parseJSON<Record<string, number>>(passwordResetsJson, {});
}
/**
* Check if a URL belongs to the demo mode site.
*
* @returns Whether the URL belongs to the demo mode site.
*/
isDemoModeSite(url: string): boolean {
const demoSiteData = CoreLoginHelper.getDemoModeSiteInfo();
if (!demoSiteData) {
return false;
}
const demoSiteUrl = CoreTextUtils.addEndingSlash(CoreUrlUtils.removeProtocolAndWWW(demoSiteData.url));
url = CoreTextUtils.addEndingSlash(CoreUrlUtils.removeProtocolAndWWW(url));
return demoSiteUrl.indexOf(url) === 0;
}
}
export const CoreLoginHelper = makeSingleton(CoreLoginHelperProvider);

View File

@ -113,7 +113,7 @@ export class CoreMainMenuUserMenuComponent implements OnInit, OnDestroy {
* @returns Promise resolved when done.
*/
protected async loadSiteLogo(currentSite: CoreSite): Promise<void> {
if (CoreConstants.CONFIG.forceLoginLogo) {
if (CoreConstants.CONFIG.forceLoginLogo || currentSite.isDemoModeSite()) {
this.siteLogo = 'assets/img/login_logo.png';
this.siteLogoLoaded = true;

View File

@ -25,8 +25,10 @@
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
[siteId]="accountsList.currentSite.id"></core-format-text>
</p>
<p><a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">{{
accountsList.currentSite.siteUrlWithoutProtocol }}</a>
<p *ngIf="!accountsList.currentSite.isDemoModeSite">
<a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">
{{ accountsList.currentSite.siteUrlWithoutProtocol }}
</a>
</p>
</ion-label>
</ion-item-divider>
@ -46,7 +48,9 @@
<p class="item-heading">
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</p>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
<p *ngIf="!sites[0].isDemoModeSite">
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
</p>
</ion-label>
</ion-item-divider>

View File

@ -58,8 +58,10 @@
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
[siteId]="accountsList.currentSite.id"></core-format-text>
</p>
<p><a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">{{
accountsList.currentSite.siteUrlWithoutProtocol }}</a>
<p *ngIf="!accountsList.currentSite.isDemoModeSite">
<a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">
{{ accountsList.currentSite.siteUrlWithoutProtocol }}
</a>
</p>
</ion-label>
</ion-item-divider>
@ -79,7 +81,9 @@
<p class="item-heading">
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</p>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
<p *ngIf="!sites[0].isDemoModeSite">
<a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a>
</p>
</ion-label>
</ion-item-divider>

View File

@ -25,7 +25,7 @@
<p>
<core-format-text clean="true" [text]="site.siteName" [siteId]="site.id"></core-format-text>
</p>
<p>{{site.siteUrl}}</p>
<p *ngIf="!site.isDemoModeSite">{{site.siteUrl}}</p>
</ion-label>
</ion-item>
</ion-list>

View File

@ -1303,8 +1303,9 @@ export class CoreSitesProvider {
const formattedSites: CoreSiteBasicInfo[] = [];
sites.forEach((site) => {
if (!ids || ids.indexOf(site.id) > -1) {
// Parse info.
const isDemoModeSite = CoreLoginHelper.isDemoModeSite(site.siteUrl);
const siteInfo = site.info ? <CoreSiteInfo> CoreTextUtils.parseJSON(site.info) : undefined;
const basicInfo: CoreSiteBasicInfo = {
id: site.id,
siteUrl: site.siteUrl,
@ -1312,10 +1313,11 @@ export class CoreSitesProvider {
fullname: siteInfo?.fullname,
firstname: siteInfo?.firstname,
lastname: siteInfo?.lastname,
siteName: siteInfo?.sitename,
siteName: isDemoModeSite ? CoreConstants.CONFIG.appname : siteInfo?.sitename,
userpictureurl: siteInfo?.userpictureurl,
siteHomeId: siteInfo?.siteid || 1,
loggedOut: !!site.loggedOut,
isDemoModeSite,
};
formattedSites.push(basicInfo);
}
@ -2195,6 +2197,7 @@ export type CoreSiteBasicInfo = {
badge?: number; // Badge to display in the site.
siteHomeId?: number; // Site home ID.
loggedOut: boolean; // If Site is logged out.
isDemoModeSite: boolean;
};
/**
@ -2288,6 +2291,11 @@ export type CoreLoginSiteInfo = {
* Class to apply to site item.
*/
className?: string;
/**
* Whether the site is for demo mode usage.
*/
demoMode?: boolean;
};
/**

View File

@ -73,4 +73,5 @@ export interface EnvironmentConfig {
disableCallWSInBackground?: boolean; // If true, disable calling WS in background.
callWSInBackgroundExpirationTime?: number; // Ms to consider an entry expired when calling WS in background. Default: 1 week.
disableTokenFile: boolean; // Disable the use of tokenpluginfile.php for downloading files (so it fallbacks to pluginfile.php)
demoMode?: boolean; // Whether to run the app in "demo mode".
}