Webmail
The webmail page and the public API behind it.
Core serves a mail client at /webmail on the API server. Mailbox users sign in with their address and password. Nobody needs a dashboard account.
The page is a React app in resources/webmail/app.tsx, bundled with the dashboard's esbuild on first request and cached until the file changes. It uses the dashboard stylesheet and UI components. Its text comes from the core app lang package.
HTML mail is shown in a sandboxed frame with scripts off, and the page's content security policy blocks remote images.
API
Every route except sign in needs the x-webmail-token header with the token from POST /session. Sessions last 7 days and are stored hashed in webmail_sessions.
| Method | Path | What it does |
|---|---|---|
POST | /api/v1/webmail/session | Sign in with { address, password }. Returns { token, mailbox }. |
GET | /api/v1/webmail/session | The signed in mailbox. |
DELETE | /api/v1/webmail/session | Sign out. |
GET | /api/v1/webmail/folders | Folders with message and unread counts. |
POST | /api/v1/webmail/folders | Create a folder with { name }. |
PATCH | /api/v1/webmail/folders/:id | Rename with { name }. |
DELETE | /api/v1/webmail/folders/:id | Delete a folder you made and its messages. |
GET | /api/v1/webmail/messages?folder=&offset=&search= | 50 messages per page, newest first. |
GET | /api/v1/webmail/messages/:id | The full message. Marks it read. |
PATCH | /api/v1/webmail/messages/:id | { seen, flagged, folder }, any of them. |
DELETE | /api/v1/webmail/messages/:id | Moves to Trash, or deletes it when already in Trash. |
GET | /api/v1/webmail/messages/:id/attachments/:index | Download one attachment. |
POST | /api/v1/webmail/send | Send { to, cc, bcc, subject, text, attachments, reply, references }. |
attachments is a list of { name, type, data } with base64 data. reply is the ID of the message being answered, which gets \Answered once the reply is sent. Sign in is limited to 30 tries per 15 minutes per IP and sending to 20 messages a minute.