feat(auth): add email verification feature and handler
Some checks failed
CI / Get Changed Files (pull_request) Successful in 7s
CI / Docker frontend validation (pull_request) Successful in 1m2s
CI / Checkstyle Main (pull_request) Successful in 1m8s
CI / eslint (pull_request) Failing after 1m29s
CI / Docker backend validation (pull_request) Successful in 1m32s
CI / prettier (pull_request) Failing after 31s
CI / oxlint (pull_request) Successful in 44s
CI / test-build (pull_request) Successful in 38s

This commit is contained in:
csimonis 2025-05-15 10:49:24 +02:00
commit d2225decc1
14 changed files with 124 additions and 27 deletions

View file

@ -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'),

View file

@ -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);

View file

@ -0,0 +1 @@
<p>verify-email works!</p>

View file

@ -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 },
});
})
}
}

View file

@ -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<typeof setInterval> | 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() {

View file

@ -74,6 +74,10 @@ export class AuthService {
});
}
public verifyEmail(token: string): Observable<any> {
return this.http.post<any>(`${this.authUrl}/verify?token=${token}`, null);
}
private setToken(token: string): void {
localStorage.setItem(TOKEN_KEY, token);
}