From 345afab12f96acc0d67d20b979ddb899c45d6e49 Mon Sep 17 00:00:00 2001 From: Devon Hillard Date: Fri, 14 Aug 2026 23:02:33 -0600 Subject: [PATCH] chore: adopt ds-spring-user-framework 5.3.0 on Spring Boot 4.1.0 Spring Boot 4.0.4 -> 4.1.0 brings Thymeleaf 3.1.2 -> 3.1.5, which evaluates templates in a restricted expression context while the layout dialect decorates the page and rejects SpEL bean access. Every ${@environment.getProperty('user.security.*')} and ${@environment.acceptsProfiles(...)} usage threw TemplateProcessingException at render time. - bump Spring Boot to 4.1.0 and ds-spring-user-framework to 5.3.0 - migrate templates to the framework's new ${userSecurity.*} view (login/registration/forgot-password/update page URIs, loginActionURI, copyrightFirstYear) across index, layout, header/footer fragments, user register/login/registration-pending-verification/ request-new-verification-email, and event details - add DemoTemplateModelAdvice exposing ${devOrLocalProfile} for the profile check, which is not a user.security value - update CustomUserEmailService super() for the 5.3.0 UserEmailService constructor Verified: ./gradlew clean test --refresh-dependencies (301 tests, 0 failures); Playwright chromium 107 passed, chromium-mfa 1 passed. --- build.gradle | 4 +-- .../demo/service/CustomUserEmailService.java | 7 ++-- .../demo/web/DemoTemplateModelAdvice.java | 32 +++++++++++++++++++ .../resources/templates/event/details.html | 4 +-- .../resources/templates/fragments/footer.html | 2 +- .../resources/templates/fragments/header.html | 8 ++--- src/main/resources/templates/index.html | 4 +-- src/main/resources/templates/layout.html | 4 +-- src/main/resources/templates/user/login.html | 6 ++-- .../resources/templates/user/register.html | 4 +-- .../registration-pending-verification.html | 2 +- .../user/request-new-verification-email.html | 2 +- 12 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/digitalsanctuary/spring/demo/web/DemoTemplateModelAdvice.java diff --git a/build.gradle b/build.gradle index f26e113..e5b3044 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '4.0.4' + id 'org.springframework.boot' version '4.1.0' id 'io.spring.dependency-management' version '1.1.7' id "com.github.ben-manes.versions" version "0.61.0" @@ -39,7 +39,7 @@ repositories { dependencies { // DigitalSanctuary Spring User Framework - implementation 'com.digitalsanctuary:ds-spring-user-framework:5.2.0' + implementation 'com.digitalsanctuary:ds-spring-user-framework:5.3.0' // WebAuthn support (Passkey authentication) implementation 'org.springframework.security:spring-security-webauthn' diff --git a/src/main/java/com/digitalsanctuary/spring/demo/service/CustomUserEmailService.java b/src/main/java/com/digitalsanctuary/spring/demo/service/CustomUserEmailService.java index 067701b..fdb779a 100644 --- a/src/main/java/com/digitalsanctuary/spring/demo/service/CustomUserEmailService.java +++ b/src/main/java/com/digitalsanctuary/spring/demo/service/CustomUserEmailService.java @@ -14,6 +14,7 @@ import com.digitalsanctuary.spring.user.mail.MailService; import com.digitalsanctuary.spring.user.service.SessionInvalidationService; import com.digitalsanctuary.spring.user.service.TokenHasher; +import com.digitalsanctuary.spring.user.security.UserSecurityConfigProperties; import com.digitalsanctuary.spring.user.service.UserEmailService; import com.digitalsanctuary.spring.user.service.UserVerificationService; @@ -40,8 +41,10 @@ public CustomUserEmailService( UserRepository userRepository, ApplicationEventPublisher eventPublisher, SessionInvalidationService sessionInvalidationService, - TokenHasher tokenHasher) { - super(mailService, userVerificationService, passwordTokenRepository, userRepository, eventPublisher, sessionInvalidationService, tokenHasher); + TokenHasher tokenHasher, + UserSecurityConfigProperties userSecurityConfig) { + super(mailService, userVerificationService, passwordTokenRepository, userRepository, eventPublisher, sessionInvalidationService, tokenHasher, + userSecurityConfig); } @Override diff --git a/src/main/java/com/digitalsanctuary/spring/demo/web/DemoTemplateModelAdvice.java b/src/main/java/com/digitalsanctuary/spring/demo/web/DemoTemplateModelAdvice.java new file mode 100644 index 0000000..153660f --- /dev/null +++ b/src/main/java/com/digitalsanctuary/spring/demo/web/DemoTemplateModelAdvice.java @@ -0,0 +1,32 @@ +package com.digitalsanctuary.spring.demo.web; + +import org.springframework.core.env.Environment; +import org.springframework.core.env.Profiles; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ModelAttribute; + +import lombok.RequiredArgsConstructor; + +/** + * Exposes demo-only, non-{@code user.security} template values that cannot come from the framework's + * {@code ${userSecurity}} view. + * + *

Specifically {@code devOrLocalProfile}: templates previously used + * {@code ${@environment.acceptsProfiles('dev','local')}}, which Spring Boot 4.1.0's Thymeleaf 3.1.5 + * rejects as SpEL bean access in the restricted (layout-decorated) expression context. Exposing the + * boolean as a model attribute keeps the check working as an ordinary variable reference.

+ */ +@ControllerAdvice +@RequiredArgsConstructor +public class DemoTemplateModelAdvice { + + private final Environment environment; + + /** + * @return true when the {@code dev} or {@code local} profile is active + */ + @ModelAttribute("devOrLocalProfile") + public boolean devOrLocalProfile() { + return environment.acceptsProfiles(Profiles.of("dev", "local")); + } +} diff --git a/src/main/resources/templates/event/details.html b/src/main/resources/templates/event/details.html index cbca83c..46e0485 100644 --- a/src/main/resources/templates/event/details.html +++ b/src/main/resources/templates/event/details.html @@ -46,8 +46,8 @@

Event Name

To register for the event, please - Log In or - Log In or + Register.

diff --git a/src/main/resources/templates/fragments/footer.html b/src/main/resources/templates/fragments/footer.html index 72c51f0..c8617f2 100644 --- a/src/main/resources/templates/fragments/footer.html +++ b/src/main/resources/templates/fragments/footer.html @@ -6,7 +6,7 @@

- - + -

diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html index 607dae0..ea4866c 100644 --- a/src/main/resources/templates/fragments/header.html +++ b/src/main/resources/templates/fragments/header.html @@ -21,7 +21,7 @@