Add remember-me support to the reference login form (#79) - #80
Conversation
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
…r-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
Extend LoginPage with a remember-me checkbox locator and add a spec covering: persistent cookie issued when checked (httpOnly, future expiry), no cookie when unchecked, auto-login after the session cookie is dropped, and the fresh-login baseline without remember-me. Refs #79
There was a problem hiding this comment.
Pull request overview
Adds end-to-end “remember-me” support to the demo app’s canonical login flow, wiring the framework’s remember-me parameter through the reference Thymeleaf login form and validating cookie/session behavior via Playwright tests.
Changes:
- Update the login form to post the framework-default
remember-meparameter and add a new i18n label key. - Enable/configure remember-me in
application.ymlwith production hardening overrides inapplication-prd.yml. - Add Playwright page-object support + a new spec covering cookie issuance and re-authentication behavior.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| build.gradle | Bumps ds-spring-user-framework to 5.2.0 to pick up framework-side remember-me support. |
| src/main/resources/templates/user/login.html | Adds a remember-me checkbox posting remember-me. |
| src/main/resources/messages/messages.properties | Adds label.form.login-remember i18n message key. |
| src/main/resources/application.yml | Enables remember-me and configures signing key via env var with a demo fallback. |
| src/main/resources/application-prd.yml | Removes default key (fail-fast) and forces Secure on remember-me cookie in prod. |
| playwright/src/pages/LoginPage.ts | Adds a locator + helper for checking the remember-me checkbox. |
| playwright/tests/auth/remember-me.spec.ts | New E2E coverage for remember-me cookie issuance and session-expiry relogin behavior. |
Suppressed comments (1)
playwright/tests/auth/remember-me.spec.ts:131
BrowserContext.clearCookies()in Playwright does not support filtering by cookie name (e.g.{ name: 'JSESSIONID' }). This call will fail at runtime and prevent the baseline (no remember-me) test from running.
If you only want to remove the session cookie, snapshot cookies, clear all, then re-add everything except JSESSIONID (or clear all cookies if preserving others isn't important here).
await page.context().clearCookies({ name: 'JSESSIONID' });
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # 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} |
There was a problem hiding this comment.
Fixed in 65247f7 — the fallback is now ${REMEMBER_ME_KEY:${random.uuid}}, random per start, so no deployment ever runs on a publicly-known key. Cookies don't survive restarts unless REMEMBER_ME_KEY is set; the prd profile still requires it with no fallback (fail-fast).
| // Drop the server session cookie, simulating an expired/closed session. | ||
| // The remember-me cookie survives and should re-authenticate the request. | ||
| await page.context().clearCookies({ name: 'JSESSIONID' }); |
There was a problem hiding this comment.
Playwright has supported filtering in BrowserContext.clearCookies() since v1.43 (this repo uses ^1.58) — see https://playwright.dev/docs/api/class-browsercontext#browser-context-clear-cookies. The test passes locally and in this PR's Playwright E2E CI job, which exercises exactly this call.
A fixed fallback means any deployment that skips the prd profile and never sets REMEMBER_ME_KEY signs tokens with a publicly-known constant. A random per-start default keeps the demo working out of the box without that footgun; cookies just don't survive restarts unless the env var is set. Refs #79
Summary
Makes remember-me reachable from the documented login path, now that ds-spring-user-framework 5.2.0 completes the feature (devondragon/SpringUserFramework#351).
Changes
build.gradle— adopt ds-spring-user-framework 5.2.0login.html— remember-me checkbox posting the framework-defaultremember-meparameter; label via newlabel.form.login-remembermessage keyapplication.yml— remember-me enabled; signing key fromREMEMBER_ME_KEYenv var with a demo-only fallback so a fresh clone worksapplication-prd.yml— fail-fast${REMEMBER_ME_KEY}(no default) anduseSecureCookie: true, mirroring the session-cookie hardening, so the ~14-day token is never issued over plain HTTP behind a TLS-terminating proxyLoginPage.checkRememberMe()+ 4-test spec: persistent cookie issued when checked (httpOnly, future expiry), no cookie when unchecked, auto-login after session cookie removal, fresh-login baselineTesting
./gradlew testpasses with 5.2.0 (artifact resolved from Maven Central)remember-me.spec.tspasses on Chromium, Firefox, Mobile Chrome (WebKit fails locally, but pre-existing:login.spec.tsfails identically on WebKit in this environment)Closes #79