From c7b213bf1775ea9c9e88f1532962fd1f046687c6 Mon Sep 17 00:00:00 2001 From: kyy Date: Wed, 8 Apr 2026 10:49:08 +0900 Subject: [PATCH] =?UTF-8?q?devfront=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20auto=20redirect=20SSO=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/auth/AuthCallbackPage.tsx | 11 ++++- devfront/src/features/auth/LoginPage.tsx | 41 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/devfront/src/features/auth/AuthCallbackPage.tsx b/devfront/src/features/auth/AuthCallbackPage.tsx index 929bc7b4..1cf9be59 100644 --- a/devfront/src/features/auth/AuthCallbackPage.tsx +++ b/devfront/src/features/auth/AuthCallbackPage.tsx @@ -17,12 +17,19 @@ export default function AuthCallbackPage() { } if (auth.isAuthenticated) { - navigate("/", { replace: true }); + const returnTo = + typeof auth.user?.state === "object" && + auth.user?.state !== null && + "returnTo" in auth.user.state && + typeof auth.user.state.returnTo === "string" + ? auth.user.state.returnTo + : "/clients"; + navigate(returnTo, { replace: true }); } else if (auth.error) { console.error("Auth Error:", auth.error); navigate("/login", { replace: true }); } - }, [auth.isAuthenticated, auth.error, navigate]); + }, [auth.isAuthenticated, auth.error, navigate, auth.user?.state]); return
Loading Auth...
; } diff --git a/devfront/src/features/auth/LoginPage.tsx b/devfront/src/features/auth/LoginPage.tsx index 3c87a65e..cd9f8ca1 100644 --- a/devfront/src/features/auth/LoginPage.tsx +++ b/devfront/src/features/auth/LoginPage.tsx @@ -1,7 +1,8 @@ import { ExternalLink, LogIn, ShieldHalf } from "lucide-react"; -import { useEffect } from "react"; +import { useEffect, useRef } from "react"; import { useAuth } from "react-oidc-context"; import { useNavigate } from "react-router-dom"; +import { useSearchParams } from "react-router-dom"; import { Button } from "../../components/ui/button"; import { Card, @@ -14,18 +15,48 @@ import { function LoginPage() { const auth = useAuth(); const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const autoStartedRef = useRef(false); + const returnTo = searchParams.get("returnTo") || "/clients"; + const shouldAutoLogin = searchParams.get("auto") === "1"; useEffect(() => { if (auth.isAuthenticated) { - navigate("/clients", { replace: true }); + navigate(returnTo, { replace: true }); } - }, [auth.isAuthenticated, navigate]); + }, [auth.isAuthenticated, navigate, returnTo]); + + useEffect(() => { + if (!shouldAutoLogin) { + return; + } + if (autoStartedRef.current || auth.isLoading || auth.activeNavigator) { + return; + } + + autoStartedRef.current = true; + void auth.signinRedirect({ + state: { + returnTo, + }, + }); + }, [ + auth, + auth.activeNavigator, + auth.isLoading, + returnTo, + shouldAutoLogin, + ]); const handleSSOLogin = async () => { try { - await auth.signinPopup(); + await auth.signinRedirect({ + state: { + returnTo: "/clients", + }, + }); } catch (error) { - console.error("Popup login failed", error); + console.error("Redirect login failed", error); } };