diff --git a/README.md b/README.md index 5e3c833e..88c66bc5 100644 --- a/README.md +++ b/README.md @@ -1,177 +1,166 @@ # JMAP Webmail -A modern, privacy-focused webmail client built with Next.js and the JMAP protocol. +A webmail client for [Stalwart Mail Server](https://stalw.art/), built with Next.js and the JMAP protocol. -## Built for Stalwart +## Why Stalwart? -This webmail client is designed to work seamlessly with [**Stalwart Mail Server**](https://stalw.art/) - a modern, secure, and blazingly fast mail server written in Rust. +Stalwart is a mail server written in Rust with native JMAP support, not IMAP/SMTP with JMAP added as an afterthought. It handles JMAP, IMAP, SMTP, and ManageSieve. Self-hosted, no third-party dependencies. -**Why Stalwart?** -- **Modern Architecture**: Built from the ground up with Rust for performance and safety -- **JMAP-Native**: First-class support for the JMAP protocol (not just IMAP/SMTP bolted on) -- **Privacy-Focused**: Self-hosted, no third-party dependencies, full control over your data -- **Feature-Rich**: Supports JMAP, IMAP, SMTP, ManageSieve, and more - -[Stalwart GitHub](https://github.com/stalwartlabs/mail-server) | [Documentation](https://stalw.art/docs/) +[Stalwart on GitHub](https://github.com/stalwartlabs/mail-server) | [Documentation](https://stalw.art/docs/) ## Features -### Core Email Operations -- Read, compose, reply, reply-all, and forward emails -- Full HTML email rendering with security sanitization +### Email + +- Read, compose, reply, reply-all, and forward +- HTML rendering with DOMPurify sanitization - Attachment upload and download - Draft auto-save with discard confirmation -- Email threading with Gmail-style inline expansion +- Threading with inline expansion - Mark as read/unread, star/unstar - Archive and delete with configurable behavior -- Color tags/labels for email organization -- Advanced search with JMAP filter panel, search chips, and cross-mailbox queries -- Virtual scrolling for large email lists +- Color tags/labels +- Search with JMAP filter panel, search chips, cross-mailbox queries +- Virtual scrolling for large lists -### User Interface -- Clean, minimalist three-pane layout -- Dark and light theme support -- Responsive design for mobile and desktop -- Navigation rail (desktop icon sidebar + mobile bottom tab bar) -- Keyboard shortcuts for power users +### Interface + +- Three-pane layout with dark and light themes +- Responsive (desktop sidebar + mobile bottom tab bar) +- Keyboard shortcuts - Drag-and-drop email organization - Right-click context menus -- Smooth animations and transitions (respects prefers-reduced-motion) +- Animations that respect `prefers-reduced-motion` - Infinite scroll pagination -- Welcome banner for first-time users -- Confirmation dialogs with promise-based async flow -- Toast notifications with undo action support -- Inline form validation with shake animation feedback -- Empty state patterns with contextual actions -- Login UX polish (error shake, discreet 2FA toggle, password visibility toggle, session expired banner) -- Safe area inset support for notched devices -- Screen reader live region announcements +- Toast notifications with undo support +- Form validation with shake feedback +- Safe area insets for notched devices +- Screen reader live regions + +### Real-time -### Real-time Updates - Push notifications via JMAP EventSource -- Real-time unread counts -- Live email arrival notifications +- Live unread counts +- Email arrival notifications - Connection status indicator -### Identity Management +### Identity management + - Multiple sender identities with per-identity signatures -- Sub-addressing support (user+tag@domain.com) with tag suggestions -- Identity badges in email viewer and list +- Sub-addressing (user+tag@domain.com) with tag suggestions +- Identity badges in viewer and list + +### Address book -### Address Book - Contact management with search and filtering - JMAP server sync (RFC 9553/9610) with local fallback -- Email autocomplete from contacts in composer -- Contact groups/lists with group expansion in composer +- Email autocomplete in composer +- Contact groups with group expansion - vCard import/export (RFC 6350) with duplicate detection - Bulk operations (multi-select, delete, group add, export) ### Calendar -- JMAP Calendar integration (RFC 8984) with capability detection + +- JMAP Calendar (RFC 8984) with capability detection - Month, week, day, and agenda views -- Event create, edit, and delete with recurrence rules and reminders -- Participant scheduling with iTIP invitations (organizer/attendee roles, RSVP) -- Inline calendar invitation banner in email viewer (auto-detect .ics attachments, RSVP, import) -- Multi-day events spanning across days, column-based overlap layout +- Event create, edit, delete with recurrence and reminders +- Participant scheduling with iTIP invitations and RSVP +- Inline calendar invitation banner in email viewer (.ics detection, RSVP, import) +- Multi-day events, column-based overlap layout - Mini-calendar sidebar with calendar visibility toggles -- Locale-aware date formatting (respects user's language) -- Settings for first day of week, time format (12h/24h), and default view -- Drag-and-drop rescheduling (week/day time snap, month date move) -- Click-drag on empty time slots to create events with pre-filled time range -- Resize events by dragging bottom edge (15-minute snap) -- Double-click quick create with inline title input +- Locale-aware date formatting +- Settings for first day of week, time format (12h/24h), default view +- Drag-and-drop rescheduling with time snap +- Click-drag on empty slots to create events +- Resize events by dragging (15-minute snap) +- Double-click quick create - Event duplication (+1 day offset) -- Recurring event edit/delete scope (this event, this and following, all events) -- iCalendar (.ics) file import with event preview and bulk create -- Real-time updates via JMAP push notifications -- Event notifications with client-side alert evaluation and toast display -- Configurable notification sound and enable/disable toggles -- Keyboard shortcuts: m/w/d/a (views), t (today), n (new event), arrows (navigate) +- Recurring event edit/delete scope (this, this and following, all) +- iCalendar (.ics) file import with preview +- Real-time updates via JMAP push +- Event notifications with configurable sound -### Email Templates -- Reusable email templates with category organization (General, Business, Personal, Support, Follow-up) -- Dynamic placeholder variables (`{{recipientName}}`, `{{date}}`, etc.) with auto-fill from composer context -- Template picker in compose toolbar with search and category filter -- Custom placeholder prompt when inserting templates -- Template manager for creating, editing, duplicating, and deleting templates -- Settings tab for template management +### Email templates -### Email Filters -- Server-side email filtering with JMAP Sieve Scripts (RFC 9661) -- Visual rule builder with conditions (From, To, Subject, Size, Body, etc.) and actions (Move, Forward, Mark read, Star, Discard, Reject, etc.) -- Raw Sieve script editor for advanced users with syntax validation -- Auto-save on rule changes with rollback on failure +- Reusable templates organized by category +- Placeholder variables (`{{recipientName}}`, `{{date}}`, etc.) with auto-fill +- Template picker in compose toolbar with search and filter +- Template manager in settings + +### Email filters + +- Server-side filtering with JMAP Sieve Scripts (RFC 9661) +- Visual rule builder: conditions (From, To, Subject, Size, Body...) and actions (Move, Forward, Mark read, Star, Discard, Reject...) +- Raw Sieve editor with syntax validation +- Auto-save with rollback on failure - Drag-and-drop rule reordering -- Reset opaque scripts back to visual builder -- Capability-gated (only shown when server supports Sieve) +- Only shown when the server supports Sieve -### Vacation Responder -- JMAP VacationResponse management with date range scheduling -- Dedicated settings tab with message configuration -- Sidebar indicator when vacation auto-reply is active +### Vacation responder + +- JMAP VacationResponse with date range scheduling +- Settings tab for message configuration +- Sidebar indicator when active + +### Security and privacy -### Security & Privacy - External content blocked by default - Trusted senders list for automatic image loading -- HTML sanitization with DOMPurify +- HTML sanitization (DOMPurify) - SPF/DKIM/DMARC status indicators -- No password storage by default (session-based auth) -- TOTP two-factor authentication support -- "Remember me" session persistence (AES-256-GCM encrypted httpOnly cookie, opt-in) -- OAuth2/OIDC with PKCE for SSO login (opt-in, RP-initiated logout, Basic Auth remains default) +- Session-based auth, no password storage by default +- TOTP two-factor authentication +- "Remember me" with AES-256-GCM encrypted httpOnly cookie (opt-in) +- OAuth2/OIDC with PKCE for SSO (opt-in, RP-initiated logout) - External IdP support (Keycloak, Authentik) via configurable issuer URL -- Session persistence via httpOnly cookies (refresh tokens for OAuth, encrypted credentials for Basic Auth) -- CORS misconfiguration detection with actionable error messages -- Shared folder support with proper permissions -- Newsletter unsubscribe support (RFC 2369) -- CSP headers and security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) +- CORS misconfiguration detection with detailed error messages +- Shared folder support +- Newsletter unsubscribe (RFC 2369) +- CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy headers ### Internationalization -- 8 language support: English, French, Japanese, Spanish, Italian, German, Dutch, Portuguese + +- 8 languages: English, French, Japanese, Spanish, Italian, German, Dutch, Portuguese - Automatic browser language detection - Persistent language preference ### Deployment -- Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) (amd64/arm64) -- Docker support with multi-stage build and standalone output -- Runtime environment variables (no rebuild needed for config changes) -- Health check endpoint for container orchestration -- Structured server-side logging (text/JSON format) -## Tech Stack +- Pre-built Docker images on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) (amd64/arm64) +- Multi-stage build with standalone output +- Runtime environment variables (no rebuild needed) +- Health check endpoint +- Structured logging (text/JSON) -- **Framework**: [Next.js 16](https://nextjs.org/) with App Router -- **Language**: TypeScript -- **Styling**: [Tailwind CSS v4](https://tailwindcss.com/) -- **State Management**: [Zustand](https://zustand-demo.pmnd.rs/) -- **JMAP Client**: [jmap-jam](https://www.npmjs.com/package/jmap-jam) -- **i18n**: [next-intl](https://next-intl-docs.vercel.app/) -- **Icons**: [Lucide React](https://lucide.dev/) +## Tech stack -## Getting Started +- [Next.js 16](https://nextjs.org/) with App Router +- TypeScript +- [Tailwind CSS v4](https://tailwindcss.com/) +- [Zustand](https://zustand-demo.pmnd.rs/) for state management +- Custom JMAP client (RFC 8620) +- [next-intl](https://next-intl-docs.vercel.app/) for i18n +- [Lucide React](https://lucide.dev/) icons + +## Getting started ### Prerequisites - Node.js 18+ -- A JMAP-compatible mail server (we recommend [Stalwart](https://stalw.art/)) +- A JMAP-compatible mail server ([Stalwart](https://stalw.art/) recommended) ### Installation ```bash -# Clone the repository git clone https://github.com/root-fr/jmap-webmail.git cd jmap-webmail - -# Install dependencies npm install - -# Copy environment configuration cp .env.example .env.local ``` ### Configuration -Edit `.env.local` with your settings: +Edit `.env.local`: ```env # App name displayed in the UI @@ -181,7 +170,7 @@ APP_NAME=My Webmail JMAP_SERVER_URL=https://mail.example.com ``` -**Note:** These are runtime environment variables, read at request time. This enables Docker deployments to be configured without rebuilding the image. Legacy `NEXT_PUBLIC_*` variables are still supported as fallbacks. +These are runtime environment variables, read at request time. Docker deployments can be configured without rebuilding. Legacy `NEXT_PUBLIC_*` variables still work as fallbacks. #### OAuth2/OIDC (optional) @@ -194,9 +183,9 @@ OAUTH_CLIENT_SECRET= # optional, for confidential clients OAUTH_ISSUER_URL= # optional, for external IdPs (Keycloak, Authentik) ``` -OAuth endpoints are auto-discovered via `.well-known/oauth-authorization-server` or `.well-known/openid-configuration`. If your JMAP server delegates auth to an external IdP, set `OAUTH_ISSUER_URL` to the IdP's base URL (e.g., `https://keycloak.example.com/realms/mail`). +Endpoints are auto-discovered via `.well-known/oauth-authorization-server` or `.well-known/openid-configuration`. If your JMAP server delegates auth to an external IdP, set `OAUTH_ISSUER_URL` to the IdP's base URL (e.g., `https://keycloak.example.com/realms/mail`). -#### Remember Me (optional) +#### Remember me (optional) To enable "Remember me" for Basic Auth login: @@ -209,46 +198,38 @@ When set, a "Remember me" checkbox appears on the login form. Credentials are en ### Development ```bash -# Start development server -npm run dev - -# Type checking -npm run typecheck - -# Linting -npm run lint +npm run dev # Start dev server +npm run typecheck # Type checking +npm run lint # Linting ``` -### Production Build +### Production ```bash -# Build for production npm run build - -# Start production server npm start ``` ### Docker ```bash -# Using the pre-built image (recommended) +# Pre-built image docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com rootfr/jmap-webmail:latest -# Or from GHCR +# From GHCR docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com ghcr.io/root-fr/jmap-webmail:latest -# Or with docker compose +# With docker compose cp .env.example .env.local # Edit .env.local with your JMAP_SERVER_URL docker compose up -d -# Or build from source +# Build from source docker build -t jmap-webmail . docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com jmap-webmail ``` -## Keyboard Shortcuts +## Keyboard shortcuts | Key | Action | |-----|--------| @@ -317,18 +298,17 @@ docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com jmap-webmail ## Contributing -We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. +See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. ## Roadmap -See [ROADMAP.md](ROADMAP.md) for planned features and development status. +See [ROADMAP.md](ROADMAP.md) for planned features. ## Acknowledgments -- [Stalwart Labs](https://stalw.art/) for creating an excellent JMAP mail server -- The [JMAP](https://jmap.io/) working group for the protocol specification -- All contributors and users of this project +- [Stalwart Labs](https://stalw.art/) for the mail server +- The [JMAP](https://jmap.io/) working group for the protocol spec ## License -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +MIT. See [LICENSE](LICENSE). diff --git a/ROADMAP.md b/ROADMAP.md index 903f3a60..8b8714c6 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,7 +8,7 @@ This document tracks the development status and planned features for JMAP Webmai - [x] Next.js 16 with TypeScript and App Router - [x] Tailwind CSS v4 with Oxide engine - [x] Zustand state management -- [x] JMAP client implementation (jmap-jam) +- [x] Custom JMAP client implementation (RFC 8620) ### Authentication - [x] Login with JMAP server authentication