Account & Auth Emails (계정 설정 · 비밀번호 재설정 · 이메일 변경)
SPEC #145 정합. BE v0.109.0 도입. 링크(토큰 URL) 방식 · Azure Communication Services Email.
Overview
이메일 인프라 + 3 시나리오를 토큰 링크로 처리한다. 토큰 원문은 메일의 URL(?token=)에만 담기고
DB 엔 해시만 저장한다(일회용·만료·같은 type 재발급 시 이전 미사용 토큰 무효화).
| 시나리오 | 토큰 type | 만료 | 미인증 공개 페이지 |
|---|---|---|---|
| 계정 발급(setup link) | ACCOUNT_SETUP | 72h | /setup?token= |
| 비밀번호 재설정(reset link) | PASSWORD_RESET | 1h | /forgot-password · /reset-password?token= |
| 이메일 변경 인증(verify link, 새 주소) | EMAIL_CHANGE | 1h | /email-change/verify?token= |
계정 role 별 링크 도메인이 다르다 — 운영자 = apps/admin(admin.space.linkmusic.io) · 본사·점장 =
apps/space(space.linkmusic.io). 따라서 두 앱 모두 동일한 공개 페이지 4종(/setup·
/forgot-password·/reset-password·/email-change/verify)을 가진다.
FE 공개 페이지 (미인증 · 양 앱)
(auth) 그룹의 standalone AuthShell + AuthCard(로그인 류 중앙 카드, 셸·사이드바 없음). 토큰은
URL query 에서 읽는다. middleware isPublic 에 4 경로를 등록하고, BFF catch-all proxy
(/api/backend/[...path])는 공개 backend endpoint(auth/setup/*·auth/password-reset/*·
auth/email-change/confirm·terms/active·privacy-policy/active)를 세션·Authorization 없이
그대로 프록시한다(토큰이 곧 인증). terms/active·privacy-policy/active 는 SPEC #147 의 setup 약관
“보기” 링크용으로 추가됐다.
-
/setup?token=—useVerifyAccountSetup로 토큰 검증(이메일·role·만료 요약 + 활성 약관 버전) → 비밀번호 설정 폼(8~100자·확인 일치) + (SPEC #147) 약관 동의 →useCompleteAccountSetup→ 완료 후 [로그인하기]. 무효/만료(ACCOUNT_TOKEN_INVALID) 시 공용ErrorState([로그인으로]actionHref="/login"+ [비밀번호 재발급 요청]/forgot-password,setup-token-error) — dead-end 해소(SPEC #154).약관 동의 (SPEC #147) — 약관 동의 시점이 발급에서 계정 주인 본인의 이 setup 단계로 이전됐다. verify 응답의
activeTermsVersion·activePrivacyPolicyVersion(nullable)로 약관을 제시한다:- 활성 버전이 있으면 항목별 동의 체크박스(이용약관·개인정보) + 전체 동의 + 각 “보기” 링크
(public
/api/v1/terms/active·/api/v1/privacy-policy/active를 새 탭) + (선택) 동의자 이름. 필수 약관 전체 동의 + 비번 정책 통과 시에만 CTA 활성. atom-grounded(전용 시안 없음 —AuthCard·Banner·Button·raw checkbox). - 둘 다 null(OPERATOR·미게시)이면 동의 단계를 생략하고 비밀번호만 받는다.
- complete 제출 body 에
termsVersion·privacyPolicyVersion·signerName(생략 시 계정명) 동봉. - 에러
INVALID_LEGAL_VERSION(동의 중 약관 개정 — 새로고침 후 재동의 안내). admin·space 두 앱의setup-client.tsx가 동일.
- 활성 버전이 있으면 항목별 동의 체크박스(이용약관·개인정보) + 전체 동의 + 각 “보기” 링크
(public
-
/forgot-password— 이메일 입력 →useRequestPasswordReset→ 존재 은닉 안내(“가입된 계정이 있으면 재설정 메일을 보냈습니다”). 로그인 페이지 “비밀번호를 잊었나요?” 링크가 여기로 연결(기존 “준비 중” placeholder 대체). -
/reset-password?token=— 새 비밀번호 폼 →useConfirmPasswordReset. 무효 링크(token 없음)는 공용ErrorState([로그인으로]+[비밀번호 재발급 요청],reset-password-token-error, SPEC #154). 제출 시 만료는 인라인 처리. -
/email-change/verify?token=— 마운트 시useConfirmEmailChange(토큰만) → 전환 완료/실패 안내. 실패(만료·무효·EMAIL_ALREADY_IN_USE재충돌)는 공용ErrorState([로그인으로],email-change-verify-error, SPEC #154).
FE 이메일 변경 UI (인증 · 3 프로필)
공용 컴포넌트 EmailChangeSection(admin·space 미러)에 role 별 요청 훅을 wiring. 새 이메일 입력 →
요청 → “새 주소로 인증 메일을 보냈습니다” 안내. 중복(EMAIL_ALREADY_IN_USE) 에러 표시. 기존 비밀번호
변경 섹션 근처에 배치.
- 운영자 —
apps/admin/settings/profile·useRequestOperatorEmailChange - 본사 —
apps/space/admin/settings·useRequestHqEmailChange - 점장 —
apps/space/store/profile·useRequestStoreEmailChange
FE 계정 발급 UI
발급 성공 화면(AccountShareSection)에 [설정 이메일 보내기](useResendAccountSetup(accountId))를
추가했다 — 운영자가 계정 설정 안내 메일을 바로 보낼 수 있다(권장 경로). 발급 응답의 계정 id
(OperatorIssueResponse.id · StoreManagerIssueResponse.managerAccountId)를 보관해 활성화한다.
⚠️ 현황 메모 — BE v0.109.0 의 계정 발급 endpoint(
issueOperator·issueStoreManager)는 여전히 요청 body 에tempPassword를 받고 임시 비밀번호 안내문을 생성한다. 따라서 안내문 복사(temp-password)는 메일 미수신 대비 오프라인 폴백으로 유지하고, 그 위에 [설정 이메일 보내기]를 권장 경로로 얹었다. 발급 흐름을 setup-link 전용으로 완전 전환하는 것은 후속 BE 변경 과제다.
에러 코드
ACCOUNT_TOKEN_INVALID— 토큰 무효·만료·이미 사용됨.EMAIL_ALREADY_IN_USE— 이메일 변경 요청/전환 시 새 이메일 중복.