Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ tasks.named('jar') {
archiveClassifier.set('')
}

// Configure Javadoc to suppress warnings for missing constructor documentation
// This is necessary because Lombok generates constructors that cannot be documented
tasks.withType(Javadoc).configureEach {
options.addStringOption('Xdoclint:all,-missing', '-quiet')
}

def registerJdkTestTask(name, jdkVersion) {
tasks.register(name, Test) {
javaLauncher.set(javaToolchains.launcherFor {
Expand Down
6 changes: 6 additions & 0 deletions lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# This file configures Lombok for the project
# See https://projectlombok.org/features/configuration

# Add @Generated annotation to all Lombok-generated code
# This suppresses Javadoc warnings about missing constructor documentation
lombok.addLombokGeneratedAnnotation = true
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import org.springframework.core.type.AnnotationMetadata;

/**
* {@code UserAutoConfigurationRegistrar} dynamically registers the base package of this library with Spring Boot to ensure that its entities,
* Dynamically registers the base package of this library with Spring Boot to ensure that its entities,
* repositories, and other Spring-managed components are properly detected and included in the application context.
*
* <p>
* This class is designed to simplify the integration of the library into Spring Boot applications by automatically registering the library's base
* package (<i>com.digitalsanctuary.spring.user</i>) for component scanning. It ensures that:
* This class simplifies integration by automatically registering the library's base
* package ({@code com.digitalsanctuary.spring.user}) for component scanning. It ensures that:
* <ul>
* <li>The library's repositories and entities are discovered and configured correctly.</li>
* <li>The consuming application retains its ability to automatically detect its own repositories and entities.</li>
Expand All @@ -24,6 +24,8 @@
* <p>
* <b>Note:</b> This solution leverages {@link AutoConfigurationPackages#register} to dynamically register the library's package during the
* auto-configuration phase, ensuring compatibility with Spring Boot's component scanning and auto-configuration mechanisms.
*
* <p>Default constructor creates an instance of this registrar.</p>

Copilot AI Jan 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment "Default constructor creates an instance of this registrar" is unnecessary. This class doesn't have any dependencies and uses the implicit Java-generated default constructor. This comment adds no value and should be removed.

Suggested change
*
* <p>Default constructor creates an instance of this registrar.</p>

Copilot uses AI. Check for mistakes.
*/
public class UserAutoConfigurationRegistrar implements ImportBeanDefinitionRegistrar {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
import lombok.extern.slf4j.Slf4j;

/**
* The UserConfiguration class is a Spring Boot configuration class that provides configuration for the DigitalSanctuary Spring Boot User Framework
* Library. This class is used to configure the user framework library, including enabling asynchronous processing and scheduling, and scanning for
* components and repositories.
* Main auto-configuration class for the DigitalSanctuary Spring Boot User Framework Library.
* Enables asynchronous processing, retry support, scheduling, method-level security,
* and component scanning for the user framework package.
*
* <p>Default constructor creates an instance of this configuration.</p>
*

Copilot AI Jan 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment "Default constructor creates an instance of this configuration" is unnecessary and potentially misleading. This class uses Lombok's @DaTa annotation which generates a constructor. With the lombok.config setting adding @generated annotation, JavaDoc warnings for Lombok-generated constructors should already be suppressed. This explicit constructor comment should be removed.

Suggested change
* <p>Default constructor creates an instance of this configuration.</p>
*

Copilot uses AI. Check for mistakes.
* @see UserAutoConfigurationRegistrar
*/
@Slf4j
@Configuration
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/com/digitalsanctuary/spring/user/api/UserAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@
import lombok.extern.slf4j.Slf4j;

/**
* REST controller for managing user-related operations. This class handles user
* registration, account deletion, and other user-related endpoints.
* REST API controller for user management operations.
* <p>
* Provides JSON endpoints for user registration, authentication, profile updates,
* password management, and account deletion. All endpoints are mapped under
* {@code /user} and return JSON responses.
* </p>
*
* @author Digital Sanctuary
* @see UserService
* @see UserEmailService
*/
@Slf4j
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,31 @@
import lombok.Data;

/**
* The AuditConfig class is a Spring Boot configuration class that provides properties for configuring user audit logging. This class is used to
* define properties that control the behavior of the audit logging, such as the log file path and the flush rate.
* Configuration properties for the user audit logging system.
*
* <p>This class defines properties that control the behavior of audit logging,
* including the log file path, flush behavior, and event logging toggle.
* Properties are bound from the {@code user.audit.*} prefix in application configuration.
*
* <p>The class uses Lombok's {@code @Data} annotation which generates getters, setters,
* and a default no-argument constructor.
*
* @see AuditLogWriter
* @see AuditEventListener
*/
@Data
@Component
@PropertySource("classpath:config/dsspringuserconfig.properties")
@ConfigurationProperties(prefix = "user.audit")
public class AuditConfig {

/**
* Creates a new AuditConfig instance with default values.
*/
public AuditConfig() {
// Default constructor for Spring configuration binding
}

/**

Copilot AI Jan 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This explicit constructor is redundant and contradicts the approach used in the PR. Since this class uses Lombok's @DaTa annotation and the lombok.config file is configured to add @generated annotations to Lombok-generated code, the Lombok-generated constructor should already be excluded from JavaDoc warnings. This manually added constructor should be removed to maintain consistency with other @Data-annotated classes in the codebase (like RolesAndPrivilegesConfig which doesn't have an explicit constructor).

Suggested change
* Creates a new AuditConfig instance with default values.
*/
public AuditConfig() {
// Default constructor for Spring configuration binding
}
/**

Copilot uses AI. Check for mistakes.
* The enabled flag. If set to false, audit logging will be disabled.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,43 @@
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* This class processes AuditEvents. This class writes the AuditEvent data to a text file on the server. You could easily change the logic to write to
* a database, send events to a REST API, or anything else.
* Spring event listener that processes {@link AuditEvent} instances asynchronously.
*
* <p>This component listens for audit events and delegates the writing of event data
* to an {@link AuditLogWriter} implementation. The processing is asynchronous to avoid
* impacting application performance.
*
* <p>The listener only processes events when audit logging is enabled via
* {@code AuditConfig.isLogEvents()}. All exceptions are caught and logged to ensure
* audit failures never impact application flow.
*
* @see AuditEvent
* @see AuditLogWriter
* @see AuditConfig
*/
@Slf4j
@Async
@Component
@RequiredArgsConstructor
public class AuditEventListener {

private final AuditConfig auditConfig;

private final AuditLogWriter auditLogWriter;

/**
* Creates a new AuditEventListener with the required dependencies.
*
* @param auditConfig the audit configuration
* @param auditLogWriter the audit log writer
*/
public AuditEventListener(AuditConfig auditConfig, AuditLogWriter auditLogWriter) {
this.auditConfig = auditConfig;
this.auditLogWriter = auditLogWriter;
}

Copilot AI Jan 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent approach to handling JavaDoc warnings. This class removes @requiredargsconstructor and adds a manual constructor with documentation, while other similar classes keep @requiredargsconstructor and rely on lombok.config and build.gradle settings to suppress warnings.

For consistency with the rest of the codebase (e.g., UserAPI, RegistrationListener which keep @requiredargsconstructor), this class should also keep @requiredargsconstructor. The lombok.config and build.gradle settings should be sufficient to suppress JavaDoc warnings for Lombok-generated constructors.

Copilot uses AI. Check for mistakes.

/**
* Handle the AuditEvents.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,42 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* The FileAuditLogFlushScheduler class is a Spring Boot component that flushes the audit log buffer to the file. This class is used to ensure that
* the audit log buffer is flushed periodically to balance performance with data integrity.
*
* <p><strong>Conditional Activation Logic:</strong></p>
* <p>This scheduler is only active when BOTH conditions are met:</p>
* Scheduled task that periodically flushes the audit log buffer to disk.
*
* <p>This component ensures buffered audit data is written to the file at regular intervals,
* balancing write performance with data integrity.
*
* <p><strong>Conditional Activation:</strong> This scheduler is only active when both conditions are met:
* <ul>
* <li><code>user.audit.logEvents=true</code> (audit logging is enabled) AND</li>
* <li><code>user.audit.flushOnWrite=false</code> (immediate flush is disabled)</li>
* <li>{@code user.audit.logEvents=true} - audit logging is enabled</li>
* <li>{@code user.audit.flushOnWrite=false} - immediate flush is disabled</li>
* </ul>
*
* <p><strong>Why this conditional logic?</strong></p>
* <ul>
* <li>If audit logging is disabled (<code>logEvents=false</code>), no scheduler is needed</li>
* <li>If flush-on-write is enabled (<code>flushOnWrite=true</code>), logs are flushed immediately after each write,
* so periodic flushing is unnecessary and would be redundant</li>
* <li>Only when audit logging is enabled AND flush-on-write is disabled do we need this periodic scheduler
* to ensure buffered data gets written to disk at regular intervals</li>
* </ul>
*
* <p>The flush frequency is controlled by <code>user.audit.flushRate</code> (in milliseconds).</p>
*
* <p>When flush-on-write is enabled, logs are flushed immediately after each write,
* making this scheduler unnecessary. The flush frequency is controlled by
* {@code user.audit.flushRate} (in milliseconds).
*
* @see FileAuditLogWriter
* @see AuditConfig
*/
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnExpression("${user.audit.logEvents:true} && !${user.audit.flushOnWrite:true}")
public class FileAuditLogFlushScheduler {

private final FileAuditLogWriter fileAuditLogWriter;

/**
* The file audit log writer. This is the writer that is used to write audit log events to the file.
* Creates a new FileAuditLogFlushScheduler with the required dependencies.
*
* @param fileAuditLogWriter the file audit log writer to flush
*/
private final FileAuditLogWriter fileAuditLogWriter;
public FileAuditLogFlushScheduler(FileAuditLogWriter fileAuditLogWriter) {
this.fileAuditLogWriter = fileAuditLogWriter;
}

Copilot AI Jan 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent approach to handling JavaDoc warnings. This class removes @requiredargsconstructor and adds a manual constructor with documentation, while other similar classes keep @requiredargsconstructor and rely on lombok.config and build.gradle settings to suppress warnings.

For consistency with the rest of the codebase (e.g., UserAPI, RegistrationListener, AuthenticationEventListener which keep @requiredargsconstructor), this class should also keep @requiredargsconstructor. The lombok.config and build.gradle settings should be sufficient to suppress JavaDoc warnings for Lombok-generated constructors.

Copilot uses AI. Check for mistakes.

/**
* Flushes the audit log buffer to the file. This method is called on a schedule to ensure that the buffer is flushed periodically to balance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,42 @@
import org.springframework.util.StringUtils;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* Implementation of {@link AuditLogWriter} that writes audit logs to a file. This class handles the lifecycle of the log file, including opening,
* writing, and closing the file. It also supports scheduled flushing of the buffer to balance performance with data integrity.
* File-based implementation of {@link AuditLogWriter} that writes audit events to a log file.
*
* <p>This component manages the complete lifecycle of the audit log file, including:
* <ul>
* <li>Opening and creating the log file on startup ({@code @PostConstruct})</li>
* <li>Writing formatted audit events with pipe-delimited fields</li>
* <li>Periodic buffer flushing via {@link FileAuditLogFlushScheduler}</li>
* <li>Graceful cleanup on shutdown ({@code @PreDestroy})</li>
* </ul>
*
* <p>If the configured log path is not writable, the writer falls back to a temporary
* directory location.
*
* @see AuditLogWriter
* @see AuditConfig
* @see FileAuditLogFlushScheduler
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class FileAuditLogWriter implements AuditLogWriter {

private final AuditConfig auditConfig;
private BufferedWriter bufferedWriter;

/**
* Creates a new FileAuditLogWriter with the required dependencies.
*
* @param auditConfig the audit configuration
*/
public FileAuditLogWriter(AuditConfig auditConfig) {
this.auditConfig = auditConfig;
}

Copilot AI Jan 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent approach to handling JavaDoc warnings. This class removes @requiredargsconstructor and adds a manual constructor with documentation, while other similar classes (e.g., UserAPI, UserPageController, UserActionController) keep @requiredargsconstructor and rely on lombok.config and build.gradle settings to suppress warnings.

Either all classes with @requiredargsconstructor should have manual constructors added (which would be verbose and defeat the purpose of Lombok), or this class should keep @requiredargsconstructor for consistency. The lombok.config setting lombok.addLombokGeneratedAnnotation = true combined with the build.gradle Javadoc configuration should be sufficient to suppress warnings for all Lombok-generated constructors.

Copilot uses AI. Check for mistakes.

/**
* Initializes the log file writer. This method is called after the bean is constructed. It validates the configuration and opens the log file for
* writing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@
import lombok.extern.slf4j.Slf4j;

/**
* The UserActionController handles non-API, non-Page requests like token
* validation links from emails.
* Controller that handles user action requests triggered by email links.
* <p>
* This controller processes token-based actions such as email verification
* during registration and password reset token validation. These endpoints
* are typically accessed when users click links in system-generated emails.
* </p>
*
* @author Digital Sanctuary
* @see UserService
* @see UserVerificationService
*/
@Slf4j
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@
import lombok.extern.slf4j.Slf4j;

/**
* The UserPageController for the user management pages.
* MVC controller that serves user management HTML pages.
* <p>
* Handles page rendering for login, registration, password reset,
* profile update, and account management views. Each method returns
* a Thymeleaf template name for the corresponding user interface page.
* </p>
*
* @author Digital Sanctuary
*/
@Slf4j
@RequiredArgsConstructor
Expand Down Expand Up @@ -143,10 +150,12 @@ public String forgotPasswordChange() {


/**
* Displays the user profile update page with pre-populated user data.
*
* @param userDetails the user details
* @param request the request
* @param model the model
* @return String
* @return the view name for the update user page
*/
@GetMapping("${user.security.updateUserURI:/user/update-user.html}")
public String updateUser(@AuthenticationPrincipal DSUserDetails userDetails, final HttpServletRequest request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import lombok.ToString;

/**
* A new password dto. This object is used for password form actions (change password, forgot password token, save
* password, etc..).
* Data Transfer Object for password change operations.
* <p>
* Used for password form actions including change password and forgot password token flows.
* Contains the old password, new password, and optional reset token.
* </p>
*
* @author Digital Sanctuary
*/
@Data
public class PasswordDto {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
import lombok.Data;

/**
* DTO for password reset requests. Contains only the email field needed for initiating a password reset.
* Data Transfer Object for initiating password reset requests.
* <p>
* Contains only the email field needed to start the password reset flow.
* The email is validated for format and length constraints.
* </p>
*
* @author Digital Sanctuary
*/
@Data
public class PasswordResetRequestDto {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@

/**
* Data Transfer Object for saving a new password after password reset.
* <p>
* Used in the password reset flow after the user clicks the link in their email
* and enters a new password.
* and enters a new password. Contains the reset token and the new password with confirmation.
* </p>
*
* @author Digital Sanctuary
*/
@Data
public class SavePasswordDto {
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/digitalsanctuary/spring/user/dto/UserDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
import lombok.ToString;

/**
* A user dto. This object is used for handling user related form data (registration, forms passing in email addresses,
* etc...).
* Data Transfer Object for user registration and related form data.
* <p>
* Used for handling user registration forms and related operations. Contains user details
* including name, email, password with confirmation, and optional role assignment.
* Validated using {@link PasswordMatches} to ensure password confirmation matches.
* </p>
*
* @author Digital Sanctuary
*/
@Data
@PasswordMatches
Expand Down
Loading
Loading