From 8dafb98f47dd0efe1d5429e2d11559cf0c31ceef Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 11 Jun 2026 09:11:05 +0900 Subject: [PATCH] =?UTF-8?q?fix(products):=20=EB=AA=A8=EB=8B=AC=20401=20?= =?UTF-8?q?=EC=84=B8=EC=85=98=EB=A7=8C=EB=A3=8C=20=EC=B2=98=EB=A6=AC=20+?= =?UTF-8?q?=20callback=20open=20redirect=20=EB=B0=A9=EC=96=B4=20+=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=20=ED=8F=AC=EC=BB=A4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BankTransferModal: POST /api/orders 401 응답 시 setAuthState('guest')로 전환 (에러 텍스트 대신 로그인 유도 UI 복귀) - BankTransferModal: 모달 열릴 때 closeBtnRef.current?.focus() 호출 (접근성 초기 포커스) - auth/callback: next 파라미터를 safeNext 패턴으로 검증 — startsWith('/') && !startsWith('//') && !startsWith('/\') 미충족 시 /mypage 폴백 Co-Authored-By: Claude Sonnet 4.6 --- app/auth/callback/route.ts | 6 +++++- app/components/BankTransferModal.tsx | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/auth/callback/route.ts b/app/auth/callback/route.ts index 1d8195b..4d1fc9a 100644 --- a/app/auth/callback/route.ts +++ b/app/auth/callback/route.ts @@ -4,7 +4,11 @@ import { createClient } from '@/lib/supabase/server'; export async function GET(request: Request) { const { searchParams, origin } = new URL(request.url); const code = searchParams.get('code'); - const next = searchParams.get('next') ?? '/mypage'; + const rawNext = searchParams.get('next') ?? '/mypage'; + const next = + rawNext.startsWith('/') && !rawNext.startsWith('//') && !rawNext.startsWith('/\\') + ? rawNext + : '/mypage'; // 리다이렉트 기준 URL 결정 // - dev: 항상 현재 request의 origin (localhost) → NEXT_PUBLIC_SITE_URL 무시 diff --git a/app/components/BankTransferModal.tsx b/app/components/BankTransferModal.tsx index 2f3e000..331fa5d 100644 --- a/app/components/BankTransferModal.tsx +++ b/app/components/BankTransferModal.tsx @@ -82,6 +82,11 @@ export default function BankTransferModal({ product, isOpen, onClose }: Props) { }; }, [isOpen, onClose]); + // 초기 포커스: 모달 열릴 때 닫기 버튼으로 포커스 이동 + useEffect(() => { + if (isOpen) closeBtnRef.current?.focus(); + }, [isOpen]); + const handleSubmit = useCallback( async (e: React.FormEvent) => { e.preventDefault(); @@ -97,6 +102,11 @@ export default function BankTransferModal({ product, isOpen, onClose }: Props) { }); const data = await res.json().catch(() => ({})); if (!res.ok) { + if (res.status === 401) { + setSubmitting(false); + setAuthState('guest'); + return; + } setError(data?.error || '주문 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); setSubmitting(false); return;