// /api/auth/first-auth/route.ts // 1차 인증 처리 API 엔드포인트 import { authHelpers } from '@/lib/users/session/helper' import { NextRequest, NextResponse } from 'next/server' // 요청 데이터 타입 interface FirstAuthRequest { username: string password: string provider: 'email' | 'sgips' } // 응답 데이터 타입 interface FirstAuthResponse { success: boolean tempAuthKey?: string userId?: number email?: string error?: string errorCode?: string } export async function POST(request: NextRequest): Promise> { try { // 요청 데이터 파싱 const body: FirstAuthRequest = await request.json() const { username, password, provider } = body // 입력 검증 if (!username || !password || !provider) { return NextResponse.json( { success: false, error: '필수 입력값이 누락되었습니다.' }, { status: 400 } ) } if (!['email', 'sgips'].includes(provider)) { return NextResponse.json( { success: false, error: '지원하지 않는 인증 방식입니다.' }, { status: 400 } ) } // 레이트 리미팅 (옵셔널) // const rateLimitResult = await rateLimit.check(request, `first-auth:${username}`) // if (!rateLimitResult.success) { // return NextResponse.json( // { // success: false, // error: '너무 많은 시도입니다. 잠시 후 다시 시도해주세요.' // }, // { status: 429 } // ) // } // 1차 인증 수행 const authResult = await authHelpers.performFirstAuth(username, password, provider) if (!authResult.success) { // 인증 실패 응답 - 세분화된 에러 코드 처리 let errorMessage = '인증에 실패했습니다.' let errorCode = 'AUTHENTICATION_FAILED' // authResult.error에서 세분화된 에러 타입 확인 if (authResult.error) { switch (authResult.error) { case 'INVALID_CREDENTIALS': errorCode = 'INVALID_CREDENTIALS' errorMessage = provider === 'sgips' ? 'S-GIPS 계정 정보를 확인해주세요.' : '이메일 또는 비밀번호를 확인해주세요.' break case 'ACCOUNT_LOCKED': errorCode = 'ACCOUNT_LOCKED' errorMessage = '계정이 일시적으로 잠겼습니다. 잠시 후 다시 시도해주세요.' break case 'ACCOUNT_DEACTIVATED': errorCode = 'ACCOUNT_DEACTIVATED' errorMessage = '비활성화된 계정입니다. 관리자에게 문의해주세요.' break case 'RATE_LIMITED': errorCode = 'RATE_LIMITED' errorMessage = '로그인 시도가 너무 많습니다. 잠시 후 다시 시도해주세요.' break case 'VENDOR_NOT_FOUND': errorCode = 'VENDOR_NOT_FOUND' errorMessage = '등록되지 않은 벤더입니다. 담당자에게 문의해주세요.' break case 'SYSTEM_ERROR': errorCode = 'SYSTEM_ERROR' errorMessage = '일시적인 시스템 오류입니다. 계속 문제가 발생하면 담당자에게 문의해주세요.' break default: errorCode = 'AUTHENTICATION_FAILED' errorMessage = provider === 'sgips' ? 'S-Gips 인증에 실패했습니다.' : '인증에 실패했습니다.' } } return NextResponse.json( { success: false, error: errorMessage, errorCode: errorCode }, { status: 401 } ) } // 1차 인증 성공 응답 return NextResponse.json({ success: true, tempAuthKey: authResult.tempAuthKey, userId: authResult.userId, email: authResult.email }) } catch (error) { console.error('First auth API error:', error) // 에러 응답 return NextResponse.json( { success: false, error: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.' }, { status: 500 } ) } } // GET 요청은 지원하지 않음 export async function GET() { return NextResponse.json( { error: 'Method not allowed' }, { status: 405 } ) }