{{ 'core.login.faqcannotconnectanswer' | translate }} {{ 'core.whoissiteadmin' | translate }}
+{{ 'core.login.faqcannotconnectanswer' | translate }}
An email should have been sent to your address at {{$a}}
\nIt contains easy instructions to complete your registration.
\nIf you continue to have difficulty, contact the site administrator.
", - "emailconfirmsentnoemail": "An email should have been sent to your address.
It contains easy instructions to complete your registration.
If you continue to have difficulty, contact the site administrator.
", + "emailconfirmsent": "An email should have been sent to your address at {{$a}}
It contains easy instructions to complete your registration.
", + "emailconfirmsentnoemail": "An email should have been sent to your address.
It contains easy instructions to complete your registration.
", "emailconfirmsentsuccess": "Confirmation email sent successfully", "emailnotmatch": "Emails do not match", "erroraccesscontrolalloworigin": "The cross-origin call you're trying to perform has been rejected. Please check https://docs.moodle.org/dev/Moodle_Mobile_development_using_Chrome_or_Chromium", @@ -32,7 +30,7 @@ "exceededloginattemptssupportsubject": "I can't log in", "exceededpasswordresetattempts": "It seems you are having trouble accessing your account. You can contact your administrator or try again later.", "exceededpasswordresetattemptssupportsubject": "I can't reset my password", - "faqcannotconnectanswer": "Please, contact your site administrator.", + "faqcannotconnectanswer": "Please, contact your institution.", "faqcannotconnectquestion": "I typed my site address correctly but I still can't connect.", "faqcannotfindmysiteanswer": "Have you typed the name correctly? It's also possible that your site is not included in our public sites directory. If you still can't find it, please enter your site address instead.", "faqcannotfindmysitequestion": "I can't find my site.", @@ -50,12 +48,11 @@ "forcepasswordchangenotice": "You must change your password to proceed.", "forgotten": "Forgotten your username or password?", "help": "Help", - "helpmelogin": "There are many thousands of Moodle sites around the world. This app can only connect to Moodle sites that have specifically enabled Mobile app access.
If you can't connect to your Moodle site then you need to contact your site administrator and ask them to read http://docs.moodle.org/en/Mobile_app
To test the app in a Moodle demo site type teacher or student in the Site address field and click the Connect button.
", "instructions": "Instructions", - "invalidaccount": "Please check your login details or ask your site administrator to check the site configuration.", + "invalidaccount": "Please check your login details and try again.", "invaliddate": "Invalid date", "invalidemail": "Invalid email address", - "invalidmoodleversion": "Invalid Moodle site version. The Moodle app only supports Moodle systems {{$a}} onwards.
\nYou can contact your site administrators and ask them to update their Moodle system.
\n\"Site Administrators\" are the people who manages the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.
", + "invalidmoodleversion": "Invalid Moodle site version. The Moodle app only supports Moodle systems {{$a}} onwards.", "invalidsite": "The site URL is invalid.", "invalidtime": "Invalid time", "invalidurl": "Invalid URL specified", @@ -69,7 +66,7 @@ "missingemail": "Missing email address", "missingfirstname": "Missing given name", "missinglastname": "Missing surname", - "mobileservicesnotenabled": "Mobile access is not enabled on your site. Please contact your site administrator if you think it should be enabled.", + "mobileservicesnotenabled": "Mobile services are not enabled on the site.", "mustconfirm": "You need to confirm your account", "newaccount": "New account", "notloggedin": "You need to be logged in.", @@ -127,7 +124,7 @@ "usernamerequired": "Username required", "usernotaddederror": "User not added - error", "visitchangepassword": "Do you want to visit the site to change the password?", - "webservicesnotenabled": "Your host site may not have enabled Web services. Please contact your administrator for help.", + "webservicesnotenabled": "Web services are not enabled on the site.", "youcanstillconnectwithcredentials": "You can still connect to the site by entering your username and password.", "yourenteredsite": "Connect to your site" } diff --git a/src/core/features/login/tests/credentials.test.ts b/src/core/features/login/tests/credentials.test.ts index f8581b00f..2d0b98341 100644 --- a/src/core/features/login/tests/credentials.test.ts +++ b/src/core/features/login/tests/credentials.test.ts @@ -25,6 +25,26 @@ describe('Credentials page', () => { // Arrange. const siteUrl = 'https://campus.example.edu'; + mockSingleton(CoreSites, { + getPublicSiteConfigByUrl: async () => ({ + wwwroot: 'https://campus.example.edu', + httpswwwroot: 'https://campus.example.edu', + sitename: 'Example Campus', + guestlogin: 0, + rememberusername: 0, + authloginviaemail: 0, + registerauth: '', + forgottenpasswordurl: '', + authinstructions: '', + authnoneenabled: 0, + enablewebservices: 1, + enablemobilewebservice: 1, + maintenanceenabled: 0, + maintenancemessage: '', + typeoflogin: 1, + }), + }); + // Act. const fixture = await renderPageComponent(CoreLoginCredentialsPage, { routeParams: { siteUrl }, diff --git a/src/core/features/siteplugins/classes/call-ws-click-directive.ts b/src/core/features/siteplugins/classes/call-ws-click-directive.ts index 94c8b28f6..e09d7fe0e 100644 --- a/src/core/features/siteplugins/classes/call-ws-click-directive.ts +++ b/src/core/features/siteplugins/classes/call-ws-click-directive.ts @@ -15,6 +15,7 @@ import { Input, OnInit, ElementRef, Directive } from '@angular/core'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons'; import { CoreSitePluginsPluginContentComponent } from '../components/plugin-content/plugin-content'; @@ -72,7 +73,12 @@ export class CoreSitePluginsCallWSOnClickBaseDirective extends CoreSitePluginsCa await super.callWS(); } catch (error) { if (this.showError === undefined || CoreUtils.isTrueOrOne(this.showError)) { - CoreDomUtils.showErrorModalDefault(error, 'core.serverconnection', true); + CoreDomUtils.showErrorModalDefault( + error, + Translate.instant('core.serverconnection', { + details: CoreTextUtils.getErrorMessageFromError(error) ?? 'Unknown error', + }), + ); } } finally { modal.dismiss(); diff --git a/src/core/initializers/prepare-inapp-browser.ts b/src/core/initializers/prepare-inapp-browser.ts index 6c8593883..61a717249 100644 --- a/src/core/initializers/prepare-inapp-browser.ts +++ b/src/core/initializers/prepare-inapp-browser.ts @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { CoreSiteError } from '@classes/errors/siteerror'; import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CoreApp } from '@services/app'; import { CoreCustomURLSchemes } from '@services/urlschemes'; @@ -45,10 +46,12 @@ export default function(): void { if (isExternalApp && url.includes('://token=')) { // It's an SSO token for another app. Close the IAB and show an error. CoreUtils.closeInAppBrowser(); - CoreDomUtils.showErrorModal(Translate.instant('core.login.contactyouradministratorissue', { - $a: '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}}
", + "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.", "all": "All", "allgroups": "All groups", "allparticipants": "All participants", @@ -18,7 +18,7 @@ "cannotconnecttrouble": "We're having trouble connecting to your site.", "cannotconnecttroublewithoutsupport": "We're having trouble connecting to your site, please contact your institution.", "cannotconnectverify": "Please check the address is correct.", - "cannotdownloadfiles": "File downloading is disabled. Please contact your site administrator.", + "cannotdownloadfiles": "This institution has disabled downloading files.", "cannotinstallapk": "For security reasons, you can't install unknown apps on your device from this app. Please open the file using a browser.", "cannotlogoutpageblocks": "Please save or discard your changes before continuing.", "cannotopeninapp": "This file may not work as expected on this device. Would you like to open it anyway?", @@ -28,7 +28,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}}
", + "certificaterror": "The certificate of this site cannot be trusted by your device: {{details}}", "choose": "Choose", "choosedots": "Choose...", "clearsearch": "Clear search", @@ -110,7 +110,7 @@ "errordownloadingsomefiles": "Error downloading files. Some files might be missing.", "errorfileexistssamename": "A file with this name already exists.", "errorinvalidform": "The form contains invalid data. Please check that all required fields are filled in and that the data is valid.", - "errorinvalidresponse": "Invalid response received. Please contact your site administrator if the error persists.", + "errorinvalidresponse": "Invalid response received for {{method}} webservice.", "errorloadingcontent": "Error loading content.", "errorofflinedisabled": "Offline browsing is disabled on your site. You need to be connected to the internet to use the app.", "erroropenfiledownloading": "Error opening file: you need to wait for the download to complete.", @@ -275,7 +275,7 @@ "selectagroup": "Select a group", "send": "Send", "sending": "Sending", - "serverconnection": "Error connecting to the server", + "serverconnection": "Error connecting to the server: {{details}}", "show": "Show", "showadvanced": "Show advanced", "showless": "Show less...", @@ -353,7 +353,6 @@ "weeks": "weeks", "whatisyourage": "What is your age?", "wheredoyoulive": "In which country do you live?", - "whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.", "whyisthishappening": "Why is this happening?", "whyisthisrequired": "Why is this required?", "wsfunctionnotavailable": "The web service function is not available.", diff --git a/src/core/services/sites.ts b/src/core/services/sites.ts index 57c171c47..6ca213846 100644 --- a/src/core/services/sites.ts +++ b/src/core/services/sites.ts @@ -296,14 +296,14 @@ export class CoreSitesProvider { // Check that the user can authenticate. if (!config.enablewebservices) { - throw this.createCannotConnectError({ + throw this.createCannotConnectLoginError({ errorcode: 'webservicesnotenabled', errorDetails: Translate.instant('core.login.webservicesnotenabled'), siteConfig: config, critical: true, }); } else if (!config.enablemobilewebservice) { - throw this.createCannotConnectError({ + throw this.createCannotConnectLoginError({ errorcode: 'mobileservicesnotenabled', errorDetails: Translate.instant('core.login.mobileservicesnotenabled'), siteConfig: config, @@ -327,18 +327,29 @@ export class CoreSitesProvider { } /** - * Create an error to be thrown when it isn't possible to connect to a site. + * Create an error to be thrown when it isn't possible to login to a site. * * @param options Error options. * @return Cannot connect error. */ - protected createCannotConnectError(options: Partial${error}
`; - } - - return message; - } - /** * Retry all requests in the queue. * This function uses recursion in order to add a delay between requests to reduce stress. @@ -850,10 +867,12 @@ export class CoreWSProvider { } if (!data) { - throw new CoreError(Translate.instant('core.serverconnection')); + throw new CoreError(Translate.instant('core.serverconnection', { + details: Translate.instant('core.errorinvalidresponse', { method }), + })); } else if (typeof data != preSets.typeExpected) { this.logger.warn('Response of type "' + typeof data + '" received, expecting "' + preSets.typeExpected + '"'); - throw new CoreError(Translate.instant('core.errorinvalidresponse')); + throw new CoreError(Translate.instant('core.errorinvalidresponse', { method })); } if (data.exception !== undefined || data.debuginfo !== undefined) { @@ -923,15 +942,26 @@ export class CoreWSProvider { ); if (data === null) { - throw new CoreError(Translate.instant('core.errorinvalidresponse')); + throw await this.createCannotConnectSiteError(preSets.siteUrl, { + errorcode: 'invalidresponse', + errorDetails: Translate.instant('core.errorinvalidresponse', { method: 'upload.php' }), + }); } if (!data) { - throw new CoreError(Translate.instant('core.serverconnection')); + throw await this.createCannotConnectSiteError(preSets.siteUrl, { + errorcode: 'serverconnectionupload', + errorDetails: Translate.instant('core.serverconnection', { + details: Translate.instant('core.errorinvalidresponse', { method: 'upload.php' }), + }), + }); } else if (typeof data != 'object') { this.logger.warn('Upload file: Response of type "' + typeof data + '" received, expecting "object"'); - throw new CoreError(Translate.instant('core.errorinvalidresponse')); + throw await this.createCannotConnectSiteError(preSets.siteUrl, { + errorcode: 'invalidresponse', + errorDetails: Translate.instant('core.errorinvalidresponse', { method: 'upload.php' }), + }); } if (data.exception !== undefined) { @@ -1091,6 +1121,28 @@ export class CoreWSProvider { } } + /** + * Create an error to be thrown when it isn't possible to connect to a site. + * + * @param siteUrl Site url. + * @param options Error options. + * @return Cannot connect error. + */ + protected async createCannotConnectSiteError( + siteUrl: string, + options?: Partial