41 Commits
Author SHA1 Message Date
Matthieu MALVACHE 147f1b36b5 fix: remove the dead-end sub-addressing Learn More control
The button in Settings > Identities opened the identity manager, which
says nothing about sub-addressing. The info row keeps the explanation;
acting on +tag mail (auto-filing into folders) is planned as part of
the filter rule builder. Refs #76
2026-08-28 02:21:27 +02:00
Matthieu MALVACHE c3a79a8bc3 feat: v1.7.0 - unified inbox across accounts, cross-account search, send-as for shared accounts 2026-08-28 01:59:13 +02:00
Matthieu MALVACHE 6aa83258cd feat: v1.6.0 - global search, list pagination fix, server-side sort, Polish locale, menu accessibility 2026-07-05 14:25:39 +02:00
Matthieu MALVACHE e6a712f8b8 fix: v1.5.3 - stability and security fixes across send, filters, shared mailboxes and CSP 2026-07-05 04:53:54 +02:00
Matthieu MALVACHE f3e84a9549 fix: v1.5.1 - Gmail-origin attachments render, email-to-self delivered
- Attachments from providers that stamp a Content-ID on every part
  (e.g. Gmail) now show in the attachment panel; previously they were
  silently filtered out as "inline" even when the HTML body never
  cited their cid. The viewer now parses the body for actual cid:
  references and treats only those attachments as inline (#58).
- Email-to-self no longer gets discarded as a duplicate by the
  sender's own MTA. The send flow keeps the outgoing message in
  Drafts during submission and uses EmailSubmission.onSuccessUpdate\
Email to move it to Sent only after SMTP has accepted it, so the
  inbound delivery for self-send doesn't match a pre-existing
  Message-ID in the account (#60).

Thanks @melges-morgen and @tamisoft for the reports.
2026-04-17 14:58:11 +02:00
Matthieu MALVACHE 41cc48203c feat: v1.5.0 - print, archive-thread, favicon badge + avatars, ru/uk locales
Community PRs and targeted feature work. Highlights:

Features
- Archive now operates on the whole conversation, matching Gmail (#49)
- Russian and Ukrainian locales, full translation sets (#59 @VsevolodSauta)
- Custom favicon with unread badge painted over the base mail icon;
  also fixes stale sidebar counters on JMAP push (#63 @jabiinfante)
- Optional domain-favicon avatars with a privacy-preserving proxy and
  a freemail denylist so the same provider logo isn't shown for every
  sender on a shared host (#22)

Fixes
- Print (Ctrl+P, button, menu) produces a clean single-column page for
  plain text and HTML emails alike, with actions/reply panels hidden,
  dark-mode overridden, and wide newsletters shrunk to fit A4
- Contacts now load past 500 entries by batching ContactCard/get to
  the server's maxObjectsInGet (#45 @capitanroy, #46)
- Sieve filter destinations use the full Parent/Child folder path so
  Stalwart can resolve them (#62 @travier)
- OIDC over plain HTTP shows a clear HTTPS-required banner instead of
  throwing crypto.subtle is undefined (#23 @jothoma1)
- Missing contacts delete-confirm translation keys added to every
  locale (only Dutch had them before)
- Favicon badge hook stopped tearing out Next.js's managed icon link,
  fixing a parentNode-is-null crash on route changes
- Contact empty-state action buttons fit their container (#56)
- Print layout excludes sidebar/list (#55 @prastowoagungwidodo)

Docs
- README example for OAUTH_ONLY=true to disable Basic Auth (#61
  @travier)

Infrastructure
- Container images also published under jmap-webmail:1 for major-tag
  pinning (#57 @joelpurra, closes #54)
2026-04-17 14:39:50 +02:00
Matthieu MALVACHE cc01b84f46 fix(security): XSS in plain-text linkifier, bump vulnerable dependencies
The plain-text email renderer escaped <, >, and & before building anchor
tags for linkified URLs, but did not escape " or '. A crafted URL
containing a quote broke out of the href attribute and could inject
event handlers into the rendered HTML. Affects both the single-email
viewer and the threaded conversation view.

Fix by extracting a shared plainTextToSafeHtml helper that escapes all
five HTML-significant characters in the correct order before
linkification. Both views route through it. Regression tests parse the
output and assert no event handler lands on the anchor element.

Reported privately by Linus Rath. Thank you for the responsible
disclosure.

Also bumps dependencies flagged by npm audit:
- Next.js 16.1.5 -> 16.2.4 (DoS in Server Components)
- next-intl 4.5.8 -> 4.9.1 (open redirect)
- DOMPurify 3.3.1 -> 3.4.0 (FORBID_TAGS bypass)
- picomatch, vite, brace-expansion resolve transitively

Also carries the Apache JAMES compose fix from the 1.4.0 cycle (explicit
text/plain type on textBody per RFC 8621 section 4.1.4) and the missing
email_viewer.send translation.

Release 1.4.1.
2026-04-16 22:51:58 +02:00
Matthieu MALVACHE 384b757815 feat: v1.4.0 - folder management, mail multi-selection, bug fixes
New features:
- Folder management with context menu, inline editing, drag-and-drop (#44)
- Mail multi-selection with batch move/delete and shift-click (#43)

Bug fixes:
- Health endpoint false-positive restarts (#41, thanks @wrenix and @ClemaX)
- Identity deletion failing (#42, thanks @freddij)
- Inline CID images, email list flicker, dark mode clipboard tint

Feature requests from @dlecourtaltimafr (#43, #44).
Contact pagination fix contributed by @capitanroy (#46).

Dependencies: Next.js 16.2.1, Tailwind 4.2.2, Zustand 5.0.12,
flatted CVE fix (GHSA-rf6f-7fwh-wjgh).
2026-03-23 15:24:46 +01:00
Matthieu MALVACHE f6e188560f chore: release v1.3.3 - security patches, community contributions
Next.js 16.2.0 security update, plus merged PRs #33-#40 from
rensreinders and wrenix (calendar improvements, contacts UX, navigation)
2026-03-20 16:54:09 +01:00
Rens Reinders 6758fae3ef fix: participant/invitation handling for Stalwart JMAP and deduplicate self-attendees (#36)
* fix: align calendar event payload with stalwart scheduling

* fix: dedupe calendar participants by normalized address

* chore: document calendar uid generation

* chore: clarify organizer participant guard
2026-03-18 21:13:36 +01:00
Rens Reinders 339c4e8640 feat: double-click to create event from month view with smart time suggestion (#37)
* feat: open event modal on month day cell click

* feat: suggest first available hour when creating from month view

* chore: document month view slot suggestion helpers

* fix(calendar): use double-click to create event in month view

* fix(calendar): use 9am fallback for non-today month slots
2026-03-18 21:13:33 +01:00
Rens Reinders 11a242ba40 fix: replace inline calendar delete confirms with centered modal dialog (#34)
* fix: more margin on the avatar to align with subject

* fix: fixed multi day events multiple items gap spacing

* fix: align sticky week headers with calendar grid

* fix: nice confirm modal

* fix: added locales

* fix: polish confirm dialog behavior and participant delete messaging

* fix: apply themed destructive colors without button shadow

* fix: restore destructive button theme styling
2026-03-17 23:46:34 +01:00
Rens Reinders ca6691fabb feat: simplify contact bulk selection actions menu (#39)
* feat(contacts): simplify bulk selection actions menu

* refactor(contacts): reuse shared context menu for bulk actions
2026-03-17 23:46:31 +01:00
Rens Reinders 9c75425503 feat: add week numbers column to month view grid (#38) 2026-03-17 23:46:28 +01:00
Matthieu MALVACHE f51c1feeab fix: consistent bottom navigation on tablet breakpoint for all pages
Bottom nav now renders on tablet/landscape viewports (768-1023px) across
Mail, Calendar, and Contacts. Added z-index for proper layering and
removed redundant active tab indicator bar.
2026-03-16 22:20:29 +01:00
Rens Reinders 8c5f11f5fa fix: align sticky week headers with calendar grid and fix scroll offset (#33)
* fix: more margin on the avatar to align with subject

* fix: fixed multi day events multiple items gap spacing

* fix: align sticky week headers with calendar grid

* fix: account for sticky header in week view initial scroll
2026-03-16 16:51:15 +01:00
Matthieu MALVACHE ede603563e feat: v1.2.0 — sandboxed email rendering, mobile UX, sidebar polish, API retry
New features:
- Sandboxed iframe rendering for rich HTML emails (CSS isolation)
- Mobile bottom action bar (Reply, Archive, Delete, More)
- Long-press context menu with haptic feedback on touch devices
- Tag counts sidebar section with batch JMAP queries
- Empty folder for Junk/Trash with batch delete progress
- Extra-compact density option (28px desktop, 44px touch)
- SPF/DKIM/DMARC security tooltips with plain-language explanations
- Resizable sidebars with drag, touch, and keyboard support
- Expandable sender info panel in email viewer
- API retry with exponential backoff for transient JMAP failures
- OAuth-only mode (OAUTH_ONLY env var)

Improvements:
- CSS-first responsive layout (no blink on orientation change)
- Touch-friendly context menu submenus (tap-to-expand)
- Click-to-toggle more-actions dropdown (was hover-only)
- Wide HTML emails horizontally scrollable in iframe
- All 8 locales updated with new translation keys
2026-03-16 16:29:47 +01:00
Matthieu MALVACHE 97546dbd58 fix: mobile navigation visibility and folder hierarchy in move dialog
- Bottom nav bar always visible on mobile, even when viewing an email (#30)
- Move-to-folder submenu shows hierarchical folder structure (#29)
2026-03-16 12:58:50 +01:00
Matthieu MALVACHE 5880120431 fix: calendar crash on missing duration, sieve filter activation, security patches
- Guard parseDuration() against undefined event.duration (#31)
- Use onSuccessActivateScript per RFC 9661 for sieve filter activation (#21)
- Update dompurify, undici, flatted for security fixes
2026-03-16 12:43:37 +01:00
Matthieu MALVACHE 58b9b70871 fix: resolve context menu submenu and move-to-folder issues (#19) 2026-03-02 09:10:03 +01:00
Matthieu MALVACHE 92620fb790 fix: details toggle UX, Edge Runtime warnings, minimatch CVE
- Keep show/hide details button in place when expanded (#18)
- Use i18n translations for details toggle text
- Split instrumentation for Edge Runtime compatibility
- Patch minimatch ReDoS (CVE-2026-27903)
2026-02-28 21:03:02 +01:00
Matthieu MALVACHE 02f4ce81e3 fix: include sender display name in From header and default identity selection
- Emails now include the identity display name in the From field so recipients
  see "Name <email>" instead of bare "<email>"
- Primary identity (matching login username) is pre-selected in composer dropdown
2026-02-25 12:35:39 +01:00
Matthieu MALVACHE 15c14b1833 chore: update dependencies and fix calendar event hooks
Bump tailwindcss 4.2.0, lucide-react 0.575.0, @typescript-eslint 8.56.0,
tailwind-merge 3.5.0, and patch-level updates across 48 transitive packages.
Fix missing useCallback dependency in calendar event card.
2026-02-22 18:07:30 +01:00
Matthieu MALVACHE 838ee4b8e5 fix(calendar): produce correct JMAP patch when removing recurrence rules
Include recurrenceRules, recurrenceOverrides, and excludedRecurrenceRules
in the update patch when clearing recurrence from an event. Also fix
"this and future" scope overriding user's recurrence changes.

Fixes #14
2026-02-22 17:52:21 +01:00
Matthieu MALVACHE ccbab654f3 feat(calendar): add drag-create, resize, recurring scope, quick-create, and duplication
- Click-drag on empty time slots to create events with pre-filled time range
- Resize events by dragging bottom edge (15-min snap, optimistic JMAP update)
- Recurring event edit/delete scope dialog (this/following/all occurrences)
- Double-click quick event creation with inline title input
- Event duplication button in modal (+1 day offset)
- Shared interaction hook for pointer-based calendar interactions

Fixes #13
2026-02-22 17:32:10 +01:00
Matthieu MALVACHE a43096485b feat: add UI/UX polish with navigation rail, confirm dialogs, welcome banner, and form validation
- Add NavigationRail component (desktop vertical icon sidebar + mobile bottom tab bar)
- Add ConfirmDialog with promise-based useConfirmDialog hook for async confirmation flow
- Add WelcomeBanner onboarding component (one-time display, localStorage persistence)
- Polish login form UX (shake on error, TOTP slide animation, password visibility toggle, session expired banner)
- Add inline form validation with shake animation in email composer and contacts
- Add empty state patterns for contacts (no data vs no search results with contextual actions)
- Improve toast notification system with undo action support and typed durations
- Add WCAG AA prefers-reduced-motion media query, safe area insets, sr-only live regions
- Add template settings tab and keyboard shortcut integration
- Update all 8 locale translations
2026-02-17 02:31:50 +01:00
Matthieu MALVACHE 2636a88820 feat: add email templates with placeholder variables and composer integration
- Reusable email templates with local storage persistence
- Dynamic placeholder variables ({{recipientName}}, {{date}}, etc.) with auto-fill
- Template manager modal with category filtering and search
- Template picker integrated in composer toolbar (Ctrl+Shift+T)
- Settings tab for template management
- 48 unit tests for template utilities
- i18n support for all 8 languages
2026-02-17 01:35:26 +01:00
Matthieu MALVACHE b65b2f26df feat: add participant scheduling with iTIP invitations and inline calendar invitation banner
Add organizer/attendee UI with RSVP, contact autocomplete for participants,
scheduling messages, and inline calendar invitation banner in email viewer
with auto-detect .ics attachments, RSVP/import to calendar, and cancellation display.
2026-02-17 01:09:57 +01:00
Matthieu MALVACHE 74763b384d fix(filters): show hierarchical folder structure in rule mailbox selector 2026-02-17 00:07:28 +01:00
Matthieu MALVACHE fea21d5bcd feat(calendar): add event notifications with alert evaluation
Add client-side calendar event notification system that evaluates JMAP
CalendarEventAlert triggers and displays toast notifications when alert
times are reached. Includes configurable notification sound, acknowledged
alert persistence, and proactive event fetching for background alerts.
Also mounts ToastContainer globally to fix silent toast failures.
2026-02-16 23:49:35 +01:00
Matthieu MALVACHE 73612313c0 feat: add email filters with JMAP Sieve Scripts (RFC 9661)
Server-side email filtering with visual rule builder and raw Sieve editor.
Conditions (From/To/Subject/Size/Body), actions (Move/Forward/Star/Discard),
auto-save with rollback, drag-and-drop reorder, opaque script reset,
accessibility focus traps, toast validation, and 8-language i18n support.
2026-02-16 23:09:18 +01:00
Matthieu MALVACHE ff65693e26 feat: add calendar drag-and-drop rescheduling and iCalendar import
- Drag events in week/day views to reschedule (15-min snap intervals)
- Drag events in month view to change date (preserves time)
- Visual snap indicators with time labels during drag
- iCalendar (.ics) file import via JMAP CalendarEvent/parse
- Import modal with file upload, event preview, calendar selector
- File validation (5MB max), bulk import with progress tracking
2026-02-16 21:09:13 +01:00
Matthieu MALVACHE e6f67c24cb feat: add JMAP Calendar integration with month/week/day/agenda views
Full calendar support via JMAP Calendars (RFC 8984):
- Event create/edit/delete with recurrence rules and reminders
- Multi-day event spanning, column-based overlap layout
- Locale-aware date formatting, first day of week and time format settings
- Real-time updates via push notifications
- ARIA accessibility, input validation, color sanitization
- Keyboard shortcuts, mobile touch targets, focus trap
- ICU pluralization for all 8 supported languages
2026-02-16 20:34:29 +01:00
Matthieu MALVACHE fb414bf2c9 feat: add contacts phase 2, advanced search, vacation responder, Docker & TOTP 2FA
- Contact groups/lists, vCard import/export (RFC 6350), bulk operations
- Advanced search with JMAP filter panel, search chips, cross-mailbox queries
- Vacation responder with JMAP VacationResponse, settings tab, sidebar indicator
- TOTP two-factor authentication support
- Docker multi-stage build with standalone output and docker-compose
- CSP Report-Only headers and security headers via proxy middleware
- Virtual scrolling for large email lists
- Structured server-side logger (text/JSON, configurable level)
- 450+ tests (contacts, vCard, threads, headers, identity, components)
- Playwright E2E framework setup
- Updated README and ROADMAP with all new features
2026-02-16 18:51:30 +01:00
Matthieu MALVACHE 8a5bc9b88d feat: add address book, fix email layout, update dependencies
- Address book with JMAP sync and local fallback (contacts CRUD,
  search/filter, composer autocomplete, i18n for 8 languages)
- Fix email layout: remove horizontal scroll, left-side clipping,
  and empty spaces from blocked external images in newsletters
- Update all dependencies to latest compatible versions
- Expand i18n from 3 to 8 languages (added ES, IT, DE, NL, PT)
- Upgrade Next.js to 16.1.6 for security patches
2026-02-16 17:25:20 +01:00
Matthieu MALVACHE 5d273e2109 feat: expand internationalization and add identity management
This release significantly expands internationalization support and adds comprehensive identity management features.

Internationalization (i18n):
- Add 5 new languages: Spanish, Italian, German, Dutch, Portuguese
- Expand from 3 to 8 total supported languages
- Redesign language switcher for better scalability (dropdown UI)
- Complete translations for all features across all languages

Identity Management:
- Multiple sender identities with per-identity signatures
- Sub-addressing support (user+tag@domain.com)
- Context-aware tag suggestions for sub-addresses
- Identity badges in email viewer and list
- Full CRUD operations for managing identities

Newsletter Management:
- RFC 2369 List-Unsubscribe support (one-click unsubscribe)
- HTTP and mailto unsubscribe methods
- Security validation prevents XSS attacks
- Two-step confirmation with persistent dismissal

Security & Accessibility:
- Dark mode email readability (intelligent color transformation)
- WCAG 2.0 Level AA color contrast compliance
- Comprehensive XSS prevention with validation utilities
- Unit test coverage for security-critical code (57 validation tests)

Testing:
- Add unit tests for validation utilities
- Add unit tests for email sanitization
- Add unit tests for color transformation
- Full test coverage for XSS attack vectors
2026-01-08 22:15:32 +01:00
Matthieu MALVACHE 0d68851b63 feat(i18n): Complete internationalization with timezone fixes and language switching
Completes full internationalization coverage for the webmail application with enhanced language support:

- Replace all remaining hardcoded English strings with translation keys
- Add timezone auto-detection to prevent hydration mismatches
- Enable instant client-side language switching without page reload
- Add 60+ new translation keys in English and French locales
- Improve language switcher component with proper state management
- Add health check endpoint for container orchestration

All user-facing text now supports English and French with no hardcoded fallbacks, providing a fully localized experience.
2026-01-08 04:29:19 +01:00
Matthieu MALVACHE 58cfe09dc6 feat: Add runtime config, trusted senders, JMAP identities, and UI improvements
- Runtime environment variables for Docker-friendly configuration
- Trusted senders list for automatic image loading
- JMAP identities for proper sender address
- Improved email composer readability
- Horizontal scroll for wide HTML emails
2026-01-08 02:08:18 +01:00
Matthieu MALVACHE dbffaf2a15 fix(email-viewer): Enable horizontal scroll for wide HTML emails
- Change overflow-hidden to overflow-x-auto on email body container
- Add CSS for email-content-wrapper with inline-block display
- Use width: max-content on email-content to respect intrinsic width
- Prevent tables with width="100%" from shrinking below content

Also updates dependencies:
- next: 16.0.10 -> 16.1.1
- react/react-dom: 19.2.1 -> 19.2.3
- next-intl: 4.5.8 -> 4.6.1
- tailwindcss: 4.1.17 -> 4.1.18
- eslint: 9.39.1 -> 9.39.2
- jmap-jam: 0.11.0 -> 0.13.1
- lucide-react: 0.556.0 -> 0.562.0
2025-12-24 04:05:28 +01:00
Matthieu MALVACHE 93834511c0 feat: Search pagination and UX improvements
- Add pagination support to search (previously limited to 50 results)
- Search now scoped to current mailbox/folder
- Support shared mailbox folders in search
- Display total results count (e.g., "50 of 1400 conversations")
- Add clear (X) button to search input
- Re-run search when changing folders during active search
- Remove unused sidebar screenshot
2025-12-17 18:39:49 +01:00
Matthieu MALVACHE cf21a84263 Initial release: JMAP Webmail Client
A modern, privacy-focused webmail client built with Next.js and the JMAP protocol.
Designed for Stalwart Mail Server.

Features:
- Full email operations (compose, reply, forward, threading)
- Real-time push notifications
- Dark/light theme support
- Mobile responsive design
- Keyboard shortcuts
- Drag-and-drop organization
- i18n (English/French)
- Security-first (external content blocked, HTML sanitization)
2025-12-10 17:54:22 +01:00