From c0f05a1c38fb9c958de920fabb698b5ecfb661f0 Mon Sep 17 00:00:00 2001 From: Alessio Gravili Date: Sun, 13 Aug 2023 16:25:14 +0200 Subject: [PATCH 1/2] fix: only allow redirects to /admin sub-routes --- src/admin/components/Routes.tsx | 2 +- src/admin/components/utilities/Auth/index.tsx | 14 ++++++++++++-- src/admin/components/views/Login/index.tsx | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/admin/components/Routes.tsx b/src/admin/components/Routes.tsx index 9bab1d07f4..8efc59fe89 100644 --- a/src/admin/components/Routes.tsx +++ b/src/admin/components/Routes.tsx @@ -315,7 +315,7 @@ const Routes: React.FC = () => { )} - ) : } + ) : } diff --git a/src/admin/components/utilities/Auth/index.tsx b/src/admin/components/utilities/Auth/index.tsx index f225734a4a..f17666acef 100644 --- a/src/admin/components/utilities/Auth/index.tsx +++ b/src/admin/components/utilities/Auth/index.tsx @@ -64,7 +64,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children setUser(json.user); } else { setUser(null); - push(`${admin}${logoutInactivityRoute}?redirect=${encodeURIComponent(window.location.pathname)}`); + if (window.location.pathname.startsWith(admin)) { + const redirectParam = `?redirect=${encodeURIComponent(window.location.pathname.replace(admin, ''))}`; + push(`${admin}${logoutInactivityRoute}${redirectParam}`); + } else { + push(`${admin}${logoutInactivityRoute}`); + } } } catch (e) { toast.error(e.message); @@ -220,7 +225,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children if (remainingTime > 0) { forceLogOut = setTimeout(() => { setUser(null); - push(`${admin}${logoutInactivityRoute}?redirect=${encodeURIComponent(window.location.pathname)}`); + if (window.location.pathname.startsWith(admin)) { + const redirectParam = `?redirect=${encodeURIComponent(window.location.pathname.replace(admin, ''))}`; + push(`${admin}${logoutInactivityRoute}${redirectParam}`); + } else { + push(`${admin}${logoutInactivityRoute}`); + } closeAllModals(); }, Math.min(remainingTime * 1000, maxTimeoutTime)); } diff --git a/src/admin/components/views/Login/index.tsx b/src/admin/components/views/Login/index.tsx index 346977a11b..7262622177 100644 --- a/src/admin/components/views/Login/index.tsx +++ b/src/admin/components/views/Login/index.tsx @@ -51,7 +51,8 @@ const Login: React.FC = () => { if (data.token) { setToken(data.token); - history.push(redirect || admin); + // Ensure the redirect always starts with the admin route, and concatenate the redirect path + history.push(admin + (redirect || '')); } }; From 679722273338064412223c627635965513ba8831 Mon Sep 17 00:00:00 2001 From: Alessio Gravili Date: Mon, 14 Aug 2023 17:19:19 +0200 Subject: [PATCH 2/2] chore: remove duplicate code --- src/admin/components/utilities/Auth/index.tsx | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/admin/components/utilities/Auth/index.tsx b/src/admin/components/utilities/Auth/index.tsx index f17666acef..7d7a7af9b4 100644 --- a/src/admin/components/utilities/Auth/index.tsx +++ b/src/admin/components/utilities/Auth/index.tsx @@ -46,6 +46,16 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children const id = user?.id; + const redirectToInactivityRoute = useCallback(() => { + if (window.location.pathname.startsWith(admin)) { + const redirectParam = `?redirect=${encodeURIComponent(window.location.pathname.replace(admin, ''))}`; + push(`${admin}${logoutInactivityRoute}${redirectParam}`); + } else { + push(`${admin}${logoutInactivityRoute}`); + } + closeAllModals(); + }, [push, admin, logoutInactivityRoute, closeAllModals]); + const refreshCookie = useCallback((forceRefresh?: boolean) => { const now = Math.round((new Date()).getTime() / 1000); const remainingTime = (exp as number || 0) - now; @@ -64,19 +74,14 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children setUser(json.user); } else { setUser(null); - if (window.location.pathname.startsWith(admin)) { - const redirectParam = `?redirect=${encodeURIComponent(window.location.pathname.replace(admin, ''))}`; - push(`${admin}${logoutInactivityRoute}${redirectParam}`); - } else { - push(`${admin}${logoutInactivityRoute}`); - } + redirectToInactivityRoute(); } } catch (e) { toast.error(e.message); } }, 1000); } - }, [exp, serverURL, api, userSlug, push, admin, logoutInactivityRoute, i18n]); + }, [exp, serverURL, api, userSlug, i18n, redirectToInactivityRoute]); const refreshCookieAsync = useCallback(async (skipSetUser?: boolean): Promise => { try { @@ -93,13 +98,13 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children } setUser(null); - push(`${admin}${logoutInactivityRoute}`); + redirectToInactivityRoute(); return null; } catch (e) { toast.error(`Refreshing token failed: ${e.message}`); return null; } - }, [serverURL, api, userSlug, push, admin, logoutInactivityRoute, i18n]); + }, [serverURL, api, userSlug, i18n, redirectToInactivityRoute]); const setToken = useCallback((token: string) => { const decoded = jwtDecode(token); @@ -225,20 +230,14 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children if (remainingTime > 0) { forceLogOut = setTimeout(() => { setUser(null); - if (window.location.pathname.startsWith(admin)) { - const redirectParam = `?redirect=${encodeURIComponent(window.location.pathname.replace(admin, ''))}`; - push(`${admin}${logoutInactivityRoute}${redirectParam}`); - } else { - push(`${admin}${logoutInactivityRoute}`); - } - closeAllModals(); + redirectToInactivityRoute(); }, Math.min(remainingTime * 1000, maxTimeoutTime)); } return () => { if (forceLogOut) clearTimeout(forceLogOut); }; - }, [exp, push, closeAllModals, admin, i18n, logoutInactivityRoute]); + }, [exp, closeAllModals, i18n, redirectToInactivityRoute]); return (