Skip to content

[BE] SIC1-202 [FEAT] 아이디 및 비밀번호 찾기 api 구현#89

Merged
discipline24 merged 10 commits intomainfrom
SISC1-202-아이디-비밀번호-찾기-api-구현
Nov 9, 2025

Hidden character warning

The head ref may contain hidden characters: "SISC1-202-\uc544\uc774\ub514-\ube44\ubc00\ubc88\ud638-\ucc3e\uae30-api-\uad6c\ud604"
Merged

[BE] SIC1-202 [FEAT] 아이디 및 비밀번호 찾기 api 구현#89
discipline24 merged 10 commits intomainfrom
SISC1-202-아이디-비밀번호-찾기-api-구현

Conversation

@msciki7
Copy link
Contributor

@msciki7 msciki7 commented Nov 9, 2025

Summary by CodeRabbit

  • 새로운 기능

    • 이메일 기반 비밀번호 재설정 전체 흐름 추가(코드 발송·검증·재설정 토큰 발급·토큰으로 비밀번호 변경), Redis 기반 임시 토큰 및 만료 처리, 관련 API 엔드포인트 추가
    • 이름·전화번호로 사용자 이메일 조회 기능 추가
    • 클라이언트 제출 비밀번호에 대한 트리밍 및 강력한 비밀번호 정책 검증 도입
    • 비밀번호 재설정용 HTML 이메일 템플릿 추가
  • 문서

    • 회원가입 비밀번호 정책 및 오류 예시 보강
  • 테스트

    • 비밀번호 재설정 흐름 전반에 대한 단위테스트 추가

@msciki7 msciki7 requested a review from discipline24 as a code owner November 9, 2025 04:54
@coderabbitai
Copy link

coderabbitai bot commented Nov 9, 2025

Walkthrough

비밀번호 재설정 기능이 추가되었습니다: 이메일 코드 발송·검증, Redis에 코드·재설정 토큰 저장·검증, 토큰으로 비밀번호 변경, 관련 컨트롤러 엔드포인트·인터페이스·구현·템플릿·단위테스트가 포함됩니다.

Changes

Cohort / File(s) 변경 요약
이메일 서비스 - 비밀번호 재설정
backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java
sendResetEmail(String email) 추가: 사용자 존재 확인, 코드 생성·Redis 저장(PASSWORD_RESET:{email}), HTML 이메일 발송(템플릿 mail/resetEmail), 실패 시 예외 처리. verifyResetEmail(String email, String code) 추가: Redis에서 코드 조회·검증·삭제. createResetMessage(String email, String code) 추가: mail/resetEmail 템플릿 기반 MIME 메시지 생성.
사용자 컨트롤러 - 재설정 엔드포인트
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java
새 API 엔드포인트 추가: POST /api/user/id/find (findUserID), POST /api/user/password/reset/send (sendReset), POST /api/user/password/reset/verify (verifyReset), POST /api/user/password/reset/commit (commitReset) — UserService로 위임 및 Swagger 문서화.
저장소 계층
backend/src/main/java/org/sejongisc/backend/user/dao/UserRepository.java
Optional<User> findByNameAndPhoneNumber(String name, String phoneNumber) 추가.
서비스 인터페이스
backend/src/main/java/org/sejongisc/backend/user/service/UserService.java
UserService 인터페이스에 4개 메서드 시그니처 추가: findEmailByNameAndPhone, passwordReset, verifyResetCodeAndIssueToken, resetPasswordByToken.
서비스 구현
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java
EmailService·RedisTemplate·RefreshTokenService·PasswordPolicyValidator 의존성 추가. 이메일 전송 호출, Redis에 코드/토큰 저장·검증·삭제, resetToken(UUID) 발급 및 저장(TTL 10분), 비밀번호 정책 검증·인코딩·저장, 리프레시 토큰 무효화 로직 및 Redis 예외 처리 보완.
비밀번호 정책 유틸리티
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java
비밀번호 유효성 검사 유틸 추가: 정규식으로 대문자·소문자·숫자·특수문자 포함 및 길이 8–20 검사; 유효성 실패 시 CustomException(ErrorCode.INVALID_INPUT) 발생.
이메일 템플릿
backend/src/main/resources/templates/mail/resetEmail.html
Thymeleaf 기반 비밀번호 재설정 이메일 템플릿 추가 (${email}, ${code} 바인딩, 3분 유효 안내).
DTOs (요청 페이로드)
backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetSendRequest.java, .../PasswordResetVerifyRequest.java, .../PasswordResetCommitRequest.java, .../UserIdFindRequest.java
비밀번호 재설정 및 ID 찾기용 요청 DTO 레코드 추가: 입력 유효성 검증(@NotBlank, @Email, @Size, @Pattern 등) 포함.
테스트
backend/src/test/java/org/sejongisc/backend/user/service/UserServiceImplTest.java
비밀번호 재설정 흐름 단위테스트 추가: 전송 성공/실패, 코드 검증 및 resetToken 발급, resetToken으로 비밀번호 변경, 리프레시 토큰 삭제, 잘못된 토큰 케이스 등 모의(mock) 의존성 사용.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Controller as UserController
    participant UserSvc as UserServiceImpl
    participant EmailSvc as EmailService
    participant Redis
    participant DB as UserRepository
    participant Encoder as PasswordEncoder
    participant Refresh as RefreshTokenService

    rect rgb(220,240,255)
    Note over User,Controller: 이메일/ID 찾기
    User->>Controller: POST /api/user/id/find (name, phone)
    Controller->>UserSvc: findEmailByNameAndPhone(name, phone)
    UserSvc->>DB: findByNameAndPhoneNumber(...)
    DB-->>UserSvc: User or empty
    UserSvc-->>Controller: 이메일 또는 404
    end

    rect rgb(240,255,240)
    Note over User,Controller: 재설정 코드 발송 & 검증
    User->>Controller: POST /api/user/password/reset/send (email)
    Controller->>UserSvc: passwordReset(email)
    UserSvc->>EmailSvc: sendResetEmail(email)
    EmailSvc->>Redis: SET PASSWORD_RESET:{email} = code (TTL)
    EmailSvc-->>User: 이메일 발송
    User->>Controller: POST /api/user/password/reset/verify (email, code)
    Controller->>UserSvc: verifyResetCodeAndIssueToken(email, code)
    UserSvc->>EmailSvc: verifyResetEmail(email, code)
    EmailSvc->>Redis: GET PASSWORD_RESET:{email} -> compare -> DEL on success
    EmailSvc-->>UserSvc: verified
    UserSvc->>Redis: SET PASSWORD_RESET:{UUID} = email (TTL for token)
    UserSvc-->>Controller: return resetToken
    end

    rect rgb(255,245,230)
    Note over User,Controller: 토큰으로 비밀번호 변경
    User->>Controller: POST /api/user/password/reset/commit (resetToken, newPassword)
    Controller->>UserSvc: resetPasswordByToken(resetToken, newPassword)
    UserSvc->>Redis: GET PASSWORD_RESET:{token} -> email
    Redis-->>UserSvc: email
    UserSvc->>DB: findByEmail(email)
    DB-->>UserSvc: User
    UserSvc->>Encoder: encode(newPassword)
    Encoder-->>UserSvc: encodedPwd
    UserSvc->>DB: update password, save
    UserSvc->>Refresh: deleteRefreshTokens(userId)
    UserSvc->>Redis: DEL PASSWORD_RESET:{token}
    UserSvc-->>Controller: success
    Controller-->>User: 200 OK
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

검토 집중 포인트:

  • Redis 키 네이밍/TTL(이메일용 키 vs 토큰용 키) 및 EmailService ↔ UserServiceImpl 간의 일관성
  • 메일 전송 실패 시 Redis에 남는 코드 처리 및 예외 복구 흐름
  • PasswordPolicyValidator 규칙과 DTO의 정규식 일관성
  • 단위테스트의 Redis ValueOperations 모킹이 실제 키/형식과 일치하는지

Possibly related PRs

Suggested reviewers

  • discipline24
  • Kosw6

🐰 깡충깡충 코드 숲을 지나,
메일 한 통에 숫자 코드가 반짝이네.
Redis에 숨은 시간은 짧게 셋,
토큰 들고 문을 열면 새 비밀번호로,
다시 한 번 밝게 뛰노는 밤 ✨🔐

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경 사항의 주요 내용과 일치합니다. 실제로 사용자 ID 찾기 API와 비밀번호 재설정 워크플로우(이메일 발송, 검증, 커밋)가 구현되었습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SISC1-202-아이디-비밀번호-찾기-api-구현

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
backend/src/main/resources/templates/mail/resetEmail.html (1)

1-23: 코드 유효시간 문구를 설정값과 동기화해 주세요

본문에 3분이 하드코딩되어 있는데, 실제 만료 시간은 EmailProperties.getCodeExpire() 값에 의해 결정됩니다. 운영 중 만료 시간을 조정하면 사용자에게 노출되는 문구와 실제 동작이 어긋나 혼선을 줄 수 있으니, 서비스에서 만료 시간을 템플릿 변수로 내려주거나 i18n 메시지에서 설정 기반으로 렌더링하도록 조정해 보시길 권장드립니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6240d4f and 392afdd.

📒 Files selected for processing (7)
  • backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (2 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/dao/UserRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserService.java (2 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (4 hunks)
  • backend/src/main/resources/templates/mail/resetEmail.html (1 hunks)
  • backend/src/test/java/org/sejongisc/backend/user/service/UserServiceImplTest.java (5 hunks)
🔇 Additional comments (3)
backend/src/main/java/org/sejongisc/backend/user/dao/UserRepository.java (1)

19-19: 이름+전화번호 조회 시그니처 적절합니다

이름과 전화번호로 단건을 찾아오는 흐름이 신규 서비스 요구와 잘 맞고, 기존에 existsByPhoneNumber로 전화번호 중복을 막고 있으니 Optional<User> 반환 형태도 자연스럽습니다.

backend/src/main/java/org/sejongisc/backend/user/service/UserService.java (1)

23-29: 비밀번호 복구용 인터페이스 확장 👍

컨트롤러와 구현체에서 사용하는 4가지 복구 메서드가 인터페이스에 정리되어 계약이 명확해졌습니다. 유지보수 시 호출 지점을 추적하기도 쉬워질 것 같습니다.

backend/src/test/java/org/sejongisc/backend/user/service/UserServiceImplTest.java (1)

423-453: 토큰 기반 재설정 플로우 테스트 좋아요

비밀번호 해시 갱신, 리프레시 토큰 제거, Redis 키 삭제까지 모두 검증해 비밀번호 재설정 시나리오의 회귀를 확실하게 막아줄 것 같습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 392afdd and 4e97e37.

📒 Files selected for processing (6)
  • backend/src/main/java/org/sejongisc/backend/auth/controller/AuthController.java (2 hunks)
  • backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (2 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1 hunks)
  • backend/src/test/java/org/sejongisc/backend/user/service/UserServiceImplTest.java (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/test/java/org/sejongisc/backend/user/service/UserServiceImplTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1)
  • PasswordPolicyValidator (9-22)
🪛 Gitleaks (8.28.0)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java

[high] 257-257: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)

195-200: 이름/전화번호 입력에서 선행·후행 공백을 제거해 주세요

현재 그대로 조회하면 사용자가 이름이나 전화번호에 실수로 공백을 포함했을 때 매칭이 실패해 이메일을 찾지 못합니다. 서비스 레이어에서 한 번만 trim()해서 빈 문자열까지 걸러 주면 UX가 훨씬 견고해집니다.

     public String findEmailByNameAndPhone(String name, String phone){
-        return userRepository.findByNameAndPhoneNumber(name, phone)
+        if (name == null || phone == null) {
+            return null;
+        }
+        String normalizedName = name.trim();
+        String normalizedPhone = phone.trim();
+        if (normalizedName.isEmpty() || normalizedPhone.isEmpty()) {
+            return null;
+        }
+
+        return userRepository.findByNameAndPhoneNumber(normalizedName, normalizedPhone)
                 .map(User::getEmail)
                 .orElse(null);
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e97e37 and 5a7539a.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1)
  • PasswordPolicyValidator (9-22)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)

264-266: Redis 토큰 삭제 실패를 기록하도록 조정하세요

Line 264-266에서 예외를 완전히 무시하면 삭제 실패가 숨어버려 토큰이 TTL 동안 남는 상황을 감지하기 어렵습니다. 최소한 경고 로그를 남기고, 필요 시 후속 조치를 고려해 주세요.

-        try {
-            redisTemplate.delete("PASSWORD_RESET:" + resetToken);
-        } catch (Exception ignored) {}
+        try {
+            redisTemplate.delete("PASSWORD_RESET:" + resetToken);
+        } catch (Exception e) {
+            log.warn("비밀번호 재설정 토큰 삭제 실패: token={}", resetToken, e);
+        }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a7539a and d3a7b01.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1)
  • PasswordPolicyValidator (9-22)
🔇 Additional comments (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)

203-209: 비회원 이메일 요청을 조용히 처리한 점 확인

Line 203-209에서 존재하지 않는 이메일에 대해 조용히 반환하도록 수정해 사용자 열거 위험을 줄인 것이 적절합니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3a7b01 and b0f2408.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1)
  • PasswordPolicyValidator (9-22)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0f2408 and 3bccb71.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1)
  • PasswordPolicyValidator (9-22)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)

271-315: LGTM - 비밀번호 재설정 로직이 매우 안전하게 구현되었습니다

Redis 조회/삭제 실패 시 즉시 예외를 발생시키고, 비밀번호 trim → 검증 → 인코딩 순서가 올바르며, 토큰 삭제 및 리프레시 토큰 무효화까지 완벽하게 처리되었습니다. 이전 리뷰의 모든 critical/major 이슈가 해결되었습니다.

선택적 정리: 주석 처리된 코드 제거

Line 274의 주석 처리된 코드는 제거하는 것이 코드 가독성에 좋습니다.

-//        String email = (String) redisTemplate.opsForValue().get("PASSWORD_RESET:" + resetToken);
         String email = null;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3bccb71 and 34c4bf8.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
backend/src/main/java/org/sejongisc/backend/user/util/PasswordPolicyValidator.java (1)
  • PasswordPolicyValidator (9-22)
🔇 Additional comments (5)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (5)

4-9: LGTM - 필요한 의존성이 올바르게 추가되었습니다

비밀번호 재설정 기능 구현에 필요한 EmailService, RefreshTokenService, RedisTemplate, PasswordPolicyValidator 등의 의존성이 적절하게 추가되었습니다.

Also applies to: 28-30, 32-32, 44-46


61-74: LGTM - 비밀번호 처리 로직이 올바르게 개선되었습니다

이전 리뷰에서 지적된 공백 패딩 우회 문제가 완벽하게 해결되었습니다. trim → null/공백 검증 → 정책 검증 → 인코딩 순서로 처리하여 "Aa1! "와 같은 입력으로 정책을 우회할 수 없습니다.


203-216: LGTM - 입력값 정규화가 올바르게 적용되었습니다

이름과 전화번호를 trim하여 정규화한 후 검증 및 조회를 수행하므로, 사용자가 실수로 공백을 포함하더라도 정상적으로 이메일을 찾을 수 있습니다. 이전 리뷰의 지적 사항이 완벽하게 반영되었습니다.


218-236: LGTM - 이메일 정규화 및 보안 처리가 우수합니다

이메일을 trim하여 정규화한 후 검증 및 조회를 수행하므로 공백이 포함된 입력에도 정상 동작합니다. 존재하지 않는 이메일에 대해 조용히 반환하는 것은 이메일 열거 공격을 방지하는 좋은 보안 관행입니다.


238-269: LGTM - 입력 검증과 에러 처리가 매우 견고합니다

이메일과 코드를 정규화하여 검증하고, Redis 저장 실패 시 즉시 예외를 발생시켜 일관성 없는 상태를 방지합니다. 이전 리뷰에서 지적된 모든 사항(입력 정규화, Redis 오류 처리)이 완벽하게 해결되었습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (1)

19-19: 사용하지 않는 import 제거를 권장합니다.

MediaType를 import했지만 코드에서 실제로 사용하지 않고 있습니다. 모든 @Content 어노테이션에서 문자열 리터럴 "application/json"을 사용하고 있습니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34c4bf8 and 1630926.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (2 hunks)
🧰 Additional context used
🪛 Gitleaks (8.28.0)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java

[high] 257-257: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetVerifyRequest.java (1)

12-14: 인증코드 입력을 숫자 형식으로 제한해야 합니다.

현재는 길이만 6자리로 제한되어 공백이나 특수문자도 그대로 통과합니다. Redis에 저장된 값은 숫자 6자리이므로, DTO 단계에서 숫자만 허용하도록 방어하면 검증 로직이 더 견고해집니다.

@@
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.Size;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.Size;
@@
-        @NotBlank(message = "인증코드는 필수입니다.")
-        @Size(min = 6, max = 6, message = "인증코드는 6자리여야 합니다.")
-        String code
+        @NotBlank(message = "인증코드는 필수입니다.")
+        @Size(min = 6, max = 6, message = "인증코드는 6자리여야 합니다.")
+        @Pattern(regexp = "^\\d{6}$", message = "인증코드는 숫자 6자리여야 합니다.")
+        String code
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1630926 and 5180336.

📒 Files selected for processing (5)
  • backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (2 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetCommitRequest.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetSendRequest.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetVerifyRequest.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/dto/UserIdFindRequest.java (1 hunks)
🧰 Additional context used
🪛 Gitleaks (8.28.0)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java

[high] 256-256: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (3)
backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetCommitRequest.java (1)

10-15: 비밀번호 정책 검증이 DTO 차원에서 잘 정의되어 있습니다.

정규식으로 정책을 명확히 강제해 서비스 로직이 단순해집니다.

backend/src/main/java/org/sejongisc/backend/user/dto/UserIdFindRequest.java (1)

9-11: 전화번호 검증 패턴이 요구 사항을 정확히 반영합니다.

010 국번과 8자리 숫자만 허용해 잘못된 요청을 초기에 걸러낼 수 있습니다.

backend/src/main/java/org/sejongisc/backend/user/dto/PasswordResetSendRequest.java (1)

7-9: 이메일 입력 검증이 간결하고 확실합니다.

필수 여부와 형식 검증이 갖춰져 있어 컨트롤러 진입 전에 오류를 차단할 수 있습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (1)

78-78: 개인정보 로깅을 제거하거나 마스킹해야 합니다.

신규 엔드포인트(Line 236)에서는 개인정보 로깅을 제거했으나, 기존 코드인 이 줄에서는 여전히 이메일을 로그에 남기고 있습니다. 일관성을 위해 개인정보 보호 정책을 적용해야 합니다.

다음과 같이 수정하세요:

-log.info("email: {} 권한: {}", user.getUsername(), user.getAuthorities());
+log.info("사용자 정보 조회 - 권한: {}", user.getAuthorities());
🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (1)

186-197: 검증된 DTO 사용으로 타입 안정성이 개선되었습니다.

과거 리뷰 코멘트를 반영하여 Map<String, String> 대신 @Valid UserIdFindRequest를 사용하도록 수정되었습니다. 입력 검증이 적절히 적용되었습니다.

참고: Line 191의 null 체크 대신 서비스 레이어에서 예외를 던지도록 하면 에러 처리가 더 일관적일 수 있습니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5180336 and fd629bf.

📒 Files selected for processing (1)
  • backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (2 hunks)
🧰 Additional context used
🪛 Gitleaks (8.28.0)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java

[high] 256-256: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (4)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (4)

15-15: DTO 패키지 import가 적절하게 추가되었습니다.

새로운 DTO들을 사용하기 위한 import가 올바르게 추가되었습니다.

Also applies to: 18-18


233-239: 과거 리뷰 코멘트가 모두 반영되었습니다.

  • @Valid PasswordResetSendRequest DTO 사용으로 타입 안정성 확보 ✓
  • trim()을 통한 공백 정규화 적용 ✓
  • 개인정보 로깅 제거 ✓

모든 개선 사항이 적절히 구현되었습니다.


275-282: 공백 정규화가 적절히 적용되었습니다.

과거 리뷰에서 지적된 공백 처리 문제가 해결되었습니다. emailcode 모두에 trim()을 적용하여 Redis 키 매칭 실패를 방지합니다.


325-329: 검증된 DTO 사용으로 구현이 개선되었습니다.

@Valid PasswordResetCommitRequest DTO를 사용하여 비밀번호 정책 검증이 DTO 레벨에서 수행됩니다. 구현이 간결하고 명확합니다.

참고: 정적 분석 도구가 Line 256에서 API 키를 감지했다고 보고했으나, 이는 Swagger 예제의 UUID 문자열이므로 false positive입니다.

Copy link
Contributor

@discipline24 discipline24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다~

@discipline24 discipline24 merged commit 1ea00da into main Nov 9, 2025
1 check passed
@discipline24 discipline24 deleted the SISC1-202-아이디-비밀번호-찾기-api-구현 branch November 9, 2025 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants