Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
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.
*
* @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 Devon Hillard
* @see UserService
* @see UserEmailService
*/
@Slf4j
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,30 @@
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}")
@RequiredArgsConstructor
public class FileAuditLogFlushScheduler {

/**
* The file audit log writer. This is the writer that is used to write audit log events to the file.
*/
private final FileAuditLogWriter fileAuditLogWriter;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,22 @@
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
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 Devon Hillard
* @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 Devon Hillard
*/
@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 Devon Hillard
*/
@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 Devon Hillard
*/
@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 Devon Hillard
*/
@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 Devon Hillard
*/
@Data
@PasswordMatches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
import lombok.Data;

/**
* DTO for updating user profile information (first name, last name).
* This is separate from UserDto to avoid requiring password fields during profile updates.
* Data Transfer Object for updating user profile information.
* <p>
* Contains only the editable profile fields (first name, last name).
* Separate from {@link UserDto} to avoid requiring password fields during profile updates.
* </p>
*
* @author Devon Hillard
*/
@Data
public class UserProfileUpdateDto {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
import lombok.extern.slf4j.Slf4j;

/**
* Global exception handler for validation errors. This class handles validation exceptions
* and returns appropriate error responses for API endpoints.
* Global exception handler for validation errors across all API endpoints.
* Handles {@link MethodArgumentNotValidException} thrown by {@code @Valid} annotations
* and returns structured error responses with field-level validation details.
*/
@Slf4j
@ControllerAdvice
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
import lombok.extern.slf4j.Slf4j;

/**
* The ExpiredTokenCleanJob is a Service which purges expired registration email verification tokens and password reset tokens based on the schedule
* defined in user.purgetokens.cron.expression in your application.properties.
* Scheduled job service that purges expired registration email verification tokens
* and password reset tokens. Runs on a cron schedule defined by the
* {@code user.purgetokens.cron.expression} property in application configuration.
*
* @see com.digitalsanctuary.spring.user.persistence.repository.VerificationTokenRepository
* @see com.digitalsanctuary.spring.user.persistence.repository.PasswordResetTokenRepository
*/
@Slf4j
@Service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@
import lombok.extern.slf4j.Slf4j;

/**
* This class is used to listen for authentication events and handle account lockout functionality if needed.
* Listens for Spring Security authentication events and manages account lockout functionality.
* Handles both successful and failed authentication attempts across different authentication
* types including form login, OAuth2, and OIDC.
*
* https://github.com/devondragon/SpringUserFramework/issues/29
* <p>
* This listener integrates with {@link LoginAttemptService} to track login attempts and
* enforce brute-force protection policies.
* </p>
*
* @see LoginAttemptService
* @see AuthenticationSuccessEvent
* @see AbstractAuthenticationFailureEvent
*/
@Slf4j
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@
import lombok.extern.slf4j.Slf4j;

/**
* This listener handles OnRegistrationCompleteEvents, and sends a password verification email, if that feature is enabled.
* Listens for user registration events and sends verification emails when enabled.
* This listener handles {@link OnRegistrationCompleteEvent} instances asynchronously
* to avoid blocking the registration flow.
*
* <p>
* Email verification is controlled by the {@code user.registration.sendVerificationEmail}
* configuration property.
* </p>
*
* @see OnRegistrationCompleteEvent
* @see UserEmailService
*/
@Slf4j
@RequiredArgsConstructor
Expand Down
Loading
Loading