.
This commit is contained in:
@@ -16,7 +16,7 @@ Why this backend:
|
||||
|
||||
- Bun keeps the runtime, package manager, and SQLite support simple.
|
||||
- ElysiaJS is a good fit for a small internal API without extra framework weight.
|
||||
- SQLite is enough for admin sessions and password reset tokens, and keeps deployment straightforward.
|
||||
- SQLite is enough for admin sessions and a small amount of panel metadata, and keeps deployment straightforward.
|
||||
- Docker CLI integration stays close to Docker Mailserver's real operational model instead of hiding it behind unnecessary layers.
|
||||
|
||||
### Frontend
|
||||
@@ -67,9 +67,9 @@ The backend is intentionally flat:
|
||||
- `apps/api/src/docker/`
|
||||
Wraps Docker CLI calls with fixed argument arrays only. No shell interpolation.
|
||||
- `apps/api/src/users/service.ts`
|
||||
Contains the mailbox user operations and password reset flow.
|
||||
Contains the mailbox user operations and the one-time link flow for password changes.
|
||||
- `apps/api/src/mail/service.ts`
|
||||
Sends reset emails through `sendmail` inside the Docker Mailserver container.
|
||||
Sends setup emails for newly created mailboxes through `sendmail` inside the Docker Mailserver container.
|
||||
- `apps/api/src/lib/`
|
||||
Holds config parsing, SQLite access, validation, HTTP helpers, and small security utilities.
|
||||
|
||||
@@ -80,7 +80,6 @@ The backend is intentionally flat:
|
||||
- `POST /api/auth/logout`
|
||||
- `GET /api/users`
|
||||
- `POST /api/users`
|
||||
- `PATCH /api/users/:email/password`
|
||||
- `DELETE /api/users/:email`
|
||||
- `POST /api/users/:email/password-reset`
|
||||
- `POST /api/password-resets/inspect`
|
||||
@@ -99,9 +98,9 @@ The dashboard includes:
|
||||
- mailbox listing
|
||||
- simple search
|
||||
- create user modal
|
||||
- edit password modal
|
||||
- temporary link generation for password changes
|
||||
- delete action
|
||||
- send reset action
|
||||
- no direct password change from the admin panel
|
||||
|
||||
The create flow intentionally generates a temporary password on the server and immediately emails a one-time reset link to the user. That means the admin panel never needs to expose an initial mailbox password in the UI.
|
||||
|
||||
@@ -109,10 +108,10 @@ The create flow intentionally generates a temporary password on the server and i
|
||||
|
||||
The reset flow is built to stay secure without becoming heavy:
|
||||
|
||||
1. An admin triggers a reset for an existing mailbox.
|
||||
1. An admin generates a one-time link for an existing mailbox.
|
||||
2. The backend generates a random opaque token.
|
||||
3. Only the SHA-256 hash of that token is stored in SQLite.
|
||||
4. The user receives an email with the one-time reset link.
|
||||
4. The admin shares the one-time link manually with the user.
|
||||
5. The reset page validates the token before showing the password form.
|
||||
6. On submit, the token is claimed for one use only.
|
||||
7. The backend updates the mailbox password through Docker Mailserver.
|
||||
@@ -140,12 +139,14 @@ Security choices here:
|
||||
|
||||
- Admin authentication uses an Argon2id-hashed bootstrap account from environment variables.
|
||||
- Panel login uses a single access key instead of an email/password pair.
|
||||
- Access key login is protected by an intentionally aggressive in-memory rate limit with escalating lockouts.
|
||||
- Sessions are server-side, opaque, and stored in an `HttpOnly` cookie with `SameSite=Strict`.
|
||||
- Password reset tokens are random, one-time, time-limited, and stored only as hashes.
|
||||
- The admin panel never changes mailbox passwords directly; it only generates one-time links.
|
||||
- Admin-only routes require a valid session cookie.
|
||||
- Validation is applied to logins, emails, passwords, and reset payloads.
|
||||
- Allowed origins are restricted by `APP_ORIGINS`.
|
||||
- Reset emails are sent from the backend only. No secrets are exposed to the frontend.
|
||||
- Setup emails for new accounts are sent from the backend only. No secrets are exposed to the frontend.
|
||||
- Docker Mailserver access is treated as privileged infrastructure access.
|
||||
|
||||
## 8. Run locally
|
||||
|
||||
Reference in New Issue
Block a user