diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 6ebfb08..366770a 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -7,38 +7,6 @@ jobs: checkstyle: name: "Checkstyle Main" runs-on: "vps-4" - container: - image: "cimg/openjdk:23.0-node" - steps: - - name: "Checkout" - uses: actions/checkout@v3 - - name: Setup Java 23 - uses: actions/setup-java@v3 - with: - distribution: "temurin" - java-version: "23" - - name: "Cache Gradle dependencies" - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-${{ runner.os }}-common - restore-keys: | - gradle-${{ runner.os }}- - - name: "Prepare Gradle" - working-directory: ./backend - run: gradle clean - - name: "Check" - working-directory: ./backend - run: gradle checkstyleMain - - name: "Stop Gradle" - working-directory: ./backend - run: gradle --stop - - test: - name: "Test" - runs-on: "vps-4" container: image: "cimg/openjdk:22.0-node" steps: @@ -49,21 +17,22 @@ jobs: with: distribution: "temurin" java-version: "22" - - name: "Cache Gradle dependencies" - uses: actions/cache@v3 + + - uses: actions/cache@v3 + working-directory: ./backend with: path: | ~/.gradle/caches ~/.gradle/wrapper - key: gradle-${{ runner.os }}-common + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | - gradle-${{ runner.os }}- + ${{ runner.os }}-gradle- - name: "Prepare Gradle" working-directory: ./backend run: gradle clean - - name: "Test" + - name: "Check" working-directory: ./backend - run: gradle test + run: gradle checkstyleMain - name: "Stop Gradle" working-directory: ./backend run: gradle --stop @@ -78,14 +47,6 @@ jobs: uses: actions/checkout@v4 - name: Install bun uses: oven-sh/setup-bun@v2 - - uses: actions/cache@v3 - working-directory: ./frontend - with: - path: | - frontend/node_modules/ - key: ${{ runner.os }}-bun- - restore-keys: | - ${{ runner.os }}-bun- - name: Install dependencies run: | cd frontend @@ -105,14 +66,6 @@ jobs: uses: actions/checkout@v4 - name: Install bun uses: oven-sh/setup-bun@v2 - - uses: actions/cache@v3 - working-directory: ./frontend - with: - path: | - frontend/node_modules/ - key: ${{ runner.os }}-bun- - restore-keys: | - ${{ runner.os }}-bun- - name: Install dependencies run: | cd frontend @@ -132,22 +85,6 @@ jobs: uses: actions/checkout@v4 - name: Install bun uses: oven-sh/setup-bun@v2 - - uses: actions/cache@v3 - working-directory: ./frontend - with: - path: | - frontend/node_modules/ - key: ${{ runner.os }}-bun- - restore-keys: | - ${{ runner.os }}-bun- - - uses: actions/cache@v3 - working-directory: ./frontend - with: - path: | - frontend/dist/ - key: ${{ runner.os }}-dist- - restore-keys: | - ${{ runner.os }}-dist- - name: Install dependencies run: | cd frontend diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index a2060f7..76efd27 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -24,7 +24,7 @@ version = "0.0.1-SNAPSHOT" java { toolchain { - languageVersion = JavaLanguageVersion.of(23) + languageVersion = JavaLanguageVersion.of(22) } } diff --git a/backend/requests/user.http b/backend/requests/user.http deleted file mode 100644 index 5e7aa5c..0000000 --- a/backend/requests/user.http +++ /dev/null @@ -1,27 +0,0 @@ -### Get User by ID -GET http://localhost:8080/user/52cc0208-a3bd-4367-94c5-0404b016a003 -Authorization: Bearer {{token}} - -### Get current user with token -GET http://localhost:8080/user -Authorization: Bearer {{token}} - -### Create User -POST http://localhost:8080/user -Content-Type: application/json -Authorization: Bearer {{token}} - -{ - "keycloakId": "52cc0208-a3bd-4367-94c5-0404b016a003", - "username": "john.doe" -} - -### Deposit -POST http://localhost:8080/deposit/checkout -Content-Type: application/json -Origin: http://localhost:8080 -Authorization: Bearer {{token}} - -{ - "amount": 60.12 -} \ No newline at end of file diff --git a/backend/src/main/java/de/szut/casino/deposit/DepositController.java b/backend/src/main/java/de/szut/casino/deposit/DepositController.java index 6bc0fbc..0e1ade5 100644 --- a/backend/src/main/java/de/szut/casino/deposit/DepositController.java +++ b/backend/src/main/java/de/szut/casino/deposit/DepositController.java @@ -3,13 +3,20 @@ package de.szut.casino.deposit; import com.stripe.Stripe; import com.stripe.exception.StripeException; import com.stripe.model.checkout.Session; +import com.stripe.param.InvoiceItemCreateParams; +import com.stripe.param.PriceCreateParams; import com.stripe.param.checkout.SessionCreateParams; import de.szut.casino.deposit.dto.AmountDto; import de.szut.casino.deposit.dto.SessionIdDto; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.cassandra.CassandraProperties; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; @RestController public class DepositController { @@ -17,11 +24,11 @@ public class DepositController { @Value("${stripe.secret.key}") private String stripeKey; - @Value("${app.frontend-host}") - private String frontendHost; - @PostMapping("/deposit/checkout") - public ResponseEntity checkout(@RequestBody @Valid AmountDto amountDto) throws StripeException { + public ResponseEntity checkout( + @RequestBody @Valid AmountDto amountDto, + @RequestHeader("Origin") String origin + ) throws StripeException { Stripe.apiKey = stripeKey; SessionCreateParams params = SessionCreateParams.builder() @@ -31,8 +38,7 @@ public class DepositController { .setQuantity(1L) .setName("Einzahlung") .build()) - .setSuccessUrl(frontendHost+"/home?success=true") - .setCancelUrl(frontendHost+"/home?success=false") + .setSuccessUrl(origin+"/deposit/success") .setMode(SessionCreateParams.Mode.PAYMENT) .build(); diff --git a/backend/src/main/java/de/szut/casino/security/KeycloakSecurityConfig.java b/backend/src/main/java/de/szut/casino/security/KeycloakSecurityConfig.java index 6be8b83..8ddcbcb 100644 --- a/backend/src/main/java/de/szut/casino/security/KeycloakSecurityConfig.java +++ b/backend/src/main/java/de/szut/casino/security/KeycloakSecurityConfig.java @@ -14,6 +14,7 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.session.HttpSessionEventPublisher; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import java.util.ArrayList; import java.util.List; @@ -23,6 +24,10 @@ import java.util.Map; @EnableWebSecurity class KeycloakSecurityConfig { + private static final String GROUPS = "groups"; + private static final String REALM_ACCESS_CLAIM = "realm_access"; + private static final String ROLES_CLAIM = "roles"; + private final KeycloakLogoutHandler keycloakLogoutHandler; KeycloakSecurityConfig(KeycloakLogoutHandler keycloakLogoutHandler) { diff --git a/backend/src/main/java/de/szut/casino/user/UserEntity.java b/backend/src/main/java/de/szut/casino/user/UserEntity.java index 83d8f44..f6c1a5b 100644 --- a/backend/src/main/java/de/szut/casino/user/UserEntity.java +++ b/backend/src/main/java/de/szut/casino/user/UserEntity.java @@ -4,10 +4,10 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.math.BigDecimal; @Setter @Getter @@ -20,11 +20,9 @@ public class UserEntity { @Column(unique = true) private String keycloakId; private String username; + private float balance; - @Column(precision = 19, scale = 2) - private BigDecimal balance; - - public UserEntity(String keycloakId, String username, BigDecimal balance) { + public UserEntity(String keycloakId, String username, float balance) { this.keycloakId = keycloakId; this.username = username; this.balance = balance; diff --git a/backend/src/main/java/de/szut/casino/user/UserMappingService.java b/backend/src/main/java/de/szut/casino/user/UserMappingService.java index 80f5546..e0183ec 100644 --- a/backend/src/main/java/de/szut/casino/user/UserMappingService.java +++ b/backend/src/main/java/de/szut/casino/user/UserMappingService.java @@ -4,8 +4,6 @@ import de.szut.casino.user.dto.CreateUserDto; import de.szut.casino.user.dto.GetUserDto; import org.springframework.stereotype.Service; -import java.math.BigDecimal; - @Service public class UserMappingService { public GetUserDto mapToGetUserDto(UserEntity user) { @@ -13,6 +11,7 @@ public class UserMappingService { } public UserEntity mapToUserEntity(CreateUserDto createUserDto) { - return new UserEntity(createUserDto.getKeycloakId(), createUserDto.getUsername(), BigDecimal.ZERO); } + return new UserEntity(createUserDto.getKeycloakId(), createUserDto.getUsername(), 0); + } } diff --git a/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java b/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java index 8521029..fb690af 100644 --- a/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java +++ b/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java @@ -5,8 +5,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.math.BigDecimal; - @Getter @Setter @AllArgsConstructor @@ -14,5 +12,5 @@ import java.math.BigDecimal; public class GetUserDto { private String keycloakId; private String username; - private BigDecimal balance; + private float balance; } diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index c7ccadf..268279f 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -4,7 +4,6 @@ spring.datasource.password=postgres_pass server.port=8080 spring.jpa.hibernate.ddl-auto=create-drop stripe.secret.key=${STRIPE_SECRET_KEY:sk_test_51QrePYIvCfqz7ANgqam8rEwWcMeKiLOof3j6SCMgu2sl4sESP45DJxca16mWcYo1sQaiBv32CMR6Z4AAAGQPCJo300ubuZKO8I} -app.frontend-host=http://localhost:4200 spring.application.name=lf12_starter #client registration configuration diff --git a/backend/src/test/java/de/szut/casino/health/HealthControllerTest.java b/backend/src/test/java/de/szut/casino/health/HealthControllerTest.java deleted file mode 100644 index 1214c7a..0000000 --- a/backend/src/test/java/de/szut/casino/health/HealthControllerTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.szut.casino.health; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.test.web.servlet.MockMvc; - -@WebMvcTest(HealthController.class) -@AutoConfigureMockMvc(addFilters = false) -public class HealthControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Test - void healthCheckReturnsUpStatus() throws Exception { - mockMvc.perform(get("/health")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.status").value("UP")); - } -} \ No newline at end of file diff --git a/backend/src/test/java/de/szut/casino/user/UserControllerTest.java b/backend/src/test/java/de/szut/casino/user/UserControllerTest.java deleted file mode 100644 index 2addb43..0000000 --- a/backend/src/test/java/de/szut/casino/user/UserControllerTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package de.szut.casino.user; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.szut.casino.user.dto.CreateUserDto; -import de.szut.casino.user.dto.GetUserDto; - -@WebMvcTest(UserController.class) -@AutoConfigureMockMvc(addFilters = false) -public class UserControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - @MockBean - private UserService userService; - - private GetUserDto getUserDto; - private CreateUserDto createUserDto; - private UserEntity testUser; - private final String TEST_ID = "test-id-123"; - private final String AUTH_TOKEN = "Bearer test-token"; - - @BeforeEach - void setUp() { - getUserDto = new GetUserDto(); - getUserDto.setKeycloakId(TEST_ID); - getUserDto.setUsername("testuser"); - - testUser = new UserEntity(); - testUser.setKeycloakId(TEST_ID); - testUser.setUsername("testuser"); - - createUserDto = new CreateUserDto(); - createUserDto.setKeycloakId(TEST_ID); - createUserDto.setUsername("testuser"); - } - - @Test - void getUserByIdSuccess() throws Exception { - when(userService.exists(TEST_ID)).thenReturn(true); - when(userService.getUser(TEST_ID)).thenReturn(getUserDto); - - mockMvc.perform(get("/user/" + TEST_ID)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.keycloakId").value(TEST_ID)) - .andExpect(jsonPath("$.username").value("testuser")); - } - - @Test - void getUserByIdNotFound() throws Exception { - when(userService.exists(TEST_ID)).thenReturn(false); - - mockMvc.perform(get("/user/" + TEST_ID)) - .andExpect(status().isNotFound()); - } - - @Test - void createUserSuccess() throws Exception { - when(userService.exists(TEST_ID)).thenReturn(false); - when(userService.createUser(any(CreateUserDto.class))).thenReturn(testUser); - - mockMvc.perform(post("/user") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(createUserDto))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.keycloakId").value(TEST_ID)) - .andExpect(jsonPath("$.username").value("testuser")); - } - - @Test - void createUserAlreadyExists() throws Exception { - when(userService.exists(TEST_ID)).thenReturn(true); - - mockMvc.perform(post("/user") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(createUserDto))) - .andExpect(status().isFound()) - .andExpect(header().string("Location", "/user/" + TEST_ID)); - } - - @Test - void getCurrentUserSuccess() throws Exception { - when(userService.getCurrentUser(AUTH_TOKEN)).thenReturn(getUserDto); - - mockMvc.perform(get("/user") - .header("Authorization", AUTH_TOKEN)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.keycloakId").value(TEST_ID)) - .andExpect(jsonPath("$.username").value("testuser")); - } - - @Test - void getCurrentUserNotFound() throws Exception { - when(userService.getCurrentUser(anyString())).thenReturn(null); - - mockMvc.perform(get("/user") - .header("Authorization", AUTH_TOKEN)) - .andExpect(status().isNotFound()); - } -} \ No newline at end of file diff --git a/frontend/bun.lock b/frontend/bun.lock index 5b0629c..91de068 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -10,6 +10,7 @@ "@angular/compiler": "^18.2.0", "@angular/core": "^18.2.0", "@angular/forms": "^18.2.0", + "@angular/material": "~18.2.14", "@angular/platform-browser": "^18.2.0", "@angular/platform-browser-dynamic": "^18.2.0", "@angular/router": "^18.2.0", @@ -19,7 +20,6 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@stripe/stripe-js": "^5.6.0", "@tailwindcss/postcss": "^4.0.3", - "gsap": "^3.12.7", "keycloak-angular": "^16.0.1", "keycloak-js": "^25.0.5", "postcss": "^8.5.1", @@ -93,6 +93,8 @@ "@angular/forms": ["@angular/forms@18.2.13", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/common": "18.2.13", "@angular/core": "18.2.13", "@angular/platform-browser": "18.2.13", "rxjs": "^6.5.3 || ^7.4.0" } }, "sha512-A67D867fu3DSBhdLWWZl/F5pr7v2+dRM2u3U7ZJ0ewh4a+sv+0yqWdJW+a8xIoiHxS+btGEJL2qAKJiH+MCFfg=="], + "@angular/material": ["@angular/material@18.2.14", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "^18.0.0 || ^19.0.0", "@angular/cdk": "18.2.14", "@angular/common": "^18.0.0 || ^19.0.0", "@angular/core": "^18.0.0 || ^19.0.0", "@angular/forms": "^18.0.0 || ^19.0.0", "@angular/platform-browser": "^18.0.0 || ^19.0.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "sha512-28pxzJP49Mymt664WnCtPkKeg7kXUsQKTKGf/Kl95rNTEdTJLbnlcc8wV0rT0yQNR7kXgpfBnG7h0ETLv/iu5Q=="], + "@angular/platform-browser": ["@angular/platform-browser@18.2.13", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "18.2.13", "@angular/common": "18.2.13", "@angular/core": "18.2.13" }, "optionalPeers": ["@angular/animations"] }, "sha512-tu7ZzY6qD3ATdWFzcTcsAKe7M6cJeWbT/4/bF9unyGO3XBPcNYDKoiz10+7ap2PUd0fmPwvuvTvSNJiFEBnB8Q=="], "@angular/platform-browser-dynamic": ["@angular/platform-browser-dynamic@18.2.13", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/common": "18.2.13", "@angular/compiler": "18.2.13", "@angular/core": "18.2.13", "@angular/platform-browser": "18.2.13" } }, "sha512-kbQCf9+8EpuJC7buBxhSiwBtXvjAwAKh6MznD6zd2pyCYqfY6gfRCZQRtK59IfgVtKmEONWI9grEyNIRoTmqJg=="], @@ -1069,8 +1071,6 @@ "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], - "gsap": ["gsap@3.12.7", "", {}, "sha512-V4GsyVamhmKefvcAKaoy0h6si0xX7ogwBoBSs2CTJwt7luW0oZzC0LhdkyuKV8PJAXr7Yaj8pMjCKD4GJ+eEMg=="], - "handle-thing": ["handle-thing@2.0.1", "", {}, "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], diff --git a/frontend/package.json b/frontend/package.json index 0ad0967..c79aae0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,7 @@ "@angular/compiler": "^18.2.0", "@angular/core": "^18.2.0", "@angular/forms": "^18.2.0", + "@angular/material": "~18.2.14", "@angular/platform-browser": "^18.2.0", "@angular/platform-browser-dynamic": "^18.2.0", "@angular/router": "^18.2.0", @@ -28,7 +29,6 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@stripe/stripe-js": "^5.6.0", "@tailwindcss/postcss": "^4.0.3", - "gsap": "^3.12.7", "keycloak-angular": "^16.0.1", "keycloak-js": "^25.0.5", "postcss": "^8.5.1", @@ -53,4 +53,4 @@ "typescript": "~5.5.2", "typescript-eslint": "8.23.0" } -} \ No newline at end of file +} diff --git a/frontend/public/blackjack.webp b/frontend/public/blackjack.webp deleted file mode 100644 index a791c14..0000000 Binary files a/frontend/public/blackjack.webp and /dev/null differ diff --git a/frontend/public/liars-dice.webp b/frontend/public/liars-dice.webp deleted file mode 100644 index df1fd1c..0000000 Binary files a/frontend/public/liars-dice.webp and /dev/null differ diff --git a/frontend/public/lootbox.webp b/frontend/public/lootbox.webp deleted file mode 100644 index 710deed..0000000 Binary files a/frontend/public/lootbox.webp and /dev/null differ diff --git a/frontend/public/plinko.webp b/frontend/public/plinko.webp deleted file mode 100644 index c11370b..0000000 Binary files a/frontend/public/plinko.webp and /dev/null differ diff --git a/frontend/public/poker.webp b/frontend/public/poker.webp deleted file mode 100644 index 9c60024..0000000 Binary files a/frontend/public/poker.webp and /dev/null differ diff --git a/frontend/public/slots.webp b/frontend/public/slots.webp deleted file mode 100644 index 5cf639a..0000000 Binary files a/frontend/public/slots.webp and /dev/null differ diff --git a/frontend/src/app/feature/deposit/deposit.component.html b/frontend/src/app/feature/deposit/deposit.component.html index e8e4dfb..707d145 100644 --- a/frontend/src/app/feature/deposit/deposit.component.html +++ b/frontend/src/app/feature/deposit/deposit.component.html @@ -1,25 +1,21 @@ -@if (isOpen) { -