This commit is contained in:
Linus Rath
2026-03-18 00:31:49 +01:00
+46 -46
View File
@@ -3,7 +3,7 @@
<picture> <picture>
<source media="(prefers-color-scheme: dark)" srcset="public/branding/Bulwark_Logo_with_Lettering_White_and_Color.svg" /> <source media="(prefers-color-scheme: dark)" srcset="public/branding/Bulwark_Logo_with_Lettering_White_and_Color.svg" />
<source media="(prefers-color-scheme: light)" srcset="public/branding/Bulwark_Logo_with_Lettering_Dark_Color.svg" /> <source media="(prefers-color-scheme: light)" srcset="public/branding/Bulwark_Logo_with_Lettering_Dark_Color.svg" />
<img src="public/branding/Bulwark_Logo_with_Lettering_Dark_Color.svg" alt="Bulwark Webmail" width="280" /> <img src="public/branding/Bulwark_Logo_with_Lettering_Dark_Color.svg" alt="Bulwark Webmail" width="480" />
</picture> </picture>
# Bulwark Webmail # Bulwark Webmail
@@ -25,16 +25,16 @@ Built with Next.js and the JMAP protocol.
<tr> <tr>
<td width="50%"> <td width="50%">
<img src="screenshots/inbox.png" width="100%" alt="Inbox three-pane layout with sidebar, email list, and viewer (dark mode)"> <img src="screenshots/inbox.png" width="100%" alt="Inbox - three-pane layout with sidebar, email list, and viewer (dark mode)">
**Mail** Three-pane layout with sidebar, email list, and viewer **Mail** - Three-pane layout with sidebar, email list, and viewer
</td> </td>
<td width="50%"> <td width="50%">
<img src="screenshots/calendar.png" width="100%" alt="Calendar"> <img src="screenshots/calendar.png" width="100%" alt="Calendar">
**Calendar** Month, week, day, and agenda views with event management **Calendar** - Month, week, day, and agenda views with event management
</td> </td>
</tr> </tr>
@@ -43,14 +43,14 @@ Built with Next.js and the JMAP protocol.
<img src="screenshots/contacts.png" width="100%" alt="Contacts"> <img src="screenshots/contacts.png" width="100%" alt="Contacts">
**Contacts** Contact management with groups and vCard support **Contacts** - Contact management with groups and vCard support
</td> </td>
<td width="50%"> <td width="50%">
<img src="screenshots/files.png" width="100%" alt="File browser"> <img src="screenshots/files.png" width="100%" alt="File browser">
**Files** Cloud file browser with upload, preview, and folder navigation **Files** - Cloud file browser with upload, preview, and folder navigation
</td> </td>
</tr> </tr>
@@ -62,16 +62,16 @@ Built with Next.js and the JMAP protocol.
<tr> <tr>
<td width="50%"> <td width="50%">
<img src="screenshots/inbox%20whitemode.png" width="100%" alt="Inbox light mode"> <img src="screenshots/inbox%20whitemode.png" width="100%" alt="Inbox - light mode">
**Light mode** Full theme support with intelligent color transformation **Light mode** - Full theme support with intelligent color transformation
</td> </td>
<td width="50%"> <td width="50%">
<img src="screenshots/settings.png" width="100%" alt="Settings"> <img src="screenshots/settings.png" width="100%" alt="Settings">
**Settings** Appearance, identities, filters, templates, and more **Settings** - Appearance, identities, filters, templates, and more
</td> </td>
</tr> </tr>
@@ -80,7 +80,7 @@ Built with Next.js and the JMAP protocol.
<img src="screenshots/login.png" width="100%" alt="Login page"> <img src="screenshots/login.png" width="100%" alt="Login page">
**Login** Configurable branding with OAuth2/OIDC and 2FA support **Login** - Configurable branding with OAuth2/OIDC and 2FA support
</td> </td>
<td width="50%"> <td width="50%">
@@ -94,21 +94,21 @@ Built with Next.js and the JMAP protocol.
### Mail ### Mail
- **Read, compose, reply, reply-all, forward** with rich HTML rendering - **Read, compose, reply, reply-all, forward** with rich HTML rendering
- **Threading** Gmail-style inline expansion with thread navigation - **Threading** - Gmail-style inline expansion with thread navigation
- **Draft auto-save** with discard confirmation - **Draft auto-save** with discard confirmation
- **Attachments** upload, download, and inline preview - **Attachments** - upload, download, and inline preview
- **Search** full-text with JMAP filter panel, search chips, cross-mailbox queries, wildcard support, and OR conditions - **Search** - full-text with JMAP filter panel, search chips, cross-mailbox queries, wildcard support, and OR conditions
- **Batch operations** multi-select with checkboxes, archive, delete, move, tag - **Batch operations** - multi-select with checkboxes, archive, delete, move, tag
- **Archive modes** archive directly or organize archived mail by year or month - **Archive modes** - archive directly or organize archived mail by year or month
- **Print** emails directly from the viewer - **Print** emails directly from the viewer
- **Color tags/labels** and star/unstar - **Color tags/labels** and star/unstar
- **Virtual scrolling** for large mailboxes - **Virtual scrolling** for large mailboxes
- **Quick reply** from the viewer - **Quick reply** from the viewer
- **Sender avatars** favicon-based with negative caching for performance - **Sender avatars** - favicon-based with negative caching for performance
- **Recipient popover** for quick contact interaction - **Recipient popover** for quick contact interaction
- **TNEF support** — extract Outlook `winmail.dat` message bodies and attachments automatically - **Folder management** - create, rename, delete folders with icon picker and subfolder support
- **Folder management** — create, rename, delete folders with icon picker and subfolder support - **Tag counts** - unread and total counts displayed in sidebar
- **Tag counts** — unread and total counts displayed in sidebar - **TNEF support** - extract Outlook `winmail.dat` message bodies and attachments automatically
### Calendar ### Calendar
@@ -116,8 +116,8 @@ Built with Next.js and the JMAP protocol.
- **Event hover preview** popover with details - **Event hover preview** popover with details
- **Drag-and-drop rescheduling**, click-drag creation, edge-resize (15-min snap) - **Drag-and-drop rescheduling**, click-drag creation, edge-resize (15-min snap)
- **Recurring events** with edit/delete scope (this / this and following / all) - **Recurring events** with edit/delete scope (this / this and following / all)
- **Participant scheduling** iTIP invitations, organizer/attendee UI, RSVP - **Participant scheduling** - iTIP invitations, organizer/attendee UI, RSVP
- **Inline calendar invitations** in email viewer auto-detect `.ics`, RSVP, import - **Inline calendar invitations** in email viewer - auto-detect `.ics`, RSVP, import
- **iCalendar import** with preview and bulk create - **iCalendar import** with preview and bulk create
- **Notifications** with configurable sound and alert persistence - **Notifications** with configurable sound and alert persistence
- **Real-time sync** via JMAP push - **Real-time sync** via JMAP push
@@ -128,15 +128,15 @@ Built with Next.js and the JMAP protocol.
- **Contact groups** with group expansion and member management - **Contact groups** with group expansion and member management
- **vCard import/export** (RFC 6350) with duplicate detection - **vCard import/export** (RFC 6350) with duplicate detection
- **Autocomplete** in composer (To/Cc/Bcc) - **Autocomplete** in composer (To/Cc/Bcc)
- **Bulk operations** multi-select, delete, group add, export - **Bulk operations** - multi-select, delete, group add, export
### Filters & Automation ### Filters & Automation
- **Server-side email filters** via JMAP Sieve Scripts (RFC 9661) - **Server-side email filters** via JMAP Sieve Scripts (RFC 9661)
- **Visual rule builder** conditions (From, To, Subject, Size, Body…) and actions (Move, Forward, Star, Discard…) - **Visual rule builder** - conditions (From, To, Subject, Size, Body…) and actions (Move, Forward, Star, Discard…)
- **Raw Sieve editor** with syntax validation - **Raw Sieve editor** with syntax validation
- **Vacation responder** with date range scheduling and sidebar indicator - **Vacation responder** with date range scheduling and sidebar indicator
- **Email templates** reusable, categorized, with placeholder auto-fill (`{{recipientName}}`, `{{date}}`, etc.) - **Email templates** - reusable, categorized, with placeholder auto-fill (`{{recipientName}}`, `{{date}}`, etc.)
### Files ### Files
@@ -144,39 +144,39 @@ Built with Next.js and the JMAP protocol.
- **Upload and download** files with progress tracking and folder upload support - **Upload and download** files with progress tracking and folder upload support
- **Folder navigation** with breadcrumb path and tree sidebar - **Folder navigation** with breadcrumb path and tree sidebar
- **Grid and list views** with sorting by name, size, or date - **Grid and list views** with sorting by name, size, or date
- **Clipboard operations** cut, copy, paste, duplicate files - **Clipboard operations** - cut, copy, paste, duplicate files
- **File preview** for images, text, audio, video, and more - **File preview** for images, text, audio, video, and more
- **Favorites and recent files** for quick access - **Favorites and recent files** for quick access
- **Bulk operations** multi-select, delete, move, download - **Bulk operations** - multi-select, delete, move, download
### Security & Privacy ### Security & Privacy
- **External content blocked** by default trusted senders list for auto-load - **External content blocked** by default - trusted senders list for auto-load
- **HTML sanitization** via DOMPurify with XSS prevention - **HTML sanitization** via DOMPurify with XSS prevention
- **S/MIME** manage certificates, sign outgoing mail, encrypt to recipients, decrypt messages, and verify signatures - **S/MIME** - manage certificates, sign outgoing mail, encrypt to recipients, decrypt messages, and verify signatures
- **SPF/DKIM/DMARC** status indicators - **SPF/DKIM/DMARC** status indicators
- **OAuth2/OIDC with PKCE** for SSO (Keycloak, Authentik, or built-in), with OAuth-only mode - **OAuth2/OIDC with PKCE** for SSO (Keycloak, Authentik, or built-in), with OAuth-only mode
- **TOTP two-factor authentication** - **TOTP two-factor authentication**
- **Account security panel** manage passwords and 2FA via Stalwart admin API - **Account security panel** - manage passwords and 2FA via Stalwart admin API
- **"Remember me"** AES-256-GCM encrypted httpOnly cookie (opt-in) - **"Remember me"** - AES-256-GCM encrypted httpOnly cookie (opt-in)
- **Security headers** CSP with per-request nonce, X-Frame-Options, Referrer-Policy - **Security headers** - CSP with per-request nonce, X-Frame-Options, Referrer-Policy
- **Newsletter unsubscribe** (RFC 2369) - **Newsletter unsubscribe** (RFC 2369)
### Interface ### Interface
- **Three-pane layout** sidebar, email list, viewer with resizable columns - **Three-pane layout** - sidebar, email list, viewer with resizable columns
- **Dark and light themes** with intelligent email color transformation - **Dark and light themes** with intelligent email color transformation
- **Always-light email rendering** option for problematic HTML messages in dark theme - **Responsive** - desktop sidebar + mobile bottom tab bar with tablet support
- **Responsive** — desktop sidebar + mobile bottom tab bar with tablet support - **Keyboard shortcuts** - full navigation without a mouse
- **Keyboard shortcuts** — full navigation without a mouse
- **Drag-and-drop** email organization between mailboxes and tag assignment - **Drag-and-drop** email organization between mailboxes and tag assignment
- **Right-click context menus**, toast notifications with undo, form validation with shake feedback - **Right-click context menus**, toast notifications with undo, form validation with shake feedback
- **Always-light email rendering** option for problematic HTML messages in dark theme
- **Customizable toolbar** position, custom favicon, sidebar/login logos, and login page branding - **Customizable toolbar** position, custom favicon, sidebar/login logos, and login page branding
- **Sidebar apps** pin custom tools to the navigation rail and open them inline or in a new tab - **Sidebar apps** - pin custom tools to the navigation rail and open them inline or in a new tab
- **Settings sync** preferences synchronized with the server (encrypted) - **Settings sync** - preferences synchronized with the server (encrypted)
- **Storage quota** display - **Storage quota** display
- **Shared folders** multi-account access - **Shared folders** - multi-account access
- **Accessibility** WCAG AA contrast, reduced-motion support, focus trap, screen reader live regions - **Accessibility** - WCAG AA contrast, reduced-motion support, focus trap, screen reader live regions
### Internationalization ### Internationalization
@@ -187,13 +187,13 @@ Automatic browser detection with persistent preference.
### Identity Management ### Identity Management
- **Multiple sender identities** with per-identity signatures - **Multiple sender identities** with per-identity signatures
- **Identity refresh** — keep the identity manager aligned with server-side changes after edits - **Sub-addressing** - `user+tag@domain.com` with contextual tag suggestions
- **Sub-addressing** — `user+tag@domain.com` with contextual tag suggestions - **Identity refresh** - keep the identity manager aligned with server-side changes after edits
- **Identity badges** in viewer and email list - **Identity badges** in viewer and email list
### Operations ### Operations
- **Automatic update check** server logs when a newer release is available - **Automatic update check** - server logs when a newer release is available
--- ---
@@ -211,7 +211,7 @@ Or with Docker Compose:
```bash ```bash
cp .env.example .env.local cp .env.example .env.local
# Edit .env.local set JMAP_SERVER_URL # Edit .env.local - set JMAP_SERVER_URL
docker compose up -d docker compose up -d
``` ```
@@ -222,7 +222,7 @@ git clone https://github.com/bulwarkmail/webmail.git
cd webmail cd webmail
npm install npm install
cp .env.example .env.local cp .env.example .env.local
# Edit .env.local set JMAP_SERVER_URL # Edit .env.local - set JMAP_SERVER_URL
npm run build && npm start npm run build && npm start
``` ```
@@ -246,7 +246,7 @@ JMAP_SERVER_URL=https://mail.example.com
APP_NAME=My Webmail APP_NAME=My Webmail
``` ```
All variables are **runtime** Docker deployments can be configured without rebuilding. All variables are **runtime** - Docker deployments can be configured without rebuilding.
<details> <details>
<summary>Server Listen Address</summary> <summary>Server Listen Address</summary>
@@ -313,7 +313,7 @@ Credentials encrypted with AES-256-GCM, stored in an httpOnly cookie (30-day exp
## Why Stalwart? ## Why Stalwart?
[Stalwart](https://github.com/stalwartlabs/mail-server) is a mail server written in Rust with **native JMAP support** not IMAP/SMTP with JMAP bolted on. It handles JMAP, IMAP, SMTP, and ManageSieve in a single binary. Self-hosted, no third-party dependencies. [Stalwart](https://github.com/stalwartlabs/mail-server) is a mail server written in Rust with **native JMAP support** - not IMAP/SMTP with JMAP bolted on. It handles JMAP, IMAP, SMTP, and ManageSieve in a single binary. Self-hosted, no third-party dependencies.
## Contributing ## Contributing