- Created demo emails with various states (inbox, sent, drafts, trash, etc.) in `emails.ts`.
- Added demo file nodes representing directories and files in `files.ts`.
- Implemented demo Sieve capabilities and scripts in `filters.ts`.
- Defined demo identities for users in `identities.ts`.
- Established demo mailboxes with permissions and counts in `mailboxes.ts`.
- Created a demo vacation response in `vacation.ts`.
- Introduced a comprehensive JMAP client interface in `client-interface.ts` to standardize interactions with the JMAP API.
- Add AccountSwitcher component for managing user accounts with UI for switching, adding, and logging out.
- Create account state manager to handle snapshots of account-specific states for efficient switching.
- Introduce utility functions for account management, including ID generation and avatar color assignment.
- Implement Zustand store for account management, supporting addition, removal, and state retrieval of accounts.
Add a new Files section powered by WebDAV for browsing, uploading,
downloading, renaming, and deleting files and folders.
New features:
- WebDAV file browser with grid/list views and breadcrumb navigation
- File upload (drag-and-drop and button), folder creation, rename, delete
- File preview modals for images and other file types
- WebDAV proxy API route to handle authentication
- Navigation rail entry for Files (auto-hidden when WebDAV is unsupported)
Auth improvements:
- Fix premature redirects on calendar, contacts, and settings pages by
adding explicit auth check on mount before redirecting to login
- Persist active settings tab in localStorage
Other:
- Expose getAuthHeader() and getServerUrl() on JMAPClient
- Add WebDAV store with connection testing and capability detection
- Add i18n translations for file browser in all 8 locales (de, en, es,
fr, it, ja, nl, pt)
- Display Bulwark logo on the login page, with theme-aware switching
between light and dark variants based on the resolved theme
- Add LOGIN_LOGO_LIGHT_URL and LOGIN_LOGO_DARK_URL env variables to
allow custom logo overrides (defaults to bundled Bulwark branding)
- Expose logo config through /api/config endpoint and useConfig hook
- Add logo URL prompts to the setup.sh installer branding step
- Rename branding assets to use underscores instead of spaces
- Added support for parsing and generating additional vCard properties including GENDER, LOGO, SOUND, LABEL, CALURI, CALADRURI, FBURL, and SOURCE.
- Extended ContactCard interface to include new fields such as gender, media, anniversaries, online services, and personal info.
- Implemented logic to handle multi-part TLDs for domain extraction in avatars.
- Improved avatar component to prioritize contact photos and handle inline images in emails.
- Updated localization files to include new fields and labels for contact details.
- Refactored contact store to expose a method for retrieving contact photos.
- Enhanced unit tests to cover new vCard properties and ensure correct parsing and generation.
Replace all mock data in the dev JMAP server with European-themed
content: 42 emails (was 13), 20 contacts across 2 address books
(was 3), 5 calendars and 35 events with recurrence, overlaps,
and all-day entries.
Move keyword tags in email/thread list items from the subject line
to the header row alongside the date for a cleaner layout.
Update test assertions to match the new mock data.
Resizable Columns
- Add ResizeHandle component with mouse drag, keyboard (Arrow keys),
and double-click to reset to default width
- Add sidebarWidth/emailListWidth to ui-store with clamping + persistence
- Wire resize handles between sidebar/email-list panels on desktop
Navigation Rail Overhaul
- Move StorageQuotaCircle, push-status, sign-out from Sidebar to NavigationRail
- Interactive SVG ring with popover breakdown (used/free/total)
- Sidebar collapse state lifted to ui-store
- Show total email count per mailbox alongside unread badge
Email Multi-Selection & Drag-and-Drop
- Ctrl+Click (toggle) and Shift+Click (range) on all list items
- Add selectRangeEmails and lastSelectedEmailId to email-store
- Enable drag-and-drop on thread items and thread headers
- useEmailDrag accepts optional threadEmails for full-thread drag
Email Viewer Layout
- Remove card wrapper for cleaner full-width reading
- Always render HTML body when available
- Adjust skeleton loader to match flat layout
Modal & UI Polish
- Standardise backdrops, close buttons, padding, border-radius, transitions
- Migrate template-string classNames to cn() in settings
- Unify focus-ring token to ring-ring on form controls
i18n
- Add storage_used/free/total keys to all 8 locales
Dev Mock JMAP Server (new, gated by DEV_MOCK_JMAP=true)
- Session, Mailbox/Email/Thread/Identity CRUD, back-references, upload
- GET /download with Content-Disposition, GET /eventsource SSE
Tests (46 new)
- ui-store (13), email-selection (10), resize-handle (9), mock-server (14)
Add opt-in SSO authentication alongside Basic Auth. OAuth endpoints are
auto-discovered via .well-known, with support for external IdPs
(Keycloak, Authentik) via configurable OAUTH_ISSUER_URL. Sessions
persist through httpOnly refresh token cookies with automatic renewal.
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.