From 79d11f5ca0f0a1b3abf08ba45df2e140f41ed4a3 Mon Sep 17 00:00:00 2001 From: Bart Ledoux Date: Fri, 13 Dec 2024 11:28:34 +0100 Subject: [PATCH 1/3] fix: avoid redirect loops when axios calls an unauthorized API --- ui/src/utils/axios.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/src/utils/axios.js b/ui/src/utils/axios.js index 7436074e565..958709a1c44 100644 --- a/ui/src/utils/axios.js +++ b/ui/src/utils/axios.js @@ -7,6 +7,8 @@ let requestsTotal = 0 let requestsCompleted = 0 let latencyThreshold = 0 +const JWT_REFRESHED_QUERY = "__jwt_refreshed__"; + const progressComplete = () => { requestsTotal = 0 requestsCompleted = 0 @@ -115,6 +117,11 @@ export default (callback, store, router) => { const originalRequest = errorResponse.config if (!refreshing) { + // if we already tried refreshing the token, + // the user simply does not have access to this feature + if(originalRequest.data[JWT_REFRESHED_QUERY] !== 1) { + return Promise.reject(errorResponse) + } refreshing = true; try { await instance.post("/oauth/access_token?grant_type=refresh_token", null, {headers: {"Content-Type": "application/json"}}); @@ -125,7 +132,6 @@ export default (callback, store, router) => { refreshing = false; return instance(originalRequest) - } catch { document.body.classList.add("login"); store.dispatch("core/isUnsaved", false); From 1693488c4d0c67b07eae246f8294f2e0771dc5da Mon Sep 17 00:00:00 2001 From: Bart Ledoux Date: Fri, 13 Dec 2024 12:03:58 +0100 Subject: [PATCH 2/3] use the proper structure for axios --- ui/src/utils/axios.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ui/src/utils/axios.js b/ui/src/utils/axios.js index 958709a1c44..66c6be14d71 100644 --- a/ui/src/utils/axios.js +++ b/ui/src/utils/axios.js @@ -117,11 +117,14 @@ export default (callback, store, router) => { const originalRequest = errorResponse.config if (!refreshing) { + const originalRequestData = JSON.parse(originalRequest.data); + // if we already tried refreshing the token, // the user simply does not have access to this feature - if(originalRequest.data[JWT_REFRESHED_QUERY] !== 1) { + if(originalRequestData[JWT_REFRESHED_QUERY] === 1) { return Promise.reject(errorResponse) } + refreshing = true; try { await instance.post("/oauth/access_token?grant_type=refresh_token", null, {headers: {"Content-Type": "application/json"}}); @@ -131,6 +134,8 @@ export default (callback, store, router) => { toRefreshQueue = []; refreshing = false; + originalRequestData[JWT_REFRESHED_QUERY] = 1; + originalRequest.data = JSON.stringify(originalRequestData); return instance(originalRequest) } catch { document.body.classList.add("login"); From 7c4633980deab0d32477b19ca60e6278d756e2dd Mon Sep 17 00:00:00 2001 From: Bart Ledoux Date: Fri, 13 Dec 2024 12:10:53 +0100 Subject: [PATCH 3/3] protect against empty request data --- ui/src/utils/axios.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/utils/axios.js b/ui/src/utils/axios.js index 66c6be14d71..8d3fe4b197b 100644 --- a/ui/src/utils/axios.js +++ b/ui/src/utils/axios.js @@ -117,7 +117,7 @@ export default (callback, store, router) => { const originalRequest = errorResponse.config if (!refreshing) { - const originalRequestData = JSON.parse(originalRequest.data); + const originalRequestData = JSON.parse(originalRequest.data ?? "{}"); // if we already tried refreshing the token, // the user simply does not have access to this feature