diff --git a/app/auth/callback/route.ts b/app/auth/callback/route.ts index 6fe38d4..7873e82 100644 --- a/app/auth/callback/route.ts +++ b/app/auth/callback/route.ts @@ -62,8 +62,33 @@ export async function GET(request: NextRequest) { if (!exchangeError) { // ---------------------------------------------------------------------- // 3-1. 교환 성공: 리다이렉트 처리 - // 코드 파라미터 등을 제거하고 깨끗한 URL로 이동합니다. + // code 교환으로 세션이 생성된 상태입니다. // ---------------------------------------------------------------------- + + const { + data: { user }, + } = await supabase.auth.getUser(); + + // 회원가입 직후 인증 여부 확인 (생성된 지 1분 이내) + // 별도의 type 파라미터 없이 데이터 기반으로 판단합니다. + const isNewUser = + user && + user.created_at && + new Date(user.created_at).getTime() > Date.now() - 60 * 1000; // 1분 이내 생성 + + // 회원가입 인증인 경우: + // 이메일 인증만 완료하고, 자동 로그인된 세션은 종료시킨 뒤 로그인 페이지로 보냅니다. + if (isNewUser) { + await supabase.auth.signOut(); + return NextResponse.redirect( + `${origin}${AUTH_ROUTES.LOGIN}?message=${encodeURIComponent( + AUTH_ERROR_MESSAGES.EMAIL_VERIFIED_SUCCESS, + )}`, + ); + } + + // 그 외 일반적인 로그인/인증인 경우: + // 코드 파라미터 등을 제거하고 깨끗한 URL로 이동합니다. const forwardedHost = request.headers.get("x-forwarded-host"); // 로드밸런서 지원 const isLocalEnv = process.env.NODE_ENV === "development"; diff --git a/features/auth/constants.ts b/features/auth/constants.ts index c60ee3a..b42a628 100644 --- a/features/auth/constants.ts +++ b/features/auth/constants.ts @@ -40,6 +40,7 @@ export const AUTH_ERROR_MESSAGES = { // === 인증 링크 === INVALID_AUTH_LINK: "인증 링크가 만료되었거나 유효하지 않습니다.", + EMAIL_VERIFIED_SUCCESS: "이메일 인증이 완료되었습니다. 로그인해 주세요.", // === 소셜 로그인 (OAuth) 관련 === OAUTH_ACCESS_DENIED: "로그인이 취소되었습니다.", @@ -106,8 +107,10 @@ export const AUTH_ERROR_CODE_MESSAGES = { mfa_verification_failed: "MFA 검증에 실패했습니다.", mfa_verification_rejected: "MFA 검증이 거부되었습니다.", mfa_verified_factor_exists: "이미 검증된 전화 MFA가 존재합니다.", - mfa_web_authn_enroll_not_enabled: "WebAuthn MFA 등록이 비활성화되어 있습니다.", - mfa_web_authn_verify_not_enabled: "WebAuthn MFA 검증이 비활성화되어 있습니다.", + mfa_web_authn_enroll_not_enabled: + "WebAuthn MFA 등록이 비활성화되어 있습니다.", + mfa_web_authn_verify_not_enabled: + "WebAuthn MFA 검증이 비활성화되어 있습니다.", no_authorization: "Authorization 헤더가 필요합니다.", not_admin: "관리자 권한이 없습니다.", oauth_provider_not_supported: "OAuth 제공자가 비활성화되어 있습니다.",