-
Notifications
You must be signed in to change notification settings - Fork 0
@coderabbitai #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@coderabbitai #20
Conversation
…t and add authentication manager
…te SecurityFilter
… in login response
…for API integration
…rove token validation error handling
…ronment variable management
…ables from .env file
…dEncoder instance
Remove unused import Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
WalkthroughThis update introduces user authentication and security features using Spring Security and JWT. It adds new DTOs, a controller for authentication, a security filter, and a token service. The configuration is updated to support environment variables via dotenv, and the application properties and documentation are revised accordingly. Some legacy configuration files are removed. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthenticationController
participant AuthenticationManager
participant UserRepository
participant TokenService
Client->>AuthenticationController: POST /api/auth/login (login, password)
AuthenticationController->>AuthenticationManager: authenticate(login, password)
AuthenticationManager-->>AuthenticationController: Authentication result
AuthenticationController->>TokenService: generateToken(user)
TokenService-->>AuthenticationController: JWT token
AuthenticationController-->>Client: LoginResponseDTO (token, login, role)
Client->>AuthenticationController: POST /api/auth/register (login, password, role)
AuthenticationController->>UserRepository: findByLogin(login)
UserRepository-->>AuthenticationController: UserDetails/null
AuthenticationController->>UserRepository: save(new User)
AuthenticationController-->>Client: OK/Conflict
sequenceDiagram
participant Client
participant SecurityFilter
participant TokenService
participant UserRepository
Client->>SecurityFilter: Request with Authorization: Bearer <token>
SecurityFilter->>TokenService: validateToken(token)
TokenService-->>SecurityFilter: username
SecurityFilter->>UserRepository: findByLogin(username)
UserRepository-->>SecurityFilter: UserDetails
SecurityFilter-->>Client: Continue filter chain (request proceeds)
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
src/main/java/com/otavio/aifoodapp/model/User.java (1)
43-60:⚠️ Potential issue
Userdoes not compile – missing 4 mandatoryUserDetailsmethods
UserimplementsUserDetailsbut overrides onlygetUsername,getPassword, andgetAuthorities.
The following abstract methods are still missing and compilation will fail:boolean isAccountNonExpired(); boolean isAccountNonLocked(); boolean isCredentialsNonExpired(); boolean isEnabled();Add trivial
trueimplementations or proper flags:+ @Override public boolean isAccountNonExpired() { return true; } + @Override public boolean isAccountNonLocked() { return true; } + @Override public boolean isCredentialsNonExpired() { return true; } + @Override public boolean isEnabled() { return true; }
🧹 Nitpick comments (22)
src/main/java/com/otavio/aifoodapp/dto/RegisterDTO.java (2)
5-14: Consider replacing the verbose POJO with a Javarecord.The class is an immutable data carrier and only overrides
toString(). A Javarecordwould auto-generate the constructor, accessors,equals,hashCode, andtoString(which you can still customise to omit the password) while keeping the code concise and error-free.-package com.otavio.aifoodapp.dto; - -import com.otavio.aifoodapp.enums.UserRoles; - -public class RegisterDTO { - private final String login; - private final String password; - private final UserRoles role; - - public RegisterDTO(String login, String password, UserRoles role) { - this.login = login; - this.password = password; - this.role = role; - } - ... -} +package com.otavio.aifoodapp.dto; + +import com.otavio.aifoodapp.enums.UserRoles; + +public record RegisterDTO(String login, String password, UserRoles role) { }
21-25:toString()still exposes the identifier – ensure it never lands in logs.Although the password is omitted, the login (which is often an e-mail) is still PII. Make sure log levels or exception traces do not inadvertently print this DTO.
src/main/resources/META-INF/spring.factories (1)
1-2: Line-continuation backslash is unnecessary and occasionally mis-parsed.Spring Boot treats every line as a property entry; the backslash may be interpreted literally on some class-path scanners. Safer to keep it on a single line:
-org.springframework.boot.env.EnvironmentPostProcessor=\ -com.otavio.aifoodapp.config.DotenvEnvironmentPostProcessor +org.springframework.boot.env.EnvironmentPostProcessor=com.otavio.aifoodapp.config.DotenvEnvironmentPostProcessorsrc/main/java/com/otavio/aifoodapp/dto/AuthenticationDTO.java (1)
3-4: Optionally annotate fields to enforce validation.Adding Jakarta Bean Validation annotations (
@NotBlank,@Size) guards against empty credentials before reaching the service layer.public record AuthenticationDTO( @NotBlank String login, @NotBlank String password) {}src/main/java/com/otavio/aifoodapp/model/User.java (1)
53-57: Possible NPE whenroleisnull
getAuthorities()dereferencesthis.rolewithout a null-check.
Either validaterolein constructors/setters or handlenullhere to preventNullPointerException.src/main/java/com/otavio/aifoodapp/service/AuthorizationService.java (1)
21-27:loadUserByUsernamecan be simplified and made null-safeIf
UserRepositoryreturnsOptional<User>(see previous comment) the code becomes:-UserDetails user = userRepository.findByLogin(username); -if (user == null) { - throw new UsernameNotFoundException("User not found with username: " + username); -} -return user; +return userRepository.findByLogin(username) + .orElseThrow(() -> + new UsernameNotFoundException("User not found: " + username));Cleaner, null-safe, and avoids an extra local variable.
src/main/java/com/otavio/aifoodapp/config/DotenvEnvironmentPostProcessor.java (1)
15-22: Avoid adding an empty property sourceWhen
.envis absent or contains only comments, an emptyMapPropertySourceis still added, slightly polluting the environment. Guard against this:-Map<String, Object> envMap = new HashMap<>(); -dotenv.entries().forEach(entry -> envMap.put(entry.getKey(), entry.getValue())); -environment.getPropertySources().addFirst(new MapPropertySource("dotenv", envMap)); +Map<String, Object> envMap = new HashMap<>(); +dotenv.entries().forEach(entry -> envMap.put(entry.getKey(), entry.getValue())); +if (!envMap.isEmpty()) { + environment.getPropertySources().addFirst(new MapPropertySource("dotenv", envMap)); +}pom.xml (2)
97-111:reactor-coreis redundant
reactor-coreis already transitively provided byspring-boot-starter-webflux. Keeping the explicit dependency makes the POM noisier and risks version drift if Boot upgrades.- <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-core</artifactId> - </dependency>
26-28:tomcat.versionproperty is unusedNo plugin or dependency refers to
${tomcat.version}. Remove the property or wire it into<spring-boot-maven-plugin>only if you plan to override Boot’s managed Tomcat version.src/main/java/com/otavio/aifoodapp/security/TokenService.java (1)
47-49: Hard-codingZoneOffset.of("-03:00")will break on servers running in other time-zonesPrefer
ZoneOffset.UTC(with shorter TTL if required) or inject the offset via configuration.src/main/java/com/otavio/aifoodapp/controller/AuthenticationController.java (3)
30-35: InjectPasswordEncoder, not concreteBCryptPasswordEncoderRelying on the interface keeps the controller agnostic and eases algorithm swaps.
- private final BCryptPasswordEncoder passwordEncoder; - public AuthenticationController(..., BCryptPasswordEncoder passwordEncoder) { + private final PasswordEncoder passwordEncoder; + public AuthenticationController(..., PasswordEncoder passwordEncoder) {
41-47: Expose principal info instead of echoing request payload
data.login()may differ from the authenticated principal (e.g., case-insensitive login). Useauth.getName()and return authorities as a collection, not a rawString.
49-58: Consider201 Createdand location header for successful registrationReturning
200 OKprovides no clue where the new resource lives.- return ResponseEntity.ok().build(); + return ResponseEntity.created(URI.create("/api/users/" + newUser.getId())).build();README.MD (9)
19-30: Consider adding hyperlinks para bibliotecas externas
Poderíamos enriquecer a seção de tecnologias incluindo links diretos para o repositório ou documentação deMaritaca AIedotenv-java, facilitando a referência para novos contribuidores.🧰 Tools
🪛 LanguageTool
[grammar] ~19-~19: Possível erro de concordância de número.
Context: ...adas - Spring Boot: Framework para aplicações Java - Spring Data JPA: Persistência de ...(GENERAL_NUMBER_AGREEMENT_ERRORS)
34-41: IncluirDotenvEnvironmentPostProcessorna visão arquitetural
A arquitetura já listaConfig, mas vale explicitar a presença do processador de variáveis de ambiente introduzido (DotenvEnvironmentPostProcessor) na documentação para cobertura completa.
43-48: Especificar padrões de exclusão de endpoint no Spring Security
No momento mencionamos/api/auth/logine/api/auth/register, mas é recomendável usar/api/auth/**para cobrir possíveis futuros endpoints de autenticação.
51-67: Padronizar placeholders e convenções no exemplo de.env
Sugiro usar nomes de variáveis em uppercase sem espaços (por exemploMARITACA_API_MODEL=MODEL_NAME) e indicar que aspas só são necessárias quando há espaços.
98-101: Adicionar exemplos de requisição e resposta para autenticação
Incluir payloads de exemplo e códigos de status HTTP esperados ajudará contribuidores a testar e integrar com mais facilidade.
112-113: Uniformizar nomeação de endpoint de receitas
Avalie renomear/api/recipes/genpara/api/recipes/generatepara manter consistência sem abreviações.
118-127: Incluir instruções para Windows e permissão de execução
Para facilitar em ambientes Windows, mencionemvnw.cmd; e indiquechmod +x mvnwem Unix antes de./mvnw spring-boot:run.
133-142: Especificar uso deenv_fileno Docker Compose
Reforce que o.envdeve ser referenciado nodocker-compose.yml(viaenv_file) para garantir carregamento correto das variáveis.
165-171: Adicionar link para CONTRIBUTING e CÓDIGO DE CONDUTA
Para orientar novos contribuintes, considere referenciar umCONTRIBUTING.mde umCODE_OF_CONDUCT.mdno repositório.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
README.MD(1 hunks)pom.xml(1 hunks)src/main/java/com/otavio/aifoodapp/AiFoodAppApplication.java(1 hunks)src/main/java/com/otavio/aifoodapp/config/CorsConfig.java(0 hunks)src/main/java/com/otavio/aifoodapp/config/DotenvEnvironmentPostProcessor.java(1 hunks)src/main/java/com/otavio/aifoodapp/config/SecurityConfig.java(0 hunks)src/main/java/com/otavio/aifoodapp/controller/AuthenticationController.java(1 hunks)src/main/java/com/otavio/aifoodapp/dto/AuthenticationDTO.java(1 hunks)src/main/java/com/otavio/aifoodapp/dto/LoginResponseDTO.java(1 hunks)src/main/java/com/otavio/aifoodapp/dto/RegisterDTO.java(1 hunks)src/main/java/com/otavio/aifoodapp/model/User.java(2 hunks)src/main/java/com/otavio/aifoodapp/repository/UserRepository.java(1 hunks)src/main/java/com/otavio/aifoodapp/security/SecurityConfig.java(1 hunks)src/main/java/com/otavio/aifoodapp/security/SecurityFilter.java(1 hunks)src/main/java/com/otavio/aifoodapp/security/TokenService.java(1 hunks)src/main/java/com/otavio/aifoodapp/service/AuthorizationService.java(1 hunks)src/main/resources/META-INF/spring.factories(1 hunks)src/main/resources/application.properties(1 hunks)
💤 Files with no reviewable changes (2)
- src/main/java/com/otavio/aifoodapp/config/CorsConfig.java
- src/main/java/com/otavio/aifoodapp/config/SecurityConfig.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/com/otavio/aifoodapp/controller/AuthenticationController.java (1)
src/main/java/com/otavio/aifoodapp/dto/RegisterDTO.java (1)
RegisterDTO(5-27)
🪛 LanguageTool
README.MD
[grammar] ~19-~19: Possível erro de concordância de número.
Context: ...adas - Spring Boot: Framework para aplicações Java - Spring Data JPA: Persistência de ...
(GENERAL_NUMBER_AGREEMENT_ERRORS)
🔇 Additional comments (7)
src/main/java/com/otavio/aifoodapp/dto/RegisterDTO.java (1)
15-18: Accessor names break Java-Bean conventions – verify framework bindings.Spring’s object-mapping (e.g.,
@RequestBody→ DTO) works fine with records, but if you keep the class form, most libraries expectgetLogin(),getPassword(),getRole(). Using the currentlogin()/password()/role()style could silently break validation or Jackson serialisation in some edge cases.src/main/java/com/otavio/aifoodapp/AiFoodAppApplication.java (1)
8-8: Whitespace-only change – no functional impact.pom.xml (1)
30-41:Details
❌ Incorrect review comment
Avoid mixing
spring-boot-starter-webandspring-boot-starter-webfluxunless you really need bothHaving both starters on the class-path pulls in two servlet stacks (Spring MVC on Tomcat and Spring WebFlux on Reactor Netty).
Unless you explicitly run a hybrid application, this increases startup time, memory footprint and may lead to ambiguous handler mappings.Run a quick grep to confirm no reactive controllers are present:
If nothing is returned, consider removing the WebFlux starter.
🏁 Script executed:
#!/bin/bash fd --extension java | rg '@RestController' -A2 | rg 'org.springframework.web.reactive'Length of output: 84
🏁 Script executed:
#!/bin/bash # Search for any WebFlux or Reactor usage in the Java sources rg -n --glob '*.java' 'import org.springframework.web.reactive' rg -n --glob '*.java' 'import reactor.core.publisher' rg -n --glob '*.java' '@EnableWebFlux' rg -n --glob '*.java' 'RouterFunction' rg -n --glob '*.java' 'Mono<' rg -n --glob '*.java' 'Flux<'Length of output: 2052
Reactive WebFlux usage detected – retaining both Web and WebFlux starters is required
The codebase includes multiple reactive components that depend on Spring WebFlux and Reactor:
- WebClient usage in
src/main/java/com/otavio/aifoodapp/config/WebClientConfig.javasrc/main/java/com/otavio/aifoodapp/config/MaritacaChatClient.java- Reactor types (
Mono,Flux) in
src/main/java/com/otavio/aifoodapp/service/ChatService.javasrc/main/java/com/otavio/aifoodapp/config/MaritacaChatClient.java- Reactive controller endpoints returning
Mono<ResponseEntity<…>>in
src/main/java/com/otavio/aifoodapp/controller/RecipeController.javaSince you’re using WebFlux’s
WebClient, Reactor’sMono/Flux, and reactive controllers, you need bothspring-boot-starter-webandspring-boot-starter-webfluxon the classpath.Likely an incorrect or invalid review comment.
src/main/java/com/otavio/aifoodapp/security/TokenService.java (1)
34-45: UnhandledJWTVerificationExceptionbubbles up as 500
validateToken()throwsRuntimeException; the filter catches nothing, so an invalid token becomes a 500 instead of 401. Either:
- Return
nullon verification failure, or- Throw a custom exception and map it to
HttpStatus.UNAUTHORIZED.src/main/java/com/otavio/aifoodapp/security/SecurityConfig.java (1)
26-40: LGTM – concise stateless JWT configConfiguration is minimal yet sufficient: CSRF disabled, stateless, endpoints whitelisted, custom filter registered correctly.
README.MD (2)
15-15: Update project description to highlight security features
A descrição foi atualizada para mencionar autenticação e JWT; parece adequada e clara.
71-77: Verificar migração Flyway para tabelatb_user
Confirme se existe um script de migração que criatb_userpara evitar inconsistências entre a documentação e as migrations.
| public record LoginResponseDTO(String token, String login, String role) { | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use the enum type instead of plain String for role.
Returning UserRoles directly preserves type-safety and avoids downstream string/enum conversions.
-public record LoginResponseDTO(String token, String login, String role) {}
+import com.otavio.aifoodapp.enums.UserRoles;
+
+public record LoginResponseDTO(String token, String login, UserRoles role) {}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public record LoginResponseDTO(String token, String login, String role) { | |
| } | |
| import com.otavio.aifoodapp.enums.UserRoles; | |
| public record LoginResponseDTO(String token, String login, UserRoles role) {} |
🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/dto/LoginResponseDTO.java at lines 3 to 4,
the role field is currently a String, which reduces type safety. Change the type
of the role field from String to the enum type UserRoles to ensure type safety
and avoid unnecessary conversions. Update the record declaration accordingly to
use UserRoles for the role parameter.
| public User(String login, String password, UserRoles role) { | ||
| this.login = login; | ||
| this.password = password; | ||
| this.role = role; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Constructor leaves other non-nullable columns uninitialised
firstName, lastName, and email are declared without nullable = true/false on the column but stay null when this constructor is used.
If the DB columns are NOT NULL, inserts will fail at runtime.
public User(String login, String password, UserRoles role
- /* missing params */) {
- this.login = login;
- this.password = password;
- this.role = role;
+ , String firstName, String lastName, String email) {
+ this.login = login;
+ this.password = password;
+ this.role = role;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.email = email;
}Either supply the remaining fields or mark the DB columns nullable.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public User(String login, String password, UserRoles role) { | |
| this.login = login; | |
| this.password = password; | |
| this.role = role; | |
| } | |
| public User(String login, String password, UserRoles role, | |
| String firstName, String lastName, String email) { | |
| this.login = login; | |
| this.password = password; | |
| this.role = role; | |
| this.firstName = firstName; | |
| this.lastName = lastName; | |
| this.email = email; | |
| } |
🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/model/User.java around lines 37 to 41, the
constructor initializes only login, password, and role, leaving firstName,
lastName, and email uninitialized. Since these fields map to database columns
that are likely NOT NULL, this will cause insert failures. To fix this, either
extend the constructor to accept and initialize firstName, lastName, and email,
or update the entity annotations to mark these columns as nullable if they can
be null.
| import com.otavio.aifoodapp.model.User; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.security.core.userdetails.UserDetails; | ||
|
|
||
| import com.otavio.aifoodapp.model.User; | ||
|
|
||
| public interface UserRepository extends JpaRepository<User, Long>{ | ||
| public interface UserRepository extends JpaRepository<User, Long> { | ||
|
|
||
|
|
||
| UserDetails findByLogin(String login); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Return concrete User and keep Optional to avoid null handling
Spring-Data query methods normally return the entity type. Returning UserDetails works (covariance) but loses type information and forces manual null checks downstream.
-UserDetails findByLogin(String login);
+Optional<User> findByLogin(String login);This restores type‐safety and lets callers use orElseThrow, eliminating ad-hoc null checks.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/repository/UserRepository.java around
lines 3 to 11, change the return type of the method findByLogin from UserDetails
to Optional<User>. This improves type safety by returning the concrete User
entity wrapped in an Optional, allowing callers to handle absence of a user more
cleanly with Optional methods like orElseThrow, instead of manual null checks.
| .withExpiresAt(genExperationDate()) | ||
| .sign(algorithm); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo & public API leak: rename genExperationDate() → generateExpirationDate()
Spelling errors hurt readability and leak into stack-traces. Rename the method and fix the call site.
- .withExpiresAt(genExperationDate())
+ .withExpiresAt(generateExpirationDate())
...
- private Instant genExperationDate() {
+ private Instant generateExpirationDate() {
return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00"));
}Also applies to: 47-49
🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/security/TokenService.java around lines
26-28 and 47-49, the method name genExperationDate() contains a typo and is
publicly accessible, which can cause confusion and leak implementation details.
Rename the method to generateExpirationDate() and update all call sites
accordingly to fix the spelling and improve API clarity.
| private String recoverToken(HttpServletRequest request) { | ||
| var authHeader = request.getHeader("Authorization"); | ||
| if (authHeader == null) return null; | ||
| return authHeader.replace("Bearer ", ""); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
recoverToken should strictly check the prefix
- var authHeader = request.getHeader("Authorization");
- if (authHeader == null) return null;
- return authHeader.replace("Bearer ", "");
+ var authHeader = request.getHeader("Authorization");
+ if (authHeader == null || !authHeader.startsWith("Bearer ")) return null;
+ return authHeader.substring(7);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private String recoverToken(HttpServletRequest request) { | |
| var authHeader = request.getHeader("Authorization"); | |
| if (authHeader == null) return null; | |
| return authHeader.replace("Bearer ", ""); | |
| } | |
| private String recoverToken(HttpServletRequest request) { | |
| var authHeader = request.getHeader("Authorization"); | |
| if (authHeader == null || !authHeader.startsWith("Bearer ")) return null; | |
| return authHeader.substring(7); | |
| } |
🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/security/SecurityFilter.java around lines
46 to 50, the recoverToken method currently removes the "Bearer " prefix without
verifying it is present. Update the method to first check if the Authorization
header starts exactly with "Bearer " and only then remove the prefix and return
the token; otherwise, return null. This ensures the token is only extracted when
the header format is correct.
| var token = this.recoverToken(request); | ||
| if (token != null) { | ||
| var login = tokenService.validateToken(token); | ||
| if (login != null && !login.isEmpty()) { | ||
| var userExists = userRepository.findByLogin(login); | ||
| if (userExists != null) { | ||
| UserDetails user = userExists; | ||
| var authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); | ||
| SecurityContextHolder.getContext().setAuthentication(authentication); | ||
| } | ||
| } | ||
| } | ||
| filterChain.doFilter(request, response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gracefully handle malformed / missing Bearer tokens
tokenService.validateToken() is invoked for any non-null Authorization header, even if it doesn’t start with Bearer . This throws and aborts the request pipeline.
- var token = this.recoverToken(request);
- if (token != null) {
+ var token = this.recoverToken(request);
+ if (token != null && !token.isBlank()) {
var login = tokenService.validateToken(token);Also consider surrounding validateToken with try/catch to convert verification failures into 401.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| var token = this.recoverToken(request); | |
| if (token != null) { | |
| var login = tokenService.validateToken(token); | |
| if (login != null && !login.isEmpty()) { | |
| var userExists = userRepository.findByLogin(login); | |
| if (userExists != null) { | |
| UserDetails user = userExists; | |
| var authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); | |
| SecurityContextHolder.getContext().setAuthentication(authentication); | |
| } | |
| } | |
| } | |
| filterChain.doFilter(request, response); | |
| // … earlier in the filter … | |
| var token = this.recoverToken(request); | |
| if (token != null && !token.isBlank()) { | |
| var login = tokenService.validateToken(token); | |
| if (login != null && !login.isEmpty()) { | |
| var userExists = userRepository.findByLogin(login); | |
| if (userExists != null) { | |
| UserDetails user = userExists; | |
| var authentication = new UsernamePasswordAuthenticationToken( | |
| user, | |
| null, | |
| user.getAuthorities() | |
| ); | |
| SecurityContextHolder.getContext().setAuthentication(authentication); | |
| } | |
| } | |
| } | |
| filterChain.doFilter(request, response); |
🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/security/SecurityFilter.java around lines
31 to 43, the code calls tokenService.validateToken() on any non-null token
without verifying it starts with "Bearer ", causing exceptions on malformed
tokens. To fix this, first check if the Authorization header starts with "Bearer
" before extracting and validating the token. Additionally, wrap the
validateToken call in a try/catch block to catch verification exceptions and
respond with a 401 Unauthorized status instead of aborting the request pipeline.
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import javax.validation.Valid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use jakarta.validation.Valid with Spring Boot 3
Boot 3 ships with Jakarta EE 9; mixing javax.validation may lead to NoSuchMethodError at runtime if a legacy artifact sneaks in.
-import javax.validation.Valid;
+import jakarta.validation.Valid;🤖 Prompt for AI Agents
In src/main/java/com/otavio/aifoodapp/controller/AuthenticationController.java
at line 18, replace the import statement from javax.validation.Valid to
jakarta.validation.Valid to ensure compatibility with Spring Boot 3 and avoid
runtime errors caused by mixing legacy javax packages with Jakarta EE 9.
| - `GET /api/foods/list`: Lista alimentos | ||
| - `GET /api/foods/list/{id}`: Busca alimento por ID | ||
| - `PUT /api/foods/update`: Atualiza alimento | ||
| - `DELETE /api/foods/delete/{id}`: Remove alimento | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Revisar convenção REST nos endpoints de alimentos
Em vez de usar /api/foods/create, considere POST /api/foods para seguir a convenção sem verbos na URL.
🤖 Prompt for AI Agents
In README.MD around lines 104 to 108, the REST API endpoints for foods use verbs
in the URL paths, which is against REST conventions. Update the endpoints to
remove verbs by using HTTP methods to indicate actions: replace
`/api/foods/create` with `POST /api/foods`, `/api/foods/update` with `PUT
/api/foods/{id}`, and `/api/foods/delete/{id}` with `DELETE /api/foods/{id}`.
Adjust the documentation accordingly to reflect these standard RESTful patterns.
Summary by CodeRabbit
.envfiles.