318 lines
10 KiB
Markdown
318 lines
10 KiB
Markdown
<div align="center">
|
|
|
|
<picture>
|
|
<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" />
|
|
<img src="public/branding/Bulwark_Logo_with_Lettering_Dark_Color.svg" alt="Bulwark Webmail" width="280" />
|
|
</picture>
|
|
|
|
# Bulwark Webmail
|
|
|
|
A modern, self-hosted webmail client for [Stalwart Mail Server](https://stalw.art/).<br/>
|
|
Built with Next.js and the JMAP protocol.
|
|
|
|
[](LICENSE)
|
|
[](CHANGELOG.md)
|
|
[](https://ghcr.io/bulwarkmail/webmail)
|
|
|
|
</div>
|
|
|
|
---
|
|
|
|
## Screenshots
|
|
|
|
<table>
|
|
<tr>
|
|
<td width="50%">
|
|
|
|
<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
|
|
|
|
</td>
|
|
<td width="50%">
|
|
|
|
<img src="screenshots/calendar.png" width="100%" alt="Calendar">
|
|
|
|
**Calendar** — Month, week, day, and agenda views with event management
|
|
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="50%">
|
|
|
|
<img src="screenshots/contacts.png" width="100%" alt="Contacts">
|
|
|
|
**Contacts** — Contact management with groups and vCard support
|
|
|
|
</td>
|
|
<td width="50%">
|
|
|
|
<img src="screenshots/files.png" width="100%" alt="File browser">
|
|
|
|
**Files** — Cloud file browser with upload, preview, and folder navigation
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<details>
|
|
<summary>More screenshots</summary>
|
|
<table>
|
|
<tr>
|
|
<td width="50%">
|
|
|
|
<img src="screenshots/inbox%20whitemode.png" width="100%" alt="Inbox — light mode">
|
|
|
|
**Light mode** — Full theme support with intelligent color transformation
|
|
|
|
</td>
|
|
<td width="50%">
|
|
|
|
<img src="screenshots/settings.png" width="100%" alt="Settings">
|
|
|
|
**Settings** — Appearance, identities, filters, templates, and more
|
|
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="50%">
|
|
|
|
<img src="screenshots/login.png" width="100%" alt="Login page">
|
|
|
|
**Login** — Configurable branding with OAuth2/OIDC and 2FA support
|
|
|
|
</td>
|
|
<td width="50%">
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</details>
|
|
|
|
## Features
|
|
|
|
### Mail
|
|
|
|
- **Read, compose, reply, reply-all, forward** with rich HTML rendering
|
|
- **Threading** — Gmail-style inline expansion with thread navigation
|
|
- **Draft auto-save** with discard confirmation
|
|
- **Attachments** — upload, download, and inline preview
|
|
- **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
|
|
- **Print** emails directly from the viewer
|
|
- **Color tags/labels** and star/unstar
|
|
- **Virtual scrolling** for large mailboxes
|
|
- **Quick reply** from the viewer
|
|
- **Sender avatars** — favicon-based with negative caching for performance
|
|
- **Recipient popover** for quick contact interaction
|
|
- **Folder management** — create, rename, delete folders with icon picker and subfolder support
|
|
- **Tag counts** — unread and total counts displayed in sidebar
|
|
|
|
### Calendar
|
|
|
|
- **Month, week, day, and agenda views** with mini-calendar sidebar
|
|
- **Event hover preview** popover with details
|
|
- **Drag-and-drop rescheduling**, click-drag creation, edge-resize (15-min snap)
|
|
- **Recurring events** with edit/delete scope (this / this and following / all)
|
|
- **Participant scheduling** — iTIP invitations, organizer/attendee UI, RSVP
|
|
- **Inline calendar invitations** in email viewer — auto-detect `.ics`, RSVP, import
|
|
- **iCalendar import** with preview and bulk create
|
|
- **Notifications** with configurable sound and alert persistence
|
|
- **Real-time sync** via JMAP push
|
|
|
|
### Contacts
|
|
|
|
- **Contact management** with JMAP sync (RFC 9553/9610) and local fallback
|
|
- **Contact groups** with group expansion and member management
|
|
- **vCard import/export** (RFC 6350) with duplicate detection
|
|
- **Autocomplete** in composer (To/Cc/Bcc)
|
|
- **Bulk operations** — multi-select, delete, group add, export
|
|
|
|
### Filters & Automation
|
|
|
|
- **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…)
|
|
- **Raw Sieve editor** with syntax validation
|
|
- **Vacation responder** with date range scheduling and sidebar indicator
|
|
- **Email templates** — reusable, categorized, with placeholder auto-fill (`{{recipientName}}`, `{{date}}`, etc.)
|
|
|
|
### Files
|
|
|
|
- **File browser** with JMAP FileNode cloud storage (Stalwart native)
|
|
- **Upload and download** files with progress tracking and folder upload support
|
|
- **Folder navigation** with breadcrumb path and tree sidebar
|
|
- **Grid and list views** with sorting by name, size, or date
|
|
- **Clipboard operations** — cut, copy, paste, duplicate files
|
|
- **File preview** for images, text, audio, video, and more
|
|
- **Favorites and recent files** for quick access
|
|
- **Bulk operations** — multi-select, delete, move, download
|
|
|
|
### Security & Privacy
|
|
|
|
- **External content blocked** by default — trusted senders list for auto-load
|
|
- **HTML sanitization** via DOMPurify with XSS prevention
|
|
- **SPF/DKIM/DMARC** status indicators
|
|
- **OAuth2/OIDC with PKCE** for SSO (Keycloak, Authentik, or built-in), with OAuth-only mode
|
|
- **TOTP two-factor authentication**
|
|
- **Account security panel** — manage passwords and 2FA via Stalwart admin API
|
|
- **"Remember me"** — AES-256-GCM encrypted httpOnly cookie (opt-in)
|
|
- **Security headers** — CSP with per-request nonce, X-Frame-Options, Referrer-Policy
|
|
- **Newsletter unsubscribe** (RFC 2369)
|
|
|
|
### Interface
|
|
|
|
- **Three-pane layout** — sidebar, email list, viewer with resizable columns
|
|
- **Dark and light themes** with intelligent email color transformation
|
|
- **Responsive** — desktop sidebar + mobile bottom tab bar with tablet support
|
|
- **Keyboard shortcuts** — full navigation without a mouse
|
|
- **Drag-and-drop** email organization between mailboxes and tag assignment
|
|
- **Right-click context menus**, toast notifications with undo, form validation with shake feedback
|
|
- **Customizable toolbar** position and login page branding
|
|
- **Configurable logo** with light/dark mode variants
|
|
- **Settings sync** — preferences synchronized with the server (encrypted)
|
|
- **Storage quota** display
|
|
- **Shared folders** — multi-account access
|
|
- **Accessibility** — WCAG AA contrast, reduced-motion support, focus trap, screen reader live regions
|
|
|
|
### Internationalization
|
|
|
|
8 languages: English · Français · 日本語 · Español · Italiano · Deutsch · Nederlands · Português
|
|
|
|
Automatic browser detection with persistent preference.
|
|
|
|
### Identity Management
|
|
|
|
- **Multiple sender identities** with per-identity signatures
|
|
- **Sub-addressing** — `user+tag@domain.com` with contextual tag suggestions
|
|
- **Identity badges** in viewer and email list
|
|
|
|
### Operations
|
|
|
|
- **Automatic update check** — server logs when a newer release is available
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### Docker (recommended)
|
|
|
|
```bash
|
|
docker run -d -p 3000:3000 \
|
|
-e JMAP_SERVER_URL=https://mail.example.com \
|
|
ghcr.io/bulwarkmail/webmail:latest
|
|
```
|
|
|
|
Or with Docker Compose:
|
|
|
|
```bash
|
|
cp .env.example .env.local
|
|
# Edit .env.local — set JMAP_SERVER_URL
|
|
docker compose up -d
|
|
```
|
|
|
|
### From Source
|
|
|
|
```bash
|
|
git clone https://github.com/bulwarkmail/webmail.git
|
|
cd webmail
|
|
npm install
|
|
cp .env.example .env.local
|
|
# Edit .env.local — set JMAP_SERVER_URL
|
|
npm run build && npm start
|
|
```
|
|
|
|
### Development
|
|
|
|
```bash
|
|
npm run dev # Start dev server (mock JMAP server included)
|
|
npm run typecheck # Type checking
|
|
npm run lint # Linting
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Edit `.env.local`:
|
|
|
|
```env
|
|
# Required
|
|
JMAP_SERVER_URL=https://mail.example.com
|
|
|
|
# Optional
|
|
APP_NAME=My Webmail
|
|
```
|
|
|
|
All variables are **runtime** — Docker deployments can be configured without rebuilding.
|
|
|
|
<details>
|
|
<summary>OAuth2/OIDC (SSO)</summary>
|
|
|
|
```env
|
|
OAUTH_ENABLED=true
|
|
OAUTH_CLIENT_ID=webmail
|
|
OAUTH_CLIENT_SECRET= # optional, for confidential clients
|
|
OAUTH_ISSUER_URL= # optional, for external IdPs (Keycloak, Authentik)
|
|
```
|
|
|
|
Endpoints are auto-discovered via `.well-known/oauth-authorization-server` or `.well-known/openid-configuration`.
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Remember Me</summary>
|
|
|
|
```env
|
|
SESSION_SECRET=your-secret-key # Generate with: openssl rand -base64 32
|
|
```
|
|
|
|
Credentials encrypted with AES-256-GCM, stored in an httpOnly cookie (30-day expiry).
|
|
|
|
</details>
|
|
|
|
## Keyboard Shortcuts
|
|
|
|
| Key | Action |
|
|
| ------------- | ----------------------- |
|
|
| `j` / `k` | Navigate between emails |
|
|
| `Enter` / `o` | Open email |
|
|
| `Esc` | Close / deselect |
|
|
| `c` | Compose |
|
|
| `r` / `R` | Reply / Reply all |
|
|
| `f` | Forward |
|
|
| `s` | Star |
|
|
| `e` | Archive |
|
|
| `#` | Delete |
|
|
| `/` | Search |
|
|
| `?` | Show all shortcuts |
|
|
|
|
## Tech Stack
|
|
|
|
| | |
|
|
| ------------- | ------------------------------------------------- |
|
|
| **Framework** | [Next.js 16](https://nextjs.org/) with App Router |
|
|
| **Language** | TypeScript |
|
|
| **Styling** | [Tailwind CSS v4](https://tailwindcss.com/) |
|
|
| **State** | [Zustand](https://zustand-demo.pmnd.rs/) |
|
|
| **Protocol** | Custom JMAP client (RFC 8620) |
|
|
| **i18n** | [next-intl](https://next-intl-docs.vercel.app/) |
|
|
| **Icons** | [Lucide React](https://lucide.dev/) |
|
|
|
|
## 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.
|
|
|
|
## Contributing
|
|
|
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
|
|
## Roadmap
|
|
|
|
See [ROADMAP.md](ROADMAP.md) for planned features and current status.
|
|
|
|
## License
|
|
|
|
[MIT](LICENSE)
|
|
|
|
## Acknowledgments
|
|
|
|
Thanks to [root-fr/jmap-webmail](https://github.com/root-fr/jmap-webmail/) and [@ma2t](https://github.com/ma2t) for doing most of the groundwork that this project builds upon.
|