Skip to content

Commit eba3b7b

Browse files
committed
fix: prevent abuse of redirect behavior
1 parent 4ad7f82 commit eba3b7b

File tree

3 files changed

+34
-19
lines changed

3 files changed

+34
-19
lines changed

packages/diracx-web-components/src/components/Login/LoginForm.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import { Stack } from "@mui/material";
1414
import { useOidc } from "@axa-fr/react-oidc";
1515
import { useMetadata, Metadata } from "../../hooks/metadata";
1616
import { useOIDCContext } from "../../hooks/oidcConfiguration";
17-
18-
import { useSearchParamsUtils } from "../../hooks/searchParamsUtils";
1917
import { NavigationContext } from "../../contexts/NavigationProvider";
2018
import { useDiracxUrl } from "../../hooks";
2119

@@ -39,7 +37,6 @@ export function LoginForm({
3937
const { configuration, setConfiguration } = useOIDCContext();
4038
const { isAuthenticated, login } = useOidc(configuration?.scope);
4139
const { setPath } = useContext(NavigationContext);
42-
const { getParam } = useSearchParamsUtils();
4340
const OIDC_LOGIN_ATTEMPTED_KEY = "oidcLoginAttempted";
4441

4542
// Login if not authenticated
@@ -60,14 +57,10 @@ export function LoginForm({
6057
// Redirect to dashboard if already authenticated
6158
if (isAuthenticated) {
6259
sessionStorage.removeItem(OIDC_LOGIN_ATTEMPTED_KEY);
63-
const redirect = getParam("redirect");
64-
if (redirect) {
65-
setPath(redirect);
66-
} else {
67-
setPath("/");
68-
}
60+
// Redirect to the root path
61+
setPath("/");
6962
}
70-
}, [getParam, isAuthenticated, setPath]);
63+
}, [isAuthenticated, setPath]);
7164

7265
// Get default group
7366
const getDefaultGroup = (

packages/diracx-web-components/src/components/OIDC/OIDCSecure.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,14 @@ export function OIDCSecure({ children }: OIDCProps) {
1818
const { configuration } = useOIDCContext();
1919
const { isAuthenticated } = useOidc(configuration?.scope);
2020
const { setPath } = useContext(NavigationContext);
21+
const pathName = useContext(NavigationContext).getPath();
2122

2223
useEffect(() => {
2324
// Redirect to login page if not authenticated
24-
if (!isAuthenticated) {
25-
setPath(
26-
"/auth?" +
27-
// URLSearchParams to ensure that auth redirects users to the URL they came from
28-
new URLSearchParams({
29-
redirect: window.location.pathname + window.location.search,
30-
}).toString(),
31-
);
25+
if (!isAuthenticated && !pathName.startsWith("/auth")) {
26+
setPath("/auth");
3227
}
33-
}, [isAuthenticated, setPath]);
28+
}, [isAuthenticated, setPath, pathName]);
3429

3530
return <>{children}</>;
3631
}

packages/diracx-web/test/e2e/loginOut.cy.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,31 @@ describe("Login and Logout", () => {
6969
cy.visit("/");
7070
cy.url().should("include", "/auth");
7171
});
72+
73+
it("prevent infinite login loop", () => {
74+
// The user is redirected to the /auth page because not authenticated
75+
// Make sure we are on the /auth page
76+
cy.url().should("include", "/auth");
77+
78+
const currentUrl = cy.url();
79+
80+
cy.wait(5000); // Wait 5 seconds to let a possible infinite loop happen
81+
82+
// Check that the URL has not changed
83+
cy.url().should("eq", currentUrl);
84+
85+
// Login
86+
cy.get('[data-testid="button-login"]').click();
87+
cy.get("#login").type("[email protected]");
88+
cy.get("#password").type("password");
89+
90+
// Find the login button and click on it
91+
cy.get("button").click();
92+
// Grant access
93+
cy.get(":nth-child(1) > form > .dex-btn").click();
94+
cy.url().should("include", "/auth");
95+
96+
// The user is redirected to the dashboard page
97+
cy.url().should("eq", Cypress.config().baseUrl);
98+
});
7299
});

0 commit comments

Comments
 (0)