.
This commit is contained in:
@@ -67,9 +67,7 @@ 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 the one-time link flow for password changes.
|
||||
- `apps/api/src/mail/service.ts`
|
||||
Sends setup emails for newly created mailboxes through `sendmail` inside the Docker Mailserver container.
|
||||
Contains the mailbox user operations, pending mailbox invites, and the one-time link flow for password changes.
|
||||
- `apps/api/src/lib/`
|
||||
Holds config parsing, SQLite access, validation, HTTP helpers, and small security utilities.
|
||||
|
||||
@@ -98,24 +96,24 @@ The dashboard includes:
|
||||
- mailbox listing
|
||||
- simple search
|
||||
- create user modal
|
||||
- temporary link generation for password changes
|
||||
- 48-hour setup link generation for new mailboxes
|
||||
- temporary link generation for password changes on existing mailboxes
|
||||
- delete 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.
|
||||
The create flow now generates a 48-hour setup link. The mailbox does not exist yet at that point. It is created only when the user opens the link and chooses a password.
|
||||
|
||||
## 5. Password reset flow
|
||||
|
||||
The reset flow is built to stay secure without becoming heavy:
|
||||
|
||||
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 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.
|
||||
8. Used or expired tokens are rejected.
|
||||
1. For a new mailbox, the admin generates a 48-hour setup link.
|
||||
2. The mailbox is not created yet.
|
||||
3. The backend stores only the SHA-256 hash of the invite token.
|
||||
4. The admin shares the one-time setup link manually with the user.
|
||||
5. When the user chooses a password through the link, the backend creates the mailbox in Docker Mailserver.
|
||||
6. For existing mailboxes, the same public page is reused for password reset links.
|
||||
7. Every link is one-time and expires automatically.
|
||||
|
||||
## 6. Docker CLI integration strategy
|
||||
|
||||
@@ -142,6 +140,7 @@ Security choices here:
|
||||
- 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.
|
||||
- New mailbox setup links are also 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.
|
||||
@@ -166,6 +165,7 @@ Security choices here:
|
||||
- `MAILSERVER_CONTAINER`
|
||||
- `APP_ADMIN_EMAIL`
|
||||
- `APP_ADMIN_ACCESS_KEY`
|
||||
- `MAILBOX_INVITE_TTL_HOURS=48`
|
||||
3. Install dependencies:
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user