Skip to content

Commit 3b30586

Browse files
committed
MOBILE-4919 core: Allow overriding WS response via config
1 parent b18e58f commit 3b30586

File tree

8 files changed

+452
-23
lines changed

8 files changed

+452
-23
lines changed

src/core/classes/sites/authenticated-site.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,13 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
465465
}
466466

467467
const observable = this.performRequest<T>(method, data, preSets, wsPreSets).pipe(
468-
// Return a clone of the original object, this may prevent errors if in the callback the object is modified.
469-
map((data) => CoreUtils.clone(data)),
468+
map((data) => {
469+
// Always clone the object because it can be modified when applying patches or in the caller function
470+
// and we don't want to store the modified object in cache.
471+
const clonedData = CoreUtils.clone(data);
472+
473+
return this.applyWSOverrides(method, clonedData);
474+
}),
470475
);
471476

472477
this.setOngoingRequest(cacheId, preSets, observable);
@@ -1347,13 +1352,13 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
13471352
* @inheritdoc
13481353
*/
13491354
async getPublicConfig(options: { readingStrategy?: CoreSitesReadingStrategy } = {}): Promise<CoreSitePublicConfigResponse> {
1355+
const method = 'tool_mobile_get_public_config';
13501356
const ignoreCache = options.readingStrategy === CoreSitesReadingStrategy.ONLY_NETWORK ||
13511357
options.readingStrategy === CoreSitesReadingStrategy.PREFER_NETWORK;
13521358
if (!ignoreCache && this.publicConfig) {
1353-
return this.publicConfig;
1359+
return this.overridePublicConfig(this.publicConfig);
13541360
}
13551361

1356-
const method = 'tool_mobile_get_public_config';
13571362
const cacheId = this.getCacheId(method, {});
13581363
const cachePreSets: CoreSiteWSPreSets = {
13591364
getFromCache: true,
@@ -1378,8 +1383,7 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
13781383

13791384
const subject = new Subject<CoreSitePublicConfigResponse>();
13801385
const observable = subject.pipe(
1381-
// Return a clone of the original object, this may prevent errors if in the callback the object is modified.
1382-
map((data) => CoreUtils.clone(data)),
1386+
map((data) => this.overridePublicConfig(data)),
13831387
finalize(() => {
13841388
this.clearOngoingRequest(cacheId, cachePreSets, observable);
13851389
}),

src/core/classes/sites/unauthenticated-site.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { CoreText } from '@singletons/text';
2020
import { CoreUrl, CoreUrlPartNames } from '@singletons/url';
2121
import { CoreWS, CoreWSAjaxPreSets, CoreWSExternalWarning } from '@services/ws';
2222
import { CorePath } from '@singletons/path';
23+
import { CoreJsonPatch } from '@singletons/json-patch';
24+
import { CoreUtils } from '@singletons/utils';
2325

2426
/**
2527
* Class that represents a Moodle site where the user still hasn't authenticated.
@@ -251,7 +253,7 @@ export class CoreUnauthenticatedSite {
251253
const ignoreCache = options.readingStrategy === CoreSitesReadingStrategy.ONLY_NETWORK ||
252254
options.readingStrategy === CoreSitesReadingStrategy.PREFER_NETWORK;
253255
if (!ignoreCache && this.publicConfig) {
254-
return this.publicConfig;
256+
return this.overridePublicConfig(this.publicConfig);
255257
}
256258

257259
if (options.readingStrategy === CoreSitesReadingStrategy.ONLY_CACHE) {
@@ -263,7 +265,7 @@ export class CoreUnauthenticatedSite {
263265

264266
this.setPublicConfig(config);
265267

266-
return config;
268+
return this.overridePublicConfig(config);
267269
} catch (error) {
268270
if (options.readingStrategy === CoreSitesReadingStrategy.ONLY_NETWORK || !this.publicConfig) {
269271
throw error;
@@ -284,6 +286,20 @@ export class CoreUnauthenticatedSite {
284286
this.publicConfig = publicConfig;
285287
}
286288

289+
/**
290+
* Apply overrides to the public config of the site.
291+
*
292+
* @param config Public config.
293+
* @returns Public config with overrides if any.
294+
*/
295+
protected overridePublicConfig(config: CoreSitePublicConfigResponse): CoreSitePublicConfigResponse {
296+
// Always clone the object because it can be modified when applying patches or in the caller function
297+
// and we don't want to modify the stored public config.
298+
const clonedData = CoreUtils.clone(config);
299+
300+
return this.applyWSOverrides('tool_mobile_get_public_config', clonedData);
301+
}
302+
287303
/**
288304
* Perform a request to the server to get the public config of this site.
289305
*
@@ -452,6 +468,40 @@ export class CoreUnauthenticatedSite {
452468
return features;
453469
}
454470

471+
/**
472+
* Call a Moodle WS using the AJAX API and applies WebService overrides (if any) to the result.
473+
*
474+
* @param method WS method name.
475+
* @param data Arguments to pass to the method.
476+
* @param preSets Extra settings and information.
477+
* @returns Promise resolved with the response data in success and rejected with CoreAjaxError.
478+
*/
479+
async callAjax<T = unknown>(
480+
method: string,
481+
data: Record<string, unknown> = {},
482+
preSets: Omit<CoreWSAjaxPreSets, 'siteUrl'> = {},
483+
): Promise<T> {
484+
const result = await CoreWS.callAjax<T>(method, data, { ...preSets, siteUrl: this.siteUrl });
485+
486+
// No need to clone the data in this case because it's not stored in any cache.
487+
return this.applyWSOverrides(method, result);
488+
}
489+
490+
/**
491+
* Apply WS overrides (if any) to the data of a WebService response.
492+
*
493+
* @param method WS method name.
494+
* @param data WS response data.
495+
* @returns Modified data (or original data if no overrides).
496+
*/
497+
protected applyWSOverrides<T>(method: string, data: T): T {
498+
if (!CoreConstants.CONFIG.wsOverrides || !CoreConstants.CONFIG.wsOverrides[method]) {
499+
return data;
500+
}
501+
502+
return CoreJsonPatch.applyPatches(data, CoreConstants.CONFIG.wsOverrides[method]);
503+
}
504+
455505
}
456506

457507
/**

src/core/features/login/pages/email-signup/email-signup.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { Component, ElementRef, OnInit, ChangeDetectorRef, inject, viewChild } f
1616
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
1717
import { CoreText } from '@singletons/text';
1818
import { CoreCountries, CoreCountry } from '@singletons/countries';
19-
import { CoreWS, CoreWSExternalWarning } from '@services/ws';
19+
import { CoreWSExternalWarning } from '@services/ws';
2020
import { Translate } from '@singletons';
2121
import { CoreSitePublicConfigResponse, CoreUnauthenticatedSite } from '@classes/sites/unauthenticated-site';
2222
import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate';
@@ -197,10 +197,8 @@ export default class CoreLoginEmailSignupPage implements OnInit {
197197
if (this.ageDigitalConsentVerification === undefined) {
198198

199199
const result = await CorePromiseUtils.ignoreErrors(
200-
CoreWS.callAjax<IsAgeVerificationEnabledWSResponse>(
200+
this.site.callAjax<IsAgeVerificationEnabledWSResponse>(
201201
'core_auth_is_age_digital_consent_verification_enabled',
202-
{},
203-
{ siteUrl: this.site.getURL() },
204202
),
205203
);
206204

@@ -344,10 +342,9 @@ export default class CoreLoginEmailSignupPage implements OnInit {
344342
this.signupForm.value,
345343
);
346344

347-
const result = await CoreWS.callAjax<SignupUserWSResult>(
345+
const result = await this.site.callAjax<SignupUserWSResult>(
348346
'auth_email_signup_user',
349347
params,
350-
{ siteUrl: this.site.getURL() },
351348
);
352349

353350
if (result.success) {
@@ -430,7 +427,7 @@ export default class CoreLoginEmailSignupPage implements OnInit {
430427
params.age = parseInt(params.age, 10); // Use just the integer part.
431428

432429
try {
433-
const result = await CoreWS.callAjax<IsMinorWSResult>('core_auth_is_minor', params, { siteUrl: this.site.getURL() });
430+
const result = await this.site.callAjax<IsMinorWSResult>('core_auth_is_minor', params);
434431

435432
CoreForms.triggerFormSubmittedEvent(this.ageFormElement(), true);
436433

src/core/features/login/services/login-helper.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { CoreApp, CoreStoreConfig } from '@services/app';
2020
import { CoreConfig } from '@services/config';
2121
import { CoreEvents, CoreEventSessionExpiredData, CoreEventSiteData } from '@singletons/events';
2222
import { CoreSites, CoreLoginSiteInfo, CoreSiteBasicInfo } from '@services/sites';
23-
import { CoreWS, CoreWSExternalWarning } from '@services/ws';
23+
import { CoreWSExternalWarning } from '@services/ws';
2424
import { CoreText, CoreTextFormat } from '@singletons/text';
2525
import { CoreObject } from '@singletons/object';
2626
import { CoreConstants } from '@/core/constants';
@@ -65,6 +65,7 @@ import { CorePromiseUtils } from '@singletons/promise-utils';
6565
import { CoreOpener } from '@singletons/opener';
6666
import { CoreAlerts } from '@services/overlays/alerts';
6767
import { CorePrompts } from '@services/overlays/prompts';
68+
import { CoreSitesFactory } from '@services/sites-factory';
6869

6970
/**
7071
* Helper provider that provides some common features regarding authentication.
@@ -271,7 +272,7 @@ export class CoreLoginHelperProvider {
271272
* @returns Signup settings.
272273
*/
273274
async getEmailSignupSettings(siteUrl: string): Promise<AuthEmailSignupSettings> {
274-
return await CoreWS.callAjax('auth_email_get_signup_settings', {}, { siteUrl });
275+
return await CoreSitesFactory.makeUnauthenticatedSite(siteUrl).callAjax('auth_email_get_signup_settings');
275276
}
276277

277278
/**
@@ -830,7 +831,7 @@ export class CoreLoginHelperProvider {
830831
params.email = email.trim().toLowerCase();
831832
}
832833

833-
return CoreWS.callAjax('core_auth_request_password_reset', params, { siteUrl });
834+
return CoreSitesFactory.makeUnauthenticatedSite(siteUrl).callAjax('core_auth_request_password_reset', params);
834835
}
835836

836837
/**
@@ -1038,13 +1039,11 @@ export class CoreLoginHelperProvider {
10381039
// Call the WS to resend the confirmation email.
10391040
const modal = await CoreLoadings.show('core.sending', true);
10401041
const data = { username: username?.toLowerCase(), password };
1041-
const preSets = { siteUrl };
10421042

10431043
try {
1044-
const result = <ResendConfirmationEmailResult> await CoreWS.callAjax(
1044+
const result = <ResendConfirmationEmailResult> await CoreSitesFactory.makeUnauthenticatedSite(siteUrl).callAjax(
10451045
'core_auth_resend_confirmation_email',
10461046
data,
1047-
preSets,
10481047
);
10491048

10501049
if (!result.status) {
@@ -1077,7 +1076,7 @@ export class CoreLoginHelperProvider {
10771076
// We don't have site info before login, the only way to check if the WS is available is by calling it.
10781077
try {
10791078
// This call will always fail because we aren't sending parameters.
1080-
await CoreWS.callAjax('core_auth_resend_confirmation_email', {}, { siteUrl });
1079+
await CoreSitesFactory.makeUnauthenticatedSite(siteUrl).callAjax('core_auth_resend_confirmation_email');
10811080

10821081
return true; // We should never reach here.
10831082
} catch (error) {

src/core/services/ws.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export class CoreWSProvider {
132132
*
133133
* @param method The WebService method to be called.
134134
* @param data Arguments to pass to the method.
135-
* @param preSets Extra settings and information. Only some
135+
* @param preSets Extra settings and information.
136136
* @returns Promise resolved with the response data in success and rejected with CoreAjaxError.
137137
*/
138138
callAjax<T = unknown>(method: string, data: Record<string, unknown>, preSets: CoreWSAjaxPreSets): Promise<T> {

0 commit comments

Comments
 (0)