summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-12-10 18:08:40 +0100
committerVincent Petry <pvince81@owncloud.com>2016-02-15 12:48:47 +0100
commitb8b77709c05df3d820af2bfc83ff9d386bc19990 (patch)
tree68a6f739b0d9f4af62d2169340d2c3b35e30d27a
parent294dcb4efffabc30fb85f50f2e01af2904b476a6 (diff)
downloadnextcloud-server-b8b77709c05df3d820af2bfc83ff9d386bc19990.tar.gz
nextcloud-server-b8b77709c05df3d820af2bfc83ff9d386bc19990.zip
Add handler for global ajax errors
-rw-r--r--apps/files/js/filelist.js7
-rw-r--r--apps/files/tests/js/filelistSpec.js7
-rw-r--r--core/js/files/client.js2
-rw-r--r--core/js/js.js65
-rw-r--r--core/js/setupchecks.js9
-rw-r--r--core/js/tests/specHelper.js7
-rw-r--r--core/js/tests/specs/coreSpec.js42
7 files changed, 117 insertions, 22 deletions
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 1a6f38d3d7c..3338d2b5827 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -1427,13 +1427,6 @@
delete this._reloadCall;
this.hideMask();
- if (status === 401) {
- // TODO: append current URL to be able to get back after logging in again
- OC.redirect(OC.generateUrl('apps/files'));
- OC.Notification.show(result);
- return false;
- }
-
// Firewall Blocked request?
if (status === 403) {
// Go home
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 0091a9ee6e4..122e618de96 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -2441,13 +2441,6 @@ describe('OCA.Files.FileList tests', function() {
getFolderContentsStub.restore();
fileList = undefined;
});
- it('redirects to files app in case of auth error', function () {
- deferredList.reject(401, 'Authentication error');
-
- expect(redirectStub.calledOnce).toEqual(true);
- expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files');
- expect(getFolderContentsStub.calledOnce).toEqual(true);
- });
it('redirects to root folder in case of forbidden access', function () {
deferredList.reject(403);
diff --git a/core/js/files/client.js b/core/js/files/client.js
index 55a8e2c485a..6797ba84e7f 100644
--- a/core/js/files/client.js
+++ b/core/js/files/client.js
@@ -137,6 +137,8 @@
});
return result;
};
+
+ OC.registerXHRForErrorProcessing(xhr);
return xhr;
},
diff --git a/core/js/js.js b/core/js/js.js
index b646ff5c6f9..fac9c45f668 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -235,6 +235,13 @@ var OC={
},
/**
+ * Reloads the current page
+ */
+ reload: function() {
+ window.location.reload();
+ },
+
+ /**
* Protocol that is used to access this ownCloud instance
* @return {string} Used protocol
*/
@@ -727,6 +734,56 @@ var OC={
isUserAdmin: function() {
return oc_isadmin;
},
+
+ /**
+ * Process ajax error, redirects to main page
+ * if an error/auth error status was returned.
+ */
+ _processAjaxError: function(xhr) {
+ // purposefully aborted request ?
+ if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout')) {
+ return;
+ }
+
+ if (_.contains([0, 302, 307, 401], xhr.status)) {
+ OC.reload();
+ }
+ },
+
+ /**
+ * Registers XmlHttpRequest object for global error processing.
+ *
+ * This means that if this XHR object returns 401 or session timeout errors,
+ * the current page will automatically be reloaded.
+ *
+ * @param {XMLHttpRequest} xhr
+ */
+ registerXHRForErrorProcessing: function(xhr) {
+ var loadCallback = function() {
+ if (xhr.readyState !== 4) {
+ return;
+ }
+
+ if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
+ return;
+ }
+
+ // fire jquery global ajax error handler
+ $(document).trigger(new $.Event('ajaxError'), xhr);
+ };
+
+ var errorCallback = function() {
+ // fire jquery global ajax error handler
+ $(document).trigger(new $.Event('ajaxError'), xhr);
+ };
+
+ // FIXME: also needs an IE8 way
+ if (xhr.addEventListener) {
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
+ }
+
+ }
};
/**
@@ -1311,11 +1368,11 @@ function initCore() {
$('html').addClass('edge');
}
- $( document ).ajaxError(function( event, request, settings ) {
- if (_.contains([302, 307, 401], request.status)) {
- var app = $('#content').attr('class').substring(4);
- OC.redirect(OC.generateUrl('apps/' + app));
+ $(document).on('ajaxError.main', function( event, request, settings ) {
+ if (settings && settings.allowAuthErrors) {
+ return;
}
+ OC._processAjaxError(request);
});
/**
diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js
index de41b66ec32..1819b5a9c1e 100644
--- a/core/js/setupchecks.js
+++ b/core/js/setupchecks.js
@@ -40,7 +40,8 @@
'<d:propfind xmlns:d="DAV:">' +
'<d:prop><d:resourcetype/></d:prop>' +
'</d:propfind>',
- complete: afterCall
+ complete: afterCall,
+ allowAuthErrors: true
});
return deferred.promise();
},
@@ -157,7 +158,8 @@
$.ajax({
type: 'GET',
- url: OC.generateUrl('settings/ajax/checksetup')
+ url: OC.generateUrl('settings/ajax/checksetup'),
+ allowAuthErrors: true
}).then(afterCall, afterCall);
return deferred.promise();
},
@@ -181,7 +183,8 @@
$.ajax({
type: 'GET',
- url: OC.generateUrl('heartbeat')
+ url: OC.generateUrl('heartbeat'),
+ allowAuthErrors: true
}).then(afterCall, afterCall);
return deferred.promise();
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index d13691845a7..f9bdeae0d64 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -116,7 +116,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
// global setup for all tests
(function setupTests() {
var fakeServer = null,
- $testArea = null;
+ $testArea = null,
+ ajaxErrorStub = null;
/**
* Utility functions for testing
@@ -162,6 +163,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
// dummy select2 (which isn't loaded during the tests)
$.fn.select2 = function() { return this; };
+
+ ajaxErrorStub = sinon.stub(OC, '_processAjaxError');
});
afterEach(function() {
@@ -172,6 +175,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
$testArea.remove();
delete($.fn.select2);
+
+ ajaxErrorStub.restore();
});
})();
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 2e970f7e707..32eb8df32d1 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -302,6 +302,7 @@ describe('Core base tests', function() {
/* jshint camelcase: false */
window.oc_config = oldConfig;
routeStub.restore();
+ $(document).off('ajaxError');
});
it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
/* jshint camelcase: false */
@@ -473,6 +474,7 @@ describe('Core base tests', function() {
});
afterEach(function() {
clock.restore();
+ $(document).off('ajaxError');
});
it('Sets up menu toggle', function() {
window.initCore();
@@ -841,5 +843,45 @@ describe('Core base tests', function() {
// verification is done in afterEach
});
});
+ describe('global ajax errors', function() {
+ var reloadStub, ajaxErrorStub;
+
+ beforeEach(function() {
+ reloadStub = sinon.stub(OC, 'reload');
+ // unstub the error processing method
+ ajaxErrorStub = OC._processAjaxError;
+ ajaxErrorStub.restore();
+ window.initCore();
+ });
+ afterEach(function() {
+ reloadStub.restore();
+ $(document).off('ajaxError');
+ });
+
+ it('reloads current page in case of auth error', function () {
+ var dataProvider = [
+ [200, false],
+ [400, false],
+ [401, true],
+ [302, true],
+ [307, true]
+ ];
+
+ for (var i = 0; i < dataProvider.length; i++) {
+ var xhr = { status: dataProvider[i][0] };
+ var expectedCall = dataProvider[i][1];
+
+ reloadStub.reset();
+
+ $(document).trigger(new $.Event('ajaxError'), xhr);
+
+ if (expectedCall) {
+ expect(reloadStub.calledOnce).toEqual(true);
+ } else {
+ expect(reloadStub.notCalled).toEqual(true);
+ }
+ }
+ });
+ })
});