From fe62e58d2ac8453b8f28b57700e0d62d467bdc73 Mon Sep 17 00:00:00 2001 From: Devon Hillard Date: Wed, 12 Aug 2026 01:58:55 -0600 Subject: [PATCH 1/5] chore: adopt ds-spring-user-framework 5.2.0 Brings in completed remember-me support (devondragon/SpringUserFramework#351): configurable token validity, parameter/cookie names, secure-cookie flag, and an optional persistent token store with server-side revocation. Refs #79 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 69f8867..6bb2621 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ repositories { dependencies { // DigitalSanctuary Spring User Framework - implementation 'com.digitalsanctuary:ds-spring-user-framework:5.1.1' + implementation 'com.digitalsanctuary:ds-spring-user-framework:5.2.0' // WebAuthn support (Passkey authentication) implementation 'org.springframework.security:spring-security-webauthn' From 1a840d2e4ab414343b7c90ebb33623c1b4c21e6d Mon Sep 17 00:00:00 2001 From: Devon Hillard Date: Wed, 12 Aug 2026 01:59:04 -0600 Subject: [PATCH 2/5] feat(auth): add remember-me checkbox to login form and enable remember-me Add the remember-me checkbox to the reference login form so the framework's remember-me support is reachable from the documented login path. The parameter name matches the framework default (remember-me); without it AbstractRememberMeServices never issues a cookie. Enable user.security.rememberMe in the demo config with an env-var-backed signing key (demo-only default so a fresh clone works out of the box). The prd profile requires REMEMBER_ME_KEY with no fallback (fail-fast) and forces useSecureCookie so the ~14-day token is never sent over plain HTTP behind a TLS-terminating proxy. Refs #79 --- src/main/resources/application-prd.yml | 10 +++++++++- src/main/resources/application.yml | 8 ++++++++ src/main/resources/messages/messages.properties | 1 + src/main/resources/templates/user/login.html | 4 ++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application-prd.yml b/src/main/resources/application-prd.yml index 8ce600b..7c74024 100644 --- a/src/main/resources/application-prd.yml +++ b/src/main/resources/application-prd.yml @@ -50,4 +50,12 @@ user: # NOTE: allowInitialPasswordSetWithoutStepUp is intentionally left at its secure default (false) here. In # production, setting an initial password on a passkey-only account should require step-up (a StepUpService bean), # not just an authenticated session (SUF-02). - disableCSRFdURIs: # No CSRF disabled URIs in production for better security \ No newline at end of file + disableCSRFdURIs: # No CSRF disabled URIs in production for better security + rememberMe: + # No default on purpose: the demo signing key in application.yml must never reach production. Startup fails + # unless REMEMBER_ME_KEY is provided. + key: ${REMEMBER_ME_KEY} + # Force the Secure flag unconditionally, mirroring the session cookie above. Spring's default falls back to + # request.isSecure(), which is false behind a TLS-terminating proxy unless forwarded-header processing is + # configured - without this a ~14-day login token could be sent over plain HTTP. + useSecureCookie: true \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 93c5597..0c960dd 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -140,6 +140,14 @@ user: bcryptStrength: 12 # The bcrypt strength to use for password hashing. The higher the number, the longer it takes to hash the password. The default is 12. The minimum is 4. The maximum is 31. testHashTime: true # If true, the test hash time will be logged to the console on startup. This is useful for determining the optimal bcryptStrength value. defaultAction: deny # The default action for all requests. This can be either deny or allow. + rememberMe: + enabled: true # Issue a remember-me cookie when the login form posts the remember-me parameter (the checkbox on login.html). + # Secret used to sign remember-me tokens. The default below exists only so the demo works out of the box; + # in production set REMEMBER_ME_KEY (or override this property) to a long random value from your secret + # manager and keep it stable across restarts/instances. + key: ${REMEMBER_ME_KEY:local-demo-only-remember-me-key} + # tokenValiditySeconds: 1209600 # How long a remember-me token stays valid. Default is 14 days. + # usePersistentTokens: true # Store tokens in the persistent_logins table (see framework db-scripts) so they can be revoked server-side. unprotectedURIs: /,/index.html,/favicon.ico,/apple-touch-icon-precomposed.png,/css/*,/js/*,/js/user/*,/js/event/*,/js/utils/*,/img/**,/user/registration,/user/registration/passwordless,/user/resendRegistrationToken,/user/resetPassword,/user/registrationConfirm,/user/changePassword,/user/savePassword,/oauth2/authorization/*,/login,/user/login,/user/login.html,/swagger-ui.html,/swagger-ui/**,/v3/api-docs/**,/event/,/event/list.html,/event/**,/about.html,/error,/error.html,/webauthn/authenticate/**,/login/webauthn # A comma delimited list of URIs that should not be protected by Spring Security if the defaultAction is deny. protectedURIs: /protected.html # A comma delimited list of URIs that should be protected by Spring Security if the defaultAction is allow. disableCSRFdURIs: /no-csrf-test # A comma delimited list of URIs that should not be protected by CSRF protection. This may include API endpoints that need to be called without a CSRF token. diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index 4fb1897..201ccd1 100644 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -36,6 +36,7 @@ label.form.login-link=Sign In label.form.login-title=Log In label.form.login-email=Email label.form.login-pass=Password +label.form.login-remember=Remember me label.form.login-signup=Sign up label.form.update-user=Update Your Profile label.form.delete-account=Delete Your Account diff --git a/src/main/resources/templates/user/login.html b/src/main/resources/templates/user/login.html index ca1505c..94ed104 100644 --- a/src/main/resources/templates/user/login.html +++ b/src/main/resources/templates/user/login.html @@ -74,6 +74,10 @@
Log in with
th:placeholder="#{label.form.login-pass}" aria-label="Password"> +
+ + +