Commit Graph
100 Commits
Author SHA1 Message Date
Sylvain Zimmer b1778c24c7 🐛(imports) harden imports code 2026-07-23 01:10:06 +02:00
Sylvain Zimmerandjbpenrath 7fdca12426 (build) add cache-busting source version in build 2026-07-22 16:11:19 +02:00
Sylvain Zimmerandjbpenrath 31144b1a88 📝(spam) add full documentation on spam processing 2026-07-22 16:11:19 +02:00
Sylvain Zimmerandjbpenrath 07e906a390 🔥(testdomain) remove the TESTDOMAIN feature
It was intended for early tests. We can create autojoin domains now instead.
2026-07-22 16:11:19 +02:00
Sylvain Zimmerandjbpenrath 19cfa2dcfc (push) add Push Notifications system for iOS, Android, Web 2026-07-22 16:11:18 +02:00
Sylvain Zimmerandjbpenrath 732b6028d3 (imports) refactor import code: retries, continuous mode, list UI (#742)
Largely improves user & operator visibility on imports, resiliency with retries,
direct-to-offload storage, import cancellation (deleting imported messages) & more.
Remove the modal import and manage all within the import tab in the settings modal
2026-07-22 16:11:18 +02:00
Sylvain Zimmerandjbpenrath f4d235825f ️(devx) improve "make bootstrap" setup time and overall DevX
Notably, we try to reduce disk usage by standardizind on common
base Docker images. We also improve node_modules by reducing
duplicate dependencies and install speed.
2026-07-22 11:34:27 +02:00
Sylvain Zimmerandjbpenrath c668326896 🐛(inbound) improve re-processing of inboundmessages from the admin 2026-07-06 16:20:52 +02:00
Sylvain Zimmerandjbpenrath 109211e0a0 (ssrf) add a host allowlist to bypass SSRF in internal networks 2026-07-06 16:20:52 +02:00
Sylvain Zimmerandjbpenrath 85dd0b4806 🐛(pymta) save the origin IP across STARTTLS restarts 2026-07-06 16:20:52 +02:00
Sylvain Zimmerandjbpenrath 23a63d9730 (inbound) add webhooks, message postmarks, spam fixes
This refactors our inbound pipeline into a more future-proof, extensible system.
2026-07-06 16:20:52 +02:00
Sylvain Zimmerandjbpenrath d8fb367cfe 🚨(lint) lint subprojects 2026-07-06 16:20:51 +02:00
Sylvain Zimmerandjbpenrath 632f38da2d (mta-in) rewrite MTA-in in pure Python to remove dep on Postfix (#692)
Postfix was already removed as a mta-out dependency, this is the second step so we have a pure python, more auditable path for incoming emails. We plan to keep postfix as a compatible option for a while but it won't be the default once this is battle tested.
2026-07-06 16:20:51 +02:00
Sylvain Zimmer 39c385e112 🐛(lang) fix hardcoded lang=en that might trigger auto-translate
That would result in garbled icons like some users reported
2026-06-19 12:00:42 +02:00
Sylvain ZimmerandGitHub 24a0f0ad1d 🐛(mda) add To header to outbound mails missing one (#712)
Mails sent without a To recipient (Bcc- or Cc-only) ship with no To
header, which anti-spam filters treat as a negative signal. Inject an
RFC 4356 empty-group "To: undisclosed-recipients:;" before DKIM signing
so it's covered by the signature.
2026-06-17 12:57:30 +02:00
Sylvain ZimmerandGitHub 061b97332e (identity) allow passwordless mailbox creation when id sync is off (#707)
This allows maildomains admins using an external IDP to create mailboxes that can received emails even before the user logs in for the first time
2026-06-15 16:32:35 +02:00
Sylvain ZimmerandGitHub 745b626e4e 🔒️(hardening) add some defense-in-depth bits (#706)
Performed a large LLM-assisted review, no gaping holes found but many small future footguns prevented.
2026-06-15 16:06:41 +02:00
Sylvain Zimmer 1fe34391a8 👷(jmap-email) add PyPI release scripts 2026-06-09 15:44:46 +02:00
Sylvain ZimmerandGitHub 1f33b84381 ♻️(rfc5322) move email parser & composer to new jmap-email lib (#700)
New standalone email library for parsing/composing with strict validation and helpers
2026-06-09 14:41:46 +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 Zimmerandjbpenrath ad6521c272 🔒️(smtp) harden SMTP connection & proxies config 2026-06-08 16:34:15 +02:00
Sylvain Zimmerandjbpenrath 906f55894b 🐛(rsvp) fix order and default calendar selection when RSVPing (#699) 2026-06-08 16:34:15 +02:00
Sylvain ZimmerandGitHub e3c183a625 🐛(smtp) fix opportunistic TLS against MXes with mismatched certs (#687)
The "may" level was verifying the peer cert and falling back to
cleartext on mismatch, which then bounced on STARTTLS-required
servers (e.g. Mandrill's SES-backed inbound returns 530 to MAIL
FROM in cleartext). Realigned on Postfix's documented behavior:

- "may":    opportunistic TLS, no cert verification.
- "secure": mandatory TLS + CA chain + hostname check; defers if
            STARTTLS isn't advertised or handshake fails.
- "encrypt" is dropped (replaced by "secure").

Also wires MTA_OUT_SMTP_TLS_SECURITY_LEVEL through both the direct
and relay paths — it had been declared but never read — and
collapses the four proxy_* kwargs + sender_hostname of
send_smtp_mail into a single SmtpProxy dataclass.
2026-06-04 16:20:57 +02:00
Sylvain ZimmerandGitHub 89dac5a86f 🐛(import) fix mbox detection as text/html with some libmagic versions (#696) 2026-06-04 16:20:04 +02:00
Sylvain ZimmerandGitHub d2a10256ef 🐛(backend) harden inbound email parsing (#695)
Two distinct AttributeError crashes were firing on legitimate inbound
  mail and producing 5xx-equivalent failures (parse aborts, autoreply
  skipped).

  1. Flanker scanner crashed on `multipart/report` bounces whose status
     part used an RFC 6533 i18n content type (`message/global-delivery-
     status` and siblings). The same crash path was reachable for every
     `message/*` subtype not in flanker's hardcoded list — `partial`,
     `imdn+xml`, `sip`, `cpim`, future / vendor subtypes. Fixed in the
     flanker fork (i18n predicates + traverse fallback + make_part guard);
     pin bumped to 77f4582044f1a8549d49333d50d9bded1176ca09.

  2. `parsed["headers"]` returned `str` for single occurrences and
     `list[str]` when duplicated. Every scalar consumer (`.strip()`,
     `.lower()`, `.startswith()` on Subject / Message-ID / Precedence /
     Return-Path / etc.) crashed the moment a header was repeated. The
     parser now applies a fixed per-header type contract driven by the
     IANA Provisional Message Header Field Registry: headers registered
     with max=1 (RFC 5322 §3.6, RFC 3834, RFC 2045/2046/2183, RFC 4021,
     RFC 3798, RFC 5703, RFC 8058, RFC 8098) are `str` with first-wins
     semantics matching stdlib `email.message.Message[name]`; every
     other header is `list[str]` in document order. `headers_blocks`
     stays uniformly list-typed for the trusted-relays cut.
2026-06-04 15:43:29 +02:00
Sylvain ZimmerandGitHub f7786b3d0f (backend) report selfcheck status to Sentry crons (#694)
Use the new (documented) env var MESSAGES_SELFCHECK_SENTRY_MONITOR_SLUG
to enable
2026-06-04 00:38:59 +02:00
Sylvain ZimmerandGitHub b68f0c4d37 🐛(mta-in) fix milter socket permission race on startup (#693) 2026-06-03 23:38:11 +02:00
Sylvain ZimmerandGitHub d91e97d8c2 🐛(cal) fix display of recurring events with exceptions (#686) 2026-05-29 16:03:51 +02:00
Sylvain ZimmerandGitHub 7528d3543b 🐛(caldav) use the OIDC email instead of the mailbox email (#679)
This allows the user to see the exact list of calendars seen on the
other Calendars app
2026-05-28 17:56:25 +02:00
Sylvain ZimmerandGitHub bd779a15d5 (calendar) add link to a CalDAV instance to accept events directly (#584)
CalDAV-backed mailbox calendar actions: RSVP (Accept/Decline/Maybe), Add to calendar, calendar chooser, calendar listing, and conflict detection — actions enqueue background tasks and return task IDs; new API endpoints documented.
2026-05-26 10:52:00 +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 ZimmerandGitHub cdd8be1641 🐛(perf) fix performance issue with large recipient counts (#672) 2026-05-21 01:53:40 +02:00
Sylvain Zimmer b3d3f36e00 ️(admin) avoid N+1 queries in admin & slow lookups 2026-05-21 00:22:31 +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
Sylvain ZimmerandGitHub d0de96ccdf 🐛(flanker) fix email parsing edge cases with UTF8 (#656) 2026-05-06 00:24:45 +02:00
Sylvain ZimmerandGitHub 99caf3208b (invites) enable inviting users that haven't logged in yet (#644)
No invitation email for now
2026-04-30 14:49:48 +02:00
Sylvain ZimmerandGitHub a5b2c2d0bc 🔒️(ssrf) factorize SSRF code, allow redirects in image proxy (#631)
Also use the SSRF code in IMAP imports.
2026-04-17 10:00:56 +02:00
Sylvain ZimmerandGitHub b4da8a3af7 (inbound) add configurable inbound auth backends (#636)
Added sender authentication checks (DKIM/DMARC) with multiple modes (native, rspamd, authentication-results). Message UI now shows a clear error banner for forged senders and a warning for unverified senders; contact chips display a forged state.
2026-04-17 09:22:00 +02:00
Sylvain ZimmerandGitHub 16acb5d820 (dns) add recursive SPF check and optional send-time validation (#625)
- Optional outgoing SPF validation that can block or mark external deliveries when sender SPF fails.
 - SPF cache invalidation so DNS rechecks are used immediately after DNS validation.
 - More robust SPF evaluation including recursive include resolution, improved TXT handling, duplicate/limit detection, and clearer result statuses.
2026-04-12 00:47:29 +02:00
Sylvain ZimmerandGitHub a3ccc7a57b (channels) add encryption, custom scopes and levels, auditing (#599)
- Scoped API-key channels with per-scope authorization, personal user channels (users/me/channels), encrypted channel secrets, API-key regeneration (API + admin UI), channel last-used tracking, and a raw email submission endpoint.
 - Provisioning mailbox lookup/listing API.
 - Stricter outbound MIME size checks, DKIM signing improvements, and hardened channel/permission validation.
 - Expanded end-to-end and unit coverage for channels, auth/scopes, provisioning, submission, metrics, and admin flows.
2026-04-09 00:53:03 +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
e1970cc732 (autoreply) add autoreply feature (#569)
This reuses message templates and allows to define scheduling

Co-authored-by: Sylvain Zimmer <sylvinus@users.noreply.github.com>
2026-03-16 16:59:54 +01:00
Sylvain ZimmerandGitHub 6f0a022bf8 ♻️(metrics) rename usage API params to be more generic (#589) 2026-03-12 22:01:23 +01:00
4a18fe2019 (threads) add an action to split a thread from a message (#561)
Co-authored-by: Sylvain Zimmer <sylvinus@users.noreply.github.com>
2026-03-11 18:09:24 +01:00
Sylvain ZimmerandGitHub d153f5ad69 (entitlements) add DeployCenter backend for syncing maildomain admins (#572)
Entitlements system with pluggable backends and automatic mail-domain admin sync on login.
Provisioning API to create/update mail domains (bulk input, custom attributes)
Feature flags to enable/disable mail-domain creation and access management; UI and public config expose these flags
2026-03-03 15:06:55 +01:00
Sylvain Zimmer 83005e058d 💚(ci) reuse amd64 frontend artifacts in arm64 build 2026-02-26 00:59:06 +01:00
Sylvain Zimmer 7a8bd1f865 💚(ci) restore npm cache 2026-02-25 23:12:23 +01:00
Sylvain Zimmer bdbb1fe7ce 💚(ci) disable npm cache for now 2026-02-25 22:47:08 +01:00
Sylvain Zimmer 54f65a0731 💚(ci) restore default npm version, 11.x was crashing on arm64 2026-02-25 21:14:05 +01:00
Sylvain Zimmer 18dcdf6273 💚(ci) avoid cleaning up old attestations or releases 2026-02-25 15:15:54 +01:00
Sylvain Zimmer 7750ad835d 💚(docker) fix buildx digest sha256 computation 2026-02-25 12:53:22 +01:00
Sylvain Zimmer 6e5ddc81c0 💚(packages) add packages for tagged versions and fix multi-arch
Platform-specific images now have explicit tags (-amd64, -arm64) so delete-only-untagged-versions won't garbage collect them
2026-02-25 11:26:33 +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 ab24b60160 (throttle) add outbound message recipients throttling (#506)
This is inspired by #466 but focuses on outbound backend-only changes.
2026-02-20 00:41:58 +01:00
Sylvain ZimmerandGitHub e5ce447905 (exports) add task to export a mailbox in mbox, with labels (#553)
This also makes sure we can reimport X-Keywords later.

For now it's admin-side only, we'll add a user-facing UI. First part of #211.
2026-02-19 18:10:19 +01:00
Sylvain ZimmerandGitHub 9b5375cba3 (import) add support for PST imports & stream data for mbox (#544)
Fixes #183. Replaces #517.
2026-02-19 14:03:43 +01:00
Sylvain ZimmerandGitHub d8afd35847 (mailboxes) add a denylist for personal mailbox prefixes (#540)
Personal mailboxes now enforce configurable prefix restrictions; blocked prefixes return a clear error. Domains can indicate identity synchronization status; when disabled, creating personal mailboxes is prevented and returns a specific error.
2026-02-19 12:52:44 +01:00
Sylvain ZimmerandGitHub 6bd7292460 (metrics) new API route for storage usage metrics (#538)
Will be queried by deploy center
2026-02-08 17:41:04 +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 55993a9780 (dns) stronger DNS checks + configurable records (#522)
adds "Insecure" and "Conflicting" DNS status badges and messages with new checks, and introduces a new MESSAGES_DNS_RECORDS setting.  Fixes #482.
2026-02-05 11:15:42 +01:00
Sylvain ZimmerandGitHub 6fe2db7be2 (print) add Print button in messages context menu (#518) 2026-02-04 00:38:50 +01:00
Sylvain ZimmerandGitHub 314e0857d4 🐛(dns) raise new "DUPLICATE" error when there are 2 SPF records (#521) 2026-02-01 21:40:51 +01:00
Sylvain Zimmer 76c8dd32ba 🐛(scalingo) fix env var still overriding the Celery default 2026-01-29 13:56:19 +01:00
Sylvain Zimmer 27661e739d 🐛(invites) add default "invitation.ics" name for invite downloads 2026-01-29 13:42:11 +01:00
Sylvain Zimmer af83580a17 🐛(worker) make celery app name explicit for fix potential $APP override 2026-01-29 13:19:31 +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 78596bb34e (calendar) display calendar invites (#481)
Fixes #433.
2026-01-29 01:06:26 +01:00
Sylvain ZimmerandGitHub e6296f9b3a (integrations) add integrations view in mailbox (#488)
For now this allows users to create feedback widgets linked to their
mailbox. We will also have API keys and recurring imports there.
2026-01-25 17:29:19 +01:00
Sylvain ZimmerandGitHub 1ce35a4580 (admin) add inboundmessage admin view & other small admin fixes (#505) 2026-01-24 17:02:28 +01:00
Sylvain ZimmerandGitHub 9a48eda9c6 ♻️(permissions) refactor some permissions code for viewsets (#503)
We want to avoid relying on role__gte, so we add role list aliases.
2026-01-24 13:48:43 +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
888ff9e42d 🐛(rfc5322) improve email parsing & display multiparts in frontend (#463)
* 🩹(mime) fix inline HTML being treated as attachment

Previously, any MIME part with a Content-Disposition header (including
'inline') was treated as an attachment. This caused HTML email bodies
with 'Content-Disposition: inline' to appear as downloadable attachments
instead of being rendered as the message body.

The fix clarifies the classification logic:
- Parts with 'Content-Disposition: attachment' are always attachments
- Parts with 'Content-Disposition: inline' and text/plain or text/html
  are treated as message body
- Parts with filenames but no disposition follow existing rules

* ♻️(mime) refactor parser to use Flanker's built-in methods

Replace manual disposition parsing with Flanker's is_attachment(),
is_body(), and is_inline() methods which properly implement RFC standards.

This fixes issues where:
- text/calendar parts were incorrectly treated as attachments
- inline HTML was misclassified
- Parts without disposition were not properly categorized

The new logic uses Flanker's built-in classification:
- is_attachment(): Content-Disposition is 'attachment'
- is_body(): No filename AND (text/* or message/*)
- is_inline(): Content-Disposition is 'inline'

* fix: Add missing disposition_header variable definition

* 🛡️(mime) add defensive exception handling for MIME classification

Add try/except blocks around Flanker's is_attachment(), is_body(), and
is_inline() methods to prevent malformed MIME from crashing the parser.
When classification fails, log the error and safely fall back to treating
all checks as False, allowing parsing to continue.

Also preserve actual Content-Type for attachments instead of forcing
text/plain to application/octet-stream, and infer appropriate file
extensions from MIME types when no filename is provided.

* ♻️(mime) refactor attachment handling with helper functions

Extract duplicate attachment construction logic into reusable helper
functions and add consistent filename extension inference across all
attachment types (attachment, inline, and fallback paths).

Changes:
- Add _infer_filename_from_content_type() to map MIME types to file
  extensions for better unnamed attachment handling
- Add _build_attachment_dict() helper to eliminate ~45 lines of
  duplicated attachment dict construction code
- Apply extension inference consistently to is_attachment, is_inline,
  and fallback branches
- Update tests to expect new filename format (e.g., "unnamed.pdf")
- Clarify exception handler comment for better code documentation

* (rfc5322) fix tests & lint

* 🐛(rfc5322) sanitize attachment filenames and add many more tests

* 🐛(rfc5322) improve RFC5322 parsing logic with nested parts, per JMAP spec

* (rendering) render multipart messages in frontend

* fixup! (rendering) render multipart messages in frontend

* 🐛(review) address PR review comments

- Fix _sanitize_filename to preserve file extension when truncating
- Fix MessageBodyItemSerializer: use required fields, remove Meta class
- Fix misleading comment about text body drive attachments
- Regenerate OpenAPI schema and frontend API client

* 🐛(types) fix null fallback

* fix lint and tests

---------

Co-authored-by: Riël Notermans <riel@zzapps.nl>
Co-authored-by: Riël Notermans <riel@mosa.cloud>
Co-authored-by: jbpenrath <jb.penrath@gmail.com>
2026-01-14 01:18:32 +01:00
Sylvain ZimmerandGitHub b6394a2f56 (limits) implement MAX_RECIPIENTS_PER_MESSAGE (#474)
This is mostly cherrypicked from the larger PR #459, to reduce
complexity. We might still implement the rest in the future.
2026-01-12 12:09:52 +01:00
Sylvain Zimmer fc744543bc 🔒️(errors) avoid serializing Python error externally 2026-01-10 15:16:37 +01:00
Sylvain Zimmer 6558bf88a7 🐛(selfcheck) fix warning from a race condition in thread deletion 2025-12-18 15:03:01 +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
Sylvain Zimmer 1cd9809ddf 💄(logo) update Alpha label to Beta 2025-12-05 12:31:43 +01:00
Sylvain ZimmerandGitHub 984eb6beb4 🔒️(security) delete renovate.json 2025-12-01 16:25:21 +01:00
Sylvain ZimmerandGitHub 24f122945f 🔒️(security) create SECURITY.md for vulnerability reporting policy
Added a security policy document outlining vulnerability reporting and disclosure procedures.
2025-11-28 10:35:10 +01:00
Sylvain ZimmerandGitHub 85a8585323 (dkim) add an optional DKIM verification just before sending emails (#434)
This will catch the case where people try to send email before having
correctly configured their DNS, and would also avoid unwanted sends
of messages not supposed to go out.
2025-11-23 17:09:46 +01:00
Sylvain Zimmer b77f4aa3b5 🔧(mta-out) use MAX_OUTGOING_EMAIL_SIZE for mta-out 2025-11-21 15:26:42 +01:00
Sylvain Zimmer 2770221a13 🔧(mta-in) rename config var MESSAGE_SIZE_LIMIT to MAX_INCOMING_EMAIL_SIZE
This aligns with the config for the backend
2025-11-21 15:20:03 +01:00
Sylvain Zimmer b7d3ad6837 🐛(attachments) apply a 1.4x factor on the limit of outgoing emails
This takes into account the overhead of MIME encoding
2025-11-21 14:53:48 +01:00
670ba5699a (attachments) configurable size limits (#430)
Adds new config vars for incoming & outgoing attachment sizes, validated at draft stage
and when receiving emails.

---------

Co-authored-by: Riël Notermans <riel@mosa.cloud>
2025-11-21 13:55:26 +01:00
e89c2c179a 🩹(text rendering) fix plain text line breaks (#428)
Fix text/plain rendering while preserving newlines

---------

Co-authored-by: Riël Notermans <riel@zzapps.nl>
2025-11-20 22:00:31 +01:00
Sylvain Zimmer 0959fd4418 🐛(keycloak) assign users to subGroups if needed
Previously if a KEYCLOAK_GROUP_PATH_PREFIX with a parent folder name
was specified, users were not being added to the right subgroup
2025-11-20 18:45:15 +01:00
Sylvain Zimmer 4833968eb2 🐛(tests) fix failing tests after env var rename 2025-10-18 00:00:09 +02:00
Sylvain ZimmerandGitHub 54b14f9304 (features) add new feature flag env vars (#387)
Rename old AI_FEATURE env vars and add 2 new ones
2025-10-17 23:27:37 +02:00
Sylvain ZimmerandGitHub dfd2668c11 🐛(retries) make message send retries more reliable (#386)
Adds a comprehensive test and a fix for failing "send" tasks
2025-10-17 19:19:11 +02:00
Sylvain Zimmer 7660eb9d3a 🚑️(drafts) show draft replies in threads 2025-10-16 22:16:57 +02:00
Sylvain ZimmerandGitHub d9d3853252 (images) implement cid: image support (#378)
Parses the email and replaces cid: images with blob urls
2025-10-15 21:15:48 +02:00
Sylvain Zimmer 4b1d480d53 (download) add raw email download button 2025-10-14 23:53:02 +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
Sylvain Zimmer d9a02a2451 🐛(gaufre) fix fill color not applied on firefox 2025-10-08 10:55:59 +02:00
Sylvain Zimmer 1e88671b82 🐛(crowdin) fix crowdin env file 2025-10-07 17:01:01 +02:00
Sylvain Zimmer e23845ba02 ️(gaufre) implement aria-expanded attribute + improve some translations 2025-10-07 14:29:00 +02:00
Sylvain Zimmer 816b438097 🐛(gaufre) fix anonymous mobile gaufre and missing strings 2025-10-07 12:28:33 +02:00
Sylvain Zimmer 4cfaa16c2a 🐛(gaufre) disable Gaufre button if not configured 2025-10-07 11:00:26 +02:00