diff --git a/CHANGES.md b/CHANGES.md index cee9b1b5..4fffb701 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,26 @@ Version 0.9.0 To be released. + - Added passkey (WebAuthn) authentication. The admin *Auth* page now + has a "Passkeys" section for enrolling and managing passkeys, and + the public login page presents a "Sign in with passkey" button + (with the email/password form tucked behind a toggle) whenever at + least one passkey is enrolled. Both device-bound and synced + (multi-device) passkeys are accepted. A passkey on its own counts + as multi-factor authentication, so a successful passkey sign-in is + accepted in place of the TOTP step — the user is not asked for a + one-time code in the same session. + + Hollo uses the *@simplewebauthn/server* library for verification + and ships the matching browser helper as a static asset linked + only from the auth and login pages. Registration uses + `residentKey: required` and `userVerification: required`, so every + enrolled passkey is discoverable and tied to a biometric or PIN + gesture. Registration challenges are bound to the current login + session with a server-enforced 5-minute TTL, and login challenges + are stored in a single-use `passkey_login_challenges` table so a + captured cookie + assertion pair can be redeemed at most once. [[#487]] + - Added optional split-domain WebFinger support. When the new `HANDLE_HOST` and `WEB_ORIGIN` environment variables are set, Hollo uses Fedify's `origin` configuration so that fediverse @@ -221,6 +241,7 @@ To be released. [#482]: https://github.com/fedify-dev/hollo/pull/482 [#483]: https://github.com/fedify-dev/hollo/pull/483 [#484]: https://github.com/fedify-dev/hollo/pull/484 +[#487]: https://github.com/fedify-dev/hollo/pull/487 Version 0.8.4 diff --git a/DESIGN.md b/DESIGN.md index 6be50152..aecf4a46 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -352,3 +352,34 @@ shorthand at class extraction time, but the original string still ships in the HTML `class` attribute, where the browser splits it on whitespace and matches `ring-2` (etc.) as a standalone class. Always write each variant out long-form (`focus:border-brand-500 focus:ring-2 …`). + + +### Page-scoped client scripts + +The lightweight-SSR principle still stands: *Layout.tsx* and the +dashboard chrome stay JavaScript-free. A handful of existing pages +emit tiny inline scripts (e.g. `onsubmit="this.submit.ariaBusy='true'"` +on long-running forms, or `