From 0f14c72fdd19815418b08b4bcdcacca56efa6d6b Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Mon, 9 Jun 2025 19:57:27 +0200 Subject: [PATCH 1/2] login endpoint refactored --- .../controller/AuthController.java | 28 +++++++------ .../WrongLoginPasswordException.java | 4 ++ .../service/AuthService.java | 39 +++++++++++++++++++ .../service/ClientService.java | 28 ++++--------- 4 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java create mode 100644 src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java b/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java index 231f1df..64693b1 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java @@ -3,6 +3,7 @@ package _11.asktpk.artisanconnectbackend.controller; import _11.asktpk.artisanconnectbackend.dto.*; import _11.asktpk.artisanconnectbackend.entities.Client; import _11.asktpk.artisanconnectbackend.security.JwtUtil; +import _11.asktpk.artisanconnectbackend.service.AuthService; import _11.asktpk.artisanconnectbackend.service.ClientService; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; @@ -19,27 +20,32 @@ import java.util.Map; public class AuthController { private final ClientService clientService; + private final AuthService authService; private final JwtUtil jwtUtil; - public AuthController(ClientService clientService, JwtUtil jwtUtil) { + public AuthController(ClientService clientService, JwtUtil jwtUtil, AuthService authService) { this.clientService = clientService; + this.authService = authService; this.jwtUtil = jwtUtil; } @PostMapping("/login") - public ResponseEntity login(@RequestBody AuthRequestDTO authRequestDTO) { - if (clientService.checkClientCredentials(authRequestDTO)) { - Client client = clientService.getClientByEmail(authRequestDTO.getEmail()); - Long userId = client.getId(); - String userRole = client.getRole().getRole(); + public ResponseEntity login(@RequestBody AuthRequestDTO authRequestDTO) { + if (authRequestDTO.getEmail() == null || authRequestDTO.getPassword() == null) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO("Przekazano puste login lub hasło")); + } - String token = jwtUtil.generateToken(client.getEmail(), userRole, userId); + authRequestDTO.setEmail(authRequestDTO.getEmail().toLowerCase()); + authRequestDTO.setPassword(authRequestDTO.getPassword()); + + try { + AuthResponseDTO responseDTO = authService.login(authRequestDTO.getEmail(), authRequestDTO.getPassword()); - log.info("User logged in with {}", client.getEmail()); return ResponseEntity.status(HttpStatus.OK) - .body(new AuthResponseDTO(userId, userRole, token)); - } else { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null); + .body(responseDTO); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO(e.getMessage())); } } diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java b/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java new file mode 100644 index 0000000..235f0e9 --- /dev/null +++ b/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java @@ -0,0 +1,4 @@ +package _11.asktpk.artisanconnectbackend.customExceptions; + +public class WrongLoginPasswordException { +} diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java b/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java new file mode 100644 index 0000000..f319090 --- /dev/null +++ b/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java @@ -0,0 +1,39 @@ +package _11.asktpk.artisanconnectbackend.service; + +import _11.asktpk.artisanconnectbackend.dto.AuthResponseDTO; +import _11.asktpk.artisanconnectbackend.entities.Client; +import _11.asktpk.artisanconnectbackend.security.JwtUtil; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class AuthService { + + private final ClientService clientService; + private final PasswordEncoder passwordEncoder; + private final JwtUtil jwtUtil; + + public AuthService(ClientService clientService, JwtUtil jwtUtil) { + this.clientService = clientService; + this.jwtUtil = jwtUtil; + this.passwordEncoder = new BCryptPasswordEncoder(); + } + + public AuthResponseDTO login(String email, String password) throws Exception { + Client client = clientService.getClientByEmail(email); + if (client == null) { + throw new Exception("Klient o podanym adresie nie istnieje!"); + } + + if(passwordEncoder.matches(password, client.getPassword())) { + String token = jwtUtil.generateToken(client.getEmail(), client.getRole().getRole(), client.getId()); + log.info("User logged in with {}", client.getEmail()); + return new AuthResponseDTO(client.getId(), client.getRole().getRole(), token); + } + throw new Exception("Login lub hasło jest niepoprawny!"); + } +} + diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java b/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java index 36af97b..9848e13 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java @@ -1,6 +1,5 @@ package _11.asktpk.artisanconnectbackend.service; -import _11.asktpk.artisanconnectbackend.dto.AuthRequestDTO; import _11.asktpk.artisanconnectbackend.dto.ClientDTO; import _11.asktpk.artisanconnectbackend.dto.ClientRegistrationDTO; import _11.asktpk.artisanconnectbackend.entities.Client; @@ -86,6 +85,14 @@ public class ClientService { return toDto(clientRepository.findById(id).orElse(null)); } + public Client getClientByEmail(String email) { + return clientRepository.findByEmail(email); + } + + public Role getUserRole() { + return rolesRepository.findRoleByRole("USER"); + } + public boolean clientExists(Long id) { return clientRepository.existsById(id); } @@ -117,29 +124,10 @@ public class ClientService { clientRepository.deleteById(id); } - // И замените метод checkClientCredentials на: - public boolean checkClientCredentials(AuthRequestDTO dto) { - Client cl = clientRepository.findByEmail(dto.getEmail()); - if (cl == null) { - return false; - } - - return passwordEncoder.matches(dto.getPassword(), cl.getPassword()); - } - - // При создании нового пользователя не забудьте шифровать пароль: public ClientDTO registerClient(ClientRegistrationDTO clientDTO) { Client client = fromDto(clientDTO); client.setRole(rolesRepository.findRoleById(1L)); client.setPassword(passwordEncoder.encode(client.getPassword())); return toDto(clientRepository.save(client)); } - - public Client getClientByEmail(String email) { - return clientRepository.findByEmail(email); - } - - public Role getUserRole() { - return rolesRepository.findRoleByRole("USER"); - } } From 3355914c7058fec2c475e754fea10546291d4140 Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Tue, 10 Jun 2025 10:26:29 +0200 Subject: [PATCH 2/2] Refactor of the whole AuthController --- .../controller/AuthController.java | 95 ++++++------------- .../ClientAlreadyExistsException.java | 7 ++ .../WrongLoginPasswordException.java | 5 +- .../artisanconnectbackend/dto/ClientDTO.java | 4 + .../entities/Client.java | 9 ++ .../service/AuthService.java | 82 +++++++++++++++- .../service/ClientService.java | 9 +- 7 files changed, 138 insertions(+), 73 deletions(-) create mode 100644 src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/ClientAlreadyExistsException.java diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java b/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java index 64693b1..a992a1a 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/controller/AuthController.java @@ -1,42 +1,34 @@ package _11.asktpk.artisanconnectbackend.controller; +import _11.asktpk.artisanconnectbackend.customExceptions.ClientAlreadyExistsException; +import _11.asktpk.artisanconnectbackend.customExceptions.WrongLoginPasswordException; import _11.asktpk.artisanconnectbackend.dto.*; -import _11.asktpk.artisanconnectbackend.entities.Client; -import _11.asktpk.artisanconnectbackend.security.JwtUtil; import _11.asktpk.artisanconnectbackend.service.AuthService; -import _11.asktpk.artisanconnectbackend.service.ClientService; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import java.util.Map; @Slf4j @RestController @RequestMapping("/api/v1/auth") public class AuthController { - private final ClientService clientService; private final AuthService authService; - private final JwtUtil jwtUtil; - public AuthController(ClientService clientService, JwtUtil jwtUtil, AuthService authService) { - this.clientService = clientService; + public AuthController(AuthService authService) { this.authService = authService; - this.jwtUtil = jwtUtil; } @PostMapping("/login") public ResponseEntity login(@RequestBody AuthRequestDTO authRequestDTO) { - if (authRequestDTO.getEmail() == null || authRequestDTO.getPassword() == null) { + if (authRequestDTO.getEmail() == null || authRequestDTO.getPassword() == null + || authRequestDTO.getEmail().isEmpty() || authRequestDTO.getPassword().isEmpty()) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO("Przekazano puste login lub hasło")); } authRequestDTO.setEmail(authRequestDTO.getEmail().toLowerCase()); - authRequestDTO.setPassword(authRequestDTO.getPassword()); try { AuthResponseDTO responseDTO = authService.login(authRequestDTO.getEmail(), authRequestDTO.getPassword()); @@ -44,33 +36,33 @@ public class AuthController { return ResponseEntity.status(HttpStatus.OK) .body(responseDTO); + } catch (WrongLoginPasswordException e) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new RequestResponseDTO(e.getMessage())); } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO(e.getMessage())); } } @PostMapping("/register") - public ResponseEntity register(@RequestBody ClientRegistrationDTO clientDTO) { - if (clientService.getClientByEmail(clientDTO.getEmail()) != null) { - return ResponseEntity.status(HttpStatus.CONFLICT).build(); + public ResponseEntity register(@RequestBody ClientRegistrationDTO clientRegistrationDTO) { + if (clientRegistrationDTO.getEmail() == null || clientRegistrationDTO.getPassword() == null + || clientRegistrationDTO.getEmail().isEmpty() || clientRegistrationDTO.getPassword().isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO("Przekazano puste login lub hasło")); } - ClientDTO savedClient = clientService.registerClient(clientDTO); + clientRegistrationDTO.setEmail(clientRegistrationDTO.getEmail().toLowerCase()); - String token = jwtUtil.generateToken( - savedClient.getEmail(), - savedClient.getRole(), - savedClient.getId() - ); + try { + AuthResponseDTO registrationData = authService.register(clientRegistrationDTO.getEmail(), clientRegistrationDTO.getPassword(), clientRegistrationDTO.getFirstName(), clientRegistrationDTO.getLastName()); - log.info("New user registered with {}", savedClient.getEmail()); - - return ResponseEntity.status(HttpStatus.CREATED) - .body(new AuthResponseDTO( - savedClient.getId(), - savedClient.getRole(), - token - )); + return ResponseEntity.status(HttpStatus.CREATED) + .body(registrationData); + } catch (ClientAlreadyExistsException clientAlreadyExistsException) { + return ResponseEntity.status(HttpStatus.CONFLICT) + .body(new RequestResponseDTO(clientAlreadyExistsException.getMessage())); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO(e.getMessage())); + } } @PostMapping("/logout") @@ -79,7 +71,7 @@ public class AuthController { if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); - jwtUtil.blacklistToken(token); + authService.logout(token); return ResponseEntity.ok(new RequestResponseDTO("Successfully logged out")); } @@ -88,43 +80,16 @@ public class AuthController { @PostMapping("/google") public ResponseEntity authenticateWithGoogle(@RequestBody GoogleAuthRequestDTO dto) { + if(dto.getGoogleToken() == null){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO("Invalid or empty token")); + } + try { - String accessToken = dto.getGoogleToken(); - String googleUserInfoUrl = "https://www.googleapis.com/oauth2/v3/userinfo"; - - HttpHeaders headers = new HttpHeaders(); - headers.setBearerAuth(accessToken); - HttpEntity entity = new HttpEntity<>(headers); - - RestTemplate restTemplate = new RestTemplate(); - ResponseEntity response = restTemplate.exchange( - googleUserInfoUrl, HttpMethod.GET, entity, Map.class); - - Map userInfo = response.getBody(); - -// String googleId = (String) userInfo.get("sub"); Potencjalnie możemy używać googlowskiego ID, ale to ma konflikt z naszym generowanym - assert userInfo != null; - String email = (String) userInfo.get("email"); - String name = (String) userInfo.get("name"); - - Client client = clientService.getClientByEmail(email); - if (client == null) { - client = new Client(); - client.setEmail(email); - client.setFirstName(name); - client.setRole(clientService.getUserRole()); // to pobiera po prostu role "USER" z tabeli w bazie - clientService.saveClientToDB(client); - } - - String jwt = jwtUtil.generateToken(client.getEmail(), client.getRole().getRole(), client.getId()); - - log.info("User authenticated with google: {}", email); - return ResponseEntity.ok(new AuthResponseDTO(client.getId(), client.getRole().getRole(), jwt)); + AuthResponseDTO response = authService.googleLogin(dto.getGoogleToken()); + return ResponseEntity.status(HttpStatus.OK).body(response); } catch (HttpClientErrorException httpClientErrorException) { - log.error("Token is invalid or expired"); - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new RequestResponseDTO("Invalid access token")); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RequestResponseDTO("Google access token is invalid or expired")); } catch (Exception e) { - log.error("Error while checking Google access token", e); return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(new RequestResponseDTO("Authentication Error (Google): " + e.getMessage())); } diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/ClientAlreadyExistsException.java b/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/ClientAlreadyExistsException.java new file mode 100644 index 0000000..8cb678a --- /dev/null +++ b/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/ClientAlreadyExistsException.java @@ -0,0 +1,7 @@ +package _11.asktpk.artisanconnectbackend.customExceptions; + +public class ClientAlreadyExistsException extends Exception { + public ClientAlreadyExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java b/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java index 235f0e9..4b308eb 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/customExceptions/WrongLoginPasswordException.java @@ -1,4 +1,7 @@ package _11.asktpk.artisanconnectbackend.customExceptions; -public class WrongLoginPasswordException { +public class WrongLoginPasswordException extends Exception { + public WrongLoginPasswordException(String message) { + super(message); + } } diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/dto/ClientDTO.java b/src/main/java/_11/asktpk/artisanconnectbackend/dto/ClientDTO.java index ab6af54..a4c4495 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/dto/ClientDTO.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/dto/ClientDTO.java @@ -1,12 +1,16 @@ package _11.asktpk.artisanconnectbackend.dto; import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import jakarta.validation.constraints.Email; @Getter @Setter +@AllArgsConstructor +@NoArgsConstructor public class ClientDTO { private Long id; diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/entities/Client.java b/src/main/java/_11/asktpk/artisanconnectbackend/entities/Client.java index c6ca7c0..5857f3d 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/entities/Client.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/entities/Client.java @@ -2,6 +2,7 @@ package _11.asktpk.artisanconnectbackend.entities; import jakarta.persistence.*; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.annotations.CreationTimestamp; @@ -11,7 +12,15 @@ import java.util.List; @Entity @Table(name = "clients") @Getter @Setter +@NoArgsConstructor public class Client { + public Client(String email, String password, String firstName, String lastName) { + this.email = email; + this.password = password; + this.firstName = firstName; + this.lastName = lastName; + } + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java b/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java index f319090..0457596 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/service/AuthService.java @@ -1,12 +1,19 @@ package _11.asktpk.artisanconnectbackend.service; +import _11.asktpk.artisanconnectbackend.customExceptions.ClientAlreadyExistsException; +import _11.asktpk.artisanconnectbackend.customExceptions.WrongLoginPasswordException; import _11.asktpk.artisanconnectbackend.dto.AuthResponseDTO; +import _11.asktpk.artisanconnectbackend.dto.ClientDTO; import _11.asktpk.artisanconnectbackend.entities.Client; import _11.asktpk.artisanconnectbackend.security.JwtUtil; +import org.springframework.http.*; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; @Slf4j @Service @@ -28,12 +35,83 @@ public class AuthService { throw new Exception("Klient o podanym adresie nie istnieje!"); } - if(passwordEncoder.matches(password, client.getPassword())) { + if (passwordEncoder.matches(password, client.getPassword())) { String token = jwtUtil.generateToken(client.getEmail(), client.getRole().getRole(), client.getId()); log.info("User logged in with {}", client.getEmail()); return new AuthResponseDTO(client.getId(), client.getRole().getRole(), token); } - throw new Exception("Login lub hasło jest niepoprawny!"); + throw new WrongLoginPasswordException("Login lub hasło jest niepoprawny!"); } + + public AuthResponseDTO register(String email, String password, String firstName, String lastName) throws Exception { + if (clientService.getClientByEmail(email) != null) { + throw new ClientAlreadyExistsException("Klient o podanym adresie email już istnieje!"); + } + + Client newClient = new Client(); + newClient.setEmail(email); + newClient.setPassword(passwordEncoder.encode(password)); + newClient.setFirstName(firstName); + newClient.setLastName(lastName); + + ClientDTO savedClient = clientService.registerClient(newClient); + if (savedClient != null) { + log.info("New user registered with {}", savedClient.getEmail()); + String token = jwtUtil.generateToken( + savedClient.getEmail(), + savedClient.getRole(), + savedClient.getId() + ); + + return new AuthResponseDTO(savedClient.getId(), savedClient.getRole(), token); + } else { + throw new Exception("Rejestracja nie powiodła się!"); + } + } + + public void logout(String token) { + jwtUtil.blacklistToken(token); + } + + public AuthResponseDTO googleLogin(String googleAccessToken) throws Exception { + String googleUserInfoUrl = "https://www.googleapis.com/oauth2/v3/userinfo"; + + ResponseEntity response; + + + HttpHeaders headers = new HttpHeaders(); + headers.setBearerAuth(googleAccessToken); + RestTemplate restTemplate = new RestTemplate(); + response = restTemplate.exchange( + googleUserInfoUrl, HttpMethod.GET, new HttpEntity<>(headers), Map.class); + + + Map userInfo = response.getBody(); + +// String googleId = (String) userInfo.get("sub"); Potencjalnie możemy używać googlowskiego ID, ale to ma konflikt z naszym generowanym + if (userInfo == null) { + throw new Exception("Pobrany użytkownik jest pusty! Może to być spowodowane niepoprawnym tokenem lub brakiem dostępu do Google API."); + } + String email = (String) userInfo.get("email"); + String name = (String) userInfo.get("name"); + + Client client = clientService.getClientByEmail(email); + if (client == null) { + client = new Client(); + client.setEmail(email); + client.setFirstName(name); + client.setRole(clientService.getUserRole()); // to pobiera po prostu role "USER" z tabeli w bazie + clientService.saveClientToDB(client); + } + + String jwt = jwtUtil.generateToken(client.getEmail(), client.getRole().getRole(), client.getId()); + log.info("User authenticated with google: {}", client.getEmail()); + return new AuthResponseDTO( + client.getId(), + client.getRole().getRole(), + jwt + ); + } + } diff --git a/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java b/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java index 9848e13..467ec4c 100644 --- a/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java +++ b/src/main/java/_11/asktpk/artisanconnectbackend/service/ClientService.java @@ -24,7 +24,7 @@ public class ClientService { this.rolesRepository = rolesRepository; } - private ClientDTO toDto(Client client) { + public ClientDTO toDto(Client client) { if(client == null) { return null; } @@ -41,7 +41,7 @@ public class ClientService { return dto; } - private Client fromDto(ClientDTO dto) { + public Client fromDto(ClientDTO dto) { Client client = new Client(); Role rola; @@ -124,9 +124,8 @@ public class ClientService { clientRepository.deleteById(id); } - public ClientDTO registerClient(ClientRegistrationDTO clientDTO) { - Client client = fromDto(clientDTO); - client.setRole(rolesRepository.findRoleById(1L)); + public ClientDTO registerClient(Client client) { + client.setRole(getUserRole()); // ID 1 - USER role client.setPassword(passwordEncoder.encode(client.getPassword())); return toDto(clientRepository.save(client)); }