generated from ttipo/project-base
71f2e01d83
첫 사내 모듈인 웹메일의 백엔드다. 메일 엔진은 외부(Stalwart)에 두고 백엔드가 JMAP 으로 중계한다. - 직원 로그인 = 메일 계정: 엔진으로 비밀번호를 확인한 뒤 HttpOnly 쿠키 JWT 를 발급한다. 리프레시 세션은 DB 에 해시로 저장하고 1회용으로 회전한다 (이미 쓴 토큰이 오면 세션 폐기) - 로그인 실패 한도는 엔진에 묻기 전에 원자적으로 차지하고, IPv6 는 /64 로 묶어 센다 - 상태를 바꾸는 요청은 출처(Sec-Fetch-Site·Origin)를 검사하고, 클라이언트 IP 는 TRUST_PROXY 로만 해석한다 - 메일함·목록·읽기·발송·첨부 API: 받은 HTML 은 정화해서 내보내고, 발송은 Idempotency-Key 로 중복을 막는다 - 메일 엔진 관리자 계정은 로그인·대리 접근 대상에서 막는다 (게이트웨이가 관리자까지 대리할 수 있다) - 에러 코드 AUTH_004·MAIL_001~006 을 추가하고 클라이언트 에러 사전을 다시 생성했다 계약: docs/mail/api-contract.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
23 lines
1.5 KiB
Bash
23 lines
1.5 KiB
Bash
# ==========================================
|
|
# 백엔드 고유 시크릿 (development)
|
|
#
|
|
# ⚠️ DB / Redis / CORS / PORT 는 루트 .env.development 에서 docker-compose 가 주입한다.
|
|
# 여기에 중복 작성하지 말 것 (SSOT: 루트 .env — .claude/rules/env-structure.md).
|
|
# 이 파일에는 "루트에서 내려주지 않는 값"만 작성한다.
|
|
#
|
|
# 사용법: cp .env.development.example .env.development
|
|
# docker-compose 의 env_file 지시자 때문에 파일은 비어 있어도 존재해야 한다.
|
|
# ==========================================
|
|
|
|
# JWT 서명 키 — 액세스·리프레시 토큰을 서명한다. 환경마다 다른 값을 쓰고 절대 커밋하지 않는다.
|
|
# 반드시 **무작위로 만든다.** 사람이 지은 문장·단어 조합·회사명·날짜 등은 쓰지 않는다
|
|
# (토큰 하나만 손에 넣으면 오프라인에서 키를 대입해 볼 수 있고, 맞히면 모든 직원의 토큰을 위조할 수 있다).
|
|
# 만드는 법: openssl rand -base64 48
|
|
# (openssl 이 없으면) node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"
|
|
# 운영은 32자 이상이 아니면 기동하지 않는다 (src/shared/config/env.validation.ts).
|
|
JWT_SECRET=change-me-generate-a-long-random-string
|
|
# 만료 — 액세스 5분~1시간, 리프레시(미사용 만료) 30일 이하이며 액세스보다 길어야 한다 (env 검증).
|
|
# 세션 절대 만료(로그인 후 30일)는 코드 상수다.
|
|
JWT_ACCESS_EXPIRES_IN=1h
|
|
JWT_REFRESH_EXPIRES_IN=14d
|