feat(identity): 인증 API와 mock adapter 구성 #48 - #53
Conversation
📝 Walkthrough회원가입, 로그인, 로그아웃, refresh token 갱신, 비밀번호 재설정 API를 제공합니다. JWT와 Spring Security를 적용하고, Redis 기반 refresh token rotation과 revocation을 지원합니다. 아키텍처 변경
위험 영역
마이그레이션 및 호환성
검증 및 롤아웃
Walkthrough인증 API와 ChangesIdentity 인증 기능
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthController
participant AuthService
participant JwtTokenGenerator
participant RedisRefreshTokenRotationAdapter
participant Redis
Client->>AuthController: 로그인 요청
AuthController->>AuthService: LoginCommand 전달
AuthService->>JwtTokenGenerator: access/refresh JWT 생성
AuthService-->>AuthController: AuthTokenResult 반환
AuthController-->>Client: 사용자 응답 및 인증 쿠키
Client->>AuthController: refresh_token 쿠키 전달
AuthController->>AuthService: RefreshTokenCommand 전달
AuthService->>RedisRefreshTokenRotationAdapter: refresh token 소비
RedisRefreshTokenRotationAdapter->>Redis: 원자적 소비 요청
Redis-->>RedisRefreshTokenRotationAdapter: 소비 결과
RedisRefreshTokenRotationAdapter-->>AuthService: 소비 성공 여부
AuthService-->>AuthController: 새 AuthTokenResult 반환
AuthController-->>Client: 새 인증 쿠키
Suggested labels: ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 14
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.kt`:
- Around line 107-120: Replace the fixed values in mockAccessTokenCookie and
mockRefreshTokenCookie with a token pair produced by the AuthPort login/refresh
results or the configured token generator. Ensure mock tokens are valid signed
HS256 JWTs and are unique per user/session, then preserve the existing cookie
security, path, and expiration settings.
In
`@systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.kt`:
- Around line 118-124: AuthControllerTest의 fake 구현에서 refreshToken과
resetPassword로 전달된 커맨드를 저장하도록 변경하고, 각 실제 컨트롤러 엔드포인트를 직접 호출하는 테스트를 추가하세요. refresh
cookie 전달, 커맨드 필드 매핑, 갱신 쿠키 발급 결과를 검증하는 결정적이고 의미 있는 단언을 작성하며, 항상 참인
assertNotNull 검증은 제거하세요.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.kt`:
- Around line 3-6: Override toString consistently for the sensitive data
classes: mask password in LoginCommand at
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.kt:3-6,
authorization in LogoutCommand at
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.kt:3-5,
refreshToken in RefreshTokenCommand at
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.kt:3-5,
and JwtToken.value in JwtTokenGenerator at
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.kt:112-117;
use one shared masking convention or utility and ensure no credential value
appears in the generated string.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.kt`:
- Around line 3-5: Update AuthController and LogoutCommand so the HTTP
Authorization header is parsed in the adapter layer and LogoutCommand receives
only the extracted token value; keep Bearer-prefix handling out of the
application layer and preserve the logout flow using the pure token.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.kt`:
- Around line 36-102: Replace the custom JWT construction in
JwtTokenGenerator.generateToken, including json, escapeJson, base64UrlEncode,
and hmacSha256, with the project’s standard JWT library used by JwtFilter. Build
the header and claims through that library, sign with the configured secret and
HS256, and return a JwtToken while preserving issuer, subject, type, issuedAt,
and expiresAt values.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.kt`:
- Around line 29-39: Replace the in-memory AtomicLong user ID generation in
AuthService.signup with the established persistent sequence, database-generated
ID, or durable ID-generation port, ensuring IDs remain unique across instances
and restarts. Remove the nextUserId counter usage while preserving the existing
Account.create flow.
- Around line 21-28: Remove the Spring-specific `@Service` annotation and its
org.springframework.stereotype.Service import from AuthService, leaving the
application service as a framework-independent class. Register and construct
AuthService in the bootstrap layer through a `@Bean` or adapter configuration
instead.
- Around line 53-54: AuthService의 계정 저장과 applicationDataPort.create 호출을 하나의 트랜잭션
또는 원자적 포트 연산으로 묶어, 애플리케이션 초기화 실패 시 계정 저장도 함께 롤백되도록 수정하세요.
accountRepository.save와 applicationDataPort.create가 동일한 트랜잭션 경계에서 실행되게 하며,
IdentityServiceSupport.findApplication의 기존 조회 동작은 변경하지 마세요.
- Around line 31-99: AuthService의 signup, login, resetPassword 동작을 검증하는 행동 테스트를
identity-application 테스트 영역에 추가하세요. 정상 회원가입과 중복 계정, 비활성 계정 로그인, 비밀번호 재설정 입력 및
사용자 검증 실패를 각각 검증하고, accountRepository.save 실패가 올바르게 전파되는지도 확인하세요. 기존 테스트 가이드와
테스트 더블 패턴을 따르며 관련 의존성 상호작용까지 검증하세요.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.kt`:
- Around line 11-22: Update AccountRepository.resolveAccount and the
AuthService.logout flow to use only the principal validated and injected by
JwtFilter through SecurityFilterChain, rather than parsing
LogoutCommand.authorization or accepting arbitrary Bearer user_XXX values.
Remove the token-to-userId interpretation from resolveAccount, and handle
mock-access-token/access-token behavior only through an explicit test or
mode-specific path.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.kt`:
- Around line 3-11: IdentityApplicationModuleTest의 SuiteClasses에 AuthService,
MockAuthPortAdapter, IdentityResultMapper, IdentityServiceSupport 관련 테스트를 추가해
identity-application의 프로덕션 로직이 모두 실행되도록 하세요. 해당 테스트가 존재하지 않거나 의도적으로 제외해야 한다면, 그
근거를 테스트 코드에 명시하고 JwtTokenGeneratorTest만 포함하는 현재 범위를 명확히 설명하세요.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt`:
- Around line 33-50: Update JwtFilter to bypass JWT validation and continue the
filter chain for public authentication endpoints, including the login, token,
password-reset, and signup paths. Keep the existing token resolution and
verification behavior unchanged for all other requests, including requests
without a token.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt`:
- Around line 57-58: Update the SecurityFilterChain configuration around csrf
and JwtFilter.resolveToken so cookie-based authentication is protected:
configure an appropriate CSRF token repository and asynchronous-request
protection, or remove the access_token cookie fallback so only
Authorization-header authentication remains. Do not rely on the existing cors
disablement as CSRF protection.
In
`@systems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.kt`:
- Around line 18-35: Expand the tests in TestMain to cover the JWT filter and
security chain using a fixed Clock: verify valid, expired, tampered-signature,
malformed, and missing-token requests, including security context population and
401 versus filter-chain continuation behavior. Reuse the existing security
configuration and token-related symbols rather than limiting coverage to Java
Time mapping.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 459e6080-113b-44e6-8695-eed6a8f02cb1
📒 Files selected for processing (29)
systems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/BUILD.bazelsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.kt
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{kt,go}
📄 CodeRabbit inference engine (Custom checks)
If production logic is changed in Kotlin or Go files, require corresponding test updates in the same subsystem unless the PR description explicitly justifies why tests are unnecessary
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
**/*-application/**/*.{java,kt,scala,groovy}
📄 CodeRabbit inference engine (Custom checks)
For files under *-application modules, flag direct dependency on infrastructure-specific framework classes unless justified
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.kt
**/*.{java,kt,scala,groovy,go,js,ts,tsx,jsx,py,rb,rs,cpp,c,h,hpp,cs}
📄 CodeRabbit inference engine (Custom checks)
Flag TODO/FIXME comments introduced by this PR that do not include an issue reference in the form
#123or a full tracker key like PROJ-123
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
**/*.kt
⚙️ CodeRabbit configuration file
**/*.kt: Apply Kotlin Official Coding Conventions.Formatting and structure:
- Use 4 spaces for indentation; no tabs.
- Keep files focused and readable; avoid horizontal alignment for spacing.
- Place related declarations together and keep overloads adjacent.
- Keep implementation member order stable and logical for readability.
Naming:
- Package names are lowercase and do not use underscores.
- Class/object names use UpperCamelCase.
- Functions/properties/local variables use lowerCamelCase.
- Constants use UPPER_SNAKE_CASE only for true constants.
API and null-safety:
- Avoid platform type leakage in public APIs.
- Use explicit types in public APIs when inference obscures meaning.
- Prefer immutable values (
val) over mutable values (var) unless mutation is required.- Flag nullable flows that can be replaced with safer modeling.
Imports and idioms:
- Avoid wildcard imports unless justified by language/tooling conventions.
- Prefer expression bodies for short, clear functions.
- Prefer standard library idioms over custom utility wrappers when equivalent.
Architecture and tests:
- Respect module boundaries (domain/application/adapter/bootstrap layering).
- Highlight behavior-changing code that lacks corresponding unit/integration tests.
- Ask for deterministic tests and meaningful assertions, not only happy-path checks.
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
**/{BUILD.bazel,*.bzl}
📄 CodeRabbit inference engine (Custom checks)
In BUILD.bazel and .bzl files, require buildifier-compatible formatting and stable target naming
Files:
systems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-application/BUILD.bazel
**/BUILD.bazel
⚙️ CodeRabbit configuration file
**/BUILD.bazel: Apply Bazel BUILD style guidance.Core rules:
- BUILD formatting must match buildifier output.
- Prefer DAMP BUILD files over over-abstracted DRY patterns.
- Keep top-level layout clear: load() first, then package/default visibility, then targets.
Target definitions:
- Keep deps explicit and close to each target's real direct dependencies.
- Avoid recursive globs unless there is a clear, documented reason.
- Avoid top-level list comprehensions for generating many targets.
- Prefer literal labels and stable naming for readability and tooling compatibility.
- Use boolean values (True/False), not numeric stand-ins.
Maintenance:
- Flag duplicated target logic that should be moved into a macro.
- Flag macro usage that hides important dependency or visibility decisions.
Files:
systems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-application/BUILD.bazel
🪛 ast-grep (0.44.1)
systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
[warning] 109-109: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: private const val ACCESS_TOKEN_COOKIE = "access_token"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
[warning] 110-110: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: private const val ACCESS_TOKEN_TYPE = "access"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
🪛 detekt (1.23.8)
systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
[warning] 86-86: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled.
(detekt.exceptions.TooGenericExceptionCaught)
🔇 Additional comments (18)
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.kt (1)
33-49: LGTM!Also applies to: 68-78, 92-105
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.kt (1)
1-9: LGTM!systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.kt (1)
1-12: LGTM!systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.kt (1)
1-14: LGTM!systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.kt (1)
28-84: LGTM!systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.kt (1)
10-42: LGTM!systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.kt (1)
3-13: LGTM!systems/identity/identity-adapter-in/BUILD.bazel (1)
20-20: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt (2)
26-28: 🩺 Stability & Availability
Clock빈 등록 여부를 확인하세요.
JwtFilter가Clock을 생성자 주입받지만 이 구성에는 해당 빈이 없습니다. 별도 빈이 없다면 컨텍스트 시작 시 주입에 실패합니다.Clock.systemUTC()를 반환하는 빈을 등록하거나 기존 정의를 확인하세요.
3-11: 📐 Maintainability & Code QualityJackson 3 전환은 해당되지 않습니다.
현재 Spring Boot 4 빌드도
jackson-module-kotlin을com.fasterxml.jackson.module:jackson-module-kotlin:2.18.2로 선언하고 있어, 현재com.fasterxml.jackson.*및jacksonObjectMapper()import는 Jackson 2 API와 일치합니다.> Likely an incorrect or invalid review comment.systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.kt (1)
5-9: 🔒 Security & Privacy보안 설정값 검증이 이미 수행되고 있습니다.
JwtFilter에서secret의 byte 길이가 32 바이트 미만이면 예외가 발생하므로 빈/짧은 HMAC 키 사용은 시작 시 제거됩니다. 같은 동작을JwtProperties에 중복 추가할 필요는 없습니다.> Likely an incorrect or invalid review comment.systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.kt (1)
11-21: LGTM!systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.kt (1)
12-67: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.kt (1)
1-10: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.kt (1)
1-12: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.kt (1)
1-42: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.kt (1)
1-27: LGTM!systems/identity/identity-application/BUILD.bazel (1)
14-21: LGTM!
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@systems/identity/identity-adapter-out/deps.bzl`:
- Around line 1-6: KOTLIN_DEPS에서 spring-boot-starter-security 의존성을 제거하고,
BCryptPasswordEncoder 사용에 필요한 spring-security-crypto Maven 라벨로 교체하세요. 기존 JPA 및
애플리케이션·도메인 의존성은 유지하세요.
In
`@systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/MysqlUserIdGenerator.kt`:
- Around line 7-12: 추가된 MysqlUserIdGenerator가 의존하는 identity_user_id_sequence
테이블과 초기 USER 행을 생성하는 migration을 추가하세요. 스키마는 sequence_name을 VARCHAR(32) 기본 키로,
next_id를 BIGINT NOT NULL로 정의하고, USER 키의 next_id 초기값을 설정해 첫 회원가입이 정상적으로 ID를 할당하도록
하세요.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.kt`:
- Around line 6-12: Implement safe toString() overrides for SignupCommand in
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.kt#L6-L12
and PasswordResetCommand in
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.kt#L5-L12,
masking password, loginId, name, phone, and birthdate while preserving only
non-sensitive fields such as signupType; ensure no credential or PII is emitted
in logs or exceptions.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.kt`:
- Around line 80-89: Remove the hardcoded "mock-refresh-token" validation from
AuthService.refreshToken and replace it with verification of the refresh JWT’s
signature, expiration, and token type. Extract the verified subject, load the
corresponding account, and issue tokens using that account’s user ID, role, and
status; preserve invalid and expired token errors and ensure refresh JWTs
generated by the existing token issuance flow are accepted.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt`:
- Around line 182-183: Update the default AccountRegistrationPort lambda in the
service helper to accept both register arguments, Account and Instant, while
preserving the existing account-returning behavior.
- Around line 3-6: AuthServiceTest.kt에서 사용하는 RefreshTokenCommand가 import되지
않았습니다. 기존 command import 목록에
hs.kr.entrydsm.identity.application.port.`in`.command.RefreshTokenCommand
import를 추가해 테스트가 컴파일되도록 수정하세요.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.kt`:
- Around line 10-21: Update signupValidationRejectsBlankRequiredFields to
capture the thrown IdentityDomainException instead of using the expected
annotation, then assert that its error code is INVALID_REQUEST_BODY. Preserve
the existing invalid SignupCommand setup and requireValidSignup invocation.
In
`@systems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.kt`:
- Around line 50-52: Update tamperedAndMalformedTokensReturnUnauthorized so the
tampered case uses a well-formed JWT issued with a different secret key,
ensuring signature verification deterministically fails; keep the malformed
“not-a-jwt” case and existing unauthorized assertions unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 797ae6af-e298-46f9-94c8-c9d667115ca4
⛔ Files ignored due to path filters (1)
kotlin.MODULE.bazelis excluded by none and included by none
📒 Files selected for processing (53)
systems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-adapter-in/deps.bzlsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-adapter-out/deps.bzlsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/MysqlUserIdGenerator.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-application/BUILD.bazelsystems/identity/identity-application/deps.bzlsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/UserIdGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-bootstrap/deps.bzlsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/UserIdGeneratorConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.kt
📜 Review details
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{kt,go}
📄 CodeRabbit inference engine (Custom checks)
If production logic is changed in Kotlin or Go files, require corresponding test updates in the same subsystem unless the PR description explicitly justifies why tests are unnecessary
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/UserIdGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/UserIdGeneratorConfig.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/MysqlUserIdGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt
**/*-application/**/*.{java,kt,scala,groovy}
📄 CodeRabbit inference engine (Custom checks)
For files under *-application modules, flag direct dependency on infrastructure-specific framework classes unless justified
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/UserIdGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt
**/*.{java,kt,scala,groovy,go,js,ts,tsx,jsx,py,rb,rs,cpp,c,h,hpp,cs}
📄 CodeRabbit inference engine (Custom checks)
Flag TODO/FIXME comments introduced by this PR that do not include an issue reference in the form
#123or a full tracker key like PROJ-123
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/UserIdGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/UserIdGeneratorConfig.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/MysqlUserIdGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt
**/*.kt
⚙️ CodeRabbit configuration file
**/*.kt: Apply Kotlin Official Coding Conventions.Formatting and structure:
- Use 4 spaces for indentation; no tabs.
- Keep files focused and readable; avoid horizontal alignment for spacing.
- Place related declarations together and keep overloads adjacent.
- Keep implementation member order stable and logical for readability.
Naming:
- Package names are lowercase and do not use underscores.
- Class/object names use UpperCamelCase.
- Functions/properties/local variables use lowerCamelCase.
- Constants use UPPER_SNAKE_CASE only for true constants.
API and null-safety:
- Avoid platform type leakage in public APIs.
- Use explicit types in public APIs when inference obscures meaning.
- Prefer immutable values (
val) over mutable values (var) unless mutation is required.- Flag nullable flows that can be replaced with safer modeling.
Imports and idioms:
- Avoid wildcard imports unless justified by language/tooling conventions.
- Prefer expression bodies for short, clear functions.
- Prefer standard library idioms over custom utility wrappers when equivalent.
Architecture and tests:
- Respect module boundaries (domain/application/adapter/bootstrap layering).
- Highlight behavior-changing code that lacks corresponding unit/integration tests.
- Ask for deterministic tests and meaningful assertions, not only happy-path checks.
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/UserIdGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/UserIdGeneratorConfig.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/MysqlUserIdGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt
**/{BUILD.bazel,*.bzl}
📄 CodeRabbit inference engine (Custom checks)
In BUILD.bazel and .bzl files, require buildifier-compatible formatting and stable target naming
Files:
systems/identity/identity-adapter-out/deps.bzlsystems/identity/identity-adapter-in/deps.bzlsystems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-bootstrap/deps.bzlsystems/identity/identity-application/BUILD.bazelsystems/identity/identity-application/deps.bzl
**/*.bzl
⚙️ CodeRabbit configuration file
**/*.bzl: Apply Bazel Starlark (.bzl) style guidance.Readability and docs:
- Keep file/module docstrings and docstrings for public functions/macros.
- Use descriptive parameter names and document attribute intent.
API design:
- Macros should take a
nameargument and derive generated target names from it.- Prefer keyword arguments when calling macros for clarity and stability.
- Keep macro side effects predictable and visible.
Encapsulation:
- Use private visibility for helper targets created by macros unless explicitly public.
- Avoid exposing internal implementation targets unintentionally.
Tooling:
- Enforce buildifier formatting and lint compliance.
Files:
systems/identity/identity-adapter-out/deps.bzlsystems/identity/identity-adapter-in/deps.bzlsystems/identity/identity-bootstrap/deps.bzlsystems/identity/identity-application/deps.bzl
**/BUILD.bazel
⚙️ CodeRabbit configuration file
**/BUILD.bazel: Apply Bazel BUILD style guidance.Core rules:
- BUILD formatting must match buildifier output.
- Prefer DAMP BUILD files over over-abstracted DRY patterns.
- Keep top-level layout clear: load() first, then package/default visibility, then targets.
Target definitions:
- Keep deps explicit and close to each target's real direct dependencies.
- Avoid recursive globs unless there is a clear, documented reason.
- Avoid top-level list comprehensions for generating many targets.
- Prefer literal labels and stable naming for readability and tooling compatibility.
- Use boolean values (True/False), not numeric stand-ins.
Maintenance:
- Flag duplicated target logic that should be moved into a macro.
- Flag macro usage that hides important dependency or visibility decisions.
Files:
systems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-application/BUILD.bazel
🪛 ast-grep (0.44.1)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.kt
[warning] 83-83: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.kt
[warning] 35-35: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
[warning] 112-112: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: private const val ACCESS_TOKEN_COOKIE = "access_token"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
[warning] 113-113: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: private const val ACCESS_TOKEN_TYPE = "access"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.kt
[warning] 164-164: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt
[warning] 216-216: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
🪛 detekt (1.23.8)
systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/MysqlUserIdGenerator.kt
[warning] 26-26: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled.
(detekt.exceptions.TooGenericExceptionCaught)
🔇 Additional comments (50)
systems/identity/identity-adapter-in/BUILD.bazel (1)
14-21: LGTM!systems/identity/identity-adapter-in/deps.bzl (1)
1-11: LGTM!systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.kt (1)
1-138: LGTM!systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.kt (1)
1-9: LGTM!systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.kt (1)
1-12: LGTM!systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.kt (1)
1-14: LGTM!systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/TestMain.kt (1)
3-13: LGTM!systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.kt (1)
1-210: LGTM!systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.kt (1)
1-42: LGTM!systems/identity/identity-bootstrap/BUILD.bazel (1)
28-30: LGTM!systems/identity/identity-bootstrap/deps.bzl (1)
3-3: LGTM!Also applies to: 10-12
systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.kt (1)
14-35: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt (2)
29-98: LGTM!
100-132: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/UserIdGeneratorConfig.kt (1)
9-14: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.kt (1)
14-33: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.kt (1)
14-33: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt (3)
22-64: LGTM!
66-108: LGTM!
110-123: LGTM!systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.kt (1)
5-9: LGTM!systems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.kt (1)
21-47: LGTM!systems/identity/identity-application/BUILD.bazel (1)
20-22: LGTM!systems/identity/identity-application/deps.bzl (1)
3-5: LGTM!Also applies to: 10-10
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.kt (1)
16-51: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/UserIdGenerator.kt (1)
3-5: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.kt (1)
3-5: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.kt (1)
17-65: LGTM!Also applies to: 69-84
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.kt (1)
9-26: LGTM!systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/TestMain.kt (1)
3-19: LGTM!systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.kt (1)
16-46: LGTM!systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.kt (1)
13-85: LGTM!systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.kt (1)
17-61: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.kt (1)
1-21: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.kt (1)
1-8: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.kt (1)
1-5: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.kt (1)
1-7: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.kt (1)
1-8: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.kt (1)
1-9: LGTM!systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt (1)
7-138: LGTM!Also applies to: 149-180, 194-220
systems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.kt (1)
3-23: LGTM!systems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.kt (1)
1-52: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.kt (1)
6-15: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.kt (1)
5-10: LGTM!systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.kt (1)
25-78: LGTM!Also applies to: 92-121
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.kt (1)
11-21: LGTM!systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.kt (1)
8-14: LGTM!systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.kt (1)
8-17: LGTM!systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.kt (1)
11-21: LGTM!systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.kt (1)
8-17: LGTM!
9e372ac to
1a0d7e0
Compare
88b288a to
f70e7ce
Compare
|
Tip For best results, initiate chat on the files or code changes.
You are interacting with an AI system. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 26
♻️ Duplicate comments (1)
systems/identity/identity-adapter-out/deps.bzl (1)
1-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win의존성을 실제 직접 사용 라이브러리로 좁히고 명시하세요.
이 모듈은
BCryptPasswordEncoder(spring-security-crypto),@Component(spring-context),@Transactional과DataAccessException(spring-tx),StringRedisTemplate(spring-data-redis)만 직접 참조합니다. 현재는 두 개의 starter를 통해 transitive로 해결합니다.spring-boot-starter-security는 web/config 등 불필요한 Spring Security 의존성까지 끌어옵니다.♻️ 제안 변경
KOTLIN_DEPS = [ - "`@maven//`:org_springframework_boot_spring_boot_starter_data_redis", - "`@maven//`:org_springframework_boot_spring_boot_starter_security", + "`@maven//`:org_springframework_data_spring_data_redis", + "`@maven//`:org_springframework_security_spring_security_crypto", + "`@maven//`:org_springframework_spring_context", + "`@maven//`:org_springframework_spring_tx", "//systems/identity/identity-application:main", "//systems/identity/identity-domain:main", ]해당 Maven 좌표가
maven_install아티팩트 목록에 등록되어 있는지 확인하세요.As per path instructions: "Keep deps explicit and close to each target's real direct dependencies."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@systems/identity/identity-adapter-out/deps.bzl` around lines 1 - 6, Replace the broad Spring Boot starter entries in KOTLIN_DEPS with the explicitly used artifacts: spring-security-crypto, spring-context, spring-tx, and spring-data-redis, while retaining the application and domain dependencies. Verify each Maven coordinate is registered in the maven_install artifact list.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.kt`:
- Around line 98-110: Update resetPassword in AuthController and the underlying
AuthService flow to require and validate account ownership proof before changing
the password, such as a one-time verification code, authenticated session, or
trusted external identity result; do not rely only on loginId, name, and
birthdate. Propagate the verified proof through PasswordResetRequest and
PasswordResetCommand, and reject invalid, missing, expired, or already-used
proof; if no verification mechanism is available, disable this endpoint in
production.
In
`@systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.kt`:
- Around line 11-13: Replace character-count validation on the password field in
LoginRequest and the corresponding fields in SignupRequest and
PasswordResetRequest with a shared UTF-8 byte-length maximum of 72, and apply
the same rule in the service validation logic before BCryptPasswordHasher is
invoked. Add boundary tests covering exactly 72 bytes, over-limit values, and
multibyte passwords, ensuring invalid inputs are rejected without producing a
5xx response.
In
`@systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/AuthIdentityAdapterInModuleTest.kt`:
- Around line 9-14: Update the `@Suite.SuiteClasses` declaration in
AuthIdentityAdapterInModuleTest to include
RedisUnavailableExceptionHandlerTest::class, preserving the existing suite
entries so the Redis-unavailable 503 response test runs with the module test
suite.
In
`@systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.kt`:
- Around line 19-23: Update the register method in
AccountCommandPersistenceAdapter to document that its
DataIntegrityViolationException mapping is intended only for duplicate login ID
constraint violations. Keep the AccountRepository.register call and
AccountAlreadyExistsException conversion unchanged, while clearly isolating this
assumption so future integrity-constraint failures are not implicitly treated as
duplicate accounts.
In
`@systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.kt`:
- Around line 9-13: Update BCryptPasswordHasher to inject the BCrypt strength
through Spring’s `@Value` configuration property and pass that value to
BCryptPasswordEncoder instead of relying on its default strength of 10. Add the
required Value import and keep hash using the configured encoder.
In
`@systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapter.kt`:
- Around line 42-51: Ensure refresh-token version state survives Redis key loss
by persisting it in the account record, or configure Redis with durable AOF
persistence and an eviction policy that cannot evict version keys. Update
RedisRefreshTokenRotationAdapter’s currentVersion and revokeAll flow
consistently, preserving INITIAL_VERSION semantics and ensuring a lost key
cannot make previously revoked version-0 tokens valid again.
In
`@systems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.kt`:
- Around line 18-24: Extend the test coverage beyond annotation inspection in
registrationBoundaryIsTransactional by adding a Spring-managed integration test
using `@DataJpaTest` or `@SpringBootTest`. Invoke registration through the
application context/proxied TransactionalAccountRegistrationAdapter, force
applicationDataPort.create to fail after account persistence begins, and assert
that the account is not retained after the transaction rolls back.
- Around line 28-29: The tests currently mock final Kotlin classes instead of
using real domain instances. In
systems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.kt
lines 28-29, replace the AccountRegistration and Account mocks with
AccountRegistration(...) and Account.create(...) instances; in
systems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapterTest.kt
lines 15-18, replace the AccountRegistration mock with a real
AccountRegistration(...) instance while keeping the AccountRepository mock.
In
`@systems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterTest.kt`:
- Around line 71-90: Extend RedisRefreshTokenRotationAdapterTest with
failure-mapping tests for currentVersion() and revokeAll(), using the same
DataAccessException setup and RefreshTokenStoreUnavailableException assertion
pattern as redisFailureIsMappedToStoreUnavailable(). Configure the relevant
Redis operation mocks to throw the captured failure, invoke each adapter method,
and assert the thrown exception is the expected type with the original failure
as its cause.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthAccountRepositoryAdapter.kt`:
- Around line 1-57: 添加针对 MockAuthAccountRepositoryAdapter.kt(1-57)的专用单元测试,覆盖
register() 的重复 loginId 拒绝、findByLoginId()、findByUserId()、save() 的序列更新,并在 TOCTOU
修复后验证并发注册行为;同时为 MockAuthApplicationDataAdapter.kt(1-43)添加测试,覆盖
create()、findByUserId() 及 cancel() 的状态转换。
- Around line 52-57: Update MockAuthAccountRepositoryAdapterConfiguration and
MockAuthAccountRepositoryAdapter so the mock repository also satisfies
AccountQueryPort, AccountCommandPort, and AccountRegistrationPort, or register
dedicated mock beans for each port. Ensure
IdentityApplicationConfig.authService() can resolve all three CQRS dependencies
when no persistence adapter is present, while preserving the existing
conditional AccountRepository registration.
- Around line 30-49: Update MockAuthAccountRepositoryAdapter.register to enforce
loginId uniqueness atomically rather than relying on findByLoginId; add or reuse
a loginId-keyed map and use putIfAbsent when inserting the newly created
account, throwing AccountAlreadyExistsException when an entry already exists.
Ensure the account maps remain consistent and add deterministic concurrent tests
with assertions that only one registration succeeds.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.kt`:
- Around line 37-51: Update MockAuthPortAdapter so it cannot be registered as an
AuthPort in production: gate the adapter with a non-production Spring profile or
equivalent conditional configuration, or exclude it from component scanning.
Preserve its current mock login and token-refresh behavior for test/mock
environments.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRepository.kt`:
- Around line 13-21: Update AccountRepository to extend AccountCommandPort and
AccountQueryPort instead of redeclaring their overlapping methods. Remove the
duplicated findByLoginId, findByUserId, save, and register declarations while
preserving the existing repository API through interface inheritance.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRotationStore.kt`:
- Around line 5-8: Update the KDoc for RefreshTokenRotationStore.consume to
explicitly define its Boolean contract: return true when the tokenId is
successfully consumed for the first time, and false when it was already consumed
and therefore represents refresh-token reuse. Keep the existing method signature
and behavior unchanged.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.kt`:
- Around line 3-4: JwtTokenGenerator에서 JJWT 기반 직렬화·HS256 서명 의존성을 제거하고, 토큰 발급과
검증을 위한 outbound port를 application 레이어에 정의하세요. application 레이어에는 클레임 정책과 토큰 계약만
남기고, Jwts와 Keys를 사용하는 구현은 적절한 adapter 모듈의 구현체로 이동해 해당 port를 호출하도록 변경하세요.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.kt`:
- Around line 67-80: Update AuthService.login so passwordHasher.matches
validates the supplied password immediately after account lookup and before
checking account.status. Only after successful password verification should the
existing ACCOUNT_INACTIVE check run, while preserving the current exceptions and
token issuance behavior.
- Around line 59-63: Update IdentityDomainException to accept an optional
Throwable cause and pass the caught AccountAlreadyExistsException as that cause
when AuthService converts it to IdentityDomainException, preserving the original
exception chain.
- Around line 123-136: Update AuthService.resetPassword to require a completed
identity-verification challenge, such as a validated OTP, email/SMS
verification, or temporary reset token, before hashing or saving the new
password; do not treat loginId, name, and birthdate matching as sufficient. Also
enforce rate limiting or failed-attempt limits for this reset flow using the
existing security mechanisms.
In
`@systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.kt`:
- Around line 11-15: IdentityServiceSupportTest.kt에 resolveAccount()와
findApplication()의 직접 단위 테스트를 추가하세요. AccountQueryPort.resolveAccount는 계정을 찾지 못할
때 IdentityDomainException이 발생하고 ErrorCode.AUTH_UNAUTHORIZED를 반환하는지,
ApplicationDataPort.findApplication은 애플리케이션을 찾지 못할 때 예외가 발생하고
ErrorCode.USER_NOT_FOUND를 반환하는지 결정론적으로 검증하세요.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.kt`:
- Around line 9-48: Extend JwtTokenVerifierTest with a deterministic
expired-refresh-token test using a fixed Clock advanced beyond the token’s
expiration, then call verifyRefreshToken() and assert the thrown
JwtTokenVerificationException has Reason.EXPIRED. Reuse generator(), NOW, and
the existing refresh-token flow while preserving the current happy-path and
rejection tests.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt`:
- Around line 290-318: Move the
signupMapsDatabaseDuplicateToAccountAlreadyExists test next to the other signup
tests and before the private service() and account() helpers, keeping related
declarations grouped and overloads adjacent. Replace the fully qualified
org.mockito.Mockito calls near the referenced tests with the appropriate import
and unqualified usage.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.kt`:
- Around line 42-57: Update applicationSnapshotMapsToStatusResult to use a
non-null announcedAt value and add assertions for result.passStatus and
result.announcedAt, while retaining the existing applicantStatus, submittedAt,
and updatedAt checks so every mapped field is verified.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt`:
- Around line 135-141: JwtFilter의 PUBLIC_AUTH_PATHS, AuthController의 인증 매핑,
SecurityConfig의 permitAll 경로가 각각 문자열을 중복 정의하지 않도록 공통 경로 상수 또는 클래스를 만들고 세 위치에서 이를
참조하게 하세요. AuthFilter의 401 예외 처리도 해당 공유 상수와 동일한 공개 경로를 기준으로 동작하는지 확인하고 일치시켜 주세요.
- Around line 69-72: Update the RefreshTokenStoreUnavailableException catch
block in JwtFilter to log the caught exception, including its cause and relevant
failure context, before clearing the security context and returning HTTP 503.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt`:
- Around line 70-80: SecurityConfig의 csrf 설정만 수정하지 말고, CsrfToken을 응답에 노출해
CookieCsrfTokenRepository가 XSRF-TOKEN cookie를 발급하도록 하는 경로를 추가하세요. 보호 대상 POST,
PATCH, DELETE 요청에서 발급된 cookie와 대응하는 CSRF 헤더를 검증하는 systems/identity 통합 테스트를 작성하고,
logout 경로가 존재한다면 cookie·헤더 없이 실패하며 올바른 값을 사용하면 성공하는 경우도 검증하세요.
---
Duplicate comments:
In `@systems/identity/identity-adapter-out/deps.bzl`:
- Around line 1-6: Replace the broad Spring Boot starter entries in KOTLIN_DEPS
with the explicitly used artifacts: spring-security-crypto, spring-context,
spring-tx, and spring-data-redis, while retaining the application and domain
dependencies. Verify each Maven coordinate is registered in the maven_install
artifact list.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0cfcdf02-6940-4074-929c-ad3e644a9626
⛔ Files ignored due to path filters (1)
kotlin.MODULE.bazelis excluded by none and included by none
📒 Files selected for processing (69)
systems/identity/.env.examplesystems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-adapter-in/deps.bzlsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandler.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/AuthIdentityAdapterInModuleTest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandlerTest.ktsystems/identity/identity-adapter-out/deps.bzlsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapter.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapterTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterIntegrationTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterTest.ktsystems/identity/identity-application/BUILD.bazelsystems/identity/identity-application/deps.bzlsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthAccountRepositoryAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthApplicationDataAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountAlreadyExistsException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistration.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRepository.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRevocationStore.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRotationStore.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenStoreUnavailableException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/SensitiveValueMasker.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifier.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/AuthIdentityApplicationModuleTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-bootstrap/deps.bzlsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-bootstrap/src/main/resources/application.yamlsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.kt
📜 Review details
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{kt,go}
📄 CodeRabbit inference engine (Custom checks)
If production logic is changed in Kotlin or Go files, require corresponding test updates in the same subsystem unless the PR description explicitly justifies why tests are unnecessary
Files:
systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountAlreadyExistsException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenStoreUnavailableException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRevocationStore.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistration.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/SensitiveValueMasker.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthAccountRepositoryAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRotationStore.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandler.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRepository.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/AuthIdentityAdapterInModuleTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterTest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthApplicationDataAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterIntegrationTest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifier.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/AuthIdentityApplicationModuleTest.kt
**/*.{java,kt,scala,groovy,go,js,ts,tsx,jsx,py,rb,rs,cpp,c,h,hpp,cs}
📄 CodeRabbit inference engine (Custom checks)
Flag TODO/FIXME comments introduced by this PR that do not include an issue reference in the form
#123or a full tracker key like PROJ-123
Files:
systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountAlreadyExistsException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenStoreUnavailableException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRevocationStore.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistration.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/SensitiveValueMasker.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthAccountRepositoryAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRotationStore.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandler.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRepository.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/AuthIdentityAdapterInModuleTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterTest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthApplicationDataAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterIntegrationTest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifier.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/AuthIdentityApplicationModuleTest.kt
**/*.kt
⚙️ CodeRabbit configuration file
**/*.kt: Apply Kotlin Official Coding Conventions.Formatting and structure:
- Use 4 spaces for indentation; no tabs.
- Keep files focused and readable; avoid horizontal alignment for spacing.
- Place related declarations together and keep overloads adjacent.
- Keep implementation member order stable and logical for readability.
Naming:
- Package names are lowercase and do not use underscores.
- Class/object names use UpperCamelCase.
- Functions/properties/local variables use lowerCamelCase.
- Constants use UPPER_SNAKE_CASE only for true constants.
API and null-safety:
- Avoid platform type leakage in public APIs.
- Use explicit types in public APIs when inference obscures meaning.
- Prefer immutable values (
val) over mutable values (var) unless mutation is required.- Flag nullable flows that can be replaced with safer modeling.
Imports and idioms:
- Avoid wildcard imports unless justified by language/tooling conventions.
- Prefer expression bodies for short, clear functions.
- Prefer standard library idioms over custom utility wrappers when equivalent.
Architecture and tests:
- Respect module boundaries (domain/application/adapter/bootstrap layering).
- Highlight behavior-changing code that lacks corresponding unit/integration tests.
- Ask for deterministic tests and meaningful assertions, not only happy-path checks.
Files:
systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandlerTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountAlreadyExistsException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenStoreUnavailableException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRevocationStore.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistration.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/SensitiveValueMasker.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthAccountRepositoryAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthorizationDeniedHandler.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRotationStore.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/RedisUnavailableExceptionHandler.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountQueryPersistenceAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtProperties.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRepository.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/AuthIdentityAdapterInModuleTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/IdentityApplicationConfig.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/TestMain.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/exception/GlobalExceptionHandlerTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapterTest.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtAuthenticationEntryPoint.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterTest.ktsystems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/TransactionalAccountRegistrationAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthApplicationDataAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthControllerTest.ktsystems/identity/identity-adapter-out/src/test/kotlin/hs/kr/entrydsm/identity/adapterout/security/RedisRefreshTokenRotationAdapterIntegrationTest.ktsystems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifier.ktsystems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/AuthIdentityApplicationModuleTest.kt
**/*-application/**/*.{java,kt,scala,groovy}
📄 CodeRabbit inference engine (Custom checks)
For files under *-application modules, flag direct dependency on infrastructure-specific framework classes unless justified
Files:
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountAlreadyExistsException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenStoreUnavailableException.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRevocationStore.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupportTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountQueryPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/RefreshTokenCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistration.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/SensitiveValueMasker.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LogoutCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/AuthenticatedUser.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthAccountRepositoryAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/RefreshTokenRotationStore.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRegistrationPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/LoginCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountRepository.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapper.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/result/AuthTokenResult.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/out/AccountCommandPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/SignupCommand.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/AuthPort.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/port/in/command/PasswordResetCommand.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/IdentityServiceSupport.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGenerator.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthApplicationDataAdapter.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.ktsystems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifier.ktsystems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/AuthIdentityApplicationModuleTest.kt
**/{BUILD.bazel,*.bzl}
📄 CodeRabbit inference engine (Custom checks)
In BUILD.bazel and .bzl files, require buildifier-compatible formatting and stable target naming
Files:
systems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-application/BUILD.bazelsystems/identity/identity-adapter-in/deps.bzlsystems/identity/identity-bootstrap/deps.bzlsystems/identity/identity-application/deps.bzlsystems/identity/identity-adapter-out/deps.bzl
**/BUILD.bazel
⚙️ CodeRabbit configuration file
**/BUILD.bazel: Apply Bazel BUILD style guidance.Core rules:
- BUILD formatting must match buildifier output.
- Prefer DAMP BUILD files over over-abstracted DRY patterns.
- Keep top-level layout clear: load() first, then package/default visibility, then targets.
Target definitions:
- Keep deps explicit and close to each target's real direct dependencies.
- Avoid recursive globs unless there is a clear, documented reason.
- Avoid top-level list comprehensions for generating many targets.
- Prefer literal labels and stable naming for readability and tooling compatibility.
- Use boolean values (True/False), not numeric stand-ins.
Maintenance:
- Flag duplicated target logic that should be moved into a macro.
- Flag macro usage that hides important dependency or visibility decisions.
Files:
systems/identity/identity-bootstrap/BUILD.bazelsystems/identity/identity-adapter-in/BUILD.bazelsystems/identity/identity-application/BUILD.bazel
**/*.bzl
⚙️ CodeRabbit configuration file
**/*.bzl: Apply Bazel Starlark (.bzl) style guidance.Readability and docs:
- Keep file/module docstrings and docstrings for public functions/macros.
- Use descriptive parameter names and document attribute intent.
API design:
- Macros should take a
nameargument and derive generated target names from it.- Prefer keyword arguments when calling macros for clarity and stability.
- Keep macro side effects predictable and visible.
Encapsulation:
- Use private visibility for helper targets created by macros unless explicitly public.
- Avoid exposing internal implementation targets unintentionally.
Tooling:
- Enforce buildifier formatting and lint compliance.
Files:
systems/identity/identity-adapter-in/deps.bzlsystems/identity/identity-bootstrap/deps.bzlsystems/identity/identity-application/deps.bzlsystems/identity/identity-adapter-out/deps.bzl
🪛 ast-grep (0.45.0)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/mock/MockAuthPortAdapterTest.kt
[warning] 35-35: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenGeneratorTest.kt
[warning] 84-84: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/security/jwt/JwtTokenVerifierTest.kt
[warning] 42-42: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
[warning] 130-130: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: private const val ACCESS_TOKEN_COOKIE = "access_token"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
[warning] 131-131: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: private const val ACCESS_TOKEN_TYPE = "access"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt
[warning] 324-324: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
systems/identity/identity-bootstrap/src/test/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilterTest.kt
[warning] 253-253: A credential is hard-coded by assigning a string literal to a password/secret/API-key variable. Secrets stored in source code can be leaked and abused by internal or external malicious actors. Remove the literal, rotate the exposed secret, and load it at runtime from an environment variable, a secure secret vault, or a Hardware Security Module (HSM).
Context: const val SECRET = "01234567890123456789012345678901"
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A07:2021]: Identification and Authentication Failures
(hardcoded-password-string-literal-kotlin)
🪛 detekt (1.23.8)
systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt
[warning] 69-69: The caught exception is swallowed. The original exception could be lost.
(detekt.exceptions.SwallowedException)
systems/identity/identity-application/src/main/kotlin/hs/kr/entrydsm/identity/application/service/AuthService.kt
[warning] 61-61: The caught exception is swallowed. The original exception could be lost.
(detekt.exceptions.SwallowedException)
🪛 dotenv-linter (4.0.0)
systems/identity/.env.example
[warning] 6-6: [UnorderedKey] The DB_PASSWORD key should go before the DB_USERNAME key
(UnorderedKey)
[warning] 7-7: [UnorderedKey] The DB_URL key should go before the DB_USERNAME key
(UnorderedKey)
[warning] 12-12: [UnorderedKey] The REDIS_KEY_NAMESPACE key should go before the REDIS_URL key
(UnorderedKey)
[warning] 13-13: [UnorderedKey] The REDIS_CONNECT_TIMEOUT key should go before the REDIS_KEY_NAMESPACE key
(UnorderedKey)
[warning] 14-14: [UnorderedKey] The REDIS_COMMAND_TIMEOUT key should go before the REDIS_CONNECT_TIMEOUT key
(UnorderedKey)
[warning] 15-15: [UnorderedKey] The REDIS_CLIENT_NAME key should go before the REDIS_COMMAND_TIMEOUT key
(UnorderedKey)
| @PatchMapping("/password-reset") | ||
| fun resetPassword( | ||
| @Valid @RequestBody request: PasswordResetRequest, | ||
| ): ApiResponse<Unit> { | ||
| authPort.resetPassword( | ||
| PasswordResetCommand( | ||
| loginId = request.loginId, | ||
| name = request.name, | ||
| birthdate = request.birthdate, | ||
| newPassword = request.newPassword, | ||
| ) | ||
| ) | ||
| return ApiResponse(data = null) |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
비밀번호 재설정에 계정 소유 증명을 추가하세요.
/password-reset은 비인증 요청을 허용합니다. 이 컨트롤러는 loginId, name, birthdate만 전달합니다. 제공된 AuthService.resetPassword도 세 값만 확인한 뒤 비밀번호를 변경합니다.
이 값은 비밀 정보가 아닙니다. 공격자가 값을 알면 계정 비밀번호를 변경할 수 있습니다. 일회용 검증 코드, 기존 인증 세션 또는 외부 본인인증 결과를 검증한 뒤 비밀번호를 변경하세요. 그 흐름을 구현할 수 없으면 이 엔드포인트를 운영 환경에 노출하지 마세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.kt`
around lines 98 - 110, Update resetPassword in AuthController and the underlying
AuthService flow to require and validate account ownership proof before changing
the password, such as a one-time verification code, authenticated session, or
trusted external identity result; do not rely only on loginId, name, and
birthdate. Propagate the verified proof through PasswordResetRequest and
PasswordResetCommand, and reject invalid, missing, expired, or already-used
proof; if no verification mechanism is available, disable this endpoint in
production.
| @field:NotBlank | ||
| @field:Size(max = 72) | ||
| @JsonProperty("password") val password: String, |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -a 'BCryptPasswordHasher.kt|SignupRequest.kt|PasswordResetRequest.kt' systems/identity
rg -n -C 4 'Size\(max = 72\)|toByteArray\(.*UTF_8|BCryptPasswordEncoder|hash\(|matches\(' systems/identityRepository: EntryDSM/entrydsm-platform
Length of output: 24781
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '--- Request DTOs ---\n'
for f in \
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.kt \
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.kt \
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.kt
do
if [ -f "$f" ]; then
echo "--- $f ---"
cat -n "$f"
fi
done
printf '\n--- Build files candidates ---\n'
fd -a 'build.gradle.kts|build.gradle|build.gradle[.]kts|pom.xml|libs.versions.toml' systems/identity . | sed 's#^\./##' | head -80
printf '\n--- BCrypt dependency/version references ---\n'
rg -n 'spring-security-crypto|spring-boot|spring-security|dependency-management\b|id "org.springframework.boot"|jacoco|kotlin|versions|spring-security-crypto' -S --glob '!build/repo' . | head -120
printf '\n--- Custom validation constraints in identity ---\n'
rg -n 'Size|NotBlank|`@field`:|`@GET`|`@PostMapping`|`@Transactional`|PasswordEncoder|encode\(|matches\(' systems/identity -SRepository: EntryDSM/entrydsm-platform
Length of output: 255
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
# Read-only semantic probe for the Java BCrypt truncation behavior observed by this project's
# Spring Security crypto dependency. Use only installed classes when available; otherwise demonstrate
# the UTF-8 byte-width issue in Python Unicode strings.
from pathlib import Path
import java.lang.System as System
def utf8_bytes(s):
return len(s.encode('utf-8'))
samples = ["aH1mZ8JqG01234567890abcdefghi", "가1234567aBCDEFGHIJKLMNOPQRSTUVWXYZabc", "한1234567aBCDEFGHIJKLMNOPQRSTUVWXYZabc"]
print("utf8_bytes:")
for s in samples:
print(f"{s!r}: {utf8_bytes(s)} bytes, {len(s)} chars")
try:
from org.springframework.security.crypto.bcrypt import BCryptPasswordEncoder
for s in samples:
h = BCryptPasswordEncoder().encode(s) or "null"
# BCrypt truncates at 72 bytes and uses the next bytes only as salt/work factor context.
print(f"{s!r}: encoded starts with nulls={h.startswith('10$')}, matches original={BCryptPasswordEncoder().matches(s, h)}")
except ImportError as e:
print("spring-security-crypto class not available:", e)
print("Use BCryptPasswordEncoder (Spring Security) docs/source to confirm UTF-8 byte truncation at 72 bytes.")
PYRepository: EntryDSM/entrydsm-platform
Length of output: 281
🌐 Web query:
Spring Security BCryptPasswordEncoder source code truncates raw password 72 bytes
💡 Result:
Yes, Spring Security's BCryptPasswordEncoder enforces a maximum password length of 72 bytes [1][2]. Historically, the BCrypt algorithm has an inherent limit where it only processes the first 72 bytes of a password [3][4]. Because of this, previous versions of Spring Security would silently truncate passwords longer than 72 bytes [5][6]. However, this behavior was identified as a security vulnerability (CVE-2025-22228) because it caused different passwords with the same first 72 bytes to result in the same hash, potentially allowing unauthorized access if an attacker knew the first 72 bytes of a victim's password [5]. To address this: 1. Updated versions of Spring Security now strictly enforce a 72-byte limit [5][1]. 2. The BCryptPasswordEncoder.encode() method will now throw an IllegalArgumentException if a provided password exceeds 72 bytes [1][7]. 3. To maintain backward compatibility for existing users who already have passwords longer than 72 bytes, the BCryptPasswordEncoder.matches() method will still allow these passwords to be validated against their existing hashes [8][1]. If your application requires passwords longer than 72 bytes, it is recommended to transition to a different password hashing algorithm, such as Argon2id, which does not have this limitation [8][9].
Citations:
- 1: spring-projects/spring-security@c1aa99f
- 2: BCryptPasswordEncoderTests should password limit of 72 bytes spring-projects/spring-security#18133
- 3: https://en.wikipedia.org/wiki/BCrypt
- 4: https://security.stackexchange.com/questions/39849/does-bcrypt-have-a-maximum-password-length
- 5: https://spring.io/security/cve-2025-22228
- 6: https://stackoverflow.com/questions/49934189/is-bcryptpasswordencoders-password-length-limit-more-than-72-characters
- 7: https://github.com/spring-projects/spring-security/blob/main/crypto/src/test/java/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoderTests.java
- 8: Regression with Bcrypt max password length spring-projects/spring-security#16802
- 9: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- Request DTOs ---'
for f in \
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.kt \
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/SignupRequest.kt \
systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/PasswordResetRequest.kt
do
if [ -f "$f" ]; then
printf '%s\n' "--- $f ---"
cat -n "$f"
fi
done
printf '%s\n' ''
printf '%s\n' '--- BCrypt dependency/config references ---'
rg -n -C 3 'spring-security-crypto|spring-boot|spring-security|dependency-management|id "org.springframework.boot"|org.springframework.boot|spring-security-crypto' -S --glob '!build/repo' . | head -160Repository: EntryDSM/entrydsm-platform
Length of output: 16326
비밀번호 제한을 UTF-8 바이트 단위로 적용하세요.
@Size(max = 72)는 문자 수를 제한합니다. BCrypt는 UTF-8 바이트 72를 넘으면 입력 처리가 잘못될 수 있습니다. BCryptPasswordHasher가 예외를 던지므로, 유효한 비밀번호가 BCrypt 경계 값을 넘으면 5xx가 발생할 수 있습니다.
해당 제한을 LoginRequest, SignupRequest, PasswordResetRequest의 비밀번호 필드와 서비스 검증 로직에 같은 UTF-8 바이트 규칙으로 맞춰서 적용하세요. 경계값과 멀티바이트 비밀번호를 포함해 테스트를 추가해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/dto/request/LoginRequest.kt`
around lines 11 - 13, Replace character-count validation on the password field
in LoginRequest and the corresponding fields in SignupRequest and
PasswordResetRequest with a shared UTF-8 byte-length maximum of 72, and apply
the same rule in the service validation logic before BCryptPasswordHasher is
invoked. Add boundary tests covering exactly 72 bytes, over-limit values, and
multibyte passwords, ensuring invalid inputs are rejected without producing a
5xx response.
| @RunWith(Suite::class) | ||
| @Suite.SuiteClasses( | ||
| AuthControllerTest::class, | ||
| GlobalExceptionHandlerTest::class, | ||
| ResponseMapperTest::class, | ||
| ) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
RedisUnavailableExceptionHandlerTest가 모듈 테스트 스위트에서 빠졌습니다.
이 PR에서 RedisUnavailableExceptionHandlerTest.kt를 추가했지만, AuthIdentityAdapterInModuleTest의 @Suite.SuiteClasses에는 등록하지 않았습니다. JUnit4 Suite 구조에서는 Suite에 등록된 클래스만 이 모듈 테스트 타깃을 통해 실행됩니다. Redis 장애 시 503 응답을 검증하는 테스트가 이 경로로 실행되지 않으면, 관련 회귀를 감지하지 못할 위험이 있습니다.
Suite에 RedisUnavailableExceptionHandlerTest::class를 추가하세요.
🧪 제안 수정
import hs.kr.entrydsm.identity.adapterin.web.AuthControllerTest
import hs.kr.entrydsm.identity.adapterin.web.dto.common.ResponseMapperTest
import hs.kr.entrydsm.identity.adapterin.web.exception.GlobalExceptionHandlerTest
+import hs.kr.entrydsm.identity.adapterin.web.exception.RedisUnavailableExceptionHandlerTest
import org.junit.runner.RunWith
import org.junit.runners.Suite
`@RunWith`(Suite::class)
`@Suite.SuiteClasses`(
AuthControllerTest::class,
GlobalExceptionHandlerTest::class,
ResponseMapperTest::class,
+ RedisUnavailableExceptionHandlerTest::class,
)
class AuthIdentityAdapterInModuleTest📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @RunWith(Suite::class) | |
| @Suite.SuiteClasses( | |
| AuthControllerTest::class, | |
| GlobalExceptionHandlerTest::class, | |
| ResponseMapperTest::class, | |
| ) | |
| import hs.kr.entrydsm.identity.adapterin.web.AuthControllerTest | |
| import hs.kr.entrydsm.identity.adapterin.web.dto.common.ResponseMapperTest | |
| import hs.kr.entrydsm.identity.adapterin.web.exception.GlobalExceptionHandlerTest | |
| import hs.kr.entrydsm.identity.adapterin.web.exception.RedisUnavailableExceptionHandlerTest | |
| import org.junit.runner.RunWith | |
| import org.junit.runners.Suite | |
| `@RunWith`(Suite::class) | |
| `@Suite.SuiteClasses`( | |
| AuthControllerTest::class, | |
| GlobalExceptionHandlerTest::class, | |
| ResponseMapperTest::class, | |
| RedisUnavailableExceptionHandlerTest::class, | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-adapter-in/src/test/kotlin/hs/kr/entrydsm/identity/adapterin/AuthIdentityAdapterInModuleTest.kt`
around lines 9 - 14, Update the `@Suite.SuiteClasses` declaration in
AuthIdentityAdapterInModuleTest to include
RedisUnavailableExceptionHandlerTest::class, preserving the existing suite
entries so the Redis-unavailable 503 response test runs with the module test
suite.
| override fun register(registration: AccountRegistration, createdAt: Instant): Account = try { | ||
| accountRepository.register(registration, createdAt) | ||
| } catch (exception: DataIntegrityViolationException) { | ||
| throw AccountAlreadyExistsException(exception) | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔵 Trivial
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -a 'AccountRepository.kt' systems/identity -x ast-grep outline {}
rg -n -C 6 '\bregister\s*\(|DataIntegrityViolationException|unique|UNIQUE|constraint' systems/identity
find systems/identity -type f \( -name '*.sql' -o -name '*.yaml' -o -name '*.yml' \) -print0 |
xargs -0 rg -n -C 4 'unique|UNIQUE|constraint|account|login'Repository: EntryDSM/entrydsm-platform
Length of output: 30996
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Files containing JPA/PostgreSQL persistence adapters or migrations:\n'
git ls-files | rg 'systems/identity|migration|schema|ddl|sql' || true
printf '\nLocate AccountCommandPersistenceAdapter and repository implementations:\n'
fd -a 'AccountCommandPersistenceAdapter|Jpa|Repository|account|Account' systems/identity -e kt -e java | sed -n '1,120p'
printf '\nAccountCommandPersistenceAdapter.kt:\n'
cat -n systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.kt
printf '\nSearch AccountRepository implementations in all tracked files:\n'
rg -n -C 8 'class .*AccountRepository|class .*Account.*Repository|AccountRepositoryImpl|fun AccountRepository|DataIntegrityViolationException|`@Entity`|`@Table`|unique' .Repository: EntryDSM/entrydsm-platform
Length of output: 38040
대부분의 경우 통과하는 코드지만 중복 로그인 ID 제약 조건만 처리하도록 문서화하세요.
AccountRepository.register() 계약은 로그인 식별자 고유 제약 조건을 강제하고, 현재 테스트도 "duplicate login id" 케이스만 보입니다. 실제 JPA/DB 구현에서 이 계약이 충족되면 변환은 문제는 없지만, 향후 다른 무결성 제약 조건이 추가되면 AccountAlreadyExistsException으로 잘못 매핑되지 않도록 구현 측면에서 격리하는 편이 안전합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/persistence/AccountCommandPersistenceAdapter.kt`
around lines 19 - 23, Update the register method in
AccountCommandPersistenceAdapter to document that its
DataIntegrityViolationException mapping is intended only for duplicate login ID
constraint violations. Keep the AccountRepository.register call and
AccountAlreadyExistsException conversion unchanged, while clearly isolating this
assumption so future integrity-constraint failures are not implicitly treated as
duplicate accounts.
| class BCryptPasswordHasher : PasswordHasher { | ||
| private val encoder = BCryptPasswordEncoder() | ||
|
|
||
| override fun hash(rawPassword: String): PasswordHash = | ||
| PasswordHash.fromEncoded(requireNotNull(encoder.encode(rawPassword))) |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
BCrypt strength를 설정으로 주입하세요.
BCryptPasswordEncoder()는 strength 10을 고정합니다. 하드웨어 성능이 올라가면 strength를 올려야 합니다. 현재 구조에서는 코드 변경 없이 조정할 수 없습니다.
♻️ 제안 변경
`@Component`
-class BCryptPasswordHasher : PasswordHasher {
- private val encoder = BCryptPasswordEncoder()
+class BCryptPasswordHasher(
+ `@Value`("\${identity.security.bcrypt-strength:12}")
+ strength: Int,
+) : PasswordHasher {
+ private val encoder = BCryptPasswordEncoder(strength)org.springframework.beans.factory.annotation.Value import를 추가하세요.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| class BCryptPasswordHasher : PasswordHasher { | |
| private val encoder = BCryptPasswordEncoder() | |
| override fun hash(rawPassword: String): PasswordHash = | |
| PasswordHash.fromEncoded(requireNotNull(encoder.encode(rawPassword))) | |
| class BCryptPasswordHasher( | |
| `@Value`("\${identity.security.bcrypt-strength:12}") | |
| strength: Int, | |
| ) : PasswordHasher { | |
| private val encoder = BCryptPasswordEncoder(strength) | |
| override fun hash(rawPassword: String): PasswordHash = | |
| PasswordHash.fromEncoded(requireNotNull(encoder.encode(rawPassword))) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-adapter-out/src/main/kotlin/hs/kr/entrydsm/identity/adapterout/security/BCryptPasswordHasher.kt`
around lines 9 - 13, Update BCryptPasswordHasher to inject the BCrypt strength
through Spring’s `@Value` configuration property and pass that value to
BCryptPasswordEncoder instead of relying on its default strength of 10. Add the
required Value import and keep hash using the configured encoder.
| @Test | ||
| fun signupMapsDatabaseDuplicateToAccountAlreadyExists() { | ||
| `when`(queryPort.findByLoginId("01012345678")).thenReturn(null) | ||
| `when`(passwordHasher.hash("password123!")).thenReturn(PASSWORD_HASH) | ||
| val service = service( | ||
| registration = AccountRegistrationPort { _, _ -> | ||
| throw AccountAlreadyExistsException( | ||
| IllegalStateException("duplicate login id"), | ||
| ) | ||
| }, | ||
| ) | ||
|
|
||
| val thrown = try { | ||
| service.signup( | ||
| SignupCommand( | ||
| password = "password123!", | ||
| name = "홍길동", | ||
| phone = "01012345678", | ||
| birthdate = BIRTHDATE, | ||
| signupType = SignupType.SELF, | ||
| ) | ||
| ) | ||
| null | ||
| } catch (exception: IdentityDomainException) { | ||
| exception | ||
| } | ||
|
|
||
| assertEquals(ErrorCode.ACCOUNT_ALREADY_EXISTS, thrown?.errorCode) | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
테스트 메서드를 private helper 앞으로 옮기세요.
signupMapsDatabaseDuplicateToAccountAlreadyExists가 service()와 account() helper 뒤에 있습니다. 다른 signup 테스트는 파일 상단(Line 48, 77)에 있습니다. 관련 선언을 함께 배치하면 가독성이 유지됩니다. Line 202와 Line 241의 org.mockito.Mockito 완전 수식 호출도 import로 정리하세요.
As per path instructions: "Place related declarations together and keep overloads adjacent."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/AuthServiceTest.kt`
around lines 290 - 318, Move the
signupMapsDatabaseDuplicateToAccountAlreadyExists test next to the other signup
tests and before the private service() and account() helpers, keeping related
declarations grouped and overloads adjacent. Replace the fully qualified
org.mockito.Mockito calls near the referenced tests with the appropriate import
and unqualified usage.
Source: Path instructions
| fun applicationSnapshotMapsToStatusResult() { | ||
| val snapshot = ApplicationSnapshot( | ||
| userId = 123L, | ||
| applicantStatus = ApplicantStatus.SUBMITTED, | ||
| submittedAt = NOW, | ||
| updatedAt = NOW, | ||
| passStatus = PassStatus.NOT_ANNOUNCED, | ||
| announcedAt = null, | ||
| ) | ||
|
|
||
| val result = snapshot.toStatusResult() | ||
|
|
||
| assertEquals(ApplicantStatus.SUBMITTED, result.applicantStatus) | ||
| assertEquals(NOW, result.submittedAt) | ||
| assertEquals(NOW, result.updatedAt) | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
상태 결과의 모든 필드를 검증하세요.
passStatus를 결과에서 검증하지 않습니다. announcedAt에는 non-null 값을 사용하고 결과 값도 검증하세요. 필드 매핑 누락을 이 테스트에서 탐지해야 합니다.
As per path instructions: “Ask for deterministic tests and meaningful assertions, not only happy-path checks.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-application/src/test/kotlin/hs/kr/entrydsm/identity/application/service/IdentityResultMapperTest.kt`
around lines 42 - 57, Update applicationSnapshotMapsToStatusResult to use a
non-null announcedAt value and add assertions for result.passStatus and
result.announcedAt, while retaining the existing applicantStatus, submittedAt,
and updatedAt checks so every mapped field is verified.
Source: Path instructions
| } catch (exception: RefreshTokenStoreUnavailableException) { | ||
| SecurityContextHolder.clearContext() | ||
| response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE) | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
Redis 장애 예외를 로깅 없이 삼킵니다.
RefreshTokenStoreUnavailableException을 잡은 후 원인 예외를 로깅하지 않고 바로 503을 반환합니다. Redis 장애가 발생해도 로그에 흔적이 남지 않아 장애 원인 추적이 어렵습니다. logger.warn(...) 등으로 예외를 기록하세요.
🪵 제안 수정
} catch (exception: RefreshTokenStoreUnavailableException) {
SecurityContextHolder.clearContext()
+ logger.warn("Refresh token store unavailable while verifying access token", exception)
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } catch (exception: RefreshTokenStoreUnavailableException) { | |
| SecurityContextHolder.clearContext() | |
| response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE) | |
| } | |
| } catch (exception: RefreshTokenStoreUnavailableException) { | |
| SecurityContextHolder.clearContext() | |
| logger.warn("Refresh token store unavailable while verifying access token", exception) | |
| response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE) | |
| } |
🧰 Tools
🪛 detekt (1.23.8)
[warning] 69-69: The caught exception is swallowed. The original exception could be lost.
(detekt.exceptions.SwallowedException)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt`
around lines 69 - 72, Update the RefreshTokenStoreUnavailableException catch
block in JwtFilter to log the caught exception, including its cause and relevant
failure context, before clearing the security context and returning HTTP 503.
Source: Linters/SAST tools
| private val PUBLIC_AUTH_PATHS = setOf( | ||
| "/api/identity/v11/auth/signup", | ||
| "/api/identity/v11/auth/login", | ||
| "/api/identity/v11/auth/token", | ||
| "/api/identity/v11/auth/password-reset", | ||
| ) | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: AuthController의 실제 매핑 경로와 SecurityConfig의 permitAll 설정이
# JwtFilter.PUBLIC_AUTH_PATHS와 일치하는지 확인합니다.
set -euo pipefail
echo "== AuthController mappings =="
rg -n '`@RequestMapping`|`@PostMapping`|`@PatchMapping`|`@GetMapping`' systems/identity/identity-adapter-in/src/main/kotlin/hs/kr/entrydsm/identity/adapterin/web/AuthController.kt
echo "== SecurityConfig permitAll =="
rg -n 'permitAll|requestMatchers|/auth' systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.ktRepository: EntryDSM/entrydsm-platform
Length of output: 1003
공유 경로 상수를 사용해 JwtFilter, AuthController, SecurityConfig의 인증 공개 경로 라인을 맞춰주세요.
/api/identity/v11/auth/signup 등은 AuthController 매핑과 SecurityConfig.permitAll과 모두 일치하지만, 이 세 곳 모두 개별 문자열로 관리되고 있어 경로 갱신 시 어긋날 수 있습니다. 공통 상수나 클래스를 분리해 세 위치가 한 소스를 참조하도록 만드세요. AuthFilter의 401 처리가 이 상수와 어떻게 매핑되는지도 함께 확인해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/security/JwtFilter.kt`
around lines 135 - 141, JwtFilter의 PUBLIC_AUTH_PATHS, AuthController의 인증 매핑,
SecurityConfig의 permitAll 경로가 각각 문자열을 중복 정의하지 않도록 공통 경로 상수 또는 클래스를 만들고 세 위치에서 이를
참조하게 하세요. AuthFilter의 401 예외 처리도 해당 공유 상수와 동일한 공개 경로를 기준으로 동작하는지 확인하고 일치시켜 주세요.
| .csrf { | ||
| it | ||
| .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) | ||
| .csrfTokenRequestHandler(XorCsrfTokenRequestAttributeHandler()) | ||
| .ignoringRequestMatchers( | ||
| "/api/identity/v11/auth/signup", | ||
| "/api/identity/v11/auth/login", | ||
| "/api/identity/v11/auth/token", | ||
| "/api/identity/v11/auth/password-reset", | ||
| ) | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 4 --glob '*.kt' \
'CsrfToken|XSRF-TOKEN|CookieCsrfTokenRepository|csrfTokenRepository|csrfTokenRequestHandler' \
systems/identity
rg -n -C 4 --glob '*Test.kt' \
'csrf|CSRF|XSRF-TOKEN|Set-Cookie|logout' \
systems/identityRepository: EntryDSM/entrydsm-platform
Length of output: 14084
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== SecurityConfig outline =="
ast-grep outline systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt || true
echo "== SecurityConfig relevant sections =="
cat -n systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt | sed -n '1,180p'
echo "== web/controllers and tests search for csrf/csrf_token/xsrf/cookie cookies/integration =="
rg -n -C 3 --glob '*.kt' \
'CsrfToken|csrfTokenRequestAttributeHandler|CsrfCookieWriter|CsrfTokenRequestAttributeHandler|XSRF-TOKEN|csrf_token|csrfToken|/csrf|CookieCsrfTokenRepository|webMvcTest|MockMvc|csrf|CSRF' \
systems/identity || true
echo "== CSRF-related files across identity =="
git ls-files systems/identity | rg -i 'csrf|security|auth|test' || trueRepository: EntryDSM/entrydsm-platform
Length of output: 15678
🌐 Web query:
Spring Security CsrF cookie token request handler creates CsrfToken cookie deferred request must read CsrfToken
💡 Result:
In Spring Security 6.x and later, CSRF token loading is deferred by default to improve performance by avoiding session or token access until absolutely necessary [1][2][3]. This change can cause issues for applications relying on CookieCsrfTokenRepository, where the CSRF cookie might not be sent on the initial request [4][3]. The interaction between the CsrfTokenRequestHandler and the CsrfToken occurs as follows: 1. Deferred Loading: Spring Security provides a loadDeferredToken method in the CsrfTokenRepository interface [5]. This defers the actual generation or retrieval of the token until the application explicitly requests it (e.g., via DeferredCsrfToken.get()) [6][5]. 2. Triggering the Load: The CsrfTokenRequestHandler (such as XorCsrfTokenRequestAttributeHandler or CsrfTokenRequestAttributeHandler) is responsible for resolving the token [7][1]. When the token is needed—for example, to include it in a response or validate a request—the handler interacts with the Supplier<CsrfToken> passed to its handle method [6]. 3. Opting out of Deferred Tokens: If your application requires the token to be present on every request (e.g., to ensure a cookie is always sent to a frontend), you can disable deferred loading [1][8]. A common way to achieve this is by configuring the CsrfTokenRequestHandler to have a null csrfRequestAttributeName [8][2][3]. This forces the framework to load the token on every request to determine the correct attribute name [8][2]. Example configuration to disable deferred tokens: @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { XorCsrfTokenRequestAttributeHandler requestHandler = new XorCsrfTokenRequestAttributeHandler; requestHandler.setCsrfRequestAttributeName(null); http.csrf((csrf) -> csrf.csrfTokenRequestHandler(requestHandler)); return http.build; } When using CookieCsrfTokenRepository, ensure that you use CookieCsrfTokenRepository.withHttpOnlyFalse() if the cookie needs to be read by JavaScript [1][9][10]. If you encounter scenarios where the cookie is missing, you may also need a custom filter or request handler to eagerly load the token [3].
Citations:
- 1: https://docs.spring.io/spring-security/reference/6.5/servlet/exploits/csrf.html
- 2: https://docs.spring.io/spring-security/reference/7.0-SNAPSHOT/servlet/exploits/csrf.html
- 3: https://docs.enterprise.spring.io/spring-security/reference/5.8/migration/servlet/exploits.html
- 4: CookieCsrfTokenRepository does not set the XSRF cookie on login response with Spring Security 6 RC1 spring-projects/spring-security#12094
- 5: https://docs.spring.io/spring-security/reference/6.5/api/java/org/springframework/security/web/csrf/CsrfTokenRepository.html
- 6: https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/csrf/CsrfTokenRequestAttributeHandler.html
- 7: https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html
- 8: https://www.springframework.org/spring-security/reference/servlet/exploits/csrf.html
- 9: https://docs.spring.io/spring-security/reference/api/java/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html
- 10: https://docs.spring.io/spring-security/site/docs/6.3.x/api/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html
CSRF cookie 발급 경로와 CSRF 통합 테스트를 추가하세요.
CookieCsrfTokenRepository는 deferred token으로 동작합니다. 현재 systems/identity에는 CsrfToken을 응답에 제공해 XSRF-TOKEN cookie를 발급하거나 검증하는 경로가 없습니다. CSRF 기본 설정은 POST, PATCH, DELETE를 보호하므로, 보호 요청에 유효한 CSRF 헤더를 사용한 통합 테스트가 필요합니다. 특히 기존 logout 경로가 추가된다면, 해당 요청이 CSRF cookie와 헤더 없이 실패하거나 올바른 cookie 사용 시 성공하는 테스트를 추가해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@systems/identity/identity-bootstrap/src/main/kotlin/hs/kr/entrydsm/identity/config/SecurityConfig.kt`
around lines 70 - 80, SecurityConfig의 csrf 설정만 수정하지 말고, CsrfToken을 응답에 노출해
CookieCsrfTokenRepository가 XSRF-TOKEN cookie를 발급하도록 하는 경로를 추가하세요. 보호 대상 POST,
PATCH, DELETE 요청에서 발급된 cookie와 대응하는 CSRF 헤더를 검증하는 systems/identity 통합 테스트를 작성하고,
logout 경로가 존재한다면 cookie·헤더 없이 실패하며 올바른 값을 사용하면 성공하는 경우도 검증하세요.
Summary
AuthService는 CQRS outbound port를 통해 계정 데이터를 사용하며, 인증 PR 단독 실행을 위해 조건부 Mock outbound adapter를 제공합니다.Related Issue
Scope
/api/identity/v11/auth/signup/api/identity/v11/auth/login/api/identity/v11/auth/logout/api/identity/v11/auth/token/api/identity/v11/auth/password-resetAuthService/api/identity/v11/accounts/**계정 API/api/identity/v11/applications/**지원서 APIImplementation
AuthController는 인증 application 결과를 access·refresh HttpOnly cookie로 변환하며 토큰 생성 책임을 갖지 않습니다.AuthService는AccountQueryPort,AccountCommandPort,AccountRegistrationPort를 통해 회원가입·로그인·비밀번호 변경을 처리합니다.MockAuthAccountRepositoryAdapter와MockAuthApplicationDataAdapter는 실제 account/application adapter가 없을 때만 조건부로 등록되어bazel run을 지원합니다.JwtFilter는 검증된 principal을AuthenticatedUser로 SecurityContext에 저장하고 비활성·삭제 계정의 access token을 차단합니다.TestMain.kt와 분리된 인증 전용 suite를 사용합니다.Testing
bazel test //systems/identity/identity-domain:test //systems/identity/identity-application:test //systems/identity/identity-adapter-in:test //systems/identity/identity-adapter-out:test //systems/identity/identity-bootstrap:test통과bazel run //systems/identity/identity-bootstrap:main기본 실행으로 Spring Boot가 8080 포트에서 기동됨을 확인Deployment Notes
JWT_SECRET,JWT_ISSUER,REDIS_URL,REDIS_KEY_NAMESPACE,REDIS_CONNECT_TIMEOUT,REDIS_COMMAND_TIMEOUT을 설정해야 합니다.Checklist
bazel run