From 2e2e75fe8771562a07b9700ceba39eb4c932ba38 Mon Sep 17 00:00:00 2001 From: Gabriel Sancho Date: Sat, 28 Mar 2026 03:40:03 -0300 Subject: [PATCH] fix: update JwtService to handle default expiration and add tests for token generation --- .../condado/newsletter/service/JwtService.kt | 4 ++- .../newsletter/service/AuthServiceTest.kt | 4 +-- .../newsletter/service/JwtServiceTest.kt | 26 +++++++++++++++++++ docker-compose.prod.yml | 2 +- docker/entrypoint.sh | 2 ++ 5 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 backend/src/test/kotlin/com/condado/newsletter/service/JwtServiceTest.kt diff --git a/backend/src/main/kotlin/com/condado/newsletter/service/JwtService.kt b/backend/src/main/kotlin/com/condado/newsletter/service/JwtService.kt index 4266251..a57ee7e 100644 --- a/backend/src/main/kotlin/com/condado/newsletter/service/JwtService.kt +++ b/backend/src/main/kotlin/com/condado/newsletter/service/JwtService.kt @@ -14,8 +14,10 @@ import java.util.Date @Service class JwtService( @Value("\${app.jwt.secret}") val secret: String, - @Value("\${app.jwt.expiration-ms}") val expirationMs: Long + @Value("\${app.jwt.expiration-ms:86400000}") expirationMsRaw: String ) { + private val expirationMs: Long = expirationMsRaw.toLongOrNull() ?: 86400000L + private val signingKey by lazy { Keys.hmacShaKeyFor(secret.toByteArray(Charsets.UTF_8)) } diff --git a/backend/src/test/kotlin/com/condado/newsletter/service/AuthServiceTest.kt b/backend/src/test/kotlin/com/condado/newsletter/service/AuthServiceTest.kt index d1e6305..c7b04b9 100644 --- a/backend/src/test/kotlin/com/condado/newsletter/service/AuthServiceTest.kt +++ b/backend/src/test/kotlin/com/condado/newsletter/service/AuthServiceTest.kt @@ -40,7 +40,7 @@ class AuthServiceTest { fun should_returnValidClaims_when_jwtTokenParsed() { val realJwtService = JwtService( secret = "test-secret-key-for-testing-only-must-be-at-least-32-characters", - expirationMs = 86400000L + expirationMsRaw = "86400000" ) val token = realJwtService.generateToken() @@ -51,7 +51,7 @@ class AuthServiceTest { fun should_returnFalse_when_expiredTokenValidated() { val realJwtService = JwtService( secret = "test-secret-key-for-testing-only-must-be-at-least-32-characters", - expirationMs = 1L + expirationMsRaw = "1" ) val token = realJwtService.generateToken() diff --git a/backend/src/test/kotlin/com/condado/newsletter/service/JwtServiceTest.kt b/backend/src/test/kotlin/com/condado/newsletter/service/JwtServiceTest.kt new file mode 100644 index 0000000..c7bebe7 --- /dev/null +++ b/backend/src/test/kotlin/com/condado/newsletter/service/JwtServiceTest.kt @@ -0,0 +1,26 @@ +package com.condado.newsletter.service + +import io.jsonwebtoken.Jwts +import io.jsonwebtoken.security.Keys +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +class JwtServiceTest { + + private val secret = "12345678901234567890123456789012" + + @Test + fun should_generate_token_when_expiration_is_empty() { + val jwtService = JwtService(secret, "") + + val token = jwtService.generateToken() + + val claims = Jwts.parser() + .verifyWith(Keys.hmacShaKeyFor(secret.toByteArray(Charsets.UTF_8))) + .build() + .parseSignedClaims(token) + .payload + + assertTrue(claims.expiration.after(claims.issuedAt)) + } +} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index ce7042d..413a3da 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -9,7 +9,7 @@ services: SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD} APP_PASSWORD: ${APP_PASSWORD} JWT_SECRET: ${JWT_SECRET} - JWT_EXPIRATION_MS: ${JWT_EXPIRATION_MS} + JWT_EXPIRATION_MS: ${JWT_EXPIRATION_MS:-86400000} MAIL_HOST: ${MAIL_HOST} MAIL_PORT: ${MAIL_PORT} MAIL_USERNAME: ${MAIL_USERNAME} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 3eb01b5..b1b1465 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -27,6 +27,7 @@ mkdir -p /var/log/supervisor export SPRING_DATASOURCE_URL=${SPRING_DATASOURCE_URL:-jdbc:postgresql://localhost:5432/${APP_DB_NAME}} export SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME:-${APP_DB_USER}} export SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD:-${APP_DB_PASSWORD}} +export JWT_EXPIRATION_MS=${JWT_EXPIRATION_MS:-86400000} # ── Log all Spring Boot environment variables for debugging ────────────────── echo "========================================" @@ -35,6 +36,7 @@ echo "========================================" echo "SPRING_DATASOURCE_URL=${SPRING_DATASOURCE_URL}" echo "SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME}" echo "SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD}" +echo "JWT_EXPIRATION_MS=${JWT_EXPIRATION_MS}" echo "JAVA_OPTS=${JAVA_OPTS:-not set}" echo "OPENAI_API_KEY=${OPENAI_API_KEY:-not set}" echo "========================================"