Compare commits

..

No commits in common. "v1.52.3" and "v1.52.2" have entirely different histories.

5 changed files with 46 additions and 99 deletions

View file

@ -3,10 +3,6 @@ name: CI
on: on:
pull_request: pull_request:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
changed_files: changed_files:
name: Get Changed Files name: Get Changed Files

View file

@ -2,7 +2,6 @@ package de.szut.casino.exceptionHandling;
import de.szut.casino.exceptionHandling.exceptions.InsufficientFundsException; import de.szut.casino.exceptionHandling.exceptions.InsufficientFundsException;
import de.szut.casino.exceptionHandling.exceptions.UserNotFoundException; import de.szut.casino.exceptionHandling.exceptions.UserNotFoundException;
import jakarta.persistence.EntityExistsException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
@ -25,10 +24,4 @@ public class GlobalExceptionHandler {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false)); ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST); return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
} }
@ExceptionHandler(EntityExistsException.class)
public ResponseEntity<?> handleEntityExistsException(EntityExistsException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.CONFLICT);
}
} }

View file

@ -1,7 +1,6 @@
package de.szut.casino.user; package de.szut.casino.user;
import de.szut.casino.user.dto.CreateUserDto; import de.szut.casino.user.dto.CreateUserDto;
import jakarta.persistence.EntityExistsException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
@ -20,11 +19,11 @@ public class UserService {
public UserEntity createUser(CreateUserDto createUserDto) { public UserEntity createUser(CreateUserDto createUserDto) {
if (userRepository.existsByUsername(createUserDto.getUsername())) { if (userRepository.existsByUsername(createUserDto.getUsername())) {
throw new EntityExistsException("Username is already taken"); throw new IllegalArgumentException("Username is already taken");
} }
if (userRepository.existsByEmail(createUserDto.getEmail())) { if (userRepository.existsByEmail(createUserDto.getEmail())) {
throw new EntityExistsException("Email is already in use"); throw new IllegalArgumentException("Email is already in use");
} }
UserEntity user = new UserEntity( UserEntity user = new UserEntity(

View file

@ -2,11 +2,9 @@
<div class="modal-card max-w-md w-full"> <div class="modal-card max-w-md w-full">
<h2 class="modal-heading text-center">Konto erstellen</h2> <h2 class="modal-heading text-center">Konto erstellen</h2>
@if (errorMessage()) { <div *ngIf="errorMessage" class="bg-accent-red text-white p-4 rounded mb-4">
<div class="bg-accent-red text-white p-4 rounded mb-4"> {{ errorMessage }}
{{ errorMessage() }}
</div> </div>
}
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()" class="space-y-4"> <form [formGroup]="registerForm" (ngSubmit)="onSubmit()" class="space-y-4">
<div> <div>
@ -16,26 +14,18 @@
type="email" type="email"
formControlName="email" formControlName="email"
class="w-full px-4 py-2.5 bg-deep-blue-light/50 text-white rounded-lg my-1 border border-deep-blue-light/30 focus:border-emerald/50 focus:ring-1 focus:ring-emerald/50 outline-none transition-all duration-200" class="w-full px-4 py-2.5 bg-deep-blue-light/50 text-white rounded-lg my-1 border border-deep-blue-light/30 focus:border-emerald/50 focus:ring-1 focus:ring-emerald/50 outline-none transition-all duration-200"
[ngClass]="{ 'border-accent-red': fieldErrors()['email'] }"
placeholder="Gib deine E-Mail-Adresse ein" placeholder="Gib deine E-Mail-Adresse ein"
/> />
@if (fieldErrors()['email']) { <div
<div class="text-accent-red mt-1 text-sm"> *ngIf="form['email'].touched && form['email'].errors"
{{ fieldErrors()['email'] }} class="text-accent-red mt-1 text-sm"
>
<span *ngIf="form['email'].errors?.['required']">E-Mail ist erforderlich</span>
<span *ngIf="form['email'].errors?.['email']">
Bitte gib eine gültige E-Mail-Adresse ein
</span>
</div> </div>
}
@if (!fieldErrors()['email'] && form['email'].touched && form['email'].errors) {
<div class="text-accent-red mt-1 text-sm">
@if (form['email'].errors['required']) {
<span>E-Mail ist erforderlich</span>
}
@if (form['email'].errors['email']) {
<span>Bitte gib eine gültige E-Mail-Adresse ein</span>
}
</div>
}
</div> </div>
<div> <div>
@ -47,26 +37,18 @@
type="text" type="text"
formControlName="username" formControlName="username"
class="w-full px-4 py-2.5 bg-deep-blue-light/50 text-white rounded-lg my-1 border border-deep-blue-light/30 focus:border-emerald/50 focus:ring-1 focus:ring-emerald/50 outline-none transition-all duration-200" class="w-full px-4 py-2.5 bg-deep-blue-light/50 text-white rounded-lg my-1 border border-deep-blue-light/30 focus:border-emerald/50 focus:ring-1 focus:ring-emerald/50 outline-none transition-all duration-200"
[ngClass]="{ 'border-accent-red': fieldErrors()['username'] }"
placeholder="Wähle einen Benutzernamen" placeholder="Wähle einen Benutzernamen"
/> />
@if (fieldErrors()['username']) { <div
<div class="text-accent-red mt-1 text-sm"> *ngIf="form['username'].touched && form['username'].errors"
{{ fieldErrors()['username'] }} class="text-accent-red mt-1 text-sm"
>
<span *ngIf="form['username'].errors?.['required']">Benutzername ist erforderlich</span>
<span *ngIf="form['username'].errors?.['minlength']">
Benutzername muss mindestens 3 Zeichen haben
</span>
</div> </div>
}
@if (!fieldErrors()['username'] && form['username'].touched && form['username'].errors) {
<div class="text-accent-red mt-1 text-sm">
@if (form['username'].errors['required']) {
<span>Benutzername ist erforderlich</span>
}
@if (form['username'].errors['minlength']) {
<span>Benutzername muss mindestens 3 Zeichen haben</span>
}
</div>
}
</div> </div>
<div> <div>
@ -81,25 +63,24 @@
placeholder="Erstelle ein Passwort" placeholder="Erstelle ein Passwort"
/> />
@if (form['password'].touched && form['password'].errors) { <div
<div class="text-accent-red mt-1 text-sm"> *ngIf="form['password'].touched && form['password'].errors"
@if (form['password'].errors['required']) { class="text-accent-red mt-1 text-sm"
<span>Passwort ist erforderlich</span> >
} <span *ngIf="form['password'].errors?.['required']">Passwort ist erforderlich</span>
@if (form['password'].errors['minlength']) { <span *ngIf="form['password'].errors?.['minlength']">
<span>Passwort muss mindestens 6 Zeichen haben</span> Passwort muss mindestens 6 Zeichen haben
} </span>
</div> </div>
}
</div> </div>
<div class="pt-2"> <div class="pt-2">
<button <button
type="submit" type="submit"
[disabled]="registerForm.invalid || isLoading()" [disabled]="registerForm.invalid || isLoading"
class="button-primary w-full py-2.5 rounded" class="button-primary w-full py-2.5 rounded"
> >
{{ isLoading() ? 'Konto wird erstellt...' : 'Registrieren' }} {{ isLoading ? 'Konto wird erstellt...' : 'Registrieren' }}
</button> </button>
</div> </div>
</form> </form>

View file

@ -1,10 +1,9 @@
import { Component, signal } from '@angular/core'; import { Component } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { Router, RouterLink } from '@angular/router'; import { Router, RouterLink } from '@angular/router';
import { RegisterRequest } from '../../../model/auth/RegisterRequest'; import { RegisterRequest } from '../../../model/auth/RegisterRequest';
import { AuthService } from '@service/auth.service'; import { AuthService } from '@service/auth.service';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
@Component({ @Component({
selector: 'app-register', selector: 'app-register',
@ -14,9 +13,8 @@ import { HttpErrorResponse } from '@angular/common/http';
}) })
export class RegisterComponent { export class RegisterComponent {
registerForm: FormGroup; registerForm: FormGroup;
errorMessage = signal<string>(''); errorMessage = '';
isLoading = signal<boolean>(false); isLoading = false;
fieldErrors = signal<Record<string, string>>({});
constructor( constructor(
private fb: FormBuilder, private fb: FormBuilder,
@ -39,9 +37,8 @@ export class RegisterComponent {
return; return;
} }
this.isLoading.set(true); this.isLoading = true;
this.errorMessage.set(''); this.errorMessage = '';
this.fieldErrors.set({});
const registerRequest: RegisterRequest = { const registerRequest: RegisterRequest = {
email: this.form['email'].value, email: this.form['email'].value,
@ -51,6 +48,7 @@ export class RegisterComponent {
this.authService.register(registerRequest).subscribe({ this.authService.register(registerRequest).subscribe({
next: () => { next: () => {
// After registration, log in the user
this.authService this.authService
.login({ .login({
usernameOrEmail: registerRequest.email, usernameOrEmail: registerRequest.email,
@ -61,35 +59,15 @@ export class RegisterComponent {
this.router.navigate(['/home']); this.router.navigate(['/home']);
}, },
error: () => { error: () => {
this.isLoading.set(false); this.isLoading = false;
this.errorMessage.set( this.errorMessage =
'Registration successful but failed to login automatically. Please log in manually.' 'Registration successful but failed to login automatically. Please log in manually.';
);
}, },
}); });
}, },
error: (err: HttpErrorResponse) => { error: (err) => {
this.isLoading.set(false); this.isLoading = false;
this.errorMessage = err.error?.message || 'Failed to register. Please try again.';
if (err.status === 409) {
const message = err.error?.message;
switch (message) {
case 'Email is already in use':
this.fieldErrors.update((errors) => ({
...errors,
email: 'Diese E-Mail-Adresse wird bereits verwendet.',
}));
break;
case 'Username is already taken':
this.fieldErrors.update((errors) => ({
...errors,
username: 'Dieser Benutzername ist bereits vergeben.',
}));
break;
}
} else {
this.errorMessage.set(err.error?.message || 'Failed to register. Please try again.');
}
}, },
}); });
} }