From b68daaece32f5147dbc037abed0c3475fdb502aa Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 12 Oct 2015 00:44:04 +0200 Subject: [PATCH] Redirect to sign in on 401 ajax response closes #6496 --- Changelog.md | 1 + app/assets/javascripts/app/app.js | 17 ++++++++++++ spec/javascripts/app/app_spec.js | 45 +++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/Changelog.md b/Changelog.md index d2d1b84e7..ce5ce969e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ ## Refactor ## Bug fixes +* Redirect to sign in page when a background request fails with 401 [#6496](https://github.com/diaspora/diaspora/pull/6496) ## Features diff --git a/app/assets/javascripts/app/app.js b/app/assets/javascripts/app/app.js index 3f862abd2..007304793 100644 --- a/app/assets/javascripts/app/app.js +++ b/app/assets/javascripts/app/app.js @@ -53,6 +53,7 @@ var app = { this.setupGlobalViews(); this.setupDisabledLinks(); this.setupForms(); + this.setupAjaxErrorRedirect(); }, hasPreload : function(prop) { @@ -154,6 +155,22 @@ var app = { $(this).clearForm(); $(this).focusout(); }); + }, + + setupAjaxErrorRedirect: function() { + var self = this; + // Binds the global ajax event. To prevent this, add + // preventGlobalErrorHandling: true + // to the settings of your ajax calls + $(document).ajaxError(function(evt, jqxhr, settings) { + if(jqxhr.status === 401 && !settings.preventGlobalErrorHandling) { + self._changeLocation(Routes.newUserSession()); + } + }); + }, + + _changeLocation: function(href) { + window.location.assign(href); } }; diff --git a/spec/javascripts/app/app_spec.js b/spec/javascripts/app/app_spec.js index 84f4a72f3..bbdcae351 100644 --- a/spec/javascripts/app/app_spec.js +++ b/spec/javascripts/app/app_spec.js @@ -9,6 +9,7 @@ describe("app", function() { spyOn(app, "setupGlobalViews"); spyOn(app, "setupDisabledLinks"); spyOn(app, "setupForms"); + spyOn(app, "setupAjaxErrorRedirect"); app.initialize(); @@ -20,6 +21,7 @@ describe("app", function() { expect(app.setupGlobalViews).toHaveBeenCalled(); expect(app.setupDisabledLinks).toHaveBeenCalled(); expect(app.setupForms).toHaveBeenCalled(); + expect(app.setupAjaxErrorRedirect).toHaveBeenCalled(); }); }); @@ -44,4 +46,47 @@ describe("app", function() { expect($.fn.placeholder.calls.mostRecent().object.selector).toBe("input, textarea"); }); }); + + describe("setupAjaxErrorRedirect", function() { + it("redirects to /users/sign_in on 401 ajax responses", function() { + spyOn(app, "_changeLocation"); + $.ajax("/test"); + jasmine.Ajax.requests.mostRecent().respondWith({status: 401}); + expect(app._changeLocation).toHaveBeenCalledWith("/users/sign_in"); + }); + + it("doesn't redirect on other responses", function() { + spyOn(app, "_changeLocation"); + + [200, 201, 400, 404, 500].forEach(function(code) { + $.ajax("/test"); + jasmine.Ajax.requests.mostRecent().respondWith({status: code}); + expect(app._changeLocation).not.toHaveBeenCalled(); + }); + }); + + it("doesn't redirect when error handling is suppressed", function() { + spyOn(app, "_changeLocation"); + $.ajax("/test", {preventGlobalErrorHandling: true}); + jasmine.Ajax.requests.mostRecent().respondWith({status: 401}); + expect(app._changeLocation).not.toHaveBeenCalled(); + + $.ajax("/test", {preventGlobalErrorHandling: false}); + jasmine.Ajax.requests.mostRecent().respondWith({status: 401}); + expect(app._changeLocation).toHaveBeenCalledWith("/users/sign_in"); + }); + + it("doesn't redirect when global ajax events are disabled", function() { + spyOn(app, "_changeLocation"); + $.ajaxSetup({global: false}); + $.ajax("/test"); + jasmine.Ajax.requests.mostRecent().respondWith({status: 401}); + expect(app._changeLocation).not.toHaveBeenCalled(); + + $.ajaxSetup({global: true}); + $.ajax("/test"); + jasmine.Ajax.requests.mostRecent().respondWith({status: 401}); + expect(app._changeLocation).toHaveBeenCalledWith("/users/sign_in"); + }); + }); });