diff --git a/frontend/login.vue b/frontend/login.vue index c13db07..29965ea 100644 --- a/frontend/login.vue +++ b/frontend/login.vue @@ -60,12 +60,20 @@ definePageMeta({ layout: false }) const router = useRouter() +const route = useRoute() const email = ref('') const password = ref('') const isSubmitting = ref(false) const errorMessage = ref('') +// URL에서 error 파라미터 읽기 +onMounted(() => { + if (route.query.error) { + errorMessage.value = route.query.error as string + } +}) + async function handlePasswordLogin() { if (!email.value || !password.value) return isSubmitting.value = true diff --git a/server/api/auth/synology/callback.get.ts b/server/api/auth/synology/callback.get.ts index 9c61eb6..3d84008 100644 --- a/server/api/auth/synology/callback.get.ts +++ b/server/api/auth/synology/callback.get.ts @@ -89,8 +89,8 @@ export default defineEventHandler(async (event) => { // 5. 로그인 이력 기록 await execute(` - INSERT INTO wr_login_history (employee_id, login_type, login_ip, login_at, login_success, login_email) - VALUES ($1, 'SYNOLOGY', $2, NOW(), true, $3) + INSERT INTO wr_login_history (employee_id, login_type, login_ip, login_at, login_email) + VALUES ($1, 'SYNOLOGY', $2, NOW(), $3) `, [employee.employee_id, ip, synologyEmail]) // 6. 세션 생성 diff --git a/server/api/auth/synology/verify.post.ts b/server/api/auth/synology/verify.post.ts index ae23e50..70da675 100644 --- a/server/api/auth/synology/verify.post.ts +++ b/server/api/auth/synology/verify.post.ts @@ -23,113 +23,53 @@ export default defineEventHandler(async (event) => { console.log('[Synology SSO] Access Token:', accessToken) try { - // 1. 액세스 토큰으로 사용자 정보 조회 - const userInfoUrl = `${config.synologyServerUrl}/webman/sso/SSOUserInfo.cgi` + // SSOAccessToken.cgi로 사용자 정보 조회 + const tokenInfoUrl = `${config.synologyServerUrl}/webman/sso/SSOAccessToken.cgi?action=exchange&access_token=${accessToken}&app_id=${config.synologyClientId}` - console.log('[Synology SSO] Requesting user info...') + console.log('[Synology SSO] Requesting:', tokenInfoUrl) - let userResponse = await $fetch(userInfoUrl, { - method: 'GET', - headers: { - 'Authorization': `Bearer ${accessToken}` - } - }) + let tokenResponse = await $fetch(tokenInfoUrl) // 문자열로 온 경우 JSON 파싱 - if (typeof userResponse === 'string') { - userResponse = JSON.parse(userResponse) + if (typeof tokenResponse === 'string') { + tokenResponse = JSON.parse(tokenResponse) } - console.log('[Synology SSO] User Response:', JSON.stringify(userResponse, null, 2)) + console.log('[Synology SSO] Response:', JSON.stringify(tokenResponse, null, 2)) - if (!userResponse.data || !userResponse.data.email) { - // email이 없으면 SSOAccessToken.cgi로 시도 - const tokenInfoUrl = `${config.synologyServerUrl}/webman/sso/SSOAccessToken.cgi?action=exchange&access_token=${accessToken}&app_id=${config.synologyClientId}` - - let tokenResponse = await $fetch(tokenInfoUrl) - if (typeof tokenResponse === 'string') { - tokenResponse = JSON.parse(tokenResponse) - } - - console.log('[Synology SSO] Token Response:', JSON.stringify(tokenResponse, null, 2)) - - if (!tokenResponse.success) { - throw createError({ - statusCode: 401, - message: 'Synology 사용자 정보를 가져올 수 없습니다.' - }) - } - - // user_name으로 사용자 조회 - const synologyUsername = tokenResponse.data?.user_name - - if (!synologyUsername) { - throw createError({ - statusCode: 401, - message: 'Synology 사용자명을 가져올 수 없습니다.' - }) - } - - console.log('[Synology SSO] Username:', synologyUsername) - - // synology_id나 email의 앞부분으로 매칭 시도 - const synologyEmail = `${synologyUsername}@osolit.net` - - const employee = await queryOne(` - SELECT employee_id, employee_name, is_active, password_hash, - synology_id, synology_email, employee_email - FROM wr_employee_info - WHERE synology_id = $1 - OR employee_email = $2 - `, [synologyUsername, synologyEmail]) - - if (!employee) { - throw createError({ - statusCode: 404, - message: `Synology 계정 "${synologyUsername}"과 연결된 사용자를 찾을 수 없습니다. 관리자에게 문의하세요.` - }) - } - - if (!employee.is_active) { - throw createError({ - statusCode: 403, - message: '비활성화된 계정입니다.' - }) - } - - // 로그인 이력 기록 - await execute(` - INSERT INTO wr_login_history (employee_id, login_type, login_ip, login_at, login_success, login_email) - VALUES ($1, 'SYNOLOGY', $2, NOW(), true, $3) - `, [employee.employee_id, ip, synologyUsername]) - - // 세션 생성 - await createSession(event, employee.employee_id) - - return { - success: true, - needPasswordSet: !employee.password_hash - } + if (!tokenResponse.success) { + throw createError({ + statusCode: 401, + message: 'Synology 토큰 검증에 실패했습니다.' + }) } - // 이메일이 있는 경우 - const synologyEmail = userResponse.data.email - const synologyId = userResponse.data.user_id || userResponse.data.uid + const synologyUsername = tokenResponse.data?.user_name - console.log('[Synology SSO] Email:', synologyEmail) + if (!synologyUsername) { + throw createError({ + statusCode: 401, + message: 'Synology 사용자명을 가져올 수 없습니다.' + }) + } + + console.log('[Synology SSO] Username:', synologyUsername) + + // username@osolit.net 으로 매칭 + const synologyEmail = `${synologyUsername}@osolit.net` - // 이메일로 사용자 매칭 const employee = await queryOne(` SELECT employee_id, employee_name, is_active, password_hash, - synology_id, synology_email + synology_id, synology_email, employee_email FROM wr_employee_info - WHERE employee_email = $1 - `, [synologyEmail]) + WHERE synology_id = $1 + OR employee_email = $2 + `, [synologyUsername, synologyEmail]) if (!employee) { throw createError({ statusCode: 404, - message: '등록되지 않은 사용자입니다. 관리자에게 문의하세요.' + message: `Synology 계정 "${synologyUsername}"과 연결된 사용자를 찾을 수 없습니다. (${synologyEmail}) 관리자에게 문의하세요.` }) } @@ -140,17 +80,17 @@ export default defineEventHandler(async (event) => { }) } - // Synology 계정 연결 정보 업데이트 + // Synology ID 업데이트 await execute(` UPDATE wr_employee_info - SET synology_id = $1, synology_email = $2, synology_linked_at = NOW() - WHERE employee_id = $3 - `, [synologyId, synologyEmail, employee.employee_id]) + SET synology_id = $1, synology_linked_at = NOW() + WHERE employee_id = $2 + `, [synologyUsername, employee.employee_id]) // 로그인 이력 기록 await execute(` - INSERT INTO wr_login_history (employee_id, login_type, login_ip, login_at, login_success, login_email) - VALUES ($1, 'SYNOLOGY', $2, NOW(), true, $3) + INSERT INTO wr_login_history (employee_id, login_type, login_ip, login_at, login_email) + VALUES ($1, 'SYNOLOGY', $2, NOW(), $3) `, [employee.employee_id, ip, synologyEmail]) // 세션 생성