Merge pull request #3166 from payloadcms/fix/external-website-redirects
fix: do not allow redirects to external sites
This commit is contained in:
@@ -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 />
|
||||||
|
|||||||
@@ -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={{
|
||||||
|
|||||||
@@ -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 || ''));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user