summaryrefslogtreecommitdiff
path: root/app/api/auth/first-auth/route.ts
blob: e8d86a02f0e6b5604f40440525fa9f9bab653ba9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// /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<NextResponse<FirstAuthResponse>> {
  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 }
  )
}