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.
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.
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.
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).
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.
Fixes: CSRF bypass on Server Actions, HTTP request smuggling in
rewrites, unbounded image disk cache, postponed resume DoS, dev
HMR websocket CSRF bypass.
* 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
* 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
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.
- 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
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).
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
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
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
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.
Closesroot-fr/jmap-webmail#19
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.
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.
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
Remove npm/npx from runner stage (unused at runtime) to eliminate
minimatch and tar CVEs. Upgrade Alpine packages to patch busybox
and zlib vulnerabilities.