Commit Graph
116 Commits
Author SHA1 Message Date
Sabrina Demagny f3b5cccf5d ✨(api) Allow superuser+staff to view all mail domains in admin API
- Add condition in MailDomainAdminViewSet.get_queryset() to return all domains
  when user is both superuser and staff
- Add comprehensive tests covering all user permission combinations:
  * superuser + staff: can see all domains
  * superuser only: cannot see all domains (empty list)
  * staff only: cannot see all domains (empty list)
  * staff with domain access: can only see accessible domains
- Maintain existing behavior for regular users and domain admins

This change ensures that superusers with staff privileges have full
administrative access to all mail domains through the admin API,
while maintaining proper access control for other user types.
2025-07-10 15:45:44 +02:00
Sabrina Demagny d3df815d1f ✨(backend) add user abilities system for mail domain permissions
- Add get_abilities() method to User model to determine user permissions
- Add abilities field to UserSerializer to expose permissions via API
- Implement permission logic for create_maildomains and view_maildomains
- Add comprehensive tests for User model abilities method
- Add integration tests for abilities field in users/me endpoint
- Support superuser+staff, mail domain access, and regular user scenarios

The abilities system provides granular permission control for mail domain
operations, allowing the frontend to adapt UI based on user capabilities.
2025-07-10 14:34:49 +02:00
Sabrina Demagny 260b27f6e0 ✨(api) add multi-word search on contact name and email
- Add ability to search contacts by multiple keywords (AND logic)
  on name and email, in contacts endpoint.
- Adapt and enrich tests to cover multi-word search,
  case sensitivity, and name/email combination.
2025-07-08 12:23:17 +02:00
Sabrina Demagny 604f7121a2 🐛(api) correct alphabetical sorting of labels with accented characters
- Change label sorting from name-based to slug-based ordering in list view
- Use slug ordering for initial queryset to ensure consistent sorting
- Maintain name-based sorting in create method for consistency
- Fixes issue where "État civil et cimetière" appeared at the end

The slug-based sorting provides more predictable alphabetical ordering
since slugs are normalized versions of names without accents.
2025-06-24 17:31:57 +02:00
Sabrina Demagny 1688ef70f7 💚(lint) run make lint 2025-06-23 11:44:23 +02:00
jbpenrath 6beac632b6 ✨(front) list labels in left panel and allow to edit them
Load and display labels in left panel. Add also a modal to
create/edit/delete labels.
2025-06-20 00:58:11 +02:00
Sabrina Demagny b2b71cc405 🐛(api) fix partial update of label 2025-06-20 00:15:35 +02:00
jbpenrath 95f78e4a02 ✨(front) upload mailbox archive as blob
To import old messages from an archive we must now upload the archive file
as a blob then provide the blobId to endpoint to import messages.
2025-06-20 00:13:50 +02:00
Sabrina DemagnyandJean-Baptiste PENRATH eee7afa65c ✨(backend) upload blob for eml and mbox import 2025-06-20 00:13:50 +02:00
Sabrina Demagny ce945259c8 💚(lint) run make lint
A `make lint` run was forgotten in the last commit
2025-06-19 13:45:09 +02:00
jbpenrath e263c56450 ♻️(frontend) update thread stats and thread panel after api refactoring
We recently refactor the way we process thread stats and the filters to list
threads. We have to update the front to work with this new behavior.
2025-06-19 02:05:41 +02:00
jbpenrath 0d4e4f3536 💄(front) clean a little bit label badges
We recently display label badges into thread-item. We revamp that
a little bit to improve code structure and prepare the layout
for further improvements.
2025-06-19 02:05:41 +02:00
Sylvain ZimmerandJean-Baptiste PENRATH 6fd271bed8 ♻️(flags) refactor Thread flags and stats
Migrate from counters to simple flags, because the frontend needs
counts of threads, not sums of counts of messages. Also prepare
for spam and archive features.
2025-06-19 02:05:41 +02:00
Sabrina Demagny e18732bb47 ♻️(labels) move parent labels creation logic
Put the logic into Label model's save() method to guarantee the invariant always holds,
even when using the admin interfacee uses, the shell, bulk operations, or any code path.
2025-06-18 11:21:03 +02:00
Sabrina Demagny a500eadde8 💚(api): ensure consistent thread ordering in list endpoint
- Add secondary ordering by created_at to prevent flaky test results
- When threads have the same messaged_at value, order by newest created_at first
- Ensures deterministic API responses for better test reliability
2025-06-17 19:47:53 +02:00
Sabrina Demagny ad179ee258 ✨(api) allow to list threads by label
Add the ability to filter threads by label slug in the thread list endpoint. This feature
enables users to view all threads associated with a specific label.

Changes:
- Add label_slug query parameter to ThreadViewSet list endpoint
- Implement label-based filtering with proper permission checks
- Add OpenAPI documentation for the new label_id parameter
- Add comprehensive test suite for label filtering

Technical details:
- Filter threads by label while ensuring user has access to the label's mailbox
- Support combining label filter with existing filters (mailbox, search, etc.)
- Add proper error handling for invalid or inaccessible labels
- Add test coverage for various filtering scenarios:
  - Single label filtering
  - Combined label and mailbox filtering
  - Invalid label handling
  - Permission checks
  - Combined filters (label + unread/starred status)
2025-06-16 15:54:41 +02:00
Sabrina Demagny 6d11b9fef5 🐛(backend) fix task response returned
Ensure consistent state reporting across import task updates
2025-06-16 14:35:27 +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
Sabrina Demagny b51fa58553 🐛(backend) prevent duplicate threads during message import
Avoid duplicate threads when importing the same file multiple times.

Changes:
- Moved duplicate message check to the start of deliver_inbound_message
- Maintains proper threading relationships while preventing duplicate threads

This ensures that:
- No duplicate threads are created when importing the same file multiple times

Test coverage:
- Updated existing import tests to check thread counts
- Verified that duplicate imports don't create new threads
2025-06-15 21:54:00 +02:00
Sabrina Demagny 2ff790afb1 ✨(api) add endpoints to manage labels
This commit implements a complete label management system with the following features:

- Add CRUD operations for labels with hierarchical support (using slash-based naming)
- Implement label-thread associations (add/remove threads to/from labels)
- Add comprehensive permission checks (ADMIN/EDITOR roles required for management)
- Support hierarchical label structure with automatic parent creation
- Add color customization for labels
- Implement proper slug generation for label names
- Add extensive test coverage for all label operations

Technical details:
- New LabelViewSet with list, create, update, delete operations
- Custom actions for thread management (add-threads, remove-threads)
- Hierarchical label structure with parent-child relationships
- Automatic parent label creation when creating nested labels
- Proper permission handling based on mailbox access roles
- Comprehensive test suite covering all edge cases
- OpenAPI documentation for all endpoints
2025-06-15 18:18:31 +02:00
jbpenrath 328c1616eb 👽️(frontend) update api client
Run `make api-update`
2025-06-15 16:05:35 +02:00
Sabrina Demagny c297137bf4 ✨(backend) improve MBOX file import compatibility
Enhance support for MBOX files from various email export tools by handling
both extensionless files and text/plain MIME type. This improves compatibility
with different export formats while maintaining security through proper
validation.

Changes:
- Add support for files named "mbox" without extension
- Allow text/plain MIME type for MBOX files (common in webmail exports)
- Keep application/mbox as the primary MIME type for MBOX files
- Update validation to check both MIME types and file extensions
- Add test cases for extensionless files and text/plain MIME type
- Update error messages to be more descriptive about supported formats

The validation now handles:
- Files with .mbox extension (application/mbox or text/plain MIME type)
- Files named "mbox" without extension
- Maintains strict validation to ensure text/plain is only accepted for MBOX files

This change improves compatibility with various email export tools and webmail
services while maintaining security through proper file validation.
2025-06-15 15:13:38 +02:00
Sabrina Demagny 761784e91c ✨(backend) use a celery task for eml import
Unify the import implementations to use celery task (eml, mbox, imap)
Same returns for all import tasks.
Update openapi schema.
2025-06-11 23:53:48 +02:00
Sabrina Demagny 55c3f2a081 👽️(api) fix openapi schema for import message
Fix and re-generate schema
2025-06-11 23:32:51 +02:00
Sabrina Demagny c603350703 ✨(api) add labels info on Thread
Add details of labels info on thread list
2025-06-11 09:38:56 +02:00
Sabrina Demagny 55a7b1e49f ✨(api) add endpoints to import messages
Refactor code to import messages and add endpoints to import messages
(.eml, .mbox, imap)
2025-06-05 18:23:10 +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
jbpenrath db7631fd67 👽️(openapi) fix thread access serializer type and update schema and api
The `accesses` property into the Thread object was not propertly typed so we
update the serializer to fix the type by using dedicated sub serializers then we
run `make api-update` to update schema and api client.
2025-05-26 15:54:37 +02:00
jbpenrath e4c67558e3 👽️(api) complete openapi schema and regenerate
Improve the description of the blob api endpoint then regenerate
schema and client api through `make api-update`. Furthermore we
also update FetchApi interface to manage boundary multipart content type
2025-05-22 15:59:17 +02:00
Jean-Baptiste PENRATHandGitHub 7ddcc668f3 💚(ci) add job check-api-state (#111)
Add a job to ensure that api schema and client
are up-to-date.
2025-05-21 22:22:27 +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
Sabrina Demagny 3e98509dcc ✨(api) add endpoint to search Mailboxes
Allow to search Mailboxes from same domain of a context Mailbox.
2025-05-20 01:25:49 +02:00
Sabrina Demagny 7d8500ac22 ✨(backend) link a Mailbox to a Contact instance
Add FK to Contact on Mailbox model.
Display name of mailbox contact into list accesses of a thread
2025-05-19 20:24:22 +02:00
Sabrina Demagny 2c2eb3a39b Revert "✨(backend) enhance Mailbox model to add a display name"
This reverts commit c5d1ee220e.
2025-05-19 14:45:26 +02:00
Sabrina Demagny c5d1ee220e ✨(backend) enhance Mailbox model to add a display name
Add an optional name field
2025-05-19 13:04:26 +02:00
Sabrina Demagny 65db4fddad ✨(api) enhance Thread serializer to return thread accesses
Add list of thread accesses into Thread serializer
2025-05-19 12:55:05 +02:00
jbpenrath c61ba946fa 👽️(api) add thread_id property to Message resource
Frontend needs to be able to retrieve the thread_id of a message
so we tweak the MessageSerializer to bind this information. Then we run
`make api-update` to update api schema and client.
2025-05-19 11:16:03 +02:00
Sabrina Demagny eca469e666 ✨(api) add endpoint to manage ThreadAccess
Allows creating, updating, and deleting access to threads based on
user role.
2025-05-16 12:18:14 +02:00
Sylvain ZimmerandGitHub 87a949d4d2 ✨(attach) add initial attachments support in in/outbound & api (#93) 2025-05-15 13:45:52 +02:00
Sabrina Demagny a99b2a0fae 🐛(backend) fix bcc lost after updated draft
Enhance and fix check to allow bcc displaying. Fix #85
2025-05-14 20:35:49 +02:00
Sabrina Demagny 11ffc48ead 🐛(backend) update thread stats after message hard delete
Call update_stats after delete one of thread's messages. Fixes #84.
2025-05-14 18:16:10 +02:00
jbpenrath 37d689bcb0 ✨(frontend) add search input in the header
Allow the user to search in their email through a search input
2025-05-14 16:58:43 +02:00
jbpenrath a6427059ca 👔(frontend) manage QueueMessage timeout
Previously we expect the task retrieve endpoint could return a 404 when a task
does not exist but it is not possible (dce87f8) so instead we put a timeout to
stop to poll the task after a given delay.
2025-05-14 09:54:41 +02:00
Sylvain Zimmer dce87f864f ✅(task) add test for task API and confirm unkown task behaviour
According to Celery's author here:
https://github.com/celery/celery/issues/3596#issuecomment-262102185

There is no way to check if a task ID exists. It will just return
"PENDING" indefinitely. Add tests for this accordingly.

Closes #91
2025-05-13 23:14:57 +02:00
jbpenrath a79cfde5c4 👽️(api) update schema and api client
Fix task api schema (use enum for `status`) then run `make api-update`
2025-05-13 17:28:21 +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
Sabrina DemagnyandGitHub 84f95bf52a ✨(backend) use ThreadAccess instead of direct mailbox link (#80)
* ✨(backend) use ThreadAccess instead of direct mailbox link

Remove the direct link to a mailbox on Thread model. It is now possible to
define two types of roles for each thread (Reader and Editor) for a mailbox.
When creating a new thread, a new access to the sender's mailbox is created
with the Editor role.
It is now possible to delegate a thread to another mailbox with the Reader or
Editor role. So it is possible to forward a thread to another internal user
and avoid mail forwarding.

* ✨(backend) change MailboxAccess permission into roles

Enhance access on mailbox and thread with role everywhere!

* improve doc

* enhance tests

* lint
2025-05-12 21:29:06 +02:00
jbpenrath f99b6f2a66 👽️(api) update schema and api client
Fix thread stats api schema (use enum for `stats_fields`)
 then run `make api-update`
2025-05-12 16:30:37 +02:00
jbpenrath b83a6ef631 ✨(frontend) use dynamic views through thread counters
The api allows us to filter threads through filters. We are using this new
feature to build dynamic folders (All threads, Drafts, Send and Trash).
Furthermore we update the MessageForm logic to stick with the new draft
logic (First create a draft message then send the message)
2025-04-30 22:06:29 +02:00
jbpenrath 715f040123 👽️(api) update schema and api client
Run `make api-update`
2025-04-30 22:06:29 +02:00