MOBILE-2553 login: Detect redirect if login fails
parent
871b47369c
commit
e5b013f203
|
@ -1349,6 +1349,7 @@
|
|||
"core.login.selectsite": "local_moodlemobileapp",
|
||||
"core.login.signupplugindisabled": "local_moodlemobileapp",
|
||||
"core.login.siteaddress": "local_moodlemobileapp",
|
||||
"core.login.sitehasredirect": "local_moodlemobileapp",
|
||||
"core.login.siteinmaintenance": "local_moodlemobileapp",
|
||||
"core.login.sitepolicynotagreederror": "local_moodlemobileapp",
|
||||
"core.login.siteurl": "local_moodlemobileapp",
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
"selectsite": "Please select your site:",
|
||||
"signupplugindisabled": "{{$a}} is not enabled.",
|
||||
"siteaddress": "Site address",
|
||||
"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",
|
||||
"sitepolicynotagreederror": "Site policy not agreed.",
|
||||
"siteurl": "Site URL",
|
||||
|
|
|
@ -422,7 +422,8 @@ export class CoreSitesProvider {
|
|||
password: password,
|
||||
service: service
|
||||
},
|
||||
promise = this.http.post(siteUrl + '/login/token.php', params).timeout(CoreConstants.WS_TIMEOUT).toPromise();
|
||||
loginUrl = siteUrl + '/login/token.php',
|
||||
promise = this.http.post(loginUrl, params).timeout(CoreConstants.WS_TIMEOUT).toPromise();
|
||||
|
||||
return promise.then((data: any): any => {
|
||||
if (typeof data == 'undefined') {
|
||||
|
@ -431,12 +432,22 @@ export class CoreSitesProvider {
|
|||
if (typeof data.token != 'undefined') {
|
||||
return { token: data.token, siteUrl: siteUrl, privateToken: data.privatetoken };
|
||||
} else {
|
||||
|
||||
if (typeof data.error != 'undefined') {
|
||||
// We only allow one retry (to avoid loops).
|
||||
if (!retry && data.errorcode == 'requirecorrectaccess') {
|
||||
siteUrl = this.urlUtils.addOrRemoveWWW(siteUrl);
|
||||
|
||||
return this.getUserToken(siteUrl, username, password, service, true);
|
||||
} else if (data.errorcode == 'missingparam') {
|
||||
// It seems the server didn't receive all required params, it could be due to a redirect.
|
||||
return this.utils.checkRedirect(loginUrl).then((redirect) => {
|
||||
if (redirect) {
|
||||
return Promise.reject({ error: this.translate.instant('core.login.sitehasredirect') });
|
||||
} else {
|
||||
return Promise.reject({ error: data.error, errorcode: data.errorcode });
|
||||
}
|
||||
});
|
||||
} else if (typeof data.errorcode != 'undefined') {
|
||||
return Promise.reject({ error: data.error, errorcode: data.errorcode });
|
||||
} else {
|
||||
|
|
|
@ -26,6 +26,7 @@ import { CoreLoggerProvider } from '../logger';
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreLangProvider } from '../lang';
|
||||
import { CoreWSProvider, CoreWSError } from '../ws';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
|
||||
/**
|
||||
* Deferred promise. It's similar to the result of $q.defer() in AngularJS.
|
||||
|
@ -182,6 +183,43 @@ export class CoreUtilsProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a URL has a redirect.
|
||||
*
|
||||
* @param {string} url The URL to check.
|
||||
* @return {Promise<boolean>} Promise resolved with boolean_ whether there is a redirect.
|
||||
*/
|
||||
checkRedirect(url: string): Promise<boolean> {
|
||||
if (window.fetch) {
|
||||
const win = <any> window, // Convert to <any> to be able to use AbortController (not supported by our TS version).
|
||||
initOptions: any = {
|
||||
redirect: 'follow'
|
||||
};
|
||||
let controller;
|
||||
|
||||
// Some browsers implement fetch but no AbortController.
|
||||
if (win.AbortController) {
|
||||
controller = new win.AbortController();
|
||||
initOptions.signal = controller.signal;
|
||||
}
|
||||
|
||||
return this.timeoutPromise(window.fetch(url, initOptions), CoreConstants.WS_TIMEOUT).then((response: Response) => {
|
||||
return response.redirected;
|
||||
}).catch((error) => {
|
||||
if (error.timeout && controller) {
|
||||
// Timeout, abort the request.
|
||||
controller.abort();
|
||||
}
|
||||
|
||||
// There was a timeout, cannot determine if there's a redirect. Assume it's false.
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
// Cannot check if there is a redirect, assume it's false.
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the InAppBrowser window.
|
||||
*
|
||||
|
@ -1082,6 +1120,26 @@ export class CoreUtilsProvider {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a timeout to a Promise. If the time passes before the Promise is resolved or rejected, it will be automatically
|
||||
* rejected.
|
||||
*
|
||||
* @param {Promise<T>} promise The promise to timeout.
|
||||
* @param {number} time Number of milliseconds of the timeout.
|
||||
* @return {Promise<T>} Promise with the timeout.
|
||||
*/
|
||||
timeoutPromise<T>(promise: Promise<T>, time: number): Promise<T> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
const timeout = setTimeout(() => {
|
||||
reject({timeout: true});
|
||||
}, time);
|
||||
|
||||
promise.then(resolve).catch(reject).finally(() => {
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts locale specific floating point/comma number back to standard PHP float value.
|
||||
* Do NOT try to do any math operations before this conversion on any user submitted floats!
|
||||
|
|
Loading…
Reference in New Issue