Commit Graph
176 Commits
Author SHA1 Message Date
Matthieu MALVACHE a030707cd6 feat(jmap): add Mailbox/set methods for create, update, destroy (#44) 2026-03-23 14:13:01 +01:00
Matthieu MALVACHE cb862994e3 fix: render inline CID images in email body instead of showing as attachments
Emails with embedded images (cid: references) displayed them as
downloadable attachments because the browser cannot resolve cid: URLs
and the attachments were not filtered. Added fetchBlobAsObjectUrl to
the JMAP client, pre-fetch inline images as object URLs, replace cid:
references in sanitized HTML, and filter CID attachments from the
download list in both the email viewer and thread conversation view.
2026-03-23 14:11:25 +01:00
Matthieu MALVACHE 146921d5f0 fix: eliminate email list flicker during loading and after-action refreshes
Shared isLoading flag caused the list to dim on unrelated operations
(send, batch actions, mailbox refresh). After-action fetches also
triggered a full loading overlay unnecessarily. Now operations that
don't fetch emails no longer set isLoading, after-action refreshes
use silent refreshCurrentMailbox, and the loading overlay only appears
after a 300ms delay to skip fast fetches.
2026-03-23 14:11:09 +01:00
Matthieu MALVACHE c80a5a4d51 docs: add folder management implementation plan (#44)
8-task plan covering JMAP client methods, store layer, DragDropContext
extension, i18n, sidebar UI with inline editing and drag-and-drop.
2026-03-23 14:09:28 +01:00
Matthieu MALVACHE 7bed7ff7c7 docs: add folder management design spec (#44)
Spec for IMAP folder CRUD operations: create, rename, move, and delete
mailboxes via the sidebar context menu and drag-and-drop.
2026-03-23 13:59:28 +01:00
Matthieu MALVACHE f646badc55 fix: remove production console statements and explain eslint-disable comments
Remove ~60 console.error/log/warn calls from application code that were
leaking implementation details to browser devtools. Errors are already
surfaced to users via toast notifications or state updates.

Add missing rationale to all 9 bare eslint-disable comments so future
readers understand why deps are intentionally excluded.
2026-03-23 13:25:50 +01:00
Matthieu MALVACHE 4c97d2d41d fix(i18n): add missing delete_confirm_title and delete_confirm_message keys (#43) 2026-03-23 13:21:51 +01:00
Matthieu MALVACHE b685e37c4e fix: resolve lint errors in email store and move-to-popover (#43) 2026-03-23 13:07:24 +01:00
Matthieu MALVACHE ae92bd2cbc feat: complete multi-selection store methods, toolbar integration, and shift-click support (#43) 2026-03-23 13:02:58 +01:00
Matthieu MALVACHE 6fc7217185 feat(i18n): add translation keys for multi-selection batch actions (#43) 2026-03-23 12:56:00 +01:00
Matthieu MALVACHE 837ef722b6 feat: add MoveToPopover component with search and keyboard navigation (#43) 2026-03-23 12:55:43 +01:00
Matthieu MALVACHE 3835efb3fa feat(store): add range selection, filter selection, and lastSelectedIndex tracking (#43) 2026-03-23 12:54:23 +01:00
Matthieu MALVACHE 84c43f8b0e fix: add urn:ietf:params:jmap:submission to Identity and EmailSubmission ops (#42)
Per RFC 8621, Identity/get, Identity/set, and EmailSubmission/set require
the submission capability. Missing it caused Stalwart to reject identity
deletion (and potentially other identity operations).
2026-03-23 12:18:42 +01:00
Matthieu MALVACHE 0948108792 fix: use v8 heap_size_limit for health check instead of heapTotal (#41)
heapTotal is V8's current allocation, not the max. A 35MB process with
37MB allocated reads as 95% when the real limit is ~2GB, causing
container restarts. Also fix stale calendar-participants test expectations.
2026-03-23 12:18:27 +01:00
Matthieu MALVACHE df53c31708 chore: update Next.js 16.1.6 -> 16.2.0 (5 security fixes)
Fixes: CSRF bypass on Server Actions, HTTP request smuggling in
rewrites, unbounded image disk cache, postponed resume DoS, dev
HMR websocket CSRF bypass.
2026-03-20 16:52:32 +01:00
Rens Reinders 0153f66340 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:52 +01:00
Rens Reinders 167014871d 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:52 +01:00
WrenIX e9baac022c fix: hide vertical nav rail on tablet to avoid duplicate navigation (#40) 2026-03-18 11:09:35 +01:00
Rens Reinders 53ecfe5f69 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-18 11:09:35 +01:00
Rens Reinders ae0412d3db feat: add week numbers column to month view grid (#38) 2026-03-18 11:09:35 +01:00
Rens Reinders f6492bbeda 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-18 11:09:35 +01:00
Rens Reinders 3c0f3400b4 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-18 11:09:35 +01:00
Matthieu MALVACHE da158613ea chore: bump version to 1.3.2 2026-03-17 13:40:28 +01:00
Matthieu MALVACHE 961b3edc3a fix: consistent tablet navigation across all pages and nav bar polish
Show bottom nav on tablet breakpoint (768-1023px) for calendar and
contacts pages, matching the mail page. Add z-index to prevent content
bleeding through. Remove redundant active indicator bar since color
already signals active state.
2026-03-16 22:18:59 +01:00
Matthieu MALVACHE 52ae100c97 fix: show bottom navigation on tablet breakpoint for calendar and contacts pages
Consistent with the mail page fix - all three sections now show the
horizontal navigation bar on tablet/landscape viewports (768-1023px).
2026-03-16 21:20:10 +01:00
Matthieu MALVACHE ccd146f3da chore: bump version to 1.3.1 2026-03-16 17:14:54 +01:00
Matthieu MALVACHE 65d7f9c922 fix: show bottom navigation bar on tablet/landscape breakpoint (768-1023px)
Neither desktop vertical nav nor mobile bottom nav rendered in the
tablet range, leaving users with no way to switch sections.

Closes #30
2026-03-16 17:14:20 +01:00
Matthieu MALVACHE 05cdb6311a chore: bump version to 1.3.0 2026-03-16 16:30:46 +01:00
Matthieu MALVACHE 3bc2bc0ad8 docs: update ARCHITECTURE.md with v1.2.0 features 2026-03-16 16:24:48 +01:00
Matthieu MALVACHE 77c1133f06 fix: improve mobile/tablet layout transitions and touch interactions
- Remove isMobile/isTablet JS state from layout classes to eliminate
  orientation-change blink (CSS breakpoints apply instantly)
- Extract dismissViewer() helper for return-to-list pattern (was duplicated 4x)
- Convert more-actions dropdown from hover-only to click-toggle (works on touch)
- Add Escape key and role attributes to more-actions menu
- Reset showMoreActions on email change to prevent stale menu
- Move overflow-x:auto to iframe inner body stylesheet (was inert on iframe element)
- Reset tabletListVisible when crossing to desktop breakpoint
2026-03-16 16:14:40 +01:00
Matthieu MALVACHE 0652700256 fix: remove unused error variable in empty folder catch 2026-03-16 15:41:14 +01:00
Matthieu MALVACHE 27911dfe76 feat: add UX & robustness improvements (iframe rendering, retry, mobile, polish)
P0 Core:
- Sandboxed iframe rendering for rich HTML emails (CSS isolation)
- API retry with exponential backoff for transient JMAP failures
- Mobile bottom action bar with touch-friendly email actions
- Long-press context menu + tap-to-expand submenus on touch devices

P1 Polish:
- Tag counts sidebar section with JMAP batch queries
- Empty folder option for Junk/Trash with batch delete
- Extra-compact density option (28px rows, 44px on 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

All 8 locales updated (en/fr/ja/es/it/de/nl/pt).
2026-03-16 15:40:24 +01:00
Matthieu MALVACHE 3733a704b7 chore: bump version to 1.2.0 2026-03-16 13:07:46 +01:00
Matthieu MALVACHE 512c97f656 feat: add OAUTH_ONLY mode to hide basic auth form on login page
New OAUTH_ONLY env var hides username/password fields and promotes the
SSO button as the primary login method. Useful for deployments that
want to enforce OAuth-only authentication.

Includes retry button when OAuth discovery fails to avoid dead-end
login pages.

Closes #32
2026-03-16 13:07:08 +01:00
Matthieu MALVACHE 96ddac27da chore: bump version to 1.1.4 2026-03-16 12:58:13 +01:00
Matthieu MALVACHE 2de80badc1 fix: show mobile nav in viewer mode and add folder hierarchy to move dialog
Mobile bottom navigation bar was hidden when viewing an email, trapping
users in the mail section. Now always visible on mobile.

Move-to-folder submenu now shows hierarchical folder structure using
buildMailboxTree/flattenMailboxTree instead of a flat list.

Closes #30, closes #29
2026-03-16 12:58:04 +01:00
Matthieu MALVACHE 17b0df4c2f chore: bump version to 1.1.3 2026-03-16 12:41:37 +01:00
Matthieu MALVACHE cc89763035 chore: update dependencies to fix security vulnerabilities
dompurify 3.3.1 -> 3.3.3 (XSS fix)
undici 7.22.0 -> 7.24.4 (WebSocket crash, CRLF injection, smuggling)
flatted 3.3.3 -> 3.4.1 (DoS via unbounded recursion)
2026-03-16 12:41:26 +01:00
Matthieu MALVACHE 4aaef1ebf1 fix: resolve calendar crash on undefined duration and sieve filter save error
parseDuration() now handles undefined event.duration gracefully instead
of crashing on .match(). CalendarEvent.duration type updated to reflect
that JMAP servers may omit this field.

Sieve filter activation replaced isActive (server-set per RFC 9661) with
onSuccessActivateScript. Create/update calls merged with activation into
single JMAP roundtrips.

Closes #31, closes #21
2026-03-16 12:41:10 +01:00
Matthieu MALVACHE 2790b877c9 chore: bump version to 1.1.2 2026-03-02 09:09:21 +01:00
Matthieu MALVACHE 5623460b82 chore: update patch/minor dependencies
tailwindcss 4.2.1, lucide-react 0.576.0, @tanstack/react-virtual
3.13.19, @typescript-eslint/* 8.56.1, globals 17.4.0, @types/node 25.3.3
2026-03-02 09:08:48 +01:00
Matthieu MALVACHE c787acc34f fix: resolve context menu submenu usability and move-to-folder failures
The context menu's "Move to folder" submenu was practically unusable:
scroll events inside the folder list closed the entire menu, and moving
the mouse from the trigger to the submenu dismissed it instantly.

Additionally, the JMAP moveEmail call silently discarded server errors
and always used the primary account ID, causing moves to appear to
succeed locally while the server rejected them.

Closes root-fr/jmap-webmail#19
2026-03-02 09:08:36 +01:00
Matthieu MALVACHE 2d5b5c09b5 chore: bump version to 1.1.1 2026-02-28 21:01:56 +01:00
Matthieu MALVACHE b4f4be31f6 fix: resolve Edge Runtime warnings in instrumentation
Split instrumentation into two files so the Edge bundler never sees
Node.js-specific imports (fs, process.cwd). The thin entry point
conditionally imports the Node-only module via NEXT_RUNTIME check.
2026-02-28 20:50:19 +01:00
Matthieu MALVACHE 329401b431 fix(security): patch minimatch ReDoS vulnerability (CVE-2026-27903)
Upgrade minimatch 9.0.6→9.0.9 and 3.1.3→3.1.5 to fix high-severity
ReDoS via combinatorial backtracking in matchOne() with multiple
non-adjacent GLOBSTAR segments.
2026-02-28 20:50:09 +01:00
Matthieu MALVACHE 8554b30e5b fix: keep show/hide details toggle in place when expanded
Move the toggle button above the expandable details section so it stays
at the same position regardless of expand/collapse state. Also replace
hardcoded English text with i18n translations.

Closes #18
2026-02-28 20:49:57 +01:00
Matthieu MALVACHE bf3de065b9 chore: bump version to 1.1.0 2026-02-28 14:58:02 +01:00
Matthieu MALVACHE 0a7d266c7c feat: add server-side version update check on startup
Logs current version to server console and checks GitHub for newer
releases in production. Keeps version info out of the client bundle.
2026-02-28 14:57:15 +01:00
Matthieu MALVACHE d3d0776a50 chore: bump version to 1.0.2 2026-02-26 13:36:22 +01:00
Matthieu MALVACHE b97de51262 fix(docker): resolve 4 CVEs in production image
Remove npm/npx from runner stage (unused at runtime) to eliminate
minimatch and tar CVEs. Upgrade Alpine packages to patch busybox
and zlib vulnerabilities.
2026-02-26 13:35:45 +01:00