Files
weeklyreport/server/api/auth/reset-password.post.ts
Hyoseong Jo 4022ccf7e7 feat: 비밀번호 찾기 휴대폰 번호 필수 입력으로 변경
- 휴대폰 번호 선택 → 필수 입력으로 변경
- 이메일: 양쪽 모두 소문자로 비교
- 핸드폰: 양쪽 모두 숫자만 추출하여 비교 (하이픈, 공백 등 제거)
2026-01-11 22:05:46 +09:00

80 lines
2.5 KiB
TypeScript

import { query, execute } from '../../utils/db'
import { hashPassword, generateTempPassword } from '../../utils/password'
import { sendTempPasswordEmail } from '../../utils/email'
import { getClientIp } from '../../utils/ip'
interface ResetPasswordBody {
email: string
name: string
phone: string
}
/**
* 비밀번호 찾기 (임시 비밀번호 발급)
* POST /api/auth/reset-password
*/
export default defineEventHandler(async (event) => {
const body = await readBody<ResetPasswordBody>(event)
const clientIp = getClientIp(event)
if (!body.email || !body.name || !body.phone) {
throw createError({ statusCode: 400, message: '이메일, 이름, 휴대폰 번호를 입력해주세요.' })
}
const emailLower = body.email.toLowerCase()
const nameTrimmed = body.name.trim()
// 사용자 조회 (이메일 + 이름 + 핸드폰)
// 이메일: 양쪽 모두 소문자로 비교
// 핸드폰: 양쪽 모두 숫자만 추출해서 비교
const sql = `
SELECT * FROM wr_employee_info
WHERE LOWER(employee_email) = $1
AND employee_name = $2
AND REGEXP_REPLACE(employee_phone, '[^0-9]', '', 'g') = $3
`
const phoneClean = body.phone.replace(/[^0-9]/g, '')
const params: any[] = [emailLower, nameTrimmed, phoneClean]
const employees = await query<any>(sql, params)
if (employees.length === 0) {
// 보안상 동일한 메시지 반환
throw createError({ statusCode: 400, message: '입력하신 정보와 일치하는 계정을 찾을 수 없습니다.' })
}
const employee = employees[0]
// 임시 비밀번호 생성
const tempPassword = generateTempPassword()
const hash = await hashPassword(tempPassword)
// 비밀번호 업데이트
await execute(`
UPDATE wr_employee_info
SET password_hash = $1, updated_at = NOW(), updated_ip = $2
WHERE employee_id = $3
`, [hash, clientIp, employee.employee_id])
// 이메일 발송
const emailSent = await sendTempPasswordEmail(
employee.employee_email,
employee.employee_name,
tempPassword
)
if (!emailSent) {
// 이메일 발송 실패해도 비밀번호는 이미 변경됨
console.warn('임시 비밀번호 이메일 발송 실패:', employee.employee_email)
}
// 보안상 이메일 일부만 표시
const maskedEmail = employee.employee_email.replace(/(.{2})(.*)(@.*)/, '$1***$3')
return {
success: true,
message: `임시 비밀번호가 ${maskedEmail}로 발송되었습니다.`,
emailSent
}
})