From 7fbe1c375367494635ccbc3dff1e1619e1189fd8 Mon Sep 17 00:00:00 2001 From: csimonis Date: Wed, 14 May 2025 09:22:15 +0200 Subject: [PATCH 001/210] feat(email): add deposit confirmation email template and logic --- .../casino/deposit/TransactionService.java | 10 +- .../casino/deposit/WebhookController.java | 4 +- .../casino/security/service/EmailService.java | 22 ++- .../java/de/szut/casino/user/UserEntity.java | 4 + .../resources/templates/email/deposit.html | 136 ++++++++++++++++++ 5 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/resources/templates/email/deposit.html diff --git a/backend/src/main/java/de/szut/casino/deposit/TransactionService.java b/backend/src/main/java/de/szut/casino/deposit/TransactionService.java index fceb27b..26f2e25 100644 --- a/backend/src/main/java/de/szut/casino/deposit/TransactionService.java +++ b/backend/src/main/java/de/szut/casino/deposit/TransactionService.java @@ -3,10 +3,13 @@ package de.szut.casino.deposit; import com.stripe.exception.StripeException; import com.stripe.model.checkout.Session; import com.stripe.param.checkout.SessionRetrieveParams; +import de.szut.casino.security.service.EmailService; import de.szut.casino.user.UserEntity; import de.szut.casino.user.UserRepository; +import jakarta.mail.MessagingException; import org.springframework.stereotype.Service; +import java.io.IOException; import java.math.BigDecimal; import java.util.Optional; @@ -14,10 +17,12 @@ import java.util.Optional; public class TransactionService { private final TransactionRepository transactionRepository; private final UserRepository userRepository; + private final EmailService emailService; - public TransactionService(TransactionRepository transactionRepository, UserRepository userRepository) { + public TransactionService(TransactionRepository transactionRepository, UserRepository userRepository, EmailService emailService) { this.transactionRepository = transactionRepository; this.userRepository = userRepository; + this.emailService = emailService; } public void createTransaction( @@ -34,7 +39,7 @@ public class TransactionService { transactionRepository.save(transaction); } - public void fulfillCheckout(String sessionID) throws StripeException { + public void fulfillCheckout(String sessionID) throws StripeException, MessagingException, IOException { SessionRetrieveParams params = SessionRetrieveParams.builder() .addExpand("line_items") .build(); @@ -60,5 +65,6 @@ public class TransactionService { userRepository.save(user); transactionRepository.save(transaction); + emailService.sendDepositEmail(transaction); } } diff --git a/backend/src/main/java/de/szut/casino/deposit/WebhookController.java b/backend/src/main/java/de/szut/casino/deposit/WebhookController.java index dba9041..45ba4c1 100644 --- a/backend/src/main/java/de/szut/casino/deposit/WebhookController.java +++ b/backend/src/main/java/de/szut/casino/deposit/WebhookController.java @@ -6,6 +6,7 @@ import com.stripe.model.Event; import com.stripe.model.checkout.Session; import com.stripe.net.Webhook; import jakarta.annotation.PostConstruct; +import jakarta.mail.MessagingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -15,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; import java.util.Objects; @RestController @@ -38,7 +40,7 @@ public class WebhookController { } @PostMapping("/webhook") - public ResponseEntity webhook(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader) throws StripeException { + public ResponseEntity webhook(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader) throws StripeException, MessagingException, IOException { Event event = Webhook.constructEvent(payload, sigHeader, webhookSecret); if (Objects.equals(event.getType(), "checkout.session.completed") || Objects.equals(event.getType(), "checkout.session.async_payment_succeeded")) { diff --git a/backend/src/main/java/de/szut/casino/security/service/EmailService.java b/backend/src/main/java/de/szut/casino/security/service/EmailService.java index fb875b8..861a0c2 100644 --- a/backend/src/main/java/de/szut/casino/security/service/EmailService.java +++ b/backend/src/main/java/de/szut/casino/security/service/EmailService.java @@ -1,5 +1,6 @@ package de.szut.casino.security.service; +import de.szut.casino.deposit.TransactionEntity; import de.szut.casino.user.UserEntity; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; @@ -14,6 +15,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.StandardCharsets; +import java.util.List; @Service public class EmailService { @@ -43,13 +45,31 @@ public class EmailService { MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); helper.setFrom(mailConfig.fromAddress); - helper.setTo(user.getEmail()); + helper.setTo(user.getEmailAddress()); helper.setSubject("Willkommen bei Trustworthy Casino©"); helper.setText(htmlContent, true); mailSender.send(message); } + public void sendDepositEmail(TransactionEntity transaction) throws IOException, MessagingException { + String template = loadTemplate("email/deposit.html"); + String htmlContent = template + .replace("${username}", transaction.getUser().getUsername()) + .replace("${amount}", String.valueOf(transaction.getAmount())) + .replace("${feUrl}", feUrl); + + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setFrom(mailConfig.fromAddress); + helper.setTo(transaction.getUser().getEmailAddress()); + helper.setSubject("Einzahlung über ${amount}€ Erfolgreich".replace("${amount}", String.valueOf(transaction.getAmount()))); + helper.setText(htmlContent, true); + + mailSender.send(message); + } + private String loadTemplate(String templatePath) throws IOException { ClassPathResource resource = new ClassPathResource("templates/" + templatePath); try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { 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 913e69d..270d178 100644 --- a/backend/src/main/java/de/szut/casino/user/UserEntity.java +++ b/backend/src/main/java/de/szut/casino/user/UserEntity.java @@ -64,4 +64,8 @@ public class UserEntity { this.balance = this.balance.subtract(amountToSubtract); } + + public String getEmailAddress() { + return "${name} <${email}>".replace("${name}", this.username).replace("${email}", this.email); + } } diff --git a/backend/src/main/resources/templates/email/deposit.html b/backend/src/main/resources/templates/email/deposit.html new file mode 100644 index 0000000..632d7ab --- /dev/null +++ b/backend/src/main/resources/templates/email/deposit.html @@ -0,0 +1,136 @@ + + + + + + Einzahlung bestätigt - Trustworthy Casino© + + + +
+
+

Trustworthy Casino

+
+
+

Hallo ${username},

+ +

vielen Dank für Ihre Einzahlung bei Trustworthy Casino. Wir bestätigen den Eingang Ihres Guthabens.

+ +
+

Eingezahlter Betrag

+
${amount}€
+
+ +
+ +

Ihr Guthaben wurde Ihrem Konto sofort gutgeschrieben und steht ab sofort zum Spielen zur Verfügung.

+ + + +

Bei Fragen zu Ihrer Einzahlung kontaktieren Sie bitte unseren Kundenservice.

+ +

Mit freundlichen Grüßen,
+ Ihr Trustworthy Casino Team

+
+ +
+ + \ No newline at end of file From 45313989e702de9a61952acc742eb3e3b51441a8 Mon Sep 17 00:00:00 2001 From: jank Date: Wed, 14 May 2025 09:21:23 +0200 Subject: [PATCH 002/210] fix: only run docker pipelines when needed --- .gitea/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 50742f0..e33246b 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -77,6 +77,7 @@ jobs: validate-docker-frontend: runs-on: ubuntu-latest name: Docker frontend validation + if: ${{ needs.changed_files.outputs.frontend == 'true' || needs.changed_files.outputs.workflow == 'true' }} container: image: catthehacker/ubuntu:act-latest steps: @@ -92,6 +93,7 @@ jobs: validate-docker-backend: runs-on: ubuntu-latest name: Docker backend validation + if: ${{ needs.changed_files.outputs.backend == 'true' || needs.changed_files.outputs.workflow == 'true' }} container: image: catthehacker/ubuntu:act-latest steps: From 34ff29c7ac409513414bea4586c768d694710be4 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 14 May 2025 09:33:38 +0200 Subject: [PATCH 003/210] refactor: remove docker folder, refactor frontend files --- docker/docker-compose.yml | 18 -------- frontend/src/app/app.component.html | 1 + frontend/src/app/app.component.ts | 3 +- frontend/src/app/auth.guard.ts | 2 +- .../feature/auth/login/login.component.html | 2 - .../app/feature/auth/login/login.component.ts | 15 +++---- .../auth/register/register.component.html | 2 - .../auth/register/register.component.ts | 15 +++---- .../app/feature/deposit/deposit.component.ts | 14 +++--- .../game/blackjack/blackjack.component.html | 2 - .../game/blackjack/blackjack.component.ts | 34 +++++++-------- .../feature/game/slots/slots.component.html | 2 - .../app/feature/game/slots/slots.component.ts | 25 ++++------- .../src/app/feature/home/home.component.html | 1 - .../src/app/feature/home/home.component.ts | 22 +++++----- .../feature/landing/landing.component.html | 2 - .../app/feature/landing/landing.component.ts | 11 +++-- .../login-success/login-success.component.css | 0 .../login-success.component.html | 1 - .../login-success/login-success.component.ts | 43 ------------------- .../lootbox-opening.component.html | 2 - .../lootbox-opening.component.ts | 19 ++++---- .../lootbox-selection.component.html | 1 - .../lootbox-selection.component.ts | 21 +++++---- .../transaction-history.component.ts | 17 +++----- .../components/navbar/navbar.component.html | 8 ++-- .../components/navbar/navbar.component.ts | 3 +- 27 files changed, 94 insertions(+), 192 deletions(-) delete mode 100644 docker/docker-compose.yml delete mode 100644 frontend/src/app/feature/login-success/login-success.component.css delete mode 100644 frontend/src/app/feature/login-success/login-success.component.html delete mode 100644 frontend/src/app/feature/login-success/login-success.component.ts diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index 5487079..0000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,18 +0,0 @@ -volumes: - casino-db-data: - -services: - db: - image: postgres:17.5 - container_name: casino-db - restart: unless-stopped - volumes: - - casino-db-data:/var/lib/postgresql/data - environment: - POSTGRES_DB: postgresdb - POSTGRES_USER: postgres_user - POSTGRES_PASSWORD: postgres_pass - healthcheck: - test: "exit 0" - ports: - - "5432:5432" \ No newline at end of file diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index 41260d2..2e3cd9a 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -1,5 +1,6 @@
+
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 30666e9..07aa848 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -2,11 +2,12 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterOutlet } from '@angular/router'; import { FooterComponent } from '@shared/components/footer/footer.component'; +import {NavbarComponent} from "@shared/components/navbar/navbar.component"; @Component({ selector: 'app-root', standalone: true, - imports: [CommonModule, RouterOutlet, FooterComponent], + imports: [CommonModule, RouterOutlet, FooterComponent, NavbarComponent], providers: [], templateUrl: './app.component.html', styleUrl: './app.component.css', diff --git a/frontend/src/app/auth.guard.ts b/frontend/src/app/auth.guard.ts index d088c30..ffb2526 100644 --- a/frontend/src/app/auth.guard.ts +++ b/frontend/src/app/auth.guard.ts @@ -1,6 +1,6 @@ import { CanActivateFn, Router } from '@angular/router'; import { inject } from '@angular/core'; -import { AuthService } from './service/auth.service'; +import { AuthService } from '@service/auth.service'; export const authGuard: CanActivateFn = async () => { const authService = inject(AuthService); diff --git a/frontend/src/app/feature/auth/login/login.component.html b/frontend/src/app/feature/auth/login/login.component.html index c41002d..c10b232 100644 --- a/frontend/src/app/feature/auth/login/login.component.html +++ b/frontend/src/app/feature/auth/login/login.component.html @@ -1,5 +1,3 @@ - -