Commit Graph
33 Commits
Author SHA1 Message Date
Matthieu MALVACHE d33309a8b6 fix(security): escape quotes in plain-text linkifier, bump vulnerable deps
Plain-text email bodies were escaped for <, >, & but not " or ', and the
URL linkifier regex captured every non-whitespace character up to the
next <. A URL containing a double or single quote broke out of the
href attribute in the rendered anchor, allowing arbitrary event handlers
to be injected into otherwise plain-text mail. Reported by @rathlinus.

Extract a shared plainTextToSafeHtml helper in lib/email-sanitization.ts
that escapes all five HTML-significant characters in the correct order
before linkification, and route both email-viewer and thread view
through it. Add tests that parse the output and assert no onmouseover
attribute lands on the anchor element.

Also bump dependencies flagged by npm audit: next 16.2.4 (DoS in Server
Components), next-intl 4.9.1 (open redirect), dompurify 3.4.0
(FORBID_TAGS bypass); picomatch/vite/brace-expansion resolve
transitively. npm audit is clean.

Bump version to 1.4.1.
2026-04-16 22:47:15 +02:00
Matthieu MALVACHE 3cd3e26825 chore: bump version to 1.4.0
New features: folder management (#44), mail multi-selection (#43).
Bug fixes: health endpoint (#41), identity deletion (#42), inline CID
images, email list flicker, dependency updates.

Thanks to @wrenix, @ClemaX, @freddij, @dlecourtaltimafr, and @capitanroy
for reporting issues and contributing to this release.
2026-03-23 15:21:20 +01:00
Matthieu MALVACHE 301386c709 chore: fix stale tests, rename spam label, update deps and fix flatted CVE
- Fix oauth-discovery tests expecting removed console.error
- Rename "AI Analysis" to "Spam Analysis" in email viewer
- Update next 16.2.1, tailwind 4.2.2, zustand 5.0.12, eslint 9.39.4,
  typescript-eslint 8.57.1, tanstack/react-virtual 3.13.23
- Fix flatted prototype pollution (GHSA-rf6f-7fwh-wjgh)
2026-03-23 15:20:53 +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
Matthieu MALVACHE da158613ea chore: bump version to 1.3.2 2026-03-17 13:40:28 +01:00
Matthieu MALVACHE ccd146f3da chore: bump version to 1.3.1 2026-03-16 17:14:54 +01:00
Matthieu MALVACHE 05cdb6311a chore: bump version to 1.3.0 2026-03-16 16:30:46 +01:00
Matthieu MALVACHE 3733a704b7 chore: bump version to 1.2.0 2026-03-16 13:07:46 +01:00
Matthieu MALVACHE 96ddac27da chore: bump version to 1.1.4 2026-03-16 12:58:13 +01:00
Matthieu MALVACHE 17b0df4c2f chore: bump version to 1.1.3 2026-03-16 12:41:37 +01:00
Matthieu MALVACHE 2790b877c9 chore: bump version to 1.1.2 2026-03-02 09:09:21 +01:00
Matthieu MALVACHE 2d5b5c09b5 chore: bump version to 1.1.1 2026-02-28 21:01:56 +01:00
Matthieu MALVACHE bf3de065b9 chore: bump version to 1.1.0 2026-02-28 14:58:02 +01:00
Matthieu MALVACHE d3d0776a50 chore: bump version to 1.0.2 2026-02-26 13:36:22 +01:00
Matthieu MALVACHE f17ebbf14b feat(ci): add Docker Hub publishing and versioning policy
Push images to both Docker Hub (rootfr/jmap-webmail) and GHCR on
release. Add semver versioning guidelines to CLAUDE.md and bump
version to 1.0.0.
2026-02-26 01:12:13 +01:00
Matthieu MALVACHE 3516f030dc chore(deps): remove unused packages and explicit phantom dependencies
Remove jmap-jam (unused), @types/dompurify (bundled in dompurify 3.x),
eslint-config-next (not used in flat config), and lint-staged (unreferenced).
Add @eslint/js and eslint-plugin-react-hooks as explicit devDependencies
since they were phantom deps that would break without their former hosts.
2026-02-22 22:54:13 +01:00
Matthieu MALVACHE 7d18d2c3b7 chore(deps): update dependencies and fix ajv security vulnerability
Bump all semver-compatible packages including tailwindcss 4.2.0,
lucide-react 0.575.0, @typescript-eslint 8.56.0, and eslint 9.39.3.
Remaining minimatch advisories are ESLint-only dev deps awaiting
eslint-plugin-react ESLint 10 support.
2026-02-22 18:03:47 +01:00
Matthieu MALVACHE 83e01ae551 feat: add contacts phase 2, advanced search, vacation responder, Docker & TOTP 2FA
Contacts:
- Contact groups/lists with JMAP members map and composer expansion
- vCard import/export with RFC 6350 parser and duplicate detection
- Bulk operations (multi-select, delete, group add, export)

Search:
- Advanced search panel with JMAP filter fields
- Search chips for active filters visualization
- Debounced inputs with AbortController deduplication

Vacation:
- JMAP VacationResponse singleton management
- Settings tab with date range and message configuration
- Sidebar indicator when vacation responder is active

Auth:
- TOTP 2FA support with Stalwart-compatible password$totp format

Infrastructure:
- Docker multi-stage build with standalone Next.js output
- Structured server-side logger with text/JSON format
- CSP Report-Only and security headers via proxy middleware
- Layout refactoring (HTML structure in root layout)
- Playwright E2E framework setup

Testing: 450+ tests (identity, contacts, vCard, threads, headers, components)
i18n: All new strings added to all 8 locales
2026-02-16 18:46:33 +01:00
Matthieu MALVACHE 416b0e985e chore(deps): upgrade @types/node 22→25, jsdom 27→28, lucide-react 0.564
Major version bumps for dev dependencies. eslint 10 skipped — ecosystem
plugins (typescript-eslint, eslint-config-next) don't support it yet.
2026-02-16 17:21:59 +01:00
Matthieu MALVACHE 4499c83a37 chore(deps): update all packages to latest compatible versions
Update next 16.1.5→16.1.6, react 19.2.3→19.2.4, next-intl 4.7→4.8.3,
zustand 5.0.9→5.0.11, lucide-react 0.562→0.564, vitest 4.0.16→4.0.18,
typescript-eslint 8.50→8.55, and other minor/patch dependencies.
2026-02-16 17:20:39 +01:00
Matthieu MALVACHE b18906b8fa fix(security): upgrade Next.js to 16.1.5 to patch 3 CVEs
Fixes CVE-2026-23864 (HIGH - RSC deserialization DoS),
CVE-2025-59471 (Image Optimizer DoS), and
CVE-2025-59472 (PPR resume endpoint memory exhaustion).
2026-02-16 16:15:21 +01:00
Matthieu MALVACHE a98b48e7b4 chore: upgrade dependencies to latest stable versions
Remove unused next-auth dependency (zero imports in codebase).
Update minor/patch versions for security fixes and bug improvements:
- dompurify 3.2.7 → 3.3.1 (XSS protection improvements)
- tailwind-merge 3.3.1 → 3.4.0 (bug fixes)
- TypeScript to 5.9.3 (performance and type inference improvements)
- globals 16.5.0 → 17.0.0 (ESLint global definitions)
- @types packages to latest for React 19 compatibility

All tests passing (124/124), no breaking changes.
2026-01-08 19:21:43 +01:00
Matthieu MALVACHEandClaude Sonnet 4.5 da9fa4e28a feat(email): add spam reporting with bidirectional handling
Implement comprehensive spam management allowing users to report spam emails and restore false positives. Emails are moved to/from the Junk folder with toast notifications and undo support.

Key features:
- Mark as spam: moves email to Junk folder with 5-second undo
- Mark as not spam: restores email from Junk to inbox
- Batch spam operations via context menu
- Smart toggle based on current folder (Junk vs other folders)
- Keyboard shortcut (Shift+!) for quick spam reporting
- Full i18n support (EN/FR)
- Shared mailbox compatibility

UX improvements:
- Toast notifications with undo action using sonner library
- Auto-deselect email after spam action
- Visual distinction with red destructive styling
- Desktop button + context menu + keyboard shortcuts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-08 17:55:24 +01:00
Matthieu MALVACHEandClaude Sonnet 4.5 e8d6e0431f test(identity): add comprehensive unit tests for security utilities
- Setup Vitest testing framework with React Testing Library
- Add 27 test cases for email-sanitization.ts
  - XSS prevention (scripts, event handlers, iframes)
  - Safe HTML preservation (tables, formatting)
  - Signature-specific sanitization rules
  - HTML parsing safety checks

- Add 29 test cases for validation.ts
  - RFC 5322 email validation
  - Header injection prevention
  - Length limit enforcement
  - Email list validation

Coverage: >90% for both security-critical utilities
Zero new runtime dependencies (dev-only)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-08 16:19:45 +01:00
Matthieu MALVACHE dbadb38703 chore: Add package.json metadata and improve release script
- Add metadata to master's package.json (description, author, license, etc.)
- Update release script to merge dependencies instead of copying package.json
- Automatically removes 'private' and dev-only scripts for public release
2025-12-24 04:08:03 +01:00
Matthieu MALVACHE 1924c36a2c 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

Adds test script for injecting HTML emails via JMAP (dev only)
2025-12-24 04:02:32 +01:00
Matthieu MALVACHE 601d9ad47b chore: Fix lint command and add release script
- Fix lint command (use eslint directly instead of broken next lint)
- Add scripts/release.sh for safe GitHub releases
- Fix lint warnings in seed-demo.ts
2025-12-17 18:48:42 +01:00
Matthieu MALVACHE 35963d3f0f feat: Add demo screenshots and seed script
- Add 7 screenshots showcasing the webmail UI
- Create seed-demo.ts script for populating demo accounts
- Update README with screenshot gallery and project overview
- Document git workflow for releases in CLAUDE.md
2025-12-15 01:03:30 +01:00
Matthieu MALVACHE 8eefba5047 feat: Add email threading support with Gmail-style conversation view
- Implement thread grouping by threadId in email list
- Add ThreadListItem with collapsed/expanded states for desktop
- Create ThreadConversationView for full-screen mobile experience
- Add thread utility functions for grouping and sorting
- Extend JMAP client with getThread() and getThreadEmails() methods
- Add keyboard shortcut 'x' to expand/collapse threads
- Add thread expansion state management in email store
- Fix React hooks order in login page
- Add .env.example for environment configuration
- Add husky for git hooks
2025-12-10 17:38:03 +01:00
Matthieu MALVACHE 81ec4cb471 feat: Add error boundaries and real-time push notifications
- Implement error boundaries with graceful fallbacks for all major components
  (sidebar, email list, email viewer, composer)
- Add push notifications via EventSource for real-time email updates
- Show connection status indicator in sidebar footer
- Play notification sound and show toast for new emails
- Add global error handler and error reporting utilities
- Configure ESLint with modern flat config
- Various fixes: unused variable warnings, proper cleanup on disconnect
- Update translations for error messages (EN/FR)
2025-12-10 00:43:46 +01:00
Matthieu MALVACHE 63cb80cb1d feat: Wire up disconnected settings to actual functionality
- showPreview: Conditionally render email preview in list based on setting
- externalContentPolicy: Control external content (ask/block/allow modes)
- deleteAction: Move to trash or permanently delete based on preference
- debugMode: Add conditional logging via new lib/debug.ts utility

Also includes:
- Add moveToTrash method to JMAP client for trash-based deletion
- Update TODO.md with verified implementation status
- Migrate middleware.ts to proxy.ts (Next.js deprecation)
2025-12-09 23:51:20 +01:00
Matthieu MALVACHE 04ab18d4e5 feat: Implement comprehensive i18n support with English and French
- Add next-intl for internationalization
- Create English and French translation files
- Implement language switcher component in sidebar
- Configure automatic browser language detection
- Update all components to use translation keys
- Set up locale-aware routing with [locale] directory structure
- Add i18n guidelines to CLAUDE.md for future development
- Store user language preference in localStorage

The app now supports:
- English (en) and French (fr) languages
- Automatic browser language detection on first visit
- User language preference persistence
- Real-time language switching without page reload
- Complete translation coverage for all UI elements
2025-10-02 01:40:37 +02:00
Matthieu MALVACHE 23847f5812 Initial commit: Minimalist JMAP webmail client
- Set up Next.js 15.5 with TypeScript and Turbopack
- Configured Tailwind CSS v4 with minimalist design system
- Created core email components: list, viewer, composer
- Implemented sidebar navigation with mailbox folders
- Added JMAP client wrapper using jmap-jam library
- Set up Zustand for state management
- Created responsive layout with three-pane view
- Added mock data for development
2025-10-01 23:44:03 +02:00