- POST /api/auth/apple — nimbus-jose-jwt 로 애플 공개키(JWKS) 서명 검증 + iss/aud(번들ID)/exp 확인
- member.apple_id 컬럼(멱등 ALTER) + findByAppleId/linkApple, 구글과 동일한 이메일 자동연결 로직
- app.apple-client-id 설정(기본 kr.sblog.slimbudget)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- DELETE /api/auth/me: 본인 계정과 모든 데이터 영구 삭제
- 게시판(글/댓글/추천/이미지)·가계부 전체·포인트·결제기록·세션 → 회원 순 삭제
- WithdrawMapper(게시판/포인트/결제/세션) + BackupMapper(가계부) 재사용
- AuthServiceTest 생성자 보강
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- member.plan_product, plan_auto_renew 컬럼(구독 상품·자동갱신)
- GET /api/billing/subscription: 플랜·만료일·다음결제일·자동갱신
- POST /api/billing/cancel: 자동갱신 중단(만료일까지 이용), /resume: 재개
- verify 시 상품·자동갱신 기록, 만료 강등·관리자 변경 시 구독정보 정리
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- member.plan_expires_at + iap_purchase 테이블(중복 결제 방지)
- POST /api/billing/google/verify: 구매 검증 후 PREMIUM 부여/갱신(만료 연장), 세션 plan 즉시 동기화
- GET /api/billing/products: 구독 상품(월간/연간)
- 테스트 모드(billing.test-mode=true): test- 토큰 검증 없이 승인 → 전 과정 테스트 가능
- GooglePlayVerifier 인터페이스 + 스텁(실연동 지점), 실연동 시 구현체 교체
- 관리자 수동 plan 변경은 만료일 없이(영구), 결제는 만료일 부여
- 만료 자동 강등 스케줄러(매시), MemberResponse.planExpiresAt 노출
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- GET /api/auth/profile: 아바타·포인트 포함 전체 프로필(재로그인 없이 최신화)
- 자기 글/댓글 추천·비추천 차단(400)
- 인기 글: 등록 1일 이내 + 추천 50건 이상이면 목록 상단 최대 3건 노출(hot)
- 인기 댓글: 동일 조건으로 댓글 목록 상단 정렬(hot)
- PostSummary 에 downCount 추가(비추천 20+ 블라인드 판정용)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- member.google_picture(구글 아바타 URL), profile_image(사용자 지정 data URL) 컬럼 추가(멱등)
- 구글 로그인 시 picture 클레임 추출 → 신규 저장, 기존은 변경 시 동기화
- PUT /api/auth/profile-image: 사용자 지정 사진 설정/해제(빈값=해제→구글 폴백), data URL·용량 검증
- MemberResponse 에 googlePicture/profileImage 노출(표시 우선순위 프론트 처리)
- 관리자 목록(findAll)은 무거운 profile_image 제외해 가볍게 조회
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- member.plan(FREE/PREMIUM) 컬럼 추가 + SessionUser/MemberResponse 노출
- auth_session 백업에 plan 저장(세션 복원 시 유료 상태 유지)
- 관리자 회원 plan 변경 API (PUT /api/admin/members/{id}/plan)
- PremiumInterceptor 로 유료 전용 경로 차단(통계/예산/고정지출/태그/OCR/투자/카드알림/백업)
· 관리자는 플랜과 무관하게 허용, 무료 회원은 403 PREMIUM_REQUIRED
- WebConfigTest: 유료 경로 등록 회귀 가드 추가
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- member.google_id 컬럼 추가(멱등 ALTER) + 기존 GOOGLE 계정 sub 백필
- googleLogin: google_id 조회 → 없으면 검증된 동일 이메일 계정(LOCAL 우선)에
연결 → 그래도 없으면 신규 생성. provider 는 유지(아이디 로그인/프로필 편집 보존)
- MemberMapper: findByGoogleId/findByEmailForLink/linkGoogle 추가, google_id 매핑
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- AuthService.googleLogin: 구글 tokeninfo 로 ID 토큰 검증(aud==클라이언트 ID)
후 provider=GOOGLE 회원 조회/자동가입 → 세션 발급(login 과 동일 경로)
- GoogleLoginRequest DTO, /api/auth/google·/google-client-id 엔드포인트
- application.yml: app.google-client-id=${GOOGLE_CLIENT_ID:}
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 로그인/비밀번호 재인증에 실패 기반 레이트리밋(Redis 슬라이딩 윈도우)
· 로그인 IP당 10회/10분, 비밀번호 게이트 회원당 5회/10분, 초과 시 429
· 성공 시 실패 카운터 초기화, Redis 장애 시 통과(가용성 우선)
· 회원가입 레이트리밋도 공통 enforceRateLimit 으로 일원화
- GlobalExceptionHandler: 미처리 500 로그에 메서드+경로 기록(추적성), 잘못된 JSON은 400
- 테스트: 레이트리밋 429 케이스 2개 추가 (백엔드 총 34)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- POST /auth/verify-password, PUT /auth/profile(세션 표시 이름 동기화)
- MemberMapper.updateProfile, AuthSessionMapper.updateName
- 단위테스트(24): CardNotificationParser(8), AuthService(16, Mockito)
- CI(.gitea): 테스트 리포트 아티팩트 업로드(clean build가 곧 테스트 게이트)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 관리자 회원가입 허용 토글(app_setting), 공개 GET /auth/signup-enabled
- 회원가입 봇차단: 허니팟(website) + IP 레이트리밋(Redis, 1h 5회)
- 카드 알림: 현금 오선택 보정(카드 양방향 매칭+단일카드 자동), 광고 푸시 차단(승인신호 없는 광고성 표현 무시)
- @MapperScan 에 admin.mapper 추가
- account.sql: 매 기동 wallet MODIFY 제거(라이브 락 위험) — CREATE 정의에 255 반영됨
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>