From edc21730cd111c1aae2cd529e0702c425a51b858 Mon Sep 17 00:00:00 2001 From: Stefan Ranoszek Date: Fri, 27 Feb 2026 15:44:48 +0000 Subject: [PATCH 1/5] fix: jackson --- pom.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pom.xml b/pom.xml index 4aa7ec9..a20c32e 100644 --- a/pom.xml +++ b/pom.xml @@ -110,6 +110,25 @@ commons-io 2.15.1 + + + + com.fasterxml.jackson.core + jackson-core + 2.17.3 + + + + com.fasterxml.jackson.core + jackson-databind + 2.17.3 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.17.3 + From f5a6ce2387e76a5cedda53c7f8904ba6a9a858f1 Mon Sep 17 00:00:00 2001 From: Stefan Ranoszek Date: Fri, 27 Feb 2026 15:52:17 +0000 Subject: [PATCH 2/5] fix: switch to native JWT handling --- pom.xml | 23 +++++--- .../java/apiCalls/Utils/generic/BaseAPI.java | 53 ++++++++++++++++--- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index a20c32e..ce73cac 100644 --- a/pom.xml +++ b/pom.xml @@ -29,12 +29,12 @@ 5.3.1 - - 4.4.0 - 3.18.0 + + 2.17.3 + 2.25.3 2.25.3 @@ -274,14 +274,21 @@ - + - + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + - com.auth0 - java-jwt - ${java-jwt.version} + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} diff --git a/src/main/java/apiCalls/Utils/generic/BaseAPI.java b/src/main/java/apiCalls/Utils/generic/BaseAPI.java index 812c644..b97f3c0 100644 --- a/src/main/java/apiCalls/Utils/generic/BaseAPI.java +++ b/src/main/java/apiCalls/Utils/generic/BaseAPI.java @@ -4,18 +4,21 @@ import activesupport.system.Properties; import apiCalls.Utils.http.RestUtils; import apiCalls.actions.Token; -import com.auth0.jwt.JWT; -import com.auth0.jwt.exceptions.JWTDecodeException; import org.apache.hc.core5.http.HttpException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dvsa.testing.lib.url.api.ApiUrl; import org.dvsa.testing.lib.url.utils.EnvironmentType; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.Base64; import java.util.Date; import java.util.HashMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; public class BaseAPI extends Token { private static final Logger LOGGER = LogManager.getLogger(BaseAPI.class); @@ -44,11 +47,47 @@ public synchronized String adminJWT() throws HttpException { private boolean isTokenExpired(String token) { try { - var decodedJWT = JWT.decode(token); - return decodedJWT.getExpiresAt().before(new Date()); - } catch (JWTDecodeException e) { - LOGGER.error("Error decoding token: {}", e.getMessage()); - return true; + // JWT tokens have 3 parts separated by dots: header.payload.signature + String[] parts = token.split("\\."); + if (parts.length != 3) { + LOGGER.error("Invalid JWT token format - expected 3 parts, got {}", parts.length); + return true; + } + + // Decode the payload (second part) + String payload = parts[1]; + + // Add padding if necessary for proper Base64 decoding + int paddingLength = 4 - (payload.length() % 4); + if (paddingLength != 4) { + payload += "=".repeat(paddingLength); + } + + // Decode Base64URL + byte[] decodedBytes = Base64.getUrlDecoder().decode(payload); + String decodedPayload = new String(decodedBytes, StandardCharsets.UTF_8); + + // Parse JSON to get expiration time + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(decodedPayload); + + // Get 'exp' claim (expiration time as Unix timestamp) + if (!jsonNode.has("exp")) { + LOGGER.warn("JWT token does not contain 'exp' claim, treating as expired"); + return true; + } + + long expTimestamp = jsonNode.get("exp").asLong(); + Instant expiration = Instant.ofEpochSecond(expTimestamp); + + boolean isExpired = expiration.isBefore(Instant.now()); + LOGGER.debug("JWT token expires at: {}, is expired: {}", expiration, isExpired); + + return isExpired; + + } catch (Exception e) { + LOGGER.error("Error decoding JWT token: {}", e.getMessage()); + return true; // Treat any decoding error as expired token } } From adc153478a48a0718599f5e82b74f8f1add2a74d Mon Sep 17 00:00:00 2001 From: Stefan Ranoszek Date: Fri, 27 Feb 2026 15:56:25 +0000 Subject: [PATCH 3/5] fix: swich to jjwt lib --- pom.xml | 30 +++++++--- .../java/apiCalls/Utils/generic/BaseAPI.java | 60 +++++++------------ 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/pom.xml b/pom.xml index ce73cac..ba0d8fa 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,9 @@ 2.17.3 + + 0.13.0 + 2.25.3 2.25.3 @@ -274,21 +277,30 @@ - + - + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + - com.fasterxml.jackson.core - jackson-core - ${jackson.version} + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + runtime - + - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + runtime diff --git a/src/main/java/apiCalls/Utils/generic/BaseAPI.java b/src/main/java/apiCalls/Utils/generic/BaseAPI.java index b97f3c0..cce3646 100644 --- a/src/main/java/apiCalls/Utils/generic/BaseAPI.java +++ b/src/main/java/apiCalls/Utils/generic/BaseAPI.java @@ -4,21 +4,21 @@ import activesupport.system.Properties; import apiCalls.Utils.http.RestUtils; import apiCalls.actions.Token; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.UnsupportedJwtException; import org.apache.hc.core5.http.HttpException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dvsa.testing.lib.url.api.ApiUrl; import org.dvsa.testing.lib.url.utils.EnvironmentType; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.Base64; import java.util.Date; import java.util.HashMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.JsonNode; public class BaseAPI extends Token { private static final Logger LOGGER = LogManager.getLogger(BaseAPI.class); @@ -47,47 +47,33 @@ public synchronized String adminJWT() throws HttpException { private boolean isTokenExpired(String token) { try { - // JWT tokens have 3 parts separated by dots: header.payload.signature - String[] parts = token.split("\\."); - if (parts.length != 3) { - LOGGER.error("Invalid JWT token format - expected 3 parts, got {}", parts.length); - return true; - } - - // Decode the payload (second part) - String payload = parts[1]; - - // Add padding if necessary for proper Base64 decoding - int paddingLength = 4 - (payload.length() % 4); - if (paddingLength != 4) { - payload += "=".repeat(paddingLength); - } - - // Decode Base64URL - byte[] decodedBytes = Base64.getUrlDecoder().decode(payload); - String decodedPayload = new String(decodedBytes, StandardCharsets.UTF_8); + Claims claims = Jwts.parser() + .unsecured() + .build() + .parseUnsecuredClaims(token) + .getPayload(); - // Parse JSON to get expiration time - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode jsonNode = objectMapper.readTree(decodedPayload); - - // Get 'exp' claim (expiration time as Unix timestamp) - if (!jsonNode.has("exp")) { - LOGGER.warn("JWT token does not contain 'exp' claim, treating as expired"); + Date expiration = claims.getExpiration(); + if (expiration == null) { + LOGGER.warn("JWT token does not contain expiration claim, treating as expired"); return true; } - long expTimestamp = jsonNode.get("exp").asLong(); - Instant expiration = Instant.ofEpochSecond(expTimestamp); - - boolean isExpired = expiration.isBefore(Instant.now()); + boolean isExpired = expiration.before(new Date()); LOGGER.debug("JWT token expires at: {}, is expired: {}", expiration, isExpired); return isExpired; + } catch (ExpiredJwtException e) { + // Token is already expired + LOGGER.debug("JWT token is expired: {}", e.getMessage()); + return true; + } catch (MalformedJwtException | UnsupportedJwtException | IllegalArgumentException e) { + LOGGER.error("Invalid JWT token format: {}", e.getMessage()); + return true; // Treat invalid tokens as expired } catch (Exception e) { - LOGGER.error("Error decoding JWT token: {}", e.getMessage()); - return true; // Treat any decoding error as expired token + LOGGER.error("Unexpected error decoding JWT token: {}", e.getMessage()); + return true; // Treat any unexpected error as expired } } From 69006890a685a8745f986eb71563375f2a85ccce Mon Sep 17 00:00:00 2001 From: Stefan Ranoszek Date: Fri, 27 Feb 2026 15:57:50 +0000 Subject: [PATCH 4/5] fix: swich to jjwt lib --- pom.xml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/pom.xml b/pom.xml index ba0d8fa..f05cb60 100644 --- a/pom.xml +++ b/pom.xml @@ -32,9 +32,6 @@ 3.18.0 - - 2.17.3 - 0.13.0 @@ -113,25 +110,6 @@ commons-io 2.15.1 - - - - com.fasterxml.jackson.core - jackson-core - 2.17.3 - - - - com.fasterxml.jackson.core - jackson-databind - 2.17.3 - - - - com.fasterxml.jackson.core - jackson-annotations - 2.17.3 - From 96a6f2d6d70498c6b541590a14d0a9940b38654c Mon Sep 17 00:00:00 2001 From: Stefan Ranoszek Date: Fri, 27 Feb 2026 16:03:38 +0000 Subject: [PATCH 5/5] fix: revert code --- .../java/apiCalls/Utils/generic/BaseAPI.java | 29 +++---------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/src/main/java/apiCalls/Utils/generic/BaseAPI.java b/src/main/java/apiCalls/Utils/generic/BaseAPI.java index cce3646..dda640e 100644 --- a/src/main/java/apiCalls/Utils/generic/BaseAPI.java +++ b/src/main/java/apiCalls/Utils/generic/BaseAPI.java @@ -4,11 +4,7 @@ import activesupport.system.Properties; import apiCalls.Utils.http.RestUtils; import apiCalls.actions.Token; -import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.UnsupportedJwtException; import org.apache.hc.core5.http.HttpException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -47,33 +43,16 @@ public synchronized String adminJWT() throws HttpException { private boolean isTokenExpired(String token) { try { - Claims claims = Jwts.parser() + var decodedJWT = Jwts.parser() .unsecured() .build() .parseUnsecuredClaims(token) .getPayload(); - Date expiration = claims.getExpiration(); - if (expiration == null) { - LOGGER.warn("JWT token does not contain expiration claim, treating as expired"); - return true; - } - - boolean isExpired = expiration.before(new Date()); - LOGGER.debug("JWT token expires at: {}, is expired: {}", expiration, isExpired); - - return isExpired; - - } catch (ExpiredJwtException e) { - // Token is already expired - LOGGER.debug("JWT token is expired: {}", e.getMessage()); - return true; - } catch (MalformedJwtException | UnsupportedJwtException | IllegalArgumentException e) { - LOGGER.error("Invalid JWT token format: {}", e.getMessage()); - return true; // Treat invalid tokens as expired + return decodedJWT.getExpiration().before(new Date()); } catch (Exception e) { - LOGGER.error("Unexpected error decoding JWT token: {}", e.getMessage()); - return true; // Treat any unexpected error as expired + LOGGER.error("Error decoding token: {}", e.getMessage()); + return true; } }