From 258fb7581b37e1f6c876d4061aec722cf34000d8 Mon Sep 17 00:00:00 2001
From: Devon Hillard
Date: Sun, 22 Feb 2026 10:04:34 -0700
Subject: [PATCH 1/2] refactor(config): migrate @ConfigurationProperties from
@Component to @EnableConfigurationProperties
Remove @Component and @PropertySource from DevLoginConfigProperties and
WebAuthnConfigProperties so they are passive data holders per Spring Boot
convention. Registration is now handled by dedicated @Configuration
classes with @EnableConfigurationProperties:
- DevLoginAutoConfiguration: guards with @Profile("local") and
@ConditionalOnProperty, owns @PropertySource
- WebAuthnAutoConfiguration: always active (WebSecurityConfig requires
the properties), owns @PropertySource
Closes #263
---
.../user/dev/DevLoginAutoConfiguration.java | 24 +++++++++++++++++++
.../user/dev/DevLoginConfigProperties.java | 4 ----
.../security/WebAuthnAutoConfiguration.java | 20 ++++++++++++++++
.../security/WebAuthnConfigProperties.java | 4 ----
4 files changed, 44 insertions(+), 8 deletions(-)
create mode 100644 src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java
create mode 100644 src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java
diff --git a/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java b/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java
new file mode 100644
index 0000000..c3cbde7
--- /dev/null
+++ b/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java
@@ -0,0 +1,24 @@
+package com.digitalsanctuary.spring.user.dev;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * Auto-configuration for the dev login feature.
+ *
+ * Activates only when the {@code local} profile is active and
+ * {@code user.dev.auto-login-enabled=true}. Individual dev-login components
+ * ({@link DevLoginController}, {@link DevLoginStartupWarning}) carry their own
+ * guards for defense-in-depth.
+ *
+ */
+@Configuration
+@Profile("local")
+@ConditionalOnProperty(name = "user.dev.auto-login-enabled", havingValue = "true", matchIfMissing = false)
+@PropertySource("classpath:config/dsspringuserconfig.properties")
+@EnableConfigurationProperties(DevLoginConfigProperties.class)
+public class DevLoginAutoConfiguration {
+}
diff --git a/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfigProperties.java b/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfigProperties.java
index 1b1bf5b..d58b624 100644
--- a/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfigProperties.java
+++ b/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfigProperties.java
@@ -1,8 +1,6 @@
package com.digitalsanctuary.spring.user.dev;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.stereotype.Component;
import lombok.Data;
/**
@@ -17,8 +15,6 @@
*
*/
@Data
-@Component
-@PropertySource("classpath:config/dsspringuserconfig.properties")
@ConfigurationProperties(prefix = "user.dev")
public class DevLoginConfigProperties {
diff --git a/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java b/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java
new file mode 100644
index 0000000..87fa2cd
--- /dev/null
+++ b/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java
@@ -0,0 +1,20 @@
+package com.digitalsanctuary.spring.user.security;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * Auto-configuration that registers {@link WebAuthnConfigProperties}.
+ *
+ * This configuration is always active because {@code WebSecurityConfig} requires
+ * {@link WebAuthnConfigProperties} regardless of whether WebAuthn is enabled.
+ * Individual WebAuthn components carry their own
+ * {@code @ConditionalOnProperty(name = "user.webauthn.enabled")} guards.
+ *
+ */
+@Configuration
+@PropertySource("classpath:config/dsspringuserconfig.properties")
+@EnableConfigurationProperties(WebAuthnConfigProperties.class)
+public class WebAuthnAutoConfiguration {
+}
diff --git a/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfigProperties.java b/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfigProperties.java
index 72c277b..e30a978 100644
--- a/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfigProperties.java
+++ b/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfigProperties.java
@@ -2,16 +2,12 @@
import java.util.Set;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.stereotype.Component;
import lombok.Data;
/**
* Configuration properties for WebAuthn (Passkey) authentication.
*/
@Data
-@Component
-@PropertySource("classpath:config/dsspringuserconfig.properties")
@ConfigurationProperties(prefix = "user.webauthn")
public class WebAuthnConfigProperties {
From 23047ca3e5c6faa9fc3f04751a299db61619bba9 Mon Sep 17 00:00:00 2001
From: Devon Hillard
Date: Sun, 22 Feb 2026 12:28:13 -0700
Subject: [PATCH 2/2] fix(review): address PR #264 review feedback
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Rename DevLoginAutoConfiguration → DevLoginConfiguration and
WebAuthnAutoConfiguration → WebAuthnConfiguration to avoid implying
Spring Boot SPI semantics (these are component-scanned, not
SPI-registered via AutoConfiguration.imports)
- Remove @PropertySource from DevLoginConfiguration: the annotation
cannot influence its own @ConditionalOnProperty evaluation (condition
is checked before @PropertySource is processed), and defaults are
already available via WebAuthnConfiguration which unconditionally
loads dsspringuserconfig.properties
---
...oConfiguration.java => DevLoginConfiguration.java} | 11 +++++++----
...oConfiguration.java => WebAuthnConfiguration.java} | 4 ++--
2 files changed, 9 insertions(+), 6 deletions(-)
rename src/main/java/com/digitalsanctuary/spring/user/dev/{DevLoginAutoConfiguration.java => DevLoginConfiguration.java} (69%)
rename src/main/java/com/digitalsanctuary/spring/user/security/{WebAuthnAutoConfiguration.java => WebAuthnConfiguration.java} (86%)
diff --git a/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java b/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfiguration.java
similarity index 69%
rename from src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java
rename to src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfiguration.java
index c3cbde7..5d7e8b8 100644
--- a/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginAutoConfiguration.java
+++ b/src/main/java/com/digitalsanctuary/spring/user/dev/DevLoginConfiguration.java
@@ -4,21 +4,24 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
-import org.springframework.context.annotation.PropertySource;
/**
- * Auto-configuration for the dev login feature.
+ * Configuration that registers {@link DevLoginConfigProperties}.
*
* Activates only when the {@code local} profile is active and
* {@code user.dev.auto-login-enabled=true}. Individual dev-login components
* ({@link DevLoginController}, {@link DevLoginStartupWarning}) carry their own
* guards for defense-in-depth.
*
+ *
+ * Note: this class is registered via component scan (not Spring Boot SPI), so
+ * default property values are provided by {@code WebAuthnConfiguration}, which
+ * unconditionally loads {@code classpath:config/dsspringuserconfig.properties}.
+ *
*/
@Configuration
@Profile("local")
@ConditionalOnProperty(name = "user.dev.auto-login-enabled", havingValue = "true", matchIfMissing = false)
-@PropertySource("classpath:config/dsspringuserconfig.properties")
@EnableConfigurationProperties(DevLoginConfigProperties.class)
-public class DevLoginAutoConfiguration {
+public class DevLoginConfiguration {
}
diff --git a/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java b/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfiguration.java
similarity index 86%
rename from src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java
rename to src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfiguration.java
index 87fa2cd..c9513f7 100644
--- a/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnAutoConfiguration.java
+++ b/src/main/java/com/digitalsanctuary/spring/user/security/WebAuthnConfiguration.java
@@ -5,7 +5,7 @@
import org.springframework.context.annotation.PropertySource;
/**
- * Auto-configuration that registers {@link WebAuthnConfigProperties}.
+ * Configuration that registers {@link WebAuthnConfigProperties}.
*
* This configuration is always active because {@code WebSecurityConfig} requires
* {@link WebAuthnConfigProperties} regardless of whether WebAuthn is enabled.
@@ -16,5 +16,5 @@
@Configuration
@PropertySource("classpath:config/dsspringuserconfig.properties")
@EnableConfigurationProperties(WebAuthnConfigProperties.class)
-public class WebAuthnAutoConfiguration {
+public class WebAuthnConfiguration {
}