From 534bbbb289d45adea66363d0241304bbb3a90a8f Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 14 Sep 2021 15:18:49 +0200 Subject: [PATCH] MOBILE-3859 ws: Improve error message for certificate errors --- scripts/langindex.json | 2 ++ src/core/classes/errors/ajaxerror.ts | 6 ++-- src/core/classes/site.ts | 44 ++++++++++++++-------------- src/core/lang.json | 2 ++ src/core/services/sites.ts | 33 ++++++++++----------- src/core/services/ws.ts | 39 ++++++++++++++++++++++-- 6 files changed, 80 insertions(+), 46 deletions(-) diff --git a/scripts/langindex.json b/scripts/langindex.json index 3c46978e7..7c5324cd9 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -1384,6 +1384,7 @@ "core.add": "moodle", "core.agelocationverification": "moodle", "core.ago": "message", + "core.ajaxendpointnotfound": "local_moodlemobileapp", "core.all": "moodle", "core.allgroups": "moodle", "core.allparticipants": "moodle", @@ -1405,6 +1406,7 @@ "core.captureimage": "local_moodlemobileapp", "core.capturevideo": "local_moodlemobileapp", "core.category": "moodle", + "core.certificaterror": "local_moodlemobileapp", "core.choose": "moodle", "core.choosedots": "moodle", "core.clearsearch": "local_moodlemobileapp", diff --git a/src/core/classes/errors/ajaxerror.ts b/src/core/classes/errors/ajaxerror.ts index 7cf6b1363..f7a57cc9d 100644 --- a/src/core/classes/errors/ajaxerror.ts +++ b/src/core/classes/errors/ajaxerror.ts @@ -19,12 +19,10 @@ import { CoreError } from '@classes/errors/error'; */ export class CoreAjaxError extends CoreError { - available?: number; // Whether the AJAX call is available. 0 if unknown, 1 if available, -1 if not available. + available = 1; // @deprecated since app 4.0. AJAX endpoint should always be available in supported Moodle versions. - constructor(message: string, available?: number) { + constructor(message: string) { super(message); - - this.available = typeof available == 'undefined' ? 0 : available; } } diff --git a/src/core/classes/site.ts b/src/core/classes/site.ts index c3593943a..4050c88f9 100644 --- a/src/core/classes/site.ts +++ b/src/core/classes/site.ts @@ -1333,38 +1333,38 @@ export class CoreSite { siteUrl: this.siteUrl, }; - let config: CoreSitePublicConfigResponse | undefined; + let config: CoreSitePublicConfigResponse; try { - config = await CoreWS.callAjax('tool_mobile_get_public_config', {}, preSets); + config = await CoreWS.callAjax('tool_mobile_get_public_config', {}, preSets); } catch (error) { - if ((!this.getInfo() || this.isVersionGreaterEqualThan('3.8')) && error && error.errorcode == 'codingerror') { - // This error probably means that there is a redirect in the site. Try to use a GET request. - preSets.noLogin = true; - preSets.useGet = true; - - try { - config = await CoreWS.callAjax('tool_mobile_get_public_config', {}, preSets); - } catch (error2) { - if (this.getInfo() && this.isVersionGreaterEqualThan('3.8')) { - // GET is supported, return the second error. - throw error2; - } else { - // GET not supported or we don't know if it's supported. Return first error. - throw error; - } - } + if (!error || error.errorcode !== 'codingerror' || (this.getInfo() && !this.isVersionGreaterEqualThan('3.8'))) { + throw error; } - throw error; + // This error probably means that there is a redirect in the site. Try to use a GET request. + preSets.noLogin = true; + preSets.useGet = true; + + try { + config = await CoreWS.callAjax('tool_mobile_get_public_config', {}, preSets); + } catch (error2) { + if (this.getInfo() && this.isVersionGreaterEqualThan('3.8')) { + // GET is supported, return the second error. + throw error2; + } else { + // GET not supported or we don't know if it's supported. Return first error. + throw error; + } + } } // Use the wwwroot returned by the server. - if (config!.httpswwwroot) { - this.siteUrl = CoreUrlUtils.removeUrlParams(config!.httpswwwroot); // Make sure the URL doesn't have params. + if (config.httpswwwroot) { + this.siteUrl = CoreUrlUtils.removeUrlParams(config.httpswwwroot); // Make sure the URL doesn't have params. } - return config!; + return config; } /** diff --git a/src/core/lang.json b/src/core/lang.json index 05b6db48f..1da713f7f 100644 --- a/src/core/lang.json +++ b/src/core/lang.json @@ -3,6 +3,7 @@ "add": "Add", "agelocationverification": "Age and location verification", "ago": "{{$a}} ago", + "ajaxendpointnotfound": "

AJAX endpoint not found. This can happen if the Moodle site is too old or it blocks access to this endpoint. The Moodle app only supports Moodle systems {{$a}} onwards. Please contact your site administrator.

\n

{{whoisadmin}}

", "all": "All", "allgroups": "All groups", "allparticipants": "All participants", @@ -23,6 +24,7 @@ "captureimage": "Take picture", "capturevideo": "Record video", "category": "Category", + "certificaterror": "

The certificate of this site cannot be trusted by your device. Please contact your site administrator.

\n

{{whoisadmin}}

", "choose": "Choose", "choosedots": "Choose...", "clearsearch": "Clear search", diff --git a/src/core/services/sites.ts b/src/core/services/sites.ts index 38a35cd28..5393fd864 100644 --- a/src/core/services/sites.ts +++ b/src/core/services/sites.ts @@ -245,27 +245,24 @@ export class CoreSitesProvider { }); } } catch (error) { - // Error, check if not supported. - if (error.available === 1) { - // Service supported but an error happened. Return error. - if (error.errorcode == 'codingerror') { - // This could be caused by a redirect. Check if it's the case. - const redirect = await CoreUtils.checkRedirect(siteUrl); + // Service supported but an error happened. Return error. + if (error.errorcode == 'codingerror') { + // This could be caused by a redirect. Check if it's the case. + const redirect = await CoreUtils.checkRedirect(siteUrl); - if (redirect) { - error.error = Translate.instant('core.login.sitehasredirect'); - } else { - // We can't be sure if there is a redirect or not. Display cannot connect error. - error.error = Translate.instant('core.cannotconnecttrouble'); - } + if (redirect) { + error.message = Translate.instant('core.login.sitehasredirect'); + } else { + // We can't be sure if there is a redirect or not. Display cannot connect error. + error.message = Translate.instant('core.cannotconnecttrouble'); } - - throw new CoreSiteError({ - message: error.error, - errorcode: error.errorcode, - critical: true, - }); } + + throw new CoreSiteError({ + message: error.message, + errorcode: error.errorcode, + critical: true, + }); } siteUrl = temporarySite.getURL(); diff --git a/src/core/services/ws.ts b/src/core/services/ws.ts index 92067a6e9..549e26915 100644 --- a/src/core/services/ws.ts +++ b/src/core/services/ws.ts @@ -37,6 +37,7 @@ import { CoreWSError } from '@classes/errors/wserror'; import { CoreAjaxError } from '@classes/errors/ajaxerror'; import { CoreAjaxWSError } from '@classes/errors/ajaxwserror'; import { CoreNetworkError } from '@classes/errors/network-error'; +import { CoreSite } from '@classes/site'; /** * This service allows performing WS calls and download/upload files. @@ -474,9 +475,23 @@ export class CoreWSProvider { return data.data; }, (data) => { - const available = data.status == 404 ? -1 : 0; + let message = ''; - throw new CoreAjaxError(Translate.instant('core.serverconnection'), available); + switch (data.status) { + case -2: // Certificate error. + message = this.getCertificateErrorMessage(data.error); + break; + case 404: // AJAX endpoint not found. + message = Translate.instant('core.ajaxendpointnotfound', { + $a: CoreSite.MINIMUM_MOODLE_VERSION, + whoisadmin: Translate.instant('core.whoissiteadmin'), + }); + break; + default: + message = Translate.instant('core.serverconnection'); + } + + throw new CoreAjaxError(message); }); } @@ -675,12 +690,32 @@ export class CoreWSProvider { } return retryPromise; + } else if (error.status === -2) { + throw new CoreError(this.getCertificateErrorMessage(error.error)); } throw new CoreError(Translate.instant('core.serverconnection')); }); } + /** + * Get error message about certificate error. + * + * @param error Exact error message. + * @return Certificate error message. + */ + protected getCertificateErrorMessage(error?: string): string { + const message = Translate.instant('core.certificaterror', { + whoisadmin: Translate.instant('core.whoissiteadmin'), + }); + + if (error) { + return `${message}\n

${error}

`; + } + + return message; + } + /** * Retry all requests in the queue. * This function uses recursion in order to add a delay between requests to reduce stress.