Commit Graph
61 Commits
Author SHA1 Message Date
Sylvain Zimmer 452cea2bfe continue cleanup 2026-06-09 14:17:14 +02:00
Sylvain Zimmer 1f17de1bb7 adjust perimeter of lib 2026-06-09 14:17:14 +02:00
Sylvain Zimmer fc986b0ac0 review fixes 2026-06-09 14:17:14 +02:00
Sylvain Zimmer 27db845d43 ♻️(rfc5322) move email parsing & composing code to new jmap-email lib 2026-06-09 14:17:14 +02:00
638a2de121 ♻️(frontend) drop next.js for vite + tanstack router (#675)
Next.js has been concerned by several CVEs last time and it's clearly
overkill for our needs (static export) so in order to enlight our stack
we migrate to vite & tanstack-router

Co-authored-by: jbpenrath <jb.penrath@gmail.com>
2026-06-09 11:58:51 +02:00
Sylvain Zimmer e6bf029488 🐛(makefile) make sure we create env files before any call to compose
Fixes #674
2026-05-21 23:28:01 +02:00
Sylvain Zimmerandjbpenrath 3576968e38 (admin) add mandatory TOTP field + search field (#667)
To enable syncing a role to many users, we had to add a custom
Keycloak plugin.
2026-05-20 20:48:00 +02:00
Sylvain Zimmerandjbpenrath f360570798 (blobs) implement tiered storage and refactor blobs/attachments
This allows to use S3-compatible object storage to offload blobs, making Postgres much lighter. We design for storing ~1B emails on a single instance.

We also take this opportunity to do model changes on blobs & attachments.

Migration 0027 is one-way, no going back after this one so check your backups.
2026-05-20 20:48:00 +02:00
Sylvain Zimmerandjbpenrath 6eab1af6d6 (rfc5322) switch back to Python's stdlib for email composition
Latest fixes in the stdlib make it a more solid alternative for strict composition than Flanker. We keep Flanker for now for lenient inbound parsing. We add stronger tests and fuzzing to validate we didn't regress.
2026-05-20 18:57:36 +02:00
f002a22dd3 (global) allow user to send internal message through ThreadEvent (#566)
When a Thread has several accesses or is linked to a shared mailbox,
an input allows to post internal messages. It also allows to
mention user in a message. The ThreadEvent model
is the foundation to enrich Threads with further kind of event.

Co-authored-by: Sylvain Zimmer <sylvinus@users.noreply.github.com>
2026-04-01 18:22:30 +02:00
jbpenrath 4f5591b722 (global) store thread read state by thread access
Currently thread sharing is confusing as the read state is shared from
all thread accesses so we deprecate the `read_at` of the Message model
in favor of a `last_read_at` timestamp pointer on the thread access.

Furthermore, on the thread model, we add several date fields to store relevant
dates in which thread should be sorted according to the current view.
2026-03-05 12:10:29 +01:00
jbpenrath 8330c8df6b 🔧(Makefile) add migrations-check command
Add a command to quickly check if there are issues
with django migrations (missing one, conflict)
2026-03-05 09:56:35 +01:00
Sylvain ZimmerandGitHub f18277b742 🔨(devx) update developer experience: uv, rustfs, caddy, new makefile (#556)
This large PR modernizes the backend of the app:
 - Python Dependency Management: Poetry → uv
 - Object Storage for local dev: MinIO (now unmaintained) → RustFS
 - Makefile Target Standardization to align with other LaSuite repos
 - Internationalization Removal on backend: we only care about i18n on the frontend
 - Backend dependencies upgrade
2026-02-23 12:30:36 +01:00
Sylvain ZimmerandGitHub 8f36b1685d 🔒️(frontend) add defense in-depth for XSS vulnerabilities (#520)
Avoid using HTML strings whenever possible, always try to use the react render to string functions with JSX.
2026-02-05 11:22:39 +01:00
Sylvain ZimmerandGitHub c3560ee739 (parser) add fuzzing tests, fix a few edge cases (#507)
These cases might have caused exceptions, which might have interrupted
some imports.
2026-01-29 11:01:56 +01:00
Sylvain ZimmerandGitHub 681a1481af (worker) add worker.py command and improve task routing on queues (#504)
This avoids a case where a very large import would overflow the
"celery" queue with reindex tasks that would block the inbound
processing tasks. Now we have good priorization.
2026-01-24 11:53:22 +01:00
Sabrina DemagnyandGitHub 0cb05d9e77 (scripts) add release automation script (#472)
Add a Python script to automate the release process:
- Validates semver version format
- Calculates next version automatically based on release kind
- Updates version in pyproject.toml, package.json and package-lock.json
- Updates CHANGELOG.md with release date
- Creates release branch and commits changes

Usage:
make release
or
bin/release.py --kind m --version ...
2026-01-12 00:37:16 +01:00
Sylvain ZimmerandGitHub 6a1df09848 (spam) add rspamd integration, header rules and InboundMessage queue (#436)
This adds an intermediate Postgres-backed queue for inbound messages, that 
allows us to run filters like spam processing before inserting messages in their
final storage (soon to be object storage). Also include misc. refactorings.
2025-12-15 23:50:54 +01:00
jbpenrath a87d8f4a46 (e2e) add first tests
Add first test to test import and send message

Resolve #238
2025-11-25 23:28:21 +01:00
jbpenrath 369bf83e05 🔧(e2e) setup e2e environment
Create a new project e2e based on playwright and setup a full dockerized e2e
environment
2025-11-25 23:27:48 +01:00
Sabrina Demagny 23356c5837 (backend) remove i18n location lines in .po files 2025-11-03 11:54:57 +01:00
jbpenrath cfc12485ed (front) collapse embedded message
Currently threads are hard to read mainly because embedded
replies and other kind of messages are not collapsed like other
mail application does. So we implement a logic to detect empirically
those kind of message and wrap them into a details element.
2025-10-23 19:54:00 +02:00
Sylvain Zimmer 7d4cd48669 🚚(widgets) move widgets to integration repository
Here: https://github.com/suitenumerique/integration/pull/33
2025-10-14 22:08:21 +02:00
Jean-Baptiste PENRATHandGitHub 10be269761 (import) Enhance message import through multipart upload (#372)
- Added multipart upload capabilities for EML and MBOX files to the
  message imports bucket.
- Introduced new API endpoints for initiating uploads, completing
  uploads, and aborting uploads.
- Updated serializers and viewsets to handle file uploads efficiently.
- Improved frontend components to display upload progress and handle
  file uploads seamlessly.
- Adjusted backend services to process uploaded files asynchronously,
  ensuring better performance and user experience.
- Updated documentation and tests to reflect the new functionality.
2025-10-14 17:31:17 +02:00
Sylvain ZimmerandGitHub 1c316b7291 (widgets) add La Gaufre widget + improve accessibility (#360)
All other widgets benefit from focus trap, espace key binding, and overall linting
2025-10-07 10:19:14 +02:00
Jean-Baptiste PENRATHandGitHub bf38eaa60b (archive) implement archiving functionality for messages and threads (#363)
We want to be able to archive threads. So we update Thread model to know
if the thread is archived according to its messages state. Then update the
flag endpoint api to archive messages or threads. Also update the search indexer
to be able to search within archived threads. And finally update the frontend to
allow the user to archive a thread, get and search in archived threads.
2025-10-06 18:27:30 +02:00
jbpenrath 032501eb5f 🔧(crowdin) setup a crowdin workflow
Enable commands to upload and download translation file to/from crowdin.
Setup ci workflow to automatically update translation files on each merge on
main branch. Also add a worklow that can be manually triggered which is in
charge to update application translation files then open a PR.
2025-10-06 10:06:14 +02:00
jbpenrath f2c407f6a0 🌐(frontend) manage translation keys through i18next-cli
Rework totally the way to manage frontend translation keys. Currently we were
managing manually all those keys but now we want to use crowdin to manage our
languages so first we need to be able to extract frontend translation keys in
dedicated files.

Furthermore, we allow to setup frontend application languages and default
language through environment variables
(NEXT_PUBLIC_DEFAULT_LANGUAGE and NEXT_PUBLIC_LANGUAGES)
2025-10-06 10:06:14 +02:00
Sylvain ZimmerandGitHub f4eac6dd8f (channels) add feedback widget and multiple inbound channels support (#301)
This PR adds a new build system for embeddable widgets and a first implementation of a "Feedback" popup widget.

It also refactors inbound message routes into channels, of which there are 2 for now: MTA (by default) and Widget. More to come!
2025-09-24 14:30:40 +02:00
03a8dc743d (mta) add Direct mode for MTA out (#285)
This PR adds support for 2 MTA out modes : Direct-to-MX and SMTP-relay outbound delivery. Direct mode supports SOCKS5 proxies, and we bundle a new `src/socks-proxy` component to support it.

We also add an end-to-end self-check command plus scheduled health-check task with optional Prometheus metrics.

---------

Co-authored-by: Bastien Ogier <bastien.ogier@ext.anct.gouv.fr>
Co-authored-by: Stanislas Bruhiere <stanislas@bruhiere.fr>
2025-09-04 15:48:46 +02:00
Stanislas BruhièreandGitHub 38439b95ce Improve development docker compose (#324)
* 🐛(docker) stop ALL services when running make stop

* (docker) make sure backend is healthy before exiting docker compose up

* 🧑‍💻 (docker) use default user and not root for healthchecks

* (backend) Remove dockerflow

* (backend) add healthcheck route, and suppress healthcheck access logs

* 🚨(backend) ignore monkey patching

* 🚨(backend) coderabbitai + linter fixes

* 🚚(backend) remove version in healthz route

* 🔨(docker) use python http lib instead of curl and remove curl from dockerfile
2025-09-02 12:10:52 +02:00
Sylvain Zimmer 956679e9b2 (dns) add button to copy all DNS records 2025-08-20 16:00:24 +02:00
jbpenrath 7c07711489 👽️(openapi) improve user definition with or without abilities
The OpenAPI Schema does not embedded abilities property.
We fix that and make two serializers for User model in order to get proper
openapi definition for User instance with abilities and without abilities.
2025-07-31 17:19:23 +02:00
Sylvain ZimmerandGitHub 9b4ba9ba09 (dns) add admin page for DNS records (#283)
* (dns) add admin page for DNS records. Fixes #177

* 👷(dockerflow) add a flag to disable Dockerflow

* 💚(ghactions) fix check-api-update that was missing Orval

* 💚(ci) fix tests that depended on Keycloak

* ♻️(admin) refactor CopyableInput into a separate component

* 🎨(dns) improve code style
2025-07-21 14:41:08 +02:00
Sylvain ZimmerandGitHub 8319250fbb ♻️(dns) refactor DNS and Scaleway code to be simpler (#276) 2025-07-17 00:57:33 +02:00
jbpenrath 319918be66 🔧(make) allow to install front deps from make command
`make front-install` now accepts args to install deps from the
docker container with ease.
e.g: `make front-install react` or `make front-install -- -DE @type/react`
2025-07-16 22:22:25 +02:00
Sylvain Zimmer f29ba226e6 🐛(drafts) fix concurrent updates of drafts with blob delete 2025-07-15 23:13:07 +02:00
Sylvain ZimmerandGitHub f1a89a5bdb (all) refactor several areas before 0.1 release (#265)
We are going to release a 0.1 version soon, along with our first production deployment. Starting from there, migrations and a consistent developer experience will be officially supported. To make that easier, this large patch cleans up several areas:
 * Reset migrations one last time
 * Update models for storage efficiency (move textchoices to integerchoices on high-volume tables)
 * Use Blobs for mail mime data and draft bodies. Having them in a separate PG table is a first step, we will later start offloading them to object storage.
 * Add default ZSTD compression to blobs
 * Add per-domain DKIM Keys
 * Add DNS check and provisioning, with a first Scaleway provider
 * Fix Keycloak user provisioning
 * Fix Attachment storage, they are now stored individually only at the drafting stage. Afterwards they are extracted from the main blob. This may be optimized later but at least we only store once. For JMAP compatibility, this requires using fake IDs in the blob API route.
 * Add a management command and recurring task to retry unsent messages
 * Improve the local developer experience with new ports and make commands
 * Repackage MTA-in and MTA-out to be closer to Backend: Poetry, multi-step Dockerfile, move compose and makefile to the root
 * Migrate to OpenSearch
 * Improve overall documentation and add a self-hosting page

Contributes to #177 and #185
2025-07-15 10:41:55 +02:00
jbpenrath c3b40d41f3 🔧(Makefile) add command to check typescript issue
Add a command to run `tsc --noEmit`. It allows to quickly
know if there is ts issues without build the project.
2025-06-30 16:22:25 +02:00
Sylvain Zimmer 0912f4f660 🐛(keycloak) fix Script issue with Keycloak realm import 2025-06-16 16:23:05 +02:00
Sylvain Zimmer 577ad703ca 👷(build) add optionalDependencies for rollup
This allows the same package.json to be used for arm64 and amd64
2025-06-16 10:34:52 +02:00
Sylvain ZimmerandGitHub 460068b5d3 (identity) add MailDomain management with Keycloak identity provider (#136)
This allows user creation, passwords reset and listing users from
Keycloak, plus a new MailDomainAccess model for admins.

* (admin) add maildomainacess model, api route and backend tests

* ♻️(drf) simplify API code

* (keycloack) add deployable keycloak to PaaS

* (keycloak) add integration via API, upgrade to 26.x

* 🗑️(settings) remove invitation setting

* 🐛(tests) fix failing tests after rebase

* 🚨(all) fix lint
2025-06-16 10:03:40 +02:00
jbpenrath 328c1616eb 👽️(frontend) update api client
Run `make api-update`
2025-06-15 16:05:35 +02:00
Sylvain ZimmerandGitHub 9f04ad4d4a 📝(readme) improve README, based on LaSuite Docs (#146) 2025-06-14 01:15:20 +02:00
Sabrina Demagny d39932c353 💚(backend) fix lint and collectstatic needed
Fix lint failures and run collectstatic
before running tests
2025-06-02 16:47:29 +02:00
Sylvain ZimmerandGitHub 3259eb07a6 (admin) add maildomainaccess model, api route and backend tests (#102)
* (admin) add maildomainacess model, api route and backend tests

* ♻️(drf) simplify API code
2025-05-21 22:21:45 +02:00
jbpenrath b887e926c7 🔧(Makefile) add command to generate es index
Add `elasticsearch-index` command
2025-05-14 16:58:43 +02:00
Sylvain ZimmerandGitHub 1f4047a061 (celery) add Celery worker, search, recipient statuses, better build (#88)
Before, sending was done synchronously on the api/send POST call. Now
we just build the MIME message and mark the message for sending, and
queue the actual SMTP (or internal) sending for the worker. We use
this opportunity to add fine-grained delivery statuses for each
recipient, something that traditional email systems are unable to do!

Expanding on that, this (too large) PR adds an initial Elasticsearch
index of threads. It also overhauls the build and CI system, using
Poetry instead of Pip.
2025-05-13 00:52:48 +02:00
Sylvain Zimmer 270d07b9b2 🔨(db) add a script to make a full reset of the database, including schema 2025-04-24 15:56:02 +02:00
Sylvain ZimmerandGitHub 58226a7822 (threads) implement better threading algorithm (#53)
* 🚧(threads) implement first threading algorithm

* (threads) improve threading algorithm and add tests
2025-04-23 19:53:43 +02:00