diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts
index 3792038..48c1e8e 100644
--- a/frontend/src/app/app.routes.ts
+++ b/frontend/src/app/app.routes.ts
@@ -12,6 +12,10 @@ export const routes: Routes = [
loadComponent: () => import('./feature/home/home.component'),
canActivate: [authGuard],
},
+ {
+ path: 'verify',
+ loadComponent: () => import('./feature/auth/verify-email/verify-email.component').then(m => m.VerifyEmailComponent),
+ },
{
path: 'game/blackjack',
loadComponent: () => import('./feature/game/blackjack/blackjack.component'),
diff --git a/frontend/src/app/feature/auth/register/register.component.ts b/frontend/src/app/feature/auth/register/register.component.ts
index 60f289b..a421184 100644
--- a/frontend/src/app/feature/auth/register/register.component.ts
+++ b/frontend/src/app/feature/auth/register/register.component.ts
@@ -56,25 +56,6 @@ export class RegisterComponent {
};
this.authService.register(registerRequest).subscribe({
- next: () => {
- this.authService
- .login({
- usernameOrEmail: registerRequest.email,
- password: registerRequest.password,
- })
- .subscribe({
- next: () => {
- this.closeDialog.emit();
- this.router.navigate(['/home']);
- },
- error: () => {
- this.isLoading.set(false);
- this.errorMessage.set(
- 'Registration successful but failed to login automatically. Please log in manually.'
- );
- },
- });
- },
error: (err: HttpErrorResponse) => {
this.isLoading.set(false);
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.css b/frontend/src/app/feature/auth/verify-email/verify-email.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.html b/frontend/src/app/feature/auth/verify-email/verify-email.component.html
new file mode 100644
index 0000000..c39c8c0
--- /dev/null
+++ b/frontend/src/app/feature/auth/verify-email/verify-email.component.html
@@ -0,0 +1 @@
+
verify-email works!
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.ts b/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
new file mode 100644
index 0000000..c67e1ff
--- /dev/null
+++ b/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
@@ -0,0 +1,31 @@
+import { Component, inject, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { AuthService } from '@service/auth.service';
+
+@Component({
+ selector: 'app-verify-email',
+ imports: [],
+ templateUrl: './verify-email.component.html',
+ styleUrl: './verify-email.component.css'
+})
+export class VerifyEmailComponent implements OnInit{
+ route: ActivatedRoute = inject(ActivatedRoute);
+ router: Router = inject(Router);
+ authService: AuthService = inject(AuthService);
+
+ ngOnInit(): void {
+ const token = this.route.snapshot.queryParamMap.get('token');
+
+ if (!token) {
+ this.router.navigate(['']);
+ console.log('no token');
+ return;
+ }
+
+ this.authService.verifyEmail(token).subscribe(() => {
+ this.router.navigate([''], {
+ queryParams: { login: true },
+ });
+ })
+ }
+}
diff --git a/frontend/src/app/feature/landing/landing.component.ts b/frontend/src/app/feature/landing/landing.component.ts
index d4d6078..5cfe0c5 100644
--- a/frontend/src/app/feature/landing/landing.component.ts
+++ b/frontend/src/app/feature/landing/landing.component.ts
@@ -7,7 +7,7 @@ import {
signal,
} from '@angular/core';
import { NgFor } from '@angular/common';
-import { RouterLink } from '@angular/router';
+import { ActivatedRoute, RouterLink } from '@angular/router';
import { AuthService } from '@service/auth.service';
import { LoginComponent } from '../auth/login/login.component';
import { RegisterComponent } from '../auth/register/register.component';
@@ -23,12 +23,16 @@ export class LandingComponent implements OnInit, OnDestroy {
currentSlide = 0;
private autoplayInterval: ReturnType
| undefined;
authService: AuthService = inject(AuthService);
+ route: ActivatedRoute = inject(ActivatedRoute);
showLogin = signal(false);
showRegister = signal(false);
ngOnInit() {
this.startAutoplay();
document.body.style.overflow = 'auto';
+ if (this.route.snapshot.queryParamMap.get('login') === 'true') {
+ this.showLoginForm();
+ }
}
ngOnDestroy() {
diff --git a/frontend/src/app/service/auth.service.ts b/frontend/src/app/service/auth.service.ts
index 1066008..1133958 100644
--- a/frontend/src/app/service/auth.service.ts
+++ b/frontend/src/app/service/auth.service.ts
@@ -74,6 +74,10 @@ export class AuthService {
});
}
+ public verifyEmail(token: string): Observable {
+ return this.http.post(`${this.authUrl}/verify?token=${token}`, null);
+ }
+
private setToken(token: string): void {
localStorage.setItem(TOKEN_KEY, token);
}
From db9fe842599b9a46d0770c346b4f7c23021033cc Mon Sep 17 00:00:00 2001
From: csimonis
Date: Thu, 15 May 2025 10:51:29 +0200
Subject: [PATCH 3/7] fix: change status code for EmailNotVerifiedException
---
.../szut/casino/exceptionHandling/GlobalExceptionHandler.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/main/java/de/szut/casino/exceptionHandling/GlobalExceptionHandler.java b/backend/src/main/java/de/szut/casino/exceptionHandling/GlobalExceptionHandler.java
index 65b3b4b..9c185a8 100644
--- a/backend/src/main/java/de/szut/casino/exceptionHandling/GlobalExceptionHandler.java
+++ b/backend/src/main/java/de/szut/casino/exceptionHandling/GlobalExceptionHandler.java
@@ -36,6 +36,6 @@ public class GlobalExceptionHandler {
@ExceptionHandler(EmailNotVerifiedException.class)
public ResponseEntity> handleEmailNotVerifiedException(EmailNotVerifiedException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
- return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
+ return new ResponseEntity<>(errorDetails, HttpStatus.UNAUTHORIZED);
}
}
From 0963dbae06cdc0f534fe07fad33c046b54bf596b Mon Sep 17 00:00:00 2001
From: csimonis
Date: Thu, 15 May 2025 10:57:14 +0200
Subject: [PATCH 4/7] refactor(verify-email): remove unused CSS file and update
template
---
.../app/feature/auth/verify-email/verify-email.component.css | 0
.../app/feature/auth/verify-email/verify-email.component.html | 2 +-
.../src/app/feature/auth/verify-email/verify-email.component.ts | 1 -
3 files changed, 1 insertion(+), 2 deletions(-)
delete mode 100644 frontend/src/app/feature/auth/verify-email/verify-email.component.css
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.css b/frontend/src/app/feature/auth/verify-email/verify-email.component.css
deleted file mode 100644
index e69de29..0000000
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.html b/frontend/src/app/feature/auth/verify-email/verify-email.component.html
index c39c8c0..d7bc11c 100644
--- a/frontend/src/app/feature/auth/verify-email/verify-email.component.html
+++ b/frontend/src/app/feature/auth/verify-email/verify-email.component.html
@@ -1 +1 @@
-verify-email works!
+Verifying...
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.ts b/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
index c67e1ff..26f0317 100644
--- a/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
+++ b/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
@@ -6,7 +6,6 @@ import { AuthService } from '@service/auth.service';
selector: 'app-verify-email',
imports: [],
templateUrl: './verify-email.component.html',
- styleUrl: './verify-email.component.css'
})
export class VerifyEmailComponent implements OnInit{
route: ActivatedRoute = inject(ActivatedRoute);
From decf2e21a393bca68f9aeffc16c79a77e2ee0a15 Mon Sep 17 00:00:00 2001
From: csimonis
Date: Thu, 15 May 2025 10:58:53 +0200
Subject: [PATCH 5/7] feat(email): add welcome email sending on verification
success
---
.../src/main/java/de/szut/casino/security/AuthController.java | 2 +-
.../main/java/de/szut/casino/security/service/AuthService.java | 3 ++-
.../java/de/szut/casino/security/service/EmailService.java | 3 +--
3 files changed, 4 insertions(+), 4 deletions(-)
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 7862ae7..f833d78 100644
--- a/backend/src/main/java/de/szut/casino/security/AuthController.java
+++ b/backend/src/main/java/de/szut/casino/security/AuthController.java
@@ -36,7 +36,7 @@ public class AuthController {
}
@PostMapping("/verify")
- public ResponseEntity verifyEmail(@RequestParam("token") String token) {
+ public ResponseEntity verifyEmail(@RequestParam("token") String token) throws MessagingException, IOException {
if (authService.verifyEmail(token)) {
return ResponseEntity.badRequest().build();
}
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 714b7f3..f51ff83 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
@@ -63,7 +63,7 @@ public class AuthService {
);
}
- public Boolean verifyEmail(String token) {
+ public Boolean verifyEmail(String token) throws MessagingException, IOException {
Optional optionalUser = userService.getUserByVerificationToken(token);
if(!optionalUser.isPresent()) {
@@ -75,6 +75,7 @@ public class AuthService {
user.setEmailVerified(true);
user.setVerificationToken(null);
userService.saveUser(user);
+ this.emailService.sendWelcomeEmail(user);
return true;
}
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 348fafd..4d83262 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
@@ -15,7 +15,6 @@ 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 {
@@ -53,7 +52,7 @@ public class EmailService {
mailSender.send(message);
}
- public void sendRegistrationEmail(UserEntity user) throws IOException, MessagingException {
+ public void sendWelcomeEmail(UserEntity user) throws IOException, MessagingException {
String template = loadTemplate("email/welcome.html");
String htmlContent = template
.replace("${username}", user.getUsername())
From 51984318e6df018e041e9b08fb20c32e2a994b7c Mon Sep 17 00:00:00 2001
From: csimonis
Date: Thu, 15 May 2025 11:01:47 +0200
Subject: [PATCH 6/7] refactor(auth.service): change observable type to unknown
---
frontend/src/app/service/auth.service.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frontend/src/app/service/auth.service.ts b/frontend/src/app/service/auth.service.ts
index 1133958..657067f 100644
--- a/frontend/src/app/service/auth.service.ts
+++ b/frontend/src/app/service/auth.service.ts
@@ -74,8 +74,8 @@ export class AuthService {
});
}
- public verifyEmail(token: string): Observable {
- return this.http.post(`${this.authUrl}/verify?token=${token}`, null);
+ public verifyEmail(token: string): Observable {
+ return this.http.post(`${this.authUrl}/verify?token=${token}`, null);
}
private setToken(token: string): void {
From 2f21408e3da6db9a692286ec7e9ca3e5a16b5f95 Mon Sep 17 00:00:00 2001
From: csimonis
Date: Thu, 15 May 2025 11:03:50 +0200
Subject: [PATCH 7/7] style: format code for better readability
---
frontend/src/app/app.routes.ts | 5 ++++-
.../app/feature/auth/verify-email/verify-email.component.ts | 4 ++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts
index 48c1e8e..5c57416 100644
--- a/frontend/src/app/app.routes.ts
+++ b/frontend/src/app/app.routes.ts
@@ -14,7 +14,10 @@ export const routes: Routes = [
},
{
path: 'verify',
- loadComponent: () => import('./feature/auth/verify-email/verify-email.component').then(m => m.VerifyEmailComponent),
+ loadComponent: () =>
+ import('./feature/auth/verify-email/verify-email.component').then(
+ (m) => m.VerifyEmailComponent
+ ),
},
{
path: 'game/blackjack',
diff --git a/frontend/src/app/feature/auth/verify-email/verify-email.component.ts b/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
index 26f0317..5f2814a 100644
--- a/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
+++ b/frontend/src/app/feature/auth/verify-email/verify-email.component.ts
@@ -7,7 +7,7 @@ import { AuthService } from '@service/auth.service';
imports: [],
templateUrl: './verify-email.component.html',
})
-export class VerifyEmailComponent implements OnInit{
+export class VerifyEmailComponent implements OnInit {
route: ActivatedRoute = inject(ActivatedRoute);
router: Router = inject(Router);
authService: AuthService = inject(AuthService);
@@ -25,6 +25,6 @@ export class VerifyEmailComponent implements OnInit{
this.router.navigate([''], {
queryParams: { login: true },
});
- })
+ });
}
}