From 156379c12ceb42e5c8b92adb73afde107ccf0a35 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 8 May 2025 21:02:03 +0000 Subject: [PATCH 1/5] chore(deps): update postgres docker tag to v17.5 --- compose.yml | 2 +- docker/docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compose.yml b/compose.yml index 5e53cc6..98574ad 100644 --- a/compose.yml +++ b/compose.yml @@ -3,7 +3,7 @@ volumes: services: db: - image: postgres:17.4 + image: postgres:17.5 container_name: casino-db restart: unless-stopped volumes: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 7bc0a3b..5487079 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -3,7 +3,7 @@ volumes: services: db: - image: postgres:17.4 + image: postgres:17.5 container_name: casino-db restart: unless-stopped volumes: From 110dacb6ddae651154c3c2626734a54fce31bb79 Mon Sep 17 00:00:00 2001 From: Constantin Simonis Date: Wed, 7 May 2025 18:11:54 +0200 Subject: [PATCH 2/5] feat(email): add email service and configuration for sending emails --- backend/build.gradle.kts | 1 + .../de/szut/casino/CasinoApplication.java | 9 ++++ .../szut/casino/health/HealthController.java | 12 +++++ .../casino/security/service/EmailService.java | 48 +++++++++++++++++++ .../casino/security/service/MailConfig.java | 25 ++++++++++ .../src/main/resources/application.properties | 8 ++++ compose.yml | 12 ++++- 7 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/de/szut/casino/security/service/EmailService.java create mode 100644 backend/src/main/java/de/szut/casino/security/service/MailConfig.java diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index a0b6899..2c735c4 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -54,6 +54,7 @@ dependencies { implementation("io.jsonwebtoken:jjwt-api:0.11.5") runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5") runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5") + compileOnly("org.springframework.boot:spring-boot-starter-mail") } tasks.withType { diff --git a/backend/src/main/java/de/szut/casino/CasinoApplication.java b/backend/src/main/java/de/szut/casino/CasinoApplication.java index 2818f23..9a5db34 100644 --- a/backend/src/main/java/de/szut/casino/CasinoApplication.java +++ b/backend/src/main/java/de/szut/casino/CasinoApplication.java @@ -8,6 +8,10 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import org.springframework.mail.MailException; +import org.springframework.mail.MailSender; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.web.client.RestTemplate; import java.math.BigDecimal; @@ -26,6 +30,11 @@ public class CasinoApplication { return new RestTemplate(); } + @Bean + public static JavaMailSenderImpl javaMailSenderImpl() { + return new JavaMailSenderImpl(); + } + @Bean public CommandLineRunner initData(LootBoxRepository lootBoxRepository, RewardRepository rewardRepository) { return _ -> { diff --git a/backend/src/main/java/de/szut/casino/health/HealthController.java b/backend/src/main/java/de/szut/casino/health/HealthController.java index da05352..dbe873e 100644 --- a/backend/src/main/java/de/szut/casino/health/HealthController.java +++ b/backend/src/main/java/de/szut/casino/health/HealthController.java @@ -1,5 +1,8 @@ package de.szut.casino.health; +import de.szut.casino.security.service.EmailService; +import de.szut.casino.user.UserEntity; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -8,8 +11,17 @@ import java.util.Map; @RestController public class HealthController { + @Autowired + private EmailService emailService; + @GetMapping("/health") public Map healthCheck() { + UserEntity user = new UserEntity(); + user.setEmail("user@mail.com"); + user.setUsername("user"); + + this.emailService.sendRegistrationEmail(user); + return Map.of("status", "UP"); } } 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 new file mode 100644 index 0000000..31ad65b --- /dev/null +++ b/backend/src/main/java/de/szut/casino/security/service/EmailService.java @@ -0,0 +1,48 @@ +package de.szut.casino.security.service; + +import de.szut.casino.user.UserEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class EmailService { + private JavaMailSenderImpl mailSender; + + private MailConfig mailConfig; + + public EmailService(JavaMailSenderImpl mailSender, MailConfig mailConfig) { + try { + this.mailSender = mailSender; + this.mailConfig = mailConfig; + this.mailSender.setHost(mailConfig.host); + this.mailSender.setPort(mailConfig.port); + if (mailConfig.authenticationEnabled) { + this.mailSender.setUsername(mailConfig.username); + this.mailSender.setPassword(mailConfig.password); + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + public void sendRegistrationEmail(UserEntity user) { + String body = "Hallo " + user.getUsername() + ",\n\nA Willkommen bei Trustworthy Casino©! Wir freuen uns, Sie an Bord zu haben.\n\n"; + SimpleMailMessage mail = new SimpleMailMessage(); + + mail.setFrom(mailConfig.fromAddress); + mail.setSubject("Willkommen bei Trustworthy Casino©"); + mail.setTo(user.getEmail()); + mail.setText(body); + + sendEmail(mail); + } + + private void sendEmail(SimpleMailMessage mail) { + this.mailSender.send(mail); + } +} diff --git a/backend/src/main/java/de/szut/casino/security/service/MailConfig.java b/backend/src/main/java/de/szut/casino/security/service/MailConfig.java new file mode 100644 index 0000000..56c7250 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/security/service/MailConfig.java @@ -0,0 +1,25 @@ +package de.szut.casino.security.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class MailConfig { + @Value("${app.mail.host}") + public String host; + + @Value("${app.mail.port}") + public Integer port; + + @Value("${app.mail.authentication}") + public Boolean authenticationEnabled; + + @Value("${app.mail.username}") + public String username; + + @Value("${app.mail.password}") + public String password; + + @Value("${app.mail.from-address}") + public String fromAddress; +} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 0d18cfd..0eaca18 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -5,8 +5,16 @@ server.port=${HTTP_PORT:8080} spring.jpa.hibernate.ddl-auto=update stripe.secret.key=${STRIPE_SECRET_KEY:sk_test_51QrePYIvCfqz7ANgqam8rEwWcMeKiLOof3j6SCMgu2sl4sESP45DJxca16mWcYo1sQaiBv32CMR6Z4AAAGQPCJo300ubuZKO8I} stripe.webhook.secret=${STRIPE_WEBHOOK_SECRET:whsec_746b6a488665f6057118bdb4a2b32f4916f16c277109eeaed5e8f8e8b81b8c15} + app.frontend-host=${FE_URL:http://localhost:4200} +app.mail.authentication=${MAIL_AUTHENTICATION:false} +app.mail.host=${MAIL_HOST:localhost} +app.mail.port=${MAIL_PORT:1025} +app.mail.username=${MAIL_USER:null} +app.mail.password=${MAIL_PASS:null} +app.mail.from-address=${MAIL_FROM:casino@localhost} + spring.application.name=casino # JWT Configuration diff --git a/compose.yml b/compose.yml index 5e53cc6..88cf628 100644 --- a/compose.yml +++ b/compose.yml @@ -15,4 +15,14 @@ services: healthcheck: test: "exit 0" ports: - - "5432:5432" \ No newline at end of file + - "5432:5432" + mailpit: + image: axllent/mailpit + container_name: casino-mailpit + restart: unless-stopped + ports: + - 8025:8025 + - 1025:1025 + environment: + MP_SMTP_AUTH_ACCEPT_ANY: 1 + MP_SMTP_AUTH_ALLOW_INSECURE: 1 From 13b344312704a5fe2eba9bd22f4812545c76aa6c Mon Sep 17 00:00:00 2001 From: csimonis Date: Thu, 8 May 2025 15:39:02 +0200 Subject: [PATCH 3/5] chore: crazy ahh email template and styles --- .../casino/security/service/EmailService.java | 49 +++++-- .../templates/email/registration.html | 129 ++++++++++++++++++ 2 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 backend/src/main/resources/templates/email/registration.html 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 31ad65b..9d39134 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,19 +1,26 @@ package de.szut.casino.security.service; import de.szut.casino.user.UserEntity; -import org.springframework.beans.factory.annotation.Autowired; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import org.springframework.beans.factory.annotation.Value; -import org.springframework.mail.SimpleMailMessage; +import org.springframework.core.io.ClassPathResource; import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; +import org.springframework.util.FileCopyUtils; -import java.util.List; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; @Service public class EmailService { private JavaMailSenderImpl mailSender; - private MailConfig mailConfig; + @Value("${app.frontend-host}") + private String feUrl; public EmailService(JavaMailSenderImpl mailSender, MailConfig mailConfig) { try { @@ -31,18 +38,30 @@ public class EmailService { } public void sendRegistrationEmail(UserEntity user) { - String body = "Hallo " + user.getUsername() + ",\n\nA Willkommen bei Trustworthy Casino©! Wir freuen uns, Sie an Bord zu haben.\n\n"; - SimpleMailMessage mail = new SimpleMailMessage(); + try { + String template = loadTemplate("email/registration.html"); + String htmlContent = template + .replace("${username}", user.getUsername()) + .replace("${feUrl}", feUrl); - mail.setFrom(mailConfig.fromAddress); - mail.setSubject("Willkommen bei Trustworthy Casino©"); - mail.setTo(user.getEmail()); - mail.setText(body); - - sendEmail(mail); + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setFrom(mailConfig.fromAddress); + helper.setTo(user.getEmail()); + helper.setSubject("Willkommen bei Trustworthy Casino©"); + helper.setText(htmlContent, true); + + mailSender.send(message); + } catch (MessagingException | IOException e) { + System.err.println("Failed to send registration email: " + e.getMessage()); + } } - - private void sendEmail(SimpleMailMessage mail) { - this.mailSender.send(mail); + + private String loadTemplate(String templatePath) throws IOException { + ClassPathResource resource = new ClassPathResource("templates/" + templatePath); + try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { + return FileCopyUtils.copyToString(reader); + } } } diff --git a/backend/src/main/resources/templates/email/registration.html b/backend/src/main/resources/templates/email/registration.html new file mode 100644 index 0000000..27fe15a --- /dev/null +++ b/backend/src/main/resources/templates/email/registration.html @@ -0,0 +1,129 @@ + + + + + + Willkommen bei Trustworthy Casino© + + + +
+
+

Trustworthy Casino©

+
+
+

Hallo ${username},

+ +

Herzlich willkommen bei Trustworthy Casino©! Wir freuen uns, Sie an Bord zu haben.

+ +
+ +

Bei uns erwarten Sie:

+
    +
  • Spannende Casino-Spiele
  • +
  • Sichere Transaktionen
  • +
  • Exklusive Boni und Aktionen
  • +
+ +
+ +

Melden Sie sich jetzt an und beginnen Sie Ihr Spielerlebnis!

+ + + +

Bei Fragen stehen wir Ihnen jederzeit zur Verfügung.

+ +

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

+
+ +
+ + \ No newline at end of file From e6c34ffe90ff632ce99968cde9eaa80a6984b5af Mon Sep 17 00:00:00 2001 From: csimonis Date: Wed, 14 May 2025 08:39:05 +0200 Subject: [PATCH 4/5] feat(email): update registration email template to welcome email --- .../de/szut/casino/security/service/EmailService.java | 2 +- .../email/{registration.html => welcome.html} | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) rename backend/src/main/resources/templates/email/{registration.html => welcome.html} (90%) 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 9d39134..dba1439 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 @@ -39,7 +39,7 @@ public class EmailService { public void sendRegistrationEmail(UserEntity user) { try { - String template = loadTemplate("email/registration.html"); + String template = loadTemplate("email/welcome.html"); String htmlContent = template .replace("${username}", user.getUsername()) .replace("${feUrl}", feUrl); diff --git a/backend/src/main/resources/templates/email/registration.html b/backend/src/main/resources/templates/email/welcome.html similarity index 90% rename from backend/src/main/resources/templates/email/registration.html rename to backend/src/main/resources/templates/email/welcome.html index 27fe15a..2a10134 100644 --- a/backend/src/main/resources/templates/email/registration.html +++ b/backend/src/main/resources/templates/email/welcome.html @@ -59,7 +59,6 @@ } h2 { color: #ffffff; - border-bottom: 2px solid #34d399; padding-bottom: 10px; display: inline-block; } @@ -75,7 +74,7 @@ color: #34d399; } .highlight { - color: #fbbf24; + color: #10b981; font-weight: bold; } .divider { @@ -91,12 +90,12 @@
-

Trustworthy Casino©

+

Trustworthy Casino

Hallo ${username},

-

Herzlich willkommen bei Trustworthy Casino©! Wir freuen uns, Sie an Bord zu haben.

+

Herzlich willkommen bei Trustworthy Casino! Wir freuen uns, Sie an Bord zu haben.

@@ -118,10 +117,10 @@

Bei Fragen stehen wir Ihnen jederzeit zur Verfügung.

Mit freundlichen Grüßen,
- Ihr Trustworthy Casino© Team

+ Ihr Trustworthy Casino Team

From 73710a15423883219a90dad24020c4b2cc7c583a Mon Sep 17 00:00:00 2001 From: csimonis Date: Wed, 14 May 2025 08:44:37 +0200 Subject: [PATCH 5/5] feat: whoops --- .../szut/casino/health/HealthController.java | 12 ----- .../szut/casino/security/AuthController.java | 5 +- .../casino/security/service/AuthService.java | 11 +++- .../casino/security/service/EmailService.java | 52 ++++++++----------- 4 files changed, 36 insertions(+), 44 deletions(-) diff --git a/backend/src/main/java/de/szut/casino/health/HealthController.java b/backend/src/main/java/de/szut/casino/health/HealthController.java index dbe873e..da05352 100644 --- a/backend/src/main/java/de/szut/casino/health/HealthController.java +++ b/backend/src/main/java/de/szut/casino/health/HealthController.java @@ -1,8 +1,5 @@ package de.szut.casino.health; -import de.szut.casino.security.service.EmailService; -import de.szut.casino.user.UserEntity; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -11,17 +8,8 @@ import java.util.Map; @RestController public class HealthController { - @Autowired - private EmailService emailService; - @GetMapping("/health") public Map healthCheck() { - UserEntity user = new UserEntity(); - user.setEmail("user@mail.com"); - user.setUsername("user"); - - this.emailService.sendRegistrationEmail(user); - return Map.of("status", "UP"); } } diff --git a/backend/src/main/java/de/szut/casino/security/AuthController.java b/backend/src/main/java/de/szut/casino/security/AuthController.java index b5c0639..6d99625 100644 --- a/backend/src/main/java/de/szut/casino/security/AuthController.java +++ b/backend/src/main/java/de/szut/casino/security/AuthController.java @@ -5,6 +5,7 @@ import de.szut.casino.security.dto.LoginRequestDto; import de.szut.casino.security.service.AuthService; import de.szut.casino.user.dto.CreateUserDto; import de.szut.casino.user.dto.GetUserDto; +import jakarta.mail.MessagingException; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -13,6 +14,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.io.IOException; + @RestController @RequestMapping("/auth") public class AuthController { @@ -27,7 +30,7 @@ public class AuthController { } @PostMapping("/register") - public ResponseEntity registerUser(@Valid @RequestBody CreateUserDto signUpRequest) { + public ResponseEntity registerUser(@Valid @RequestBody CreateUserDto signUpRequest) throws MessagingException, IOException { GetUserDto response = authService.register(signUpRequest); return ResponseEntity.ok(response); } diff --git a/backend/src/main/java/de/szut/casino/security/service/AuthService.java b/backend/src/main/java/de/szut/casino/security/service/AuthService.java index 88687ba..ed2b70c 100644 --- a/backend/src/main/java/de/szut/casino/security/service/AuthService.java +++ b/backend/src/main/java/de/szut/casino/security/service/AuthService.java @@ -7,6 +7,7 @@ import de.szut.casino.user.UserEntity; import de.szut.casino.user.UserService; import de.szut.casino.user.dto.CreateUserDto; import de.szut.casino.user.dto.GetUserDto; +import jakarta.mail.MessagingException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -14,6 +15,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; +import java.io.IOException; + @Service public class AuthService { @@ -26,6 +29,9 @@ public class AuthService { @Autowired private UserService userService; + @Autowired + private EmailService emailService; + public AuthResponseDto login(LoginRequestDto loginRequest) { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( @@ -38,8 +44,11 @@ public class AuthService { return new AuthResponseDto(jwt); } - public GetUserDto register(CreateUserDto signUpRequest) { + public GetUserDto register(CreateUserDto signUpRequest) throws MessagingException, IOException { UserEntity user = userService.createUser(signUpRequest); + + this.emailService.sendRegistrationEmail(user); + return new GetUserDto( user.getId(), user.getEmail(), 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 dba1439..fb875b8 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 @@ -23,41 +23,33 @@ public class EmailService { private String feUrl; public EmailService(JavaMailSenderImpl mailSender, MailConfig mailConfig) { - try { - this.mailSender = mailSender; - this.mailConfig = mailConfig; - this.mailSender.setHost(mailConfig.host); - this.mailSender.setPort(mailConfig.port); - if (mailConfig.authenticationEnabled) { - this.mailSender.setUsername(mailConfig.username); - this.mailSender.setPassword(mailConfig.password); - } - } catch (Exception e) { - System.out.println(e.getMessage()); + this.mailSender = mailSender; + this.mailConfig = mailConfig; + this.mailSender.setHost(mailConfig.host); + this.mailSender.setPort(mailConfig.port); + if (mailConfig.authenticationEnabled) { + this.mailSender.setUsername(mailConfig.username); + this.mailSender.setPassword(mailConfig.password); } } - public void sendRegistrationEmail(UserEntity user) { - try { - String template = loadTemplate("email/welcome.html"); - String htmlContent = template - .replace("${username}", user.getUsername()) - .replace("${feUrl}", feUrl); + public void sendRegistrationEmail(UserEntity user) throws IOException, MessagingException { + String template = loadTemplate("email/welcome.html"); + String htmlContent = template + .replace("${username}", user.getUsername()) + .replace("${feUrl}", feUrl); - MimeMessage message = mailSender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); - - helper.setFrom(mailConfig.fromAddress); - helper.setTo(user.getEmail()); - helper.setSubject("Willkommen bei Trustworthy Casino©"); - helper.setText(htmlContent, true); - - mailSender.send(message); - } catch (MessagingException | IOException e) { - System.err.println("Failed to send registration email: " + e.getMessage()); - } + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setFrom(mailConfig.fromAddress); + helper.setTo(user.getEmail()); + helper.setSubject("Willkommen bei Trustworthy Casino©"); + 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)) {