Skip to content

Add refresh token functionality and related configurations#61

Merged
subsub97 merged 3 commits into
mainfrom
worktree-feat+refresh-token
Jun 29, 2026
Merged

Add refresh token functionality and related configurations#61
subsub97 merged 3 commits into
mainfrom
worktree-feat+refresh-token

Conversation

@subsub97

Copy link
Copy Markdown
Collaborator

This pull request introduces a comprehensive refresh token system for authentication, enabling secure token rotation, revocation, and reuse detection. It adds new entities, services, endpoints, and configuration for managing refresh tokens, and updates the authentication flow to issue and handle refresh tokens alongside access tokens.

The most important changes are:

Refresh Token Infrastructure:

  • Added the RefreshToken entity to persist refresh token data, including hashes, family IDs, expiration, and revocation status. (RefreshToken.kt)
  • Implemented RefreshTokenRepository for querying and revoking refresh tokens, including methods to find by token hash and revoke all tokens in a family. (RefreshTokenRepository.kt)
  • Added RefreshTokenHasher for securely generating and hashing refresh tokens. (RefreshTokenHasher.kt)
  • Created RefreshTokenService to issue, rotate, and revoke refresh tokens, with logic for reuse detection and family-wide revocation. (RefreshTokenService.kt)

Authentication Flow Updates:

  • Updated AuthService to issue refresh tokens during sign-in/up, support token rotation, and revoke tokens on logout. (AuthService.kt) [1] [2] [3] [4]
  • Modified SignInUpResponse and LogoutRequest DTOs to include refresh tokens. (SignInUpResponse.kt, LogoutRequest.kt) [1] [2]
  • Added DTOs for token refresh requests and responses. (TokenRefreshRequest.kt, TokenRefreshResponse.kt) [1] [2]

API and Controller Enhancements:

  • Added /api/v1/auth/refresh endpoint to AuthController for refreshing tokens using a valid refresh token. (AuthController.kt)

Configuration and Expiration Handling:

  • Updated JwtTokenProvider to support configurable refresh token expiration and added a method to compute refresh token expiry. (JwtTokenProvider.kt, application-local.yml, application-prod.yml) [1] [2] [3] [4]

Testing:

  • Added unit and repository tests for refresh token generation, hashing, repository operations, and controller logic. (RefreshTokenHasherTest.kt, RefreshTokenRepositoryTest.kt, AuthControllerTest.kt, JwtTokenProviderRefreshTest.kt) [1] [2] [3] [4]

Copilot AI review requested due to automatic review settings June 27, 2026 10:36
@github-actions

github-actions Bot commented Jun 27, 2026

Copy link
Copy Markdown

Test Results

134 tests   134 ✅  2s ⏱️
 24 suites    0 💤
 24 files      0 ❌

Results for commit 9d3a618.

♻️ This comment has been updated with latest results.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a persistent refresh-token mechanism to the authentication system, including token issuance, rotation (with reuse detection), revocation, a refresh endpoint, and configuration for refresh-token TTL.

Changes:

  • Introduces RefreshToken persistence + repository/service logic for issuing, rotating, and revoking refresh tokens.
  • Updates auth flows (sign-in/up, refresh, logout) and adds /api/v1/auth/refresh API + related DTOs.
  • Adds configuration for refresh-token expiration and unit/repository/controller tests for the new behavior.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/main/kotlin/com/moa/entity/RefreshToken.kt New entity to persist refresh token metadata (hash/family/expiry/revocation).
src/main/kotlin/com/moa/repository/RefreshTokenRepository.kt Repository for hash lookup and family-wide revocation.
src/main/kotlin/com/moa/service/RefreshTokenService.kt Core refresh-token issuance/rotation/revocation logic.
src/main/kotlin/com/moa/common/auth/RefreshTokenHasher.kt Secure random token generation + SHA-256 hashing.
src/main/kotlin/com/moa/common/auth/JwtTokenProvider.kt Adds refresh-token expiry calculation via configurable TTL.
src/main/kotlin/com/moa/service/AuthService.kt Issues refresh tokens on sign-in/up; adds refresh and logout revocation behavior.
src/main/kotlin/com/moa/controller/AuthController.kt Adds /api/v1/auth/refresh endpoint.
src/main/kotlin/com/moa/service/dto/TokenRefreshRequest.kt DTO for refresh requests.
src/main/kotlin/com/moa/service/dto/TokenRefreshResponse.kt DTO for refresh responses.
src/main/kotlin/com/moa/service/dto/SignInUpResponse.kt Adds refreshToken to sign-in/up response.
src/main/kotlin/com/moa/service/dto/LogoutRequest.kt Adds optional refreshToken to logout request for revocation.
src/main/resources/application-local.yml Adds refresh-token expiration config key for local profile.
src/main/resources/application-prod.yml Adds refresh-token expiration config key for prod profile.
src/test/resources/application-test.yml Adds refresh-token expiration config key for test profile.
src/test/kotlin/com/moa/common/auth/RefreshTokenHasherTest.kt Tests refresh-token generation and hashing properties.
src/test/kotlin/com/moa/common/auth/JwtTokenProviderRefreshTest.kt Tests refresh expiry time calculation.
src/test/kotlin/com/moa/repository/RefreshTokenRepositoryTest.kt Tests repository lookup and family revocation behavior.
src/test/kotlin/com/moa/service/RefreshTokenServiceTest.kt Tests issuance/rotation/reuse-detection/revocation paths.
src/test/kotlin/com/moa/service/AuthServiceRefreshTest.kt Tests AuthService integration with refresh-token issuance/rotation/logout revocation.
src/test/kotlin/com/moa/controller/AuthControllerTest.kt Tests refresh endpoint wraps service result into ApiResponse.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +32 to +34
val current = refreshTokenRepository.findByTokenHash(hasher.hash(plainRefreshToken))
?: throw UnauthorizedException()

Comment on lines +47 to +49
current.revoke(now)
val newPlain = persist(current.memberId, current.familyId, now)
return RotationResult(memberId = current.memberId, plainRefreshToken = newPlain)
Comment on lines +10 to +26
@Entity
class RefreshToken(
@Column(nullable = false)
val memberId: Long,

@Column(nullable = false)
val tokenHash: String,

@Column(nullable = false)
val familyId: String,

@Column(nullable = false)
val expiresAt: LocalDateTime,

@Column
var revokedAt: LocalDateTime? = null,
) : BaseEntity() {
- bump moa-secret submodule (a7c8138 -> c3ce3b5) to include jwt refresh config
- align RefreshToken repository test datetime precision with DB datetime(6)
@subsub97

Copy link
Copy Markdown
Collaborator Author

내일 할게

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Comment on lines +19 to +22
fun hash(plain: String): String {
val digest = MessageDigest.getInstance("SHA-256").digest(plain.toByteArray(Charsets.UTF_8))
return digest.joinToString("") { "%02x".format(it) }
}
Comment on lines +15 to +16
@Column(nullable = false)
val tokenHash: String,
Comment on lines +10 to +12
@Entity
class RefreshToken(
@Column(nullable = false)
@subsub97 subsub97 merged commit f4a155f into main Jun 29, 2026
4 checks passed
@subsub97 subsub97 deleted the worktree-feat+refresh-token branch June 29, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants