Skip to content

Phase 5 + 6: Spring Boot 1.5 → 3.3 / Java 17 / Jakarta + Spring Security 6 rewrite - #51

Open
devin-ai-integration[bot] wants to merge 2 commits into
devin/1783889597-phase4-security-hardeningfrom
devin/1783889887-phase5-backend-upgrade
Open

devin-ai-integration[bot] wants to merge 2 commits into
devin/1783889597-phase4-security-hardeningfrom
devin/1783889887-phase5-backend-upgrade

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 12, 2026

Copy link
Copy Markdown

Summary

Incremental backend framework upgrade (stacked on the Phase 4 PR #50). Done in two verified hops, each with all 37 integration tests green, then the Spring Security 6 rewrite (Phase 6) folded into the 3.x step per the plan.

Phase 5a — Spring Boot 1.5.4 → 2.7.18 (still Java 8, javax.*)

  • spring-boot-starter-parent2.7.18.
  • MySQL driver coords mysql:mysql-connector-javacom.mysql:mysql-connector-j.
  • CrudRepository.findOne(id) (removed) → findById(id).orElse(null).
  • Extract BCryptPasswordEncoder into PasswordEncoderConfigSecurityConfig both defined and consumed it, which is a self-referential bean cycle now that Boot 2.6+ prohibits circular references.
  • spring.main.allow-circular-references=true for the genuine mutual UserServiceAccountServiceTransactionService dependencies (documented; refactoring the service graph is out of scope for a safety-net upgrade).
  • Add junit-vintage-engine so the JUnit 4 safety-net suite runs on the JUnit 5 platform.
  • H2 test URL NON_KEYWORDS=USER (H2 2.x now reserves USER, and the User entity maps to table user).

Phase 5b — Spring Boot 2.7.18 → 3.3.5, Java 17, Jakarta

  • Parent → 3.3.5, java.version17; CI backend job → JDK 17.
  • Migrate every javax.persistence / javax.servlet import to jakarta.* across the 9 domain classes.
  • Hibernate 6 removed MySQL5DialectMySQLDialect.

Phase 6 — Spring Security 6 rewrite

-public class SecurityConfig extends WebSecurityConfigurerAdapter {
-  @Override protected void configure(HttpSecurity http) { http.csrf().disable().cors().disable()... }
-  @Autowired void configureGlobal(AuthenticationManagerBuilder auth) {...}
+public class SecurityConfig {
+  @Bean DaoAuthenticationProvider authenticationProvider() {...}
+  @Bean SecurityFilterChain filterChain(HttpSecurity http) {...}
+  @Bean CorsConfigurationSource corsConfigurationSource() {...}
  • @EnableGlobalMethodSecurity@EnableMethodSecurity.
  • CSRF enabled (was .csrf().disable()). Server-rendered Thymeleaf forms get the token automatically via th:action; the cross-origin /api/** SPA namespace is exempted (ignoringRequestMatchers) and relies on the CORS allowlist + authenticated session.
  • CORS via Spring Security with an explicit http://localhost:4200 allowlist (methods/headers/credentials mirror the old filter), and the hand-rolled RequestFilter is removed.
  • Fixed the invalid /error/**/* matcher (Spring 6 PathPattern requires ** to be terminal) → /error/**.

Follow-ups / coordination

  • Existing password hashes were made with the (now-removed) fixed BCrypt salt (Phase 4) and won't verify — reset/re-seed users.
  • The Angular AdminPortal must send the CSRF token and adapt to the retired filter's behavior; that's Phase 7 frontend work. Its /index login and full SPA CSRF integration are deferred there.

Verified: mvn clean test on JDK 17 → 37 tests, 0 failures; Spring context loads with the new security config.

Link to Devin session: https://app.devin.ai/sessions/82be2e41fda54343a20a9b73e01c0631
Requested by: @gaelkekatos-jpg


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)

devin-ai-integration Bot and others added 2 commits July 12, 2026 21:00
- Bump spring-boot-starter-parent to 2.7.18, keep javax.* and Java 8
- Switch MySQL driver to com.mysql:mysql-connector-j coordinates
- Add junit-vintage-engine so the JUnit 4 safety-net tests run on JUnit 5 platform
- Replace removed CrudRepository.findOne(id) with findById(id).orElse(null)
- Extract BCryptPasswordEncoder into PasswordEncoderConfig to break the
  SecurityConfig self-referential bean cycle (prohibited since Boot 2.6)
- allow-circular-references=true for the mutual service-layer dependencies
- H2 test URL: NON_KEYWORDS=USER (H2 2.x reserves USER)

All 37 backend tests pass on Java 8.

Co-Authored-By: Gael Kekatos <gael.kekatos@cognition.ai>
…curity 6 (Phase 5b & 6)

Phase 5b:
- spring-boot-starter-parent 2.7.18 -> 3.3.5, java.version 17
- Migrate all javax.persistence/javax.servlet imports to jakarta.* across the
  9 domain classes
- Hibernate 6 dialect: MySQL5Dialect (removed) -> MySQLDialect
- CI backend job now runs on JDK 17

Phase 6 (Spring Security 6 rewrite):
- Drop WebSecurityConfigurerAdapter; define a SecurityFilterChain bean and a
  DaoAuthenticationProvider instead of configureGlobal
- EnableGlobalMethodSecurity -> EnableMethodSecurity
- Enable CSRF (Spring Security default); exempt the cross-origin /api/** SPA
  namespace (relies on CORS allowlist + session), full SPA CSRF is Phase 7
- Configure CORS via Spring Security with an explicit http://localhost:4200
  allowlist and retire the hand-rolled RequestFilter
- Fix invalid /error/**/* matcher for the Spring 6 PathPattern parser

All 37 backend tests pass on Java 17.

Co-Authored-By: Gael Kekatos <gael.kekatos@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants