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/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 new file mode 100644 index 0000000..fb875b8 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/security/service/EmailService.java @@ -0,0 +1,59 @@ +package de.szut.casino.security.service; + +import de.szut.casino.user.UserEntity; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import org.springframework.beans.factory.annotation.Value; +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.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) { + 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) 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); + } + + 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/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/backend/src/main/resources/templates/email/welcome.html b/backend/src/main/resources/templates/email/welcome.html new file mode 100644 index 0000000..2a10134 --- /dev/null +++ b/backend/src/main/resources/templates/email/welcome.html @@ -0,0 +1,128 @@ + + + + + + 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 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