diff --git a/src/Umbraco.Web.UI.Client/src/common/security/retryqueue.js b/src/Umbraco.Web.UI.Client/src/common/security/retryqueue.js
index 28d91dd610..974b8c225e 100644
--- a/src/Umbraco.Web.UI.Client/src/common/security/retryqueue.js
+++ b/src/Umbraco.Web.UI.Client/src/common/security/retryqueue.js
@@ -5,10 +5,12 @@ angular.module('umbraco.security.retryQueue', [])
.factory('securityRetryQueue', ['$q', '$log', function ($q, $log) {
var retryQueue = [];
+ var retryUser = null;
+
var service = {
// The security service puts its own handler in here!
onItemAddedCallbacks: [],
-
+
hasMore: function() {
return retryQueue.length > 0;
},
@@ -23,13 +25,18 @@ angular.module('umbraco.security.retryQueue', [])
}
});
},
- pushRetryFn: function(reason, retryFn) {
+ pushRetryFn: function(reason, userName, retryFn) {
// The reason parameter is optional
- if ( arguments.length === 1) {
- retryFn = reason;
+ if ( arguments.length === 2) {
+ retryFn = userName;
+ userName = reason;
reason = undefined;
}
+ if ((retryUser && retryUser !== userName) || userName === null)
+ throw new Error('invalid user');
+ retryUser = userName;
+
// The deferred object that will be resolved or rejected by calling retry or cancel
var deferred = $q.defer();
var retryItem = {
@@ -59,8 +66,16 @@ angular.module('umbraco.security.retryQueue', [])
while(service.hasMore()) {
retryQueue.shift().cancel();
}
+ retryUser = null;
},
- retryAll: function() {
+ retryAll: function (userName) {
+
+ if (retryUser == null) return;
+ if (retryUser !== userName) {
+ service.cancelAll();
+ return;
+ }
+
while(service.hasMore()) {
retryQueue.shift().retry();
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js b/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js
index b80754ef67..e47f0663d8 100644
--- a/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js
+++ b/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js
@@ -6,7 +6,7 @@ angular.module('umbraco.security.interceptor')
return promise.then(
function(originalResponse) {
// Intercept successful requests
-
+
//Here we'll check if our custom header is in the response which indicates how many seconds the user's session has before it
//expires. Then we'll update the user in the user service accordingly.
var headers = originalResponse.headers();
@@ -15,11 +15,11 @@ angular.module('umbraco.security.interceptor')
var userService = $injector.get('userService');
userService.setUserTimeout(headers["x-umb-user-seconds"]);
}
-
+
return promise;
}, function(originalResponse) {
// Intercept failed requests
-
+
//Here we'll check if we should ignore the error, this will be based on an original header set
var headers = originalResponse.config ? originalResponse.config.headers : {};
if (headers["x-umb-ignore-error"] === "ignore") {
@@ -36,17 +36,24 @@ angular.module('umbraco.security.interceptor')
//A 401 means that the user is not logged in
if (originalResponse.status === 401) {
- // The request bounced because it was not authorized - add a new request to the retry queue
- promise = queue.pushRetryFn('unauthorized-server', function retryRequest() {
+ var userService = $injector.get('userService'); // see above
+
+ //Associate the user name with the retry to ensure we retry for the right user
+ promise = userService.getCurrentUser()
+ .then(function (user) {
+ var userName = user ? user.name : null;
+ //The request bounced because it was not authorized - add a new request to the retry queue
+ return queue.pushRetryFn('unauthorized-server', userName, function retryRequest() {
// We must use $injector to get the $http service to prevent circular dependency
return $injector.get('$http')(originalResponse.config);
+ });
});
}
else if (originalResponse.status === 404) {
//a 404 indicates that the request was not found - this could be due to a non existing url, or it could
//be due to accessing a url with a parameter that doesn't exist, either way we should notifiy the user about it
-
+
var errMsg = "The URL returned a 404 (not found):
" + originalResponse.config.url.split('?')[0] + "";
if (originalResponse.data && originalResponse.data.ExceptionMessage) {
errMsg += "
with error:
" + originalResponse.data.ExceptionMessage + "";
@@ -58,17 +65,17 @@ angular.module('umbraco.security.interceptor')
notifications.error(
"Request error",
errMsg);
-
+
}
else if (originalResponse.status === 403) {
//if the status was a 403 it means the user didn't have permission to do what the request was trying to do.
- //How do we deal with this now, need to tell the user somehow that they don't have permission to do the thing that was
+ //How do we deal with this now, need to tell the user somehow that they don't have permission to do the thing that was
//requested. We can either deal with this globally here, or we can deal with it globally for individual requests on the umbRequestHelper,
// or completely custom for services calling resources.
//http://issues.umbraco.org/issue/U4-2749
- //It was decided to just put these messages into the normal status messages.
+ //It was decided to just put these messages into the normal status messages.
var msg = "Unauthorized access to URL:
" + originalResponse.config.url.split('?')[0] + "";
if (originalResponse.config.data) {
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
index dffda24f1d..c759169752 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
@@ -31,7 +31,7 @@ angular.module('umbraco.services')
loginDialog = null;
if (success) {
- securityRetryQueue.retryAll();
+ securityRetryQueue.retryAll(currentUser.name);
}
else {
securityRetryQueue.cancelAll();
@@ -39,9 +39,9 @@ angular.module('umbraco.services')
}
}
- /**
- This methods will set the current user when it is resolved and
- will then start the counter to count in-memory how many seconds they have
+ /**
+ This methods will set the current user when it is resolved and
+ will then start the counter to count in-memory how many seconds they have
remaining on the auth session
*/
function setCurrentUser(usr) {
@@ -54,8 +54,8 @@ angular.module('umbraco.services')
countdownUserTimeout();
}
- /**
- Method to count down the current user's timeout seconds,
+ /**
+ Method to count down the current user's timeout seconds,
this will continually count down their current remaining seconds every 5 seconds until
there are no more seconds remaining.
*/
@@ -70,8 +70,8 @@ angular.module('umbraco.services')
//if there are more than 30 remaining seconds, recurse!
if (currentUser.remainingAuthSeconds > 30) {
- //we need to check when the last time the timeout was set from the server, if
- // it has been more than 30 seconds then we'll manually go and retrieve it from the
+ //we need to check when the last time the timeout was set from the server, if
+ // it has been more than 30 seconds then we'll manually go and retrieve it from the
// server - this helps to keep our local countdown in check with the true timeout.
if (lastServerTimeoutSet != null) {
var now = new Date();
@@ -79,7 +79,7 @@ angular.module('umbraco.services')
if (seconds > 30) {
- //first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
+ //first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
// wait for a response from the server otherwise we'll be making double/triple/etc... calls while we wait.
lastServerTimeoutSet = null;
@@ -98,7 +98,7 @@ angular.module('umbraco.services')
}
else {
- //we are either timed out or very close to timing out so we need to show the login dialog.
+ //we are either timed out or very close to timing out so we need to show the login dialog.
if (Umbraco.Sys.ServerVariables.umbracoSettings.keepUserLoggedIn !== true) {
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
angularHelper.safeApply($rootScope, function () {
@@ -109,14 +109,14 @@ angular.module('umbraco.services')
}
finally {
userAuthExpired();
- }
+ }
});
}
else {
//we've got less than 30 seconds remaining so let's check the server
if (lastServerTimeoutSet != null) {
- //first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
+ //first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
// wait for a response from the server otherwise we'll be making double/triple/etc... calls while we wait.
lastServerTimeoutSet = null;
@@ -211,8 +211,8 @@ angular.module('umbraco.services')
return result;
});
},
-
- /** Logs the user out
+
+ /** Logs the user out
*/
logout: function () {