Passwort reset Web
This commit is contained in:
parent
af021c7830
commit
90cc3a6963
|
|
@ -2,7 +2,6 @@ package it.boergmann.tkdApp.config;
|
||||||
|
|
||||||
import it.boergmann.tkdApp.security.CustomUserDetailsService;
|
import it.boergmann.tkdApp.security.CustomUserDetailsService;
|
||||||
import it.boergmann.tkdApp.security.JwtAuthenticationFilter;
|
import it.boergmann.tkdApp.security.JwtAuthenticationFilter;
|
||||||
import jakarta.servlet.Filter;
|
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
@ -36,8 +35,6 @@ public class SecurityConfig {
|
||||||
private final CustomUserDetailsService userDetailsService;
|
private final CustomUserDetailsService userDetailsService;
|
||||||
private final JwtAuthenticationFilter jwtAuthFilter;
|
private final JwtAuthenticationFilter jwtAuthFilter;
|
||||||
|
|
||||||
|
|
||||||
// 🧱 1. API Security (JWT, kein Redirect)
|
|
||||||
@Bean
|
@Bean
|
||||||
@Order(1)
|
@Order(1)
|
||||||
public SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
|
public SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
|
||||||
|
|
@ -57,13 +54,12 @@ public class SecurityConfig {
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🌐 2. Web Security (Form Login)
|
|
||||||
@Bean
|
@Bean
|
||||||
@Order(2)
|
@Order(2)
|
||||||
public SecurityFilterChain webSecurity(HttpSecurity http) throws Exception {
|
public SecurityFilterChain webSecurity(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeHttpRequests(authz -> authz
|
.authorizeHttpRequests(authz -> authz
|
||||||
.requestMatchers("/login", "/register", "/css/**", "/js/**", "/reset-request").permitAll()
|
.requestMatchers("/login", "/register", "/css/**", "/js/**", "/reset-request", "/password-reset", "/set-password").permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
)
|
)
|
||||||
.formLogin(form -> form
|
.formLogin(form -> form
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package it.boergmann.tkdApp.controller.web;
|
package it.boergmann.tkdApp.controller.web;
|
||||||
|
|
||||||
|
import it.boergmann.tkdApp.dto.PasswordConfirmRequest;
|
||||||
import it.boergmann.tkdApp.dto.PasswordResetRequest;
|
import it.boergmann.tkdApp.dto.PasswordResetRequest;
|
||||||
import it.boergmann.tkdApp.dto.RegisterRequest;
|
import it.boergmann.tkdApp.dto.RegisterRequest;
|
||||||
import it.boergmann.tkdApp.domain.AppUser;
|
|
||||||
import it.boergmann.tkdApp.domain.Role;
|
|
||||||
import it.boergmann.tkdApp.repository.AppUserRepository;
|
import it.boergmann.tkdApp.repository.AppUserRepository;
|
||||||
|
import it.boergmann.tkdApp.repository.AppUserRoleRepository;
|
||||||
import it.boergmann.tkdApp.service.AppUserService;
|
import it.boergmann.tkdApp.service.AppUserService;
|
||||||
import it.boergmann.tkdApp.service.MailService;
|
import it.boergmann.tkdApp.service.MailService;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
@ -15,14 +15,13 @@ import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class UserController {
|
public class UserController {
|
||||||
private final AppUserRepository userRepository;
|
private final AppUserRepository userRepository;
|
||||||
private final AppUserService appUserService;
|
private final AppUserService appUserService;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
private final AppUserRoleRepository appUserRoleRepository;
|
||||||
|
|
||||||
@GetMapping("/register")
|
@GetMapping("/register")
|
||||||
public String showRegisterForm(Model model) {
|
public String showRegisterForm(Model model) {
|
||||||
|
|
@ -43,8 +42,6 @@ public class UserController {
|
||||||
return "login"; // src/main/resources/templates/login.html
|
return "login"; // src/main/resources/templates/login.html
|
||||||
}
|
}
|
||||||
|
|
||||||
private final MailService mailService; // oder dein eigener Service
|
|
||||||
|
|
||||||
@GetMapping("/reset-request")
|
@GetMapping("/reset-request")
|
||||||
public String showRequestForm(Model model) {
|
public String showRequestForm(Model model) {
|
||||||
model.addAttribute("emailRequest", new PasswordResetRequest());
|
model.addAttribute("emailRequest", new PasswordResetRequest());
|
||||||
|
|
@ -57,4 +54,20 @@ public class UserController {
|
||||||
model.addAttribute("message", "Wenn ein Konto existiert, wurde eine Mail gesendet.");
|
model.addAttribute("message", "Wenn ein Konto existiert, wurde eine Mail gesendet.");
|
||||||
return "password_reset_request";
|
return "password_reset_request";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/set-password")
|
||||||
|
public String setNewPassword(@RequestParam String token, Model model) {
|
||||||
|
if (userRepository.existsByResetToken(token)) {
|
||||||
|
model.addAttribute("token", token);
|
||||||
|
return "set-password";
|
||||||
|
} else {
|
||||||
|
return "error/password_reset_request_error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/set-password")
|
||||||
|
public String saveNewPassword(@RequestBody PasswordConfirmRequest request){
|
||||||
|
appUserService.confirmPasswordReset(request);
|
||||||
|
return "password-reset-confirmation";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,5 @@ public class PasswordConfirmRequest {
|
||||||
private String token;
|
private String token;
|
||||||
@NotBlank(message = "Passwort darf nicht leer sein")
|
@NotBlank(message = "Passwort darf nicht leer sein")
|
||||||
private String newPassword;
|
private String newPassword;
|
||||||
|
private String newPasswordRepeated;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import java.util.UUID;
|
||||||
public interface AppUserRepository extends JpaRepository<AppUser, UUID> {
|
public interface AppUserRepository extends JpaRepository<AppUser, UUID> {
|
||||||
boolean existsByUsername(String username); // 🔥 hier hinzufügen!
|
boolean existsByUsername(String username); // 🔥 hier hinzufügen!
|
||||||
boolean existsByEmail(String email);
|
boolean existsByEmail(String email);
|
||||||
|
boolean existsByResetToken(String token);
|
||||||
Optional<AppUser> findByUsername(String username);
|
Optional<AppUser> findByUsername(String username);
|
||||||
Optional<AppUser> findByResetToken(String token);
|
Optional<AppUser> findByResetToken(String token);
|
||||||
Optional<AppUser> findByEmailVerificationToken(String token);
|
Optional<AppUser> findByEmailVerificationToken(String token);
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ public class AppUserService {
|
||||||
user.setResetExpires(LocalDateTime.now().plusHours(1));
|
user.setResetExpires(LocalDateTime.now().plusHours(1));
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
|
|
||||||
String link = "https://tkdapp.de/reset-password?token=" + user.getResetToken();
|
String link = "http://localhost:8080/set-password?token=" + user.getResetToken();
|
||||||
|
|
||||||
|
|
||||||
mailService.sendMail(
|
mailService.sendMail(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title>Passwort zurücksetzen</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Fehler</h2>
|
||||||
|
<p>kein gültiges Reset-Token</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Passwort zurückgesetzt</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Passwort erfolgreich geändert</h1>
|
||||||
|
<form th:action="@{/login}" method="post" th:object="${confirmationRequest}">
|
||||||
|
<label>Benutzername: <input type="text" name="username"/></label><br/>
|
||||||
|
<label>Passwort: <input type="password" name="password"/></label><br/>
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title>Passwort zurücksetzen</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Passwort zurücksetzen</h2>
|
||||||
|
|
||||||
|
<form th:action="@{/set-password}" method="post" th:object="${passwordConfirmRequest}">
|
||||||
|
<label>Passwort: <input type="password" name="newPassword"/></label><br/>
|
||||||
|
<label>Noch einmal: <input type="password" name="newPasswordRepeated"/></label><br/>
|
||||||
|
<input type="hidden" value=th:text="${token}"/>
|
||||||
|
<button type="submit">Zurücksetzen anfordern</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<p th:if="${message}" th:text="${message}"></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue