Files
weeklyreport/backend/api/auth/change-password.post.ts
2026-01-11 12:59:21 +09:00

66 lines
2.2 KiB
TypeScript

import { query, queryOne, execute } from '../../utils/db'
import { getClientIp } from '../../utils/ip'
import { requireAuth } from '../../utils/session'
import { hashPassword, verifyPassword } from '../../utils/password'
interface ChangePasswordBody {
currentPassword?: string
newPassword: string
confirmPassword: string
}
/**
* 비밀번호 변경
* POST /api/auth/change-password
*/
export default defineEventHandler(async (event) => {
const employeeId = await requireAuth(event)
const body = await readBody<ChangePasswordBody>(event)
const clientIp = getClientIp(event)
if (!body.newPassword || !body.confirmPassword) {
throw createError({ statusCode: 400, message: '새 비밀번호를 입력해주세요.' })
}
if (body.newPassword !== body.confirmPassword) {
throw createError({ statusCode: 400, message: '비밀번호가 일치하지 않습니다.' })
}
if (body.newPassword.length < 8) {
throw createError({ statusCode: 400, message: '비밀번호는 8자 이상이어야 합니다.' })
}
// 현재 직원 정보 조회
const employee = await queryOne<any>(`
SELECT password_hash, employee_email FROM wr_employee_info WHERE employee_id = $1
`, [employeeId])
if (!employee) {
throw createError({ statusCode: 404, message: '사용자를 찾을 수 없습니다.' })
}
// 기존 비밀번호가 있으면 현재 비밀번호 검증
if (employee.password_hash) {
if (!body.currentPassword) {
throw createError({ statusCode: 400, message: '현재 비밀번호를 입력해주세요.' })
}
const isValid = await verifyPassword(body.currentPassword, employee.password_hash)
if (!isValid) {
throw createError({ statusCode: 401, message: '현재 비밀번호가 올바르지 않습니다.' })
}
}
// 새 비밀번호 해시
const newHash = await hashPassword(body.newPassword)
// 비밀번호 업데이트
await execute(`
UPDATE wr_employee_info
SET password_hash = $1, updated_at = NOW(), updated_ip = $2, updated_email = $3
WHERE employee_id = $4
`, [newHash, clientIp, employee.employee_email, employeeId])
return { success: true, message: '비밀번호가 변경되었습니다.' }
})