Service Docs 0.184.0 버전

비밀번호 찾기 / 재설정 / 변경

세 endpoint:

  • forgot-password: 이메일 인증된 user 에게 reset OTP 발송
  • reset-password: OTP 검증 + 새 비번
  • change-password: 로그인 상태에서 currentPassword + newPassword

비밀번호 찾기 (unauthenticated)

// 1. OTP 발송 요청
await ClientAuth.forgotPassword({
  body: { tenantKey: 'classum', userId: 'windy' },
})
// 응답은 항상 200 (info leak 방지) — tenant 없음 / user 없음 / email 미인증 / cooldown 중 모두 silent

// 2. 받은 코드로 재설정
const res = await ClientAuth.resetPassword({
  body: {
    tenantKey: 'classum',
    userId: 'windy',
    code: '123456',
    newPassword: 'new-pw-67890',
  },
})
// 200 — 새 비번 저장됨. user 의 모든 기존 refresh family 자동 revoke (다른 device 도 끊김).
// 401 — 만료 / 시도초과 / 불일치 / 없음 (모두 동일)

정책

  • OTP 6자리 / 만료 10분 / 시도 5회 / 재발송 cooldown 60초 (EmailVerification 과 동일)
  • forgotPassword 응답이 silent 라 frontend 가 "이메일 보냈습니다" 같은 generic 메시지 표시 권장 (실제로 안 보냈을 수도 있지만 사용자 입장 안전)
  • resetPassword 성공 시 기존 모든 device 의 refresh 자동 무효화 — 다른 device 도 다음 refresh 시 401 받고 sign-in 강제

비밀번호 변경 (authenticated)

// client_auth required + (sign_up user 의 경우) emailVerifiedAt set 되어 있어야 함
await ClientAuth.changePassword({
  body: {
    currentPassword: 'orig-pw-12345',
    newPassword: 'new-pw-67890',
  },
})
// 204 — 새 비번 저장 + 현재 user 의 모든 refresh family revoke + cookie clear
// 401 — currentPassword 불일치 또는 token 없음
// 403 — sign_up user 의 emailVerifiedAt null (이메일 인증 미완)

변경 후 frontend 가 sessionStorage 의 access token 도 clear + 로그인 페이지 redirect 권장:

async function changePassword(input: { currentPassword: string; newPassword: string }) {
  const res = await ClientAuth.changePassword({ body: input })
  if (res.error) throw res.error
  sessionStorage.removeItem('app.access')
  sessionStorage.removeItem('app.expiresAt')
  location.href = '/sign-in'
}

에러 처리 패턴

상황 UI 처리
forgot-password — 항상 200 "입력한 이메일로 코드를 보냈습니다. 코드를 확인해주세요" (silent 라 사용자에겐 무관)
reset-password 401 (만료/오타/시도초과) "코드가 만료됐거나 잘못됐습니다. 새 코드를 받아주세요"
change-password 401 (현 비번 오타) "현재 비밀번호가 일치하지 않습니다"
change-password 403 (이메일 미인증) "비밀번호 변경은 이메일 인증 후 가능합니다"