mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-02 21:03:34 +03:00
Fix refreshing causing you to go to the Processor (#7694)
This commit is contained in:
@@ -113,6 +113,16 @@ class RequestUriUtilsTest {
|
||||
assertTrue(RequestUriUtils.isFrontendRoute("", "/split-pdf"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsFrontendRoute_editorRouteOwnedByFrontend() {
|
||||
// /editor (and its tool routes) is an SPA route: a direct-nav/refresh must
|
||||
// serve index.html, not the auth filter's 302-to-/login. Regression test for
|
||||
// the editor moving from / to /editor, whose refresh bounced processor users
|
||||
// to the processor because the redirect dropped the return path.
|
||||
assertTrue(RequestUriUtils.isFrontendRoute("", "/editor"));
|
||||
assertTrue(RequestUriUtils.isFrontendRoute("/app", "/app/editor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsFrontendRoute_filesRouteOwnedByFrontend() {
|
||||
// /files and /files/<folder-uuid> are FileManagerView routes - they
|
||||
|
||||
+3
-3
@@ -357,12 +357,12 @@ public class SecurityConfiguration {
|
||||
req -> {
|
||||
String uri = req.getRequestURI();
|
||||
String contextPath = req.getContextPath();
|
||||
// Check if it's a public auth endpoint or static
|
||||
// resource
|
||||
return RequestUriUtils.isStaticResource(
|
||||
contextPath, uri)
|
||||
|| RequestUriUtils.isPublicAuthEndpoint(
|
||||
uri, contextPath);
|
||||
uri, contextPath)
|
||||
|| RequestUriUtils.isFrontendRoute(
|
||||
contextPath, uri);
|
||||
})
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
|
||||
@@ -234,7 +234,10 @@ describe("Login", () => {
|
||||
);
|
||||
};
|
||||
|
||||
afterEach(() => window.history.replaceState({}, "", "/"));
|
||||
afterEach(() => {
|
||||
window.history.replaceState({}, "", "/");
|
||||
sessionStorage.clear();
|
||||
});
|
||||
|
||||
it("returns to where the user came from", async () => {
|
||||
signedIn();
|
||||
@@ -247,6 +250,24 @@ describe("Login", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// A full-page 401 redirect drops router state and Spring can strip ?from=,
|
||||
// leaving the return path only in the sessionStorage stash. Without reading
|
||||
// it here a processor user refreshing /editor falls through to the role
|
||||
// router and lands on the processor.
|
||||
it("returns to the stashed path when there is no ?from=", async () => {
|
||||
signedIn();
|
||||
sessionStorage.setItem("stirling_post_login_path", "/compress");
|
||||
renderAtLogin("");
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockNavigate).toHaveBeenCalledWith("/compress", {
|
||||
replace: true,
|
||||
});
|
||||
});
|
||||
// Consumed, so a later sign-in can't reuse a stale path.
|
||||
expect(sessionStorage.getItem("stirling_post_login_path")).toBeNull();
|
||||
});
|
||||
|
||||
// Delegated to the shared isSafePostLoginRedirect, so the backslash form
|
||||
// (browsers normalise "\" to "/") and auth routes are covered too.
|
||||
it.each([
|
||||
|
||||
@@ -7,7 +7,10 @@ import {
|
||||
} from "react-router-dom";
|
||||
import { Button } from "@app/ui/Button";
|
||||
import { isSafePostLoginRedirect } from "@app/auth";
|
||||
import { setPostLoginRedirectPath } from "@app/auth/spring/springAuthClient";
|
||||
import {
|
||||
setPostLoginRedirectPath,
|
||||
consumePostLoginRedirectPath,
|
||||
} from "@app/auth/spring/springAuthClient";
|
||||
import { useAuth } from "@app/auth/UseSession";
|
||||
import { useAppConfig } from "@app/contexts/AppConfigContext";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -207,7 +210,8 @@ export default function Login() {
|
||||
useEffect(() => {
|
||||
if (loading) return;
|
||||
if (!session) return;
|
||||
const returnPath = resolveReturnPath();
|
||||
const stashed = consumePostLoginRedirectPath();
|
||||
const returnPath = resolveReturnPath() ?? stashed;
|
||||
if (returnPath) {
|
||||
navigate(returnPath, { replace: true });
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { AxiosInstance, AxiosError, InternalAxiosRequestConfig } from "axios";
|
||||
import { withBasePath } from "@app/constants/app";
|
||||
import { getBrowserId } from "@app/utils/browserIdentifier";
|
||||
import { setPostLoginRedirectPath } from "@app/auth/spring/springAuthClient";
|
||||
|
||||
let isRefreshing = false;
|
||||
let failedQueue: Array<{
|
||||
@@ -93,6 +94,9 @@ async function refreshAuthToken(client: AxiosInstance): Promise<string> {
|
||||
// Redirect to login
|
||||
const loginPath = withBasePath("/login");
|
||||
if (window.location.pathname !== loginPath) {
|
||||
setPostLoginRedirectPath(
|
||||
window.location.pathname + window.location.search,
|
||||
);
|
||||
console.log("[API Client] Redirecting to login page...");
|
||||
window.location.href = loginPath;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user