Merge pull request #3166 from payloadcms/fix/external-website-redirects

fix: do not allow redirects to external sites
This commit is contained in:
Alessio Gravili
2023-08-14 17:20:07 +02:00
committed by GitHub
3 changed files with 19 additions and 9 deletions

View File

@@ -315,7 +315,7 @@ const Routes: React.FC = () => {
<Unauthorized /> <Unauthorized />
)} )}
</Fragment> </Fragment>
) : <Redirect to={`${match.url}/login?redirect=${encodeURIComponent(window.location.pathname)}`} />} ) : <Redirect to={`${match.url}/login${window.location.pathname.startsWith(routes.admin) ? `?redirect=${encodeURIComponent(window.location.pathname.replace(routes.admin, ''))}` : ''}`} />}
</Route> </Route>
<Route path={`${match.url}*`}> <Route path={`${match.url}*`}>
<NotFound /> <NotFound />

View File

@@ -46,6 +46,16 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
const id = user?.id; 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 refreshCookie = useCallback((forceRefresh?: boolean) => {
const now = Math.round((new Date()).getTime() / 1000); const now = Math.round((new Date()).getTime() / 1000);
const remainingTime = (exp as number || 0) - now; const remainingTime = (exp as number || 0) - now;
@@ -64,14 +74,14 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
setUser(json.user); setUser(json.user);
} else { } else {
setUser(null); setUser(null);
push(`${admin}${logoutInactivityRoute}?redirect=${encodeURIComponent(window.location.pathname)}`); redirectToInactivityRoute();
} }
} catch (e) { } catch (e) {
toast.error(e.message); toast.error(e.message);
} }
}, 1000); }, 1000);
} }
}, [exp, serverURL, api, userSlug, push, admin, logoutInactivityRoute, i18n]); }, [exp, serverURL, api, userSlug, i18n, redirectToInactivityRoute]);
const refreshCookieAsync = useCallback(async (skipSetUser?: boolean): Promise<User> => { const refreshCookieAsync = useCallback(async (skipSetUser?: boolean): Promise<User> => {
try { try {
@@ -88,13 +98,13 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
} }
setUser(null); setUser(null);
push(`${admin}${logoutInactivityRoute}`); redirectToInactivityRoute();
return null; return null;
} catch (e) { } catch (e) {
toast.error(`Refreshing token failed: ${e.message}`); toast.error(`Refreshing token failed: ${e.message}`);
return null; return null;
} }
}, [serverURL, api, userSlug, push, admin, logoutInactivityRoute, i18n]); }, [serverURL, api, userSlug, i18n, redirectToInactivityRoute]);
const setToken = useCallback((token: string) => { const setToken = useCallback((token: string) => {
const decoded = jwtDecode<User>(token); const decoded = jwtDecode<User>(token);
@@ -220,15 +230,14 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
if (remainingTime > 0) { if (remainingTime > 0) {
forceLogOut = setTimeout(() => { forceLogOut = setTimeout(() => {
setUser(null); setUser(null);
push(`${admin}${logoutInactivityRoute}?redirect=${encodeURIComponent(window.location.pathname)}`); redirectToInactivityRoute();
closeAllModals();
}, Math.min(remainingTime * 1000, maxTimeoutTime)); }, Math.min(remainingTime * 1000, maxTimeoutTime));
} }
return () => { return () => {
if (forceLogOut) clearTimeout(forceLogOut); if (forceLogOut) clearTimeout(forceLogOut);
}; };
}, [exp, push, closeAllModals, admin, i18n, logoutInactivityRoute]); }, [exp, closeAllModals, i18n, redirectToInactivityRoute]);
return ( return (
<Context.Provider value={{ <Context.Provider value={{

View File

@@ -51,7 +51,8 @@ const Login: React.FC = () => {
if (data.token) { if (data.token) {
setToken(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 || ''));
} }
}; };