Skip to content

Commit d00e649

Browse files
devondragonclaude
andcommitted
Complete additional high-priority framework fixes
- Fix registration email base URL in UserAPI.publishRegistrationEvent - Configure security remember-me as opt-in with explicit key requirement - Remove misleading @async annotations from event POJO classes These changes improve email link generation, security configuration, and remove confusing annotations that have no effect on POJOs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 451d6f5 commit d00e649

5 files changed

Lines changed: 21 additions & 10 deletions

File tree

FIXES.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,20 @@
2222
- **Fix**: Add synchronized blocks to protect concurrent access
2323
- **Status**: Fixed - added synchronized keyword to writeLog(), flushWriter(), setup(), and cleanup() methods
2424

25-
### 5. Fix registration email base URL
25+
### 5. Fix registration email base URL ✅ COMPLETED
2626
- **Issue**: UserAPI.publishRegistrationEvent uses request.getContextPath() (broken links)
2727
- **Fix**: Use UserUtils.getAppUrl(request) like other flows
28+
- **Status**: Fixed - updated publishRegistrationEvent to use UserUtils.getAppUrl(request) for complete URL construction
2829

29-
### 6. Configure security remember-me properly
30+
### 6. Configure security remember-me properly ✅ COMPLETED
3031
- **Issue**: Uses random key per startup, invalidates on restart
3132
- **Fix**: Make opt-in with explicit key configuration
33+
- **Status**: Fixed - added user.security.rememberMe.enabled and user.security.rememberMe.key properties, remember-me is now only enabled when explicitly configured
3234

33-
### 7. Remove @Async from event classes
35+
### 7. Remove @Async from event classes ✅ COMPLETED
3436
- **Issue**: @Async on POJOs has no effect (false impression)
3537
- **Fix**: Remove from AuditEvent and OnRegistrationCompleteEvent classes
38+
- **Status**: Fixed - removed @Async annotation and import from both AuditEvent and OnRegistrationCompleteEvent classes
3639

3740
## Security & API Issues (Priority 2)
3841

src/main/java/com/digitalsanctuary/spring/user/api/UserAPI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ private void logoutUser(HttpServletRequest request) {
257257
* @param request the HTTP servlet request
258258
*/
259259
private void publishRegistrationEvent(User user, HttpServletRequest request) {
260-
String appUrl = request.getContextPath();
260+
String appUrl = UserUtils.getAppUrl(request);
261261
eventPublisher.publishEvent(new OnRegistrationCompleteEvent(user, request.getLocale(), appUrl));
262262
}
263263

src/main/java/com/digitalsanctuary/spring/user/audit/AuditEvent.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.Date;
44
import org.springframework.context.ApplicationEvent;
5-
import org.springframework.scheduling.annotation.Async;
65
import com.digitalsanctuary.spring.user.persistence.model.User;
76
import lombok.Builder;
87
import lombok.EqualsAndHashCode;
@@ -12,7 +11,6 @@
1211
* The AuditEvent class is used to record security audit events and actions. It can be created and sent from any code, and is captured by the
1312
* AuditEventListener for handling and persistence.
1413
*/
15-
@Async
1614
@Getter
1715
@EqualsAndHashCode(callSuper = false)
1816
public class AuditEvent extends ApplicationEvent {

src/main/java/com/digitalsanctuary/spring/user/event/OnRegistrationCompleteEvent.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.Locale;
44
import org.springframework.context.ApplicationEvent;
5-
import org.springframework.scheduling.annotation.Async;
65
import com.digitalsanctuary.spring.user.persistence.model.User;
76
import lombok.Builder;
87
import lombok.Data;
@@ -12,7 +11,6 @@
1211
* The OnRegistrationCompleteEvent class is triggered when a user registers. We are using to send the registration verification email, if enabled,
1312
* asynchronously. You can also listen for this event and perform any other post-registration processing desired.
1413
*/
15-
@Async
1614
@Data
1715
@EqualsAndHashCode(callSuper = false)
1816
public class OnRegistrationCompleteEvent extends ApplicationEvent {

src/main/java/com/digitalsanctuary/spring/user/security/WebSecurityConfig.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ public class WebSecurityConfig {
109109
@Value("${user.security.bcryptStrength}")
110110
private int bcryptStrength = 10;
111111

112+
@Value("${user.security.rememberMe.enabled:false}")
113+
private boolean rememberMeEnabled;
114+
115+
@Value("${user.security.rememberMe.key:#{null}}")
116+
private String rememberMeKey;
117+
112118

113119
private final UserDetailsService userDetailsService;
114120
private final LoginSuccessService loginSuccessService;
@@ -133,8 +139,14 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
133139
log.debug("WebSecurityConfig.configure: enhanced unprotectedURIs: {}", unprotectedURIs.toString());
134140

135141
http.formLogin(
136-
formLogin -> formLogin.loginPage(loginPageURI).loginProcessingUrl(loginActionURI).successHandler(loginSuccessService).permitAll())
137-
.rememberMe(withDefaults());
142+
formLogin -> formLogin.loginPage(loginPageURI).loginProcessingUrl(loginActionURI).successHandler(loginSuccessService).permitAll());
143+
144+
// Configure remember-me only if explicitly enabled and key is provided
145+
if (rememberMeEnabled && rememberMeKey != null && !rememberMeKey.trim().isEmpty()) {
146+
http.rememberMe(rememberMe -> rememberMe
147+
.key(rememberMeKey)
148+
.userDetailsService(userDetailsService));
149+
}
138150

139151
http.logout(logout -> logout.logoutUrl(logoutActionURI).logoutSuccessUrl(logoutSuccessURI).invalidateHttpSession(true)
140152
.deleteCookies("JSESSIONID"));

0 commit comments

Comments
 (0)