added passkey support (closes #6)
All checks were successful
test-and-lint / test-and-lint (pull_request) Successful in 2m50s
All checks were successful
test-and-lint / test-and-lint (pull_request) Successful in 2m50s
This commit is contained in:
29
README.md
29
README.md
@@ -1,6 +1,6 @@
|
||||
# MiauInv
|
||||
|
||||
MiauInv is a lightweight inventory, stock, and project allocation management system written in Go. It provides a server-rendered dashboard with HTMX-style page composition, vanilla JavaScript for API interactions, SQLite for persistence, JWT-based sessions, refresh-token rotation, account settings, and optional TOTP-based two-factor authentication.
|
||||
MiauInv is a lightweight inventory, stock, and project allocation management system written in Go. It provides a server-rendered dashboard with HTMX-style page composition, vanilla JavaScript for API interactions, SQLite for persistence, JWT-based sessions, refresh-token rotation, account settings, and optional TOTP-based two-factor authentication and WebAuthn passkey authentication.
|
||||
|
||||
The project is designed for self-hosted/private deployments. It is not a full enterprise asset-management platform, but it already covers the main workflows needed for tracking items, locations, stock distribution, and project allocations.
|
||||
|
||||
@@ -38,9 +38,9 @@ The project is designed for self-hosted/private deployments. It is not a full en
|
||||
- Database-backed refresh tokens with rotation.
|
||||
- HTTP-only secure cookies for access and refresh tokens.
|
||||
- Account settings page at `/profile/settings`.
|
||||
- Passkey registration, login, removal, and full passkey disable from account settings.
|
||||
- Username change with password confirmation.
|
||||
- Password change with old-password verification and session refresh.
|
||||
- Avatar placeholder in the account settings UI for a later avatar implementation.
|
||||
|
||||
### Two-factor authentication
|
||||
|
||||
@@ -57,11 +57,21 @@ The project is designed for self-hosted/private deployments. It is not a full en
|
||||
- The setup secret is only stored after the first valid authenticator code.
|
||||
- Existing refresh sessions are revoked when 2FA is enabled or disabled.
|
||||
|
||||
### Passkeys
|
||||
|
||||
- WebAuthn-based passkey registration from account settings.
|
||||
- Passkey login from the normal sign-in page.
|
||||
- Discoverable passkey login without entering a username first.
|
||||
- User-verification required for registration and login.
|
||||
- Server-side challenge storage using opaque one-time challenge tokens.
|
||||
- Passkey removal with current-password confirmation.
|
||||
- Full passkey disable with current-password confirmation.
|
||||
- Existing refresh sessions are revoked when passkeys are added, removed, or disabled.
|
||||
|
||||
## Current Status
|
||||
|
||||
MiauInv is an active private project. The current version supports core inventory workflows and account-level security settings. Some areas are intentionally still basic:
|
||||
|
||||
- Avatar support is currently only represented by a placeholder in the UI.
|
||||
- There is no dedicated admin panel yet.
|
||||
- Basic in-memory rate limiting protects login, 2FA, refresh, registration, and sensitive account endpoints.
|
||||
- Automated testing is currently limited and will be expanded in future releases.
|
||||
@@ -77,6 +87,7 @@ MiauInv is an active private project. The current version supports core inventor
|
||||
| Authentication | JWT via `github.com/golang-jwt/jwt/v5` |
|
||||
| Password hashing | bcrypt via `golang.org/x/crypto/bcrypt` |
|
||||
| 2FA | TOTP via `github.com/pquerna/otp/totp` |
|
||||
| Passkeys | WebAuthn via `github.com/go-webauthn/webauthn` |
|
||||
| Frontend | Server-rendered HTML, HTMX-style structure, vanilla JavaScript |
|
||||
| Styling | Custom CSS with dark theme variables |
|
||||
| Deployment | Docker / Docker Compose |
|
||||
@@ -155,7 +166,7 @@ openssl rand -base64 48
|
||||
| `/items` | `GET` | Yes | Item management view. |
|
||||
| `/locations` | `GET` | Yes | Location management view. |
|
||||
| `/projects` | `GET` | Yes | Project management view. |
|
||||
| `/profile/settings` | `GET` | Yes | Account settings, password changes, 2FA setup, 2FA disable, and recovery-code management. |
|
||||
| `/profile/settings` | `GET` | Yes | Account settings, password changes, passkey management, 2FA setup, 2FA disable, and recovery-code management. |
|
||||
| `/profile/` | `GET` | No | Placeholder page for unfinished profile subpages. |
|
||||
| `/assets/*` | `GET` | No | Static CSS/JS assets. Minified CSS/JS variants are generated on request. |
|
||||
|
||||
@@ -176,6 +187,13 @@ openssl rand -base64 48
|
||||
| `/api/2fa/enable` | `POST` | Yes | Enables 2FA after validating the temporary setup token and a TOTP code. Replaces recovery codes and revokes old sessions. |
|
||||
| `/api/2fa/disable` | `POST` | Yes | Disables 2FA after password and TOTP confirmation. Revokes sessions and clears auth cookies. |
|
||||
| `/api/2fa/recovery-codes/regenerate` | `POST` | Yes | Invalidates existing recovery codes and returns a new set after password and TOTP confirmation. |
|
||||
| `/api/passkeys` | `GET` | Yes | Lists passkeys registered for the current user. |
|
||||
| `/api/passkeys` | `DELETE` | Yes | Removes one passkey after current-password confirmation. |
|
||||
| `/api/passkeys/register/options` | `POST` | Yes | Creates a server-side passkey registration challenge after current-password confirmation. |
|
||||
| `/api/passkeys/register/finish` | `POST` | Yes | Verifies and stores a new passkey credential. Revokes old sessions and issues a new current session. |
|
||||
| `/api/passkeys/login/options` | `POST` | No | Creates a discoverable passkey login challenge. |
|
||||
| `/api/passkeys/login/finish` | `POST` | No | Verifies passkey login and issues a full session. |
|
||||
| `/api/passkeys/disable` | `POST` | Yes | Deletes all passkeys after current-password confirmation. Revokes old sessions and issues a new current session. |
|
||||
|
||||
### Inventory API
|
||||
|
||||
@@ -304,10 +322,11 @@ For Docker deployments, place Caddy and MiauInv on the same Docker network and r
|
||||
- Access tokens expire after 15 minutes.
|
||||
- Refresh tokens expire after 7 days and are rotated on refresh.
|
||||
- Refresh tokens and recovery codes are stored in the database as hashes.
|
||||
- Passkey credentials store public-key credential data, not private keys. Private keys remain in the authenticator or platform passkey provider.
|
||||
- TOTP secrets are currently stored in the database because the server must validate codes. Protect the database file accordingly.
|
||||
- Recovery codes are only shown when generated. Users should download or copy them immediately. The UI warns when few unused codes remain.
|
||||
- 2FA disable and recovery-code regeneration require both the current password and a valid TOTP code.
|
||||
- Basic in-memory rate limiting is enabled for login, 2FA, refresh, registration, and sensitive account endpoints. Use persistent or distributed rate limiting for multi-instance deployments.
|
||||
- Basic in-memory rate limiting is enabled for login, passkey ceremonies, 2FA, refresh, registration, and sensitive account endpoints. Use persistent or distributed rate limiting for multi-instance deployments.
|
||||
- Automated testing is currently limited. Authentication, 2FA, recovery codes, rate limiting, account settings, and inventory handlers should be covered before production use.
|
||||
|
||||
## Screenshots
|
||||
|
||||
Reference in New Issue
Block a user