fix(auth): retain protected deep-link state through sign-in

This commit is contained in:
cesnimda
2026-10-10 14:32:24 +02:00
parent c37cab560a
commit 6843767176
6 changed files with 250 additions and 18 deletions
+12 -11
View File
@@ -5,7 +5,7 @@ import { Alert, Box, Button, Checkbox, Divider, FormControlLabel, Paper, TextFie
import { useLocation, useNavigate } from "react-router-dom";
import { api, getApiErrorMessage } from "../api";
import { getRememberMePref, setAuthPersistencePreference } from "../auth";
import { getRememberMePref, safeAuthReturnPath, setAuthPersistencePreference } from "../auth";
import GoogleAuthCard from "../components/GoogleAuthCard";
import MicrosoftAuthCard from "../components/MicrosoftAuthCard";
import TwoFactorChallenge from "../components/TwoFactorChallenge";
@@ -47,13 +47,14 @@ export default function LoginPage({ initialMode = "login" }: { initialMode?: "lo
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const requestedNextPath = location?.state?.from;
const nextPath = typeof requestedNextPath === "string"
&& requestedNextPath.startsWith("/")
&& !requestedNextPath.startsWith("//")
&& !requestedNextPath.includes("\\")
? requestedNextPath
: "/dashboard";
const returnPath = new URLSearchParams(location.search).has("sessionChanged") ? undefined : safeAuthReturnPath(location.state?.from);
const nextPath = returnPath ?? "/dashboard";
const fromState = location.state?.fromState;
const contextPath = returnPath && safeAuthReturnPath(fromState?.from);
const nextOptions = contextPath ? {
replace: true,
state: { from: contextPath, ...(Number.isSafeInteger(fromState.focusJobId) && fromState.focusJobId > 0 ? { focusJobId: fromState.focusJobId } : {}) },
} : { replace: true };
useEffect(() => {
api
@@ -66,7 +67,7 @@ export default function LoginPage({ initialMode = "login" }: { initialMode?: "lo
setAuthPersistencePreference(rememberMe ? "local" : "session");
await api.get("/auth/me");
toast(t("signedIn"), "success");
navigate(nextPath, { replace: true });
navigate(nextPath, nextOptions);
}
function validate(mode: "login" | "register") {
@@ -265,8 +266,8 @@ export default function LoginPage({ initialMode = "login" }: { initialMode?: "lo
<Box sx={{ mt: 2.5 }}>
<Divider sx={{ mb: 2 }}>{t("or")}</Divider>
<Box sx={{ display: "flex", flexDirection: "column", gap: 1.25 }}>
{cfg?.googleEnabled ? <GoogleAuthCard presentation="sign-in" onSignedIn={() => { navigate(nextPath, { replace: true }); }} /> : null}
{cfg?.microsoftEnabled ? <MicrosoftAuthCard presentation="sign-in" onSignedIn={() => { navigate(nextPath, { replace: true }); }} /> : null}
{cfg?.googleEnabled ? <GoogleAuthCard presentation="sign-in" onSignedIn={() => { navigate(nextPath, nextOptions); }} /> : null}
{cfg?.microsoftEnabled ? <MicrosoftAuthCard presentation="sign-in" onSignedIn={() => { navigate(nextPath, nextOptions); }} /> : null}
</Box>
</Box>
) : null}