generated from ttipo/project-base
docs(rules): 리뷰 반영에 맞춰 보안·환경변수·에러 코드·백엔드 스킬 갱신
- 코드 조회 한도는 회원 단위 한 바구니, 일정 코드는 한 번 쓰면 교체, 상세히 명함 공유 7일 - 개발용 로그인·서명 키 allowlist(development·test), 그 밖은 JWT_SECRET 필수 - CARD_004/005, 스로틀 가드 순서·db-lock·탈퇴 정리·파일 정리 위치 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,8 @@
|
||||
- **모바일 앱은 예외** — 앱에는 쿠키 저장소가 없어 리프레시 토큰을 응답 본문으로 받아 `flutter_secure_storage`(키: `refresh_token`)에 둔다.
|
||||
대신 서버는 리프레시 토큰을 **해시로만 저장**하고, **한 번 쓰면 폐기(회전)** 하며, 폐기된 토큰이 다시 오면 그 회원의 토큰을 모두 폐기한다 (`modules/auth`)
|
||||
- 소셜 로그인은 앱이 보낸 사용자 id 를 믿지 않는다 — 서버가 토큰을 **제공자에게 직접 확인**한다 (카카오는 앱 ID 까지 대조)
|
||||
- 개발용 로그인(`/auth/dev-sessions`)은 운영에서 **코드로 닫힌다** — env 값으로 열 수 없다
|
||||
- 개발용 로그인(`/auth/dev-sessions`)과 개발용 서명 키는 `NODE_ENV` 가 **development·test 일 때만** 열린다 (allowlist, `shared/config/node-env.ts`).
|
||||
staging·production·오타·미설정은 모두 닫히고 `JWT_SECRET` 이 없으면 기동하지 않는다 — env 값으로 열 수 없다
|
||||
- 비밀번호는 단방향 해시(`bcrypt`/`argon2`)로 저장한다. 평문·가역 암호화 금지
|
||||
- 인증 실패 응답에서 **원인을 구분해 알려주지 않는다** (아이디 없음/비밀번호 틀림 → 동일하게 AUTH_001)
|
||||
|
||||
@@ -34,8 +35,12 @@
|
||||
- 파일은 **올린 회원의 것**으로 기록하고, 다른 기록에서의 참조는 본인 파일만 허용한다.
|
||||
내려받기(`GET /files/:id`)는 본인 파일 + **함께 쓰는 기능이 등록한 열람 정책**(`FileAccessPolicy`)이 허락한 파일만이다 —
|
||||
공유 다이어리(표지·기록 사진·대상 아이·멤버 프로필)와 일정 함께 관리(연동된 사람의 프로필·아이 사진). 그 밖은 남의 파일과 없는 파일 모두 RES_001.
|
||||
- **초대 코드만으로 남의 기록에 들어오는 기능**(공유 다이어리·일정 연동)은 코드가 곧 열쇠다. 짐작하기 어렵게(`RUP-` + 6자, 혼동 글자 뺀 32자)
|
||||
만들고, 조회·참여 엔드포인트에 엄격한 rate limit(분당 30회)을 건다. 내보내거나 나가면 다이어리 코드를 바꾼다.
|
||||
- **코드만으로 남의 기록을 보거나 들어오는 기능**(명함 받기·공유 다이어리·일정 연동)은 코드가 곧 열쇠다.
|
||||
- 초대 코드는 짐작하기 어렵게(`RUP-` + 6자, 혼동 글자 뺀 32자) 만든다
|
||||
- 코드 조회·참여 엔드포인트는 모두 `@InviteCodeLookup()` 를 붙여 **회원 단위로 한 바구니**(분당 30회)를 같이 쓴다 — 엔드포인트마다 따로 세면 한도가 몇 배가 된다
|
||||
- 코드를 바꿔 옛 코드를 막는다: 다이어리는 내보내거나 나가면, 일정 연동 코드는 **한 번 연동에 쓰이거나** 나가면 바뀐다
|
||||
- 펫 명함의 상세히 공유(병원·질환·메모)는 마지막으로 공유한 뒤 7일만 상세히로 보이고, 그 뒤에는 간략히로 내려간다
|
||||
- 개수 한도(다이어리 6권·명함 10장·받은 명함 100장)는 동시 요청에 뚫리지 않게 `lockFor()`(`shared/utils/db-lock.ts`, 회원별 advisory lock)를 잡고 센다
|
||||
- **허용 목록(allowlist) 방식**으로만 받는다. 차단 목록은 언제나 빠뜨린다.
|
||||
`.html`·`.svg`·`.js` 등 **브라우저가 실행할 수 있는 형식은 넣지 않는다.**
|
||||
- **저장 파일명은 서버가 생성**한다(UUID + 검증된 확장자). 클라이언트가 보낸 이름을 경로에 쓰면
|
||||
|
||||
Reference in New Issue
Block a user