MOBILE-3846 core: Don't allow using sites not present in config
parent
83d5282852
commit
e9506a106f
|
@ -1902,6 +1902,7 @@
|
|||
"core.login.sitebadgedescription": "local_moodlemobileapp",
|
||||
"core.login.sitehasredirect": "local_moodlemobileapp",
|
||||
"core.login.siteinmaintenance": "local_moodlemobileapp",
|
||||
"core.login.sitenotallowed": "local_moodlemobileapp",
|
||||
"core.login.sitepolicynotagreederror": "local_moodlemobileapp",
|
||||
"core.login.siteurl": "local_moodlemobileapp",
|
||||
"core.login.siteurlrequired": "local_moodlemobileapp",
|
||||
|
|
|
@ -23,6 +23,7 @@ import { CoreAjaxWSError } from './ajaxwserror';
|
|||
import { CoreCaptureError } from './captureerror';
|
||||
import { CoreNetworkError } from './network-error';
|
||||
import { CoreSiteError } from './siteerror';
|
||||
import { CoreErrorWithTitle } from './errorwithtitle';
|
||||
|
||||
export const CORE_ERRORS_CLASSES: Type<unknown>[] = [
|
||||
CoreAjaxError,
|
||||
|
@ -34,4 +35,5 @@ export const CORE_ERRORS_CLASSES: Type<unknown>[] = [
|
|||
CoreSilentError,
|
||||
CoreSiteError,
|
||||
CoreWSError,
|
||||
CoreErrorWithTitle,
|
||||
];
|
||||
|
|
|
@ -12,8 +12,20 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { CoreUpdateManager } from '@services/update-manager';
|
||||
import { CoreError } from './error';
|
||||
|
||||
/**
|
||||
* Error with an explicit title describing the problem (instead of just "Error" or a generic message).
|
||||
* This title should be used to communicate the problem with users, and if it's undefined it should be omitted.
|
||||
*/
|
||||
export class CoreErrorWithTitle extends CoreError {
|
||||
|
||||
title?: string;
|
||||
|
||||
constructor(message?: string, title?: string) {
|
||||
super(message);
|
||||
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
export default async function(): Promise<void> {
|
||||
await CoreUpdateManager.load();
|
||||
}
|
|
@ -108,6 +108,7 @@
|
|||
"sitebadgedescription": "There are {{count}} unread notifications.",
|
||||
"sitehasredirect": "Your site contains at least one HTTP redirect. The app cannot follow redirects, this could be the issue that's preventing the app from connecting to your site.",
|
||||
"siteinmaintenance": "Your site is in maintenance mode",
|
||||
"sitenotallowed": "This site is no longer available.",
|
||||
"sitepolicynotagreederror": "Site policy not agreed.",
|
||||
"siteurl": "Site URL",
|
||||
"siteurlrequired": "Site URL required i.e <i>http://www.yourmoodlesite.org</i>",
|
||||
|
|
|
@ -49,6 +49,10 @@ export class CoreLoginSitesPage implements OnInit {
|
|||
* @return Promise resolved when done.
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
if (CoreNavigator.getRouteBooleanParam('openAddSite')) {
|
||||
this.add();
|
||||
}
|
||||
|
||||
const sites = await CoreUtils.ignoreErrors(CoreSites.getSortedSites(), [] as CoreSiteBasicInfo[]);
|
||||
|
||||
// Remove protocol from the url to show more url text.
|
||||
|
|
|
@ -573,9 +573,10 @@ export class CoreLoginHelperProvider {
|
|||
* Check if a site URL is "allowed". In case the app has fixed sites, only those will be allowed to connect to.
|
||||
*
|
||||
* @param siteUrl Site URL to check.
|
||||
* @param checkSiteFinder Whether to check site finder if needed. Defaults to true.
|
||||
* @return Promise resolved with boolean: whether is one of the fixed sites.
|
||||
*/
|
||||
async isSiteUrlAllowed(siteUrl: string): Promise<boolean> {
|
||||
async isSiteUrlAllowed(siteUrl: string, checkSiteFinder = true): Promise<boolean> {
|
||||
if (this.isFixedUrlSet()) {
|
||||
// Only 1 site allowed.
|
||||
return CoreUrl.sameDomainAndPath(siteUrl, <string> this.getFixedSites());
|
||||
|
@ -583,7 +584,8 @@ export class CoreLoginHelperProvider {
|
|||
const sites = <CoreLoginSiteInfo[]> this.getFixedSites();
|
||||
|
||||
return sites.some((site) => CoreUrl.sameDomainAndPath(siteUrl, site.url));
|
||||
} else if (CoreConstants.CONFIG.multisitesdisplay == 'sitefinder' && CoreConstants.CONFIG.onlyallowlistedsites) {
|
||||
} else if (CoreConstants.CONFIG.multisitesdisplay == 'sitefinder' && CoreConstants.CONFIG.onlyallowlistedsites &&
|
||||
checkSiteFinder) {
|
||||
// Call the sites finder to validate the site.
|
||||
const result = await CoreSites.findSites(siteUrl.replace(/^https?:\/\/|\.\w{2,3}\/?$/g, ''));
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { CoreApp } from '@services/app';
|
||||
import { CoreUpdateManager } from '@services/update-manager';
|
||||
|
||||
export default async function(): Promise<void> {
|
||||
await CoreUpdateManager.donePromise;
|
||||
|
||||
export default function(): void {
|
||||
CoreApp.consumeStorageRedirect();
|
||||
}
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreLang } from '@services/lang';
|
||||
import { CoreLocalNotifications } from '@services/local-notifications';
|
||||
import { CoreUpdateManager } from '@services/update-manager';
|
||||
|
||||
export default async function(): Promise<void> {
|
||||
await Promise.all([
|
||||
CoreFilepool.initialize(),
|
||||
CoreLang.initialize(),
|
||||
CoreLocalNotifications.initialize(),
|
||||
CoreUpdateManager.initialize(),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreUpdateManager } from '@services/update-manager';
|
||||
|
||||
export default async function(): Promise<void> {
|
||||
await CoreUpdateManager.donePromise;
|
||||
|
||||
await CoreSites.restoreSession();
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ import { CoreNetworkError } from '@classes/errors/network-error';
|
|||
import { CoreNavigationOptions } from './navigator';
|
||||
import { CoreSitesFactory } from './sites-factory';
|
||||
import { CoreText } from '@singletons/text';
|
||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreErrorWithTitle } from '@classes/errors/errorwithtitle';
|
||||
|
||||
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
||||
|
||||
|
@ -823,6 +825,11 @@ export class CoreSitesProvider {
|
|||
|
||||
const site = await this.getSite(siteId);
|
||||
|
||||
const siteUrlAllowed = await CoreLoginHelper.isSiteUrlAllowed(site.getURL(), false);
|
||||
if (!siteUrlAllowed) {
|
||||
throw new CoreErrorWithTitle(Translate.instant('core.login.sitenotallowed'));
|
||||
}
|
||||
|
||||
this.currentSite = site;
|
||||
|
||||
if (site.isLoggedOut()) {
|
||||
|
@ -1196,8 +1203,6 @@ export class CoreSitesProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
const db = await this.appDB;
|
||||
|
||||
const promises: Promise<unknown>[] = [];
|
||||
const siteConfig = this.currentSite.getStoredConfig();
|
||||
const siteId = this.currentSite.getId();
|
||||
|
@ -1208,7 +1213,7 @@ export class CoreSitesProvider {
|
|||
promises.push(this.setSiteLoggedOut(siteId, true));
|
||||
}
|
||||
|
||||
promises.push(db.deleteRecords(CURRENT_SITE_TABLE_NAME, { id: 1 }));
|
||||
promises.push(this.removeStoredCurrentSite());
|
||||
|
||||
await CoreUtils.ignoreErrors(Promise.all(promises));
|
||||
|
||||
|
@ -1449,6 +1454,17 @@ export class CoreSitesProvider {
|
|||
return currentSite.siteId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove current site stored in DB.
|
||||
*
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async removeStoredCurrentSite(): Promise<void> {
|
||||
const db = await this.appDB;
|
||||
|
||||
await db.deleteRecords(CURRENT_SITE_TABLE_NAME, { id: 1 });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the public config of a certain site.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,10 @@ import { CoreConstants } from '@/core/constants';
|
|||
import { CoreLogger } from '@singletons/logger';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreH5P } from '@features/h5p/services/h5p';
|
||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreSites } from './sites';
|
||||
import { CoreUtils, PromiseDefer } from './utils/utils';
|
||||
import { CoreApp } from './app';
|
||||
|
||||
const VERSION_APPLIED = 'version_applied';
|
||||
|
||||
|
@ -31,9 +35,20 @@ const VERSION_APPLIED = 'version_applied';
|
|||
export class CoreUpdateManagerProvider {
|
||||
|
||||
protected logger: CoreLogger;
|
||||
protected doneDeferred: PromiseDefer<void>;
|
||||
|
||||
constructor() {
|
||||
this.logger = CoreLogger.getInstance('CoreUpdateManagerProvider');
|
||||
this.doneDeferred = CoreUtils.promiseDefer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise resolved when the load function is done.
|
||||
*
|
||||
* @return Promise resolved when the load function is done.
|
||||
*/
|
||||
get donePromise(): Promise<void> {
|
||||
return this.doneDeferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,12 +57,16 @@ export class CoreUpdateManagerProvider {
|
|||
*
|
||||
* @return Promise resolved when the update process finishes.
|
||||
*/
|
||||
async load(): Promise<void> {
|
||||
async initialize(): Promise<void> {
|
||||
const promises: Promise<unknown>[] = [];
|
||||
const versionCode = CoreConstants.CONFIG.versioncode;
|
||||
|
||||
const versionApplied = await CoreConfig.get<number>(VERSION_APPLIED, 0);
|
||||
|
||||
if (versionCode > versionApplied) {
|
||||
promises.push(this.checkCurrentSiteAllowed());
|
||||
}
|
||||
|
||||
if (versionCode >= 3950 && versionApplied < 3950 && versionApplied > 0) {
|
||||
promises.push(CoreH5P.h5pPlayer.deleteAllContentIndexes());
|
||||
}
|
||||
|
@ -58,9 +77,47 @@ export class CoreUpdateManagerProvider {
|
|||
await CoreConfig.set(VERSION_APPLIED, versionCode);
|
||||
} catch (error) {
|
||||
this.logger.error(`Error applying update from ${versionApplied} to ${versionCode}`, error);
|
||||
} finally {
|
||||
this.doneDeferred.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a current site, check if it's still supported in the new app.
|
||||
*
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async checkCurrentSiteAllowed(): Promise<void> {
|
||||
if (!CoreLoginHelper.getFixedSites()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentSiteId = await CoreUtils.ignoreErrors(CoreSites.getStoredCurrentSiteId());
|
||||
if (!currentSiteId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const site = await CoreUtils.ignoreErrors(CoreSites.getSite(currentSiteId));
|
||||
if (!site) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isUrlAllowed = await CoreLoginHelper.isSiteUrlAllowed(site.getURL(), false);
|
||||
if (isUrlAllowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Site no longer supported, remove it as current site.
|
||||
await CoreSites.removeStoredCurrentSite();
|
||||
|
||||
// Tell the app to open add site so the user can add the new site.
|
||||
CoreApp.storeRedirect(CoreConstants.NO_SITE_ID, '/login/sites', {
|
||||
params: {
|
||||
openAddSite: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CoreUpdateManager = makeSingleton(CoreUpdateManagerProvider);
|
||||
|
|
|
@ -38,6 +38,7 @@ import { CoreViewerImageComponent } from '@features/viewer/components/image/imag
|
|||
import { CoreFormFields, CoreForms } from '../../singletons/form';
|
||||
import { CoreModalLateralTransitionEnter, CoreModalLateralTransitionLeave } from '@classes/modal-lateral-transition';
|
||||
import { CoreZoomLevel } from '@features/settings/services/settings-helper';
|
||||
import { CoreErrorWithTitle } from '@classes/errors/errorwithtitle';
|
||||
|
||||
/*
|
||||
* "Utils" service with helper functions for UI, DOM elements and HTML code.
|
||||
|
@ -1376,6 +1377,8 @@ export class CoreDomUtilsProvider {
|
|||
|
||||
if (this.isNetworkError(message, error)) {
|
||||
alertOptions.cssClass = 'core-alert-network-error';
|
||||
} else if (error instanceof CoreErrorWithTitle) {
|
||||
alertOptions.header = error.title || undefined;
|
||||
} else {
|
||||
alertOptions.header = Translate.instant('core.error');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue