From ac24db97461c65863bc75def6092c741fcb71e01 Mon Sep 17 00:00:00 2001 From: Lucas Aguiar Date: Mon, 23 Mar 2026 10:33:29 -0300 Subject: [PATCH] feat(auth): allow login with email or username --- .../application/controller/auth/AuthController.java | 6 +++--- .../notehub/application/dto/request/token/AuthREQ.java | 9 ++------- .../implementation/token/TokenServiceImpl.java | 7 +++++-- .../java/br/com/notehub/domain/token/TokenService.java | 2 +- .../br/com/notehub/infra/exception/ControllerAdvice.java | 4 ++-- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/br/com/notehub/application/controller/auth/AuthController.java b/src/main/java/br/com/notehub/application/controller/auth/AuthController.java index 1a01298..d982909 100644 --- a/src/main/java/br/com/notehub/application/controller/auth/AuthController.java +++ b/src/main/java/br/com/notehub/application/controller/auth/AuthController.java @@ -34,10 +34,10 @@ public class AuthController { private final UserService userService; private final MailProducer producer; - @Operation(summary = "Login user", description = "Authenticates a user with username and password.") + @Operation(summary = "Authenticate User", description = "Authenticates a user using an account identifier and password.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "User authenticated successfully."), - @ApiResponse(responseCode = "401", description = "Invalid password.", content = @Content(mediaType = "application/json")), + @ApiResponse(responseCode = "401", description = "Invalid identifier or password.", content = @Content(mediaType = "application/json")), @ApiResponse(responseCode = "400", description = "Missing or invalid X-Device-Id.", content = @Content(mediaType = "application/json")), @ApiResponse(responseCode = "403", description = "Email not confirmed.", content = @Content(mediaType = "application/json")), @ApiResponse(responseCode = "404", description = "User not found.", content = @Content(examples = {})), @@ -49,7 +49,7 @@ public ResponseEntity loginUser( HttpServletRequest request, @Valid @RequestBody AuthREQ dto ) { - AuthRES token = service.auth(request, dto.username(), dto.password()); + AuthRES token = service.auth(request, dto.identifier(), dto.password()); return ResponseEntity.status(HttpStatus.OK).body(token); } diff --git a/src/main/java/br/com/notehub/application/dto/request/token/AuthREQ.java b/src/main/java/br/com/notehub/application/dto/request/token/AuthREQ.java index 2315c9e..29bdeeb 100644 --- a/src/main/java/br/com/notehub/application/dto/request/token/AuthREQ.java +++ b/src/main/java/br/com/notehub/application/dto/request/token/AuthREQ.java @@ -2,18 +2,13 @@ import br.com.notehub.application.validation.constraints.NoForbiddenWords; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; public record AuthREQ( @NoForbiddenWords(message = "Não pode") @NotBlank - @Pattern( - regexp = "^(?!.*[\\p{Zs}\\u00A0\\u2007\\u202F]).*$", - message = "Não use espaços" - ) - @Size(min = 2, max = 12, message = "Tamanho inválido") - String username, + @Size(min = 2, max = 255, message = "Tamanho inválido") + String identifier, @NotBlank @Size(min = 4, max = 255, message = "Tamanho inválido") diff --git a/src/main/java/br/com/notehub/application/implementation/token/TokenServiceImpl.java b/src/main/java/br/com/notehub/application/implementation/token/TokenServiceImpl.java index 7875e77..adae8f0 100644 --- a/src/main/java/br/com/notehub/application/implementation/token/TokenServiceImpl.java +++ b/src/main/java/br/com/notehub/application/implementation/token/TokenServiceImpl.java @@ -189,9 +189,12 @@ public String validateToken(String accessToken) { @Transactional @Override - public AuthRES auth(HttpServletRequest request, String username, String password) throws BadCredentialsException { + public AuthRES auth(HttpServletRequest request, String identifier, String password) throws BadCredentialsException { - User user = userRepository.findByUsername(username.toLowerCase()).orElseThrow(() -> new BadCredentialsException("username")); + User user = (identifier.contains("@") + ? userRepository.findByEmail(identifier) + : userRepository.findByUsername(identifier)) + .orElseThrow(() -> new BadCredentialsException("identifier")); if (!user.isActive()) throw new DisabledException("Email não confirmado"); boolean matches = encoder.matches(password, user.getPassword()); diff --git a/src/main/java/br/com/notehub/domain/token/TokenService.java b/src/main/java/br/com/notehub/domain/token/TokenService.java index 6609774..954bb08 100644 --- a/src/main/java/br/com/notehub/domain/token/TokenService.java +++ b/src/main/java/br/com/notehub/domain/token/TokenService.java @@ -26,7 +26,7 @@ public interface TokenService { String validateToken(String accessToken); - AuthRES auth(HttpServletRequest request, String username, String password) throws BadCredentialsException; + AuthRES auth(HttpServletRequest request, String identifier, String password) throws BadCredentialsException; AuthRES authWithGoogleAcc(HttpServletRequest request, String token); diff --git a/src/main/java/br/com/notehub/infra/exception/ControllerAdvice.java b/src/main/java/br/com/notehub/infra/exception/ControllerAdvice.java index 578f263..609da47 100644 --- a/src/main/java/br/com/notehub/infra/exception/ControllerAdvice.java +++ b/src/main/java/br/com/notehub/infra/exception/ControllerAdvice.java @@ -144,8 +144,8 @@ private ResponseEntity handleEntityExistsException(EntityExistsExcep private ResponseEntity> handleBadCredentialsException(BadCredentialsException ex) { List errors = new ArrayList<>(); return switch (ex.getMessage()) { - case "username" -> { - errors.add(new FieldError("user", "username", "Nome não existe.")); + case "identifier" -> { + errors.add(new FieldError("user", "identifier", "Identificador não existe.")); yield ResponseEntity.status(HttpStatus.NOT_FOUND).body(errors.stream().map(CustomResponse::new).toList()); } case "password" -> {