From b7a8627bcfa64d2611e08f4d7963f35956e07400 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 28 May 2025 12:50:54 +0200 Subject: [PATCH 1/6] test: dice service --- .../casino/blackjack/BlackJackGameEntity.java | 2 - .../java/de/szut/casino/dice/DiceDto.java | 2 + .../java/de/szut/casino/dice/DiceService.java | 5 +- .../de/szut/casino/dice/DiceServiceTest.java | 216 ++++++++++++++++++ 4 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java diff --git a/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java b/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java index c9f57d7..4f22c9d 100644 --- a/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java +++ b/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java @@ -4,8 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import de.szut.casino.user.UserEntity; import jakarta.persistence.*; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/de/szut/casino/dice/DiceDto.java b/backend/src/main/java/de/szut/casino/dice/DiceDto.java index ecbf3d7..f0caf48 100644 --- a/backend/src/main/java/de/szut/casino/dice/DiceDto.java +++ b/backend/src/main/java/de/szut/casino/dice/DiceDto.java @@ -5,12 +5,14 @@ import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotNull; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import java.math.BigDecimal; @Getter @Setter +@NoArgsConstructor public class DiceDto extends BetDto { private boolean rollOver; diff --git a/backend/src/main/java/de/szut/casino/dice/DiceService.java b/backend/src/main/java/de/szut/casino/dice/DiceService.java index 71e4584..836620b 100644 --- a/backend/src/main/java/de/szut/casino/dice/DiceService.java +++ b/backend/src/main/java/de/szut/casino/dice/DiceService.java @@ -11,10 +11,11 @@ import java.util.Random; @Service public class DiceService { private static final int MAX_DICE_VALUE = 100; - private final Random random = new Random(); + private final Random random; private final BalanceService balanceService; - public DiceService(BalanceService balanceService) { + public DiceService(Random random, BalanceService balanceService) { + this.random = random; this.balanceService = balanceService; } diff --git a/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java new file mode 100644 index 0000000..21ca6cf --- /dev/null +++ b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java @@ -0,0 +1,216 @@ +package de.szut.casino.dice; + +import de.szut.casino.shared.service.BalanceService; +import de.szut.casino.user.UserEntity; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.math.BigDecimal; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class DiceServiceTest { + + @Mock + private BalanceService balanceService; + + @Mock + private Random random; + + @InjectMocks + private DiceService diceService; + + private UserEntity user; + private DiceDto diceDto; + + @BeforeEach + void setUp() { + user = new UserEntity(); + user.setId(1L); + user.setBalance(BigDecimal.valueOf(1000)); + + diceDto = new DiceDto(); + diceDto.setBetAmount(BigDecimal.valueOf(10)); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + diceDto.setRollOver(true); + } + + @Test + void play_rollOver_win() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(55); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(56), result.getRolledValue()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_lose() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(49); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(50), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(48); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(49), result.getRolledValue()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_lose() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(50); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(51), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_targetValueOne_lose() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(1)); + when(random.nextInt(anyInt())).thenReturn(0); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(1), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + } + + @Test + void play_rollUnder_targetValueOne_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(1)); + when(random.nextInt(anyInt())).thenReturn(0); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(1), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + } + + @Test + void play_rollOver_targetValueNinetyNine_win() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(99)); + when(random.nextInt(anyInt())).thenReturn(99); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(100), result.getRolledValue()); + } + + @Test + void play_rollUnder_targetValueNinetyNine_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(99)); + when(random.nextInt(anyInt())).thenReturn(97); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(98), result.getRolledValue()); + } + + @Test + void play_rollOver_targetValueOneHundred_lose() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(100)); + when(random.nextInt(anyInt())).thenReturn(99); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(100), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + } + + @Test + void play_rollUnder_targetValueOneHundred_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(100)); + when(random.nextInt(anyInt())).thenReturn(98); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(99), result.getRolledValue()); + } + + @Test + void play_payoutCalculationCorrect() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(75)); + when(random.nextInt(anyInt())).thenReturn(75); + + // Multiplier for win chance 25: (100-1)/25 = 99/25 = 3.96 + // Payout: 10 * 3.96 = 39.6 + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(39.6).stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + } + + @Test + void play_payoutCalculationCorrect_rollUnder() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(25)); + when(random.nextInt(anyInt())).thenReturn(0); + + // Multiplier for win chance 24: (100-1)/24 = 99/24 = 4.125 + // Payout: 10 * 4.125 = 41.25 + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(41.25).stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + } + + @Test + void play_betAmountSubtracted() { + when(random.nextInt(anyInt())).thenReturn(50); + + diceService.play(user, diceDto); + + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + } +} From 78b8f4696c658d15c4b388577dce59fc5a85d7be Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 28 May 2025 12:58:40 +0200 Subject: [PATCH 2/6] test: refactor --- .../de/szut/casino/dice/DiceServiceTest.java | 61 +++++++++++++++---- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java index 21ca6cf..ec5f979 100644 --- a/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java +++ b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java @@ -10,6 +10,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.Random; import static org.junit.jupiter.api.Assertions.*; @@ -101,78 +102,112 @@ class DiceServiceTest { } @Test - void play_rollOver_targetValueOne_lose() { + void play_rollOver_targetValueOne_rolledOne_lose() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(1)); - when(random.nextInt(anyInt())).thenReturn(0); + when(random.nextInt(anyInt())).thenReturn(0); // rolledValue = 1 DiceResult result = diceService.play(user, diceDto); assertFalse(result.isWin()); assertEquals(BigDecimal.valueOf(1), result.getRolledValue()); assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); } @Test - void play_rollUnder_targetValueOne_win() { + void play_rollOver_targetValueOne_rolledTwo_win() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(1)); + when(random.nextInt(anyInt())).thenReturn(1); // rolledValue = 2 + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(2), result.getRolledValue()); + // Win chance for target 1 (roll over) is 99. Multiplier = (100-1)/99 = 1 + assertEquals(diceDto.getBetAmount().stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_targetValueOne_alwaysLose_winChanceZero() { diceDto.setRollOver(false); diceDto.setTargetValue(BigDecimal.valueOf(1)); - when(random.nextInt(anyInt())).thenReturn(0); + when(random.nextInt(anyInt())).thenReturn(0); // rolledValue = 1 DiceResult result = diceService.play(user, diceDto); assertFalse(result.isWin()); assertEquals(BigDecimal.valueOf(1), result.getRolledValue()); assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); } @Test - void play_rollOver_targetValueNinetyNine_win() { + void play_rollOver_targetValueNinetyNine_rolledHundred_win() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(99)); - when(random.nextInt(anyInt())).thenReturn(99); + when(random.nextInt(anyInt())).thenReturn(99); // rolledValue = 100 DiceResult result = diceService.play(user, diceDto); assertTrue(result.isWin()); assertEquals(BigDecimal.valueOf(100), result.getRolledValue()); + // Win chance for target 99 (roll over) is 1. Multiplier = (100-1)/1 = 99 + assertEquals(diceDto.getBetAmount().multiply(BigDecimal.valueOf(99)).stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); } @Test - void play_rollUnder_targetValueNinetyNine_win() { + void play_rollUnder_targetValueNinetyNine_rolledNinetyEight_win() { diceDto.setRollOver(false); diceDto.setTargetValue(BigDecimal.valueOf(99)); - when(random.nextInt(anyInt())).thenReturn(97); + when(random.nextInt(anyInt())).thenReturn(97); // rolledValue = 98 DiceResult result = diceService.play(user, diceDto); assertTrue(result.isWin()); assertEquals(BigDecimal.valueOf(98), result.getRolledValue()); + // Win chance for target 99 (roll under) is 98. Multiplier = (100-1)/98 = 99/98 + assertEquals(diceDto.getBetAmount().multiply(BigDecimal.valueOf(99).divide(BigDecimal.valueOf(98), 4, RoundingMode.HALF_UP)), result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); } @Test - void play_rollOver_targetValueOneHundred_lose() { + void play_rollOver_targetValueOneHundred_alwaysLose_winChanceZero() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(100)); - when(random.nextInt(anyInt())).thenReturn(99); + when(random.nextInt(anyInt())).thenReturn(99); // rolledValue = 100 DiceResult result = diceService.play(user, diceDto); assertFalse(result.isWin()); assertEquals(BigDecimal.valueOf(100), result.getRolledValue()); assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); } @Test - void play_rollUnder_targetValueOneHundred_win() { - diceDto.setRollOver(false); + void play_rollUnder_targetValueOneHundred_rolledNinetyNine_win() { + diceDto.setRollOver(false); // Assuming a typo in original, should be setRollOver(false) diceDto.setTargetValue(BigDecimal.valueOf(100)); - when(random.nextInt(anyInt())).thenReturn(98); + when(random.nextInt(anyInt())).thenReturn(98); // rolledValue = 99 DiceResult result = diceService.play(user, diceDto); assertTrue(result.isWin()); assertEquals(BigDecimal.valueOf(99), result.getRolledValue()); + // Win chance for target 100 (roll under) is 99. Multiplier = (100-1)/99 = 1 + assertEquals(diceDto.getBetAmount().stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); } @Test From 3e1c15e023aac8d8c97176bb5cb6618e5f3e4233 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 28 May 2025 13:01:18 +0200 Subject: [PATCH 3/6] test: adjust commments --- .../de/szut/casino/dice/DiceServiceTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java index ec5f979..6b2e230 100644 --- a/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java +++ b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java @@ -105,7 +105,7 @@ class DiceServiceTest { void play_rollOver_targetValueOne_rolledOne_lose() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(1)); - when(random.nextInt(anyInt())).thenReturn(0); // rolledValue = 1 + when(random.nextInt(anyInt())).thenReturn(0); DiceResult result = diceService.play(user, diceDto); @@ -120,7 +120,7 @@ class DiceServiceTest { void play_rollOver_targetValueOne_rolledTwo_win() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(1)); - when(random.nextInt(anyInt())).thenReturn(1); // rolledValue = 2 + when(random.nextInt(anyInt())).thenReturn(1); DiceResult result = diceService.play(user, diceDto); @@ -136,7 +136,7 @@ class DiceServiceTest { void play_rollUnder_targetValueOne_alwaysLose_winChanceZero() { diceDto.setRollOver(false); diceDto.setTargetValue(BigDecimal.valueOf(1)); - when(random.nextInt(anyInt())).thenReturn(0); // rolledValue = 1 + when(random.nextInt(anyInt())).thenReturn(0); DiceResult result = diceService.play(user, diceDto); @@ -151,7 +151,7 @@ class DiceServiceTest { void play_rollOver_targetValueNinetyNine_rolledHundred_win() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(99)); - when(random.nextInt(anyInt())).thenReturn(99); // rolledValue = 100 + when(random.nextInt(anyInt())).thenReturn(99); DiceResult result = diceService.play(user, diceDto); @@ -167,7 +167,7 @@ class DiceServiceTest { void play_rollUnder_targetValueNinetyNine_rolledNinetyEight_win() { diceDto.setRollOver(false); diceDto.setTargetValue(BigDecimal.valueOf(99)); - when(random.nextInt(anyInt())).thenReturn(97); // rolledValue = 98 + when(random.nextInt(anyInt())).thenReturn(97); DiceResult result = diceService.play(user, diceDto); @@ -183,7 +183,7 @@ class DiceServiceTest { void play_rollOver_targetValueOneHundred_alwaysLose_winChanceZero() { diceDto.setRollOver(true); diceDto.setTargetValue(BigDecimal.valueOf(100)); - when(random.nextInt(anyInt())).thenReturn(99); // rolledValue = 100 + when(random.nextInt(anyInt())).thenReturn(99); DiceResult result = diceService.play(user, diceDto); @@ -196,9 +196,9 @@ class DiceServiceTest { @Test void play_rollUnder_targetValueOneHundred_rolledNinetyNine_win() { - diceDto.setRollOver(false); // Assuming a typo in original, should be setRollOver(false) + diceDto.setRollOver(false); diceDto.setTargetValue(BigDecimal.valueOf(100)); - when(random.nextInt(anyInt())).thenReturn(98); // rolledValue = 99 + when(random.nextInt(anyInt())).thenReturn(98); DiceResult result = diceService.play(user, diceDto); From bd1d8f83393c8c0f36c068be344ca6d56fd0e07b Mon Sep 17 00:00:00 2001 From: Jan K9f Date: Mon, 2 Jun 2025 14:04:15 +0200 Subject: [PATCH 4/6] chore: Add stale pipeline --- .gitea/workflows/stale.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .gitea/workflows/stale.yml diff --git a/.gitea/workflows/stale.yml b/.gitea/workflows/stale.yml new file mode 100644 index 0000000..773eac4 --- /dev/null +++ b/.gitea/workflows/stale.yml @@ -0,0 +1,14 @@ +name: "Close stale issues and PRs" +on: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-pr-message: "Will be closed in x days bc yo mom is a bitch. im not telling you when it will be closed fuckface" + days-before-pr-stale: 2 + days-before-pr-close: 3 From 9639525ddd35a4f9272dd98ac5e3e1a464b57fc4 Mon Sep 17 00:00:00 2001 From: Jan K9f Date: Mon, 2 Jun 2025 14:31:55 +0200 Subject: [PATCH 5/6] fix: Hourly --- .gitea/workflows/stale.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/stale.yml b/.gitea/workflows/stale.yml index 773eac4..7ba5af9 100644 --- a/.gitea/workflows/stale.yml +++ b/.gitea/workflows/stale.yml @@ -1,7 +1,8 @@ name: "Close stale issues and PRs" on: + workflow_dispatch: schedule: - - cron: "30 1 * * *" + - cron: "@hourly" jobs: stale: From a63ce082246217f54bb71074336abfaf2f509bd7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 2 Jun 2025 13:02:10 +0000 Subject: [PATCH 6/6] fix(deps): update dependencies (major and minor) --- backend/build.gradle.kts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 1d73b90..548c9aa 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -39,7 +39,7 @@ repositories { } dependencies { - implementation("com.stripe:stripe-java:29.1.0") + implementation("com.stripe:stripe-java:29.2.0") implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-web") compileOnly("org.projectlombok:lombok") @@ -47,13 +47,13 @@ dependencies { testImplementation("org.springframework.boot:spring-boot-starter-test") testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation("org.springframework.boot:spring-boot-starter-security") - implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.4.5") - implementation("org.springframework.boot:spring-boot-starter-oauth2-client:3.4.5") + implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.5.0") + implementation("org.springframework.boot:spring-boot-starter-oauth2-client:3.5.0") runtimeOnly("org.postgresql:postgresql") implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8") - implementation("io.jsonwebtoken:jjwt-api:0.11.5") - runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5") - runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5") + implementation("io.jsonwebtoken:jjwt-api:0.12.6") + runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6") + runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6") implementation("org.springframework.boot:spring-boot-starter-mail") }