Commit Graph
396 Commits
Author SHA1 Message Date
rustmailer c3a725770c fix: reconnect and retry IMAP batch on BrokenPipe/network errors 2026-06-07 18:18:37 +08:00
rustmailer c736afffb0 fix: account deletion times out #291 2026-06-07 15:34:38 +08:00
rustmailerandGitHub 62cb5264fd Add funding.json for project funding details 2026-06-06 15:56:47 +08:00
rustmailer aebb94ee4e fix: preserve non-stored search fields when updating envelope tags
update_envelope_tags lost f_body, f_from_text, f_to_text, f_cc_text,
  f_bcc_text, f_attachment_name_text and f_attachment_name_exact because
  they are not STORED and field_values() skipped them during delete+add.
  Rebuild these from stored counterparts and the blob-store EML.
2026-06-05 09:13:25 +08:00
rustmailer 769630f9d7 Merge branch 'main' of https://github.com/rustmailer/bichon 1.5.0 2026-06-04 23:46:28 +08:00
rustmailer 368b18c45f bump to v1.5.0 2026-06-04 23:46:25 +08:00
rustmailerandGitHub 42861f6cc9 Merge pull request #288 from Korov/fix/tencent-mail-uidvalidity
fix: Add fallback UIDVALIDITY support for non-compliant IMAP servers
2026-06-04 23:45:40 +08:00
rustmailerandGitHub 327a3f39d9 Merge pull request #287 from fama/dedup-cache-fix
fix: open NewIndexWriter once across all migration segments
2026-06-04 10:24:22 +08:00
fama 427f7248d2 fix: open NewIndexWriter once across all migration segments
Previously, do_migrate_segment created a fresh NewIndexWriter (and
therefore a new Fjall Database) on every call, meaning the Fjall
database at bichon-storage/ was opened and closed once per segment.

This caused the migration to fail mid-way through (observed at segment
9/16) with:

  Storage(InvalidTag(("ChecksumType", 171)))

Root cause: after segment N writes email blobs via Fjall's ingestion
API (start_ingestion / write / finish), those SSTables and KV-separated
blob files are flushed to disk and the Database is dropped. When segment
N+1 calls Database::builder(storage_dir).open(), Fjall must discover and
catalog all on-disk files produced by the previous segments. During that
discovery it reads SSTable or blob-file block headers and encounters a
ChecksumType discriminant byte (171 / 0xAB) that lsm-tree 3.1.4 does
not recognise, causing the fatal error.

The first N segments succeed because the cumulative set of ingested
SSTables stays small enough that Fjall does not need to read the
offending headers during reopen. Once enough data has accumulated the
reopen triggers a manifest or compaction read that exposes the mismatch.

Fix: open NewIndexWriter once, before the segment loop, and pass a
&mut reference into each do_migrate_segment call. finish_writers() is
called a single time after all segments complete. The Fjall Database
stays open for the entire migration and is never closed and reopened,
eliminating the incompatible-reopen path entirely.
2026-06-03 15:10:03 -06:00
rustmailer a2a51a2037 feat(imap): add message size check before download 2026-06-03 21:17:35 +08:00
rustmailer 4d783d5301 Update Cargo.lock 1.4.3 2026-05-31 06:05:50 +08:00
rustmailer 4172f11f00 Update Cargo.toml 2026-05-31 06:05:41 +08:00
rustmailer 257736a47b fix: add in-memory dedup cache to prevent duplicate emails before indexing
Use (account_id, mailbox_id, content_hash) as dedup key with time-based
  eviction to bound memory at ~50MB. Check happens before mail parsing,
  so duplicate emails skip all expensive work entirely.

  - Populate cache from Tantivy FAST columns on startup (7-day window)
  - Evict oldest 1/4 of entries when exceeding 300K capacity
  - Graceful degradation: populate failure → empty cache, still works
2026-05-31 06:04:58 +08:00
Lei Zhu e8469da3bc fix: Add fallback UIDVALIDITY support for non-compliant IMAP servers
This commit adds support for IMAP servers that don't provide UIDVALIDITY,
such as Tencent Enterprise Mail (腾讯企业邮箱).

Changes:
- Added `generate_synthetic_uidvalidity()` function that creates a stable
  hash-based UIDVALIDITY from the mailbox name
- Modified `reconcile_mailboxes()` to use synthetic UIDVALIDITY when the
  server doesn't provide one
- Servers without UIDVALIDITY can now sync all mailboxes including system
  folders (Sent Messages, Drafts, Deleted Messages)
- Incremental sync is supported via the synthetic UIDVALIDITY
- Added warning logs to indicate when synthetic UIDVALIDITY is in use
- Updated mailbox metadata to store the resolved UIDVALIDITY

Fixes issues with:
- Tencent Enterprise Mail (腾讯企业邮箱)
- Other non-compliant IMAP servers
- Mailboxes that don't properly support UIDVALIDITY"
2026-05-30 16:32:06 +08:00
rustmailer 1346dd216a fix: "No body available" #262
When the request returns an empty body, choose to skip it and print the account ID and UID information, leaving it for the user to investigate themselves. Otherwise, the IMAP download process will be blocked by this.
2026-05-29 16:43:38 +08:00
rustmailer d40ba90b54 fix: inline attachment detection and account-scoped export
- Treat MIME parts with Content-ID but no Content-Disposition as inline
  - Add account_ids filter to CLI export search to avoid pulling all accounts
  - Skip failed emails during export instead of aborting the entire batch
1.4.2
2026-05-29 16:13:19 +08:00
rustmailer 048d5f361c fix: Cant migrate with version >= 1.4.0 #277 2026-05-28 22:49:24 +08:00
rustmailer 4597df515a Update content.rs 1.4.1 2026-05-28 17:55:13 +08:00
rustmailer f4be4a2e8c bump to 1.4.1 2026-05-28 17:49:18 +08:00
rustmailer 4a3c42c1eb fix: HTTP Error 500 Internal Server Error: Failed for 58344335-2e86-4009-979d-6da0331bff63 - Failed to export an email. Aborting process... #275 2026-05-28 17:47:10 +08:00
rustmailer 8fcb55320f Update README.md 2026-05-28 02:09:58 +08:00
rustmailer 86869ac848 Update release.yml 1.4.0 2026-05-26 20:11:49 +08:00
rustmailer 38453accc6 Update release.yml 2026-05-26 20:07:40 +08:00
rustmailer a60b2c7dc4 Update release.yml 2026-05-26 20:02:55 +08:00
rustmailer 8e46c7a162 fix: use valid IMAP UID SEARCH instead of BEFORE in UID FETCH for incremental sync 2026-05-26 19:42:26 +08:00
rustmailer 1a615e1c45 bump to v1.4.0 2026-05-26 15:27:34 +08:00
rustmailer 83dd9cdd6b perf: optimize IMAP account fetch flow 2026-05-26 15:23:34 +08:00
rustmailer f30cd66e00 feat: remove folder limit 2026-05-26 15:22:14 +08:00
rustmailer 4bd714a670 chore: remove custom global allocator 2026-05-26 15:20:59 +08:00
rustmailer c0a63a1e3c feat: enhance autoconfig detection 2026-05-26 15:19:39 +08:00
rustmailer 04a022e850 add features endpoint 2026-05-24 20:31:58 +08:00
rustmailer f9c2fc77ff feat(core): wire up attachment text extraction in IMAP sync pipeline 2026-05-24 19:52:28 +08:00
rustmailer ec3e842bbb chore: add trace logging for duplicate email diagnosis #214 2026-05-24 17:27:01 +08:00
rustmailer 7311529908 bump to v1.3.0 1.3.0 2026-05-24 16:50:15 +08:00
rustmailer 0792bb546d perf: reduce tokio worker thread blocking to improve responsiveness on low-core machines
- Switch memdb durability from Full to Batch(100) with 10s flush worker
  - Offload BlobManager fjall writes to spawn_blocking
  - Wrap Tantivy commit operations in block_in_place
  - Flush memdb WAL on graceful shutdown
2026-05-24 14:34:16 +08:00
rustmailer 0be2670600 update 2026-05-24 02:37:22 +08:00
rustmailer 575f851cfb update 2026-05-24 02:27:52 +08:00
rustmailer 61430b72b0 feat(core): add ext module with EventBus and AttachmentTextExtractor traits 2026-05-24 02:04:28 +08:00
rustmailer 15c0cfc1d9 Update README.md 2026-05-23 15:57:39 +08:00
rustmailer ea8c493374 Update .gitignore 2026-05-23 15:41:39 +08:00
rustmailer 005b1c2116 feat: added Cron scheduling for email downloads #211 2026-05-23 15:40:46 +08:00
rustmailer d8b78b8010 update 1.2.0 2026-05-23 12:08:49 +08:00
rustmailer 36f3f19cdc fix(core): use email schema field for attachment hash lookup in cleanup_unused_content 2026-05-23 11:36:47 +08:00
rustmailerandGitHub 9f3097df32 Merge pull request #259 from mmaudet/feat/search-by-server-timestamp
feat: filter and sort search-messages by a server-side timestamp
2026-05-23 11:04:54 +08:00
rustmailerandGitHub c075b9ef12 Merge pull request #258 from mmaudet/fix/self-heal-missing-content
fix: self-heal a missing content blob in download-message
2026-05-23 11:03:04 +08:00
rustmailerandGitHub 21a7f7e9d5 Merge pull request #257 from mmaudet/fix/gc-blob-still-referenced
fix: prevent the dedup GC from deleting a still-referenced content blob
2026-05-23 10:58:34 +08:00
rustmailer 26c14fcaaf refactor(migrate): use searchable_segment_ids() instead of reader() for merge #261 2026-05-23 10:26:09 +08:00
Michel-Marie MAUDETandClaude Opus 4.7 6873841ba4 fix(search): expose new SortBy variants via #[oai(rename)]
InternalDate and IngestAt were renamed for the wire with #[serde(rename)] only. SortBy derives poem_openapi::Enum, which does not honour serde attributes, so the REST deserializer exposed them under their Rust identifiers instead of the intended INTERNAL_DATE / INGEST_AT — inconsistent with the existing DATE/SIZE values and rejecting the documented names with HTTP 400. Add #[oai(rename = ...)] alongside the serde rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:14:01 +02:00
rustmailer 0dd81f599d update 2026-05-22 22:21:46 +08:00
Michel-Marie MAUDETandClaude Opus 4.7 b3afc52a82 feat(search): filter and sort messages by server-side timestamps
POST /api/v1/search-messages previously filtered and sorted only on the
sender-controlled Date: header. Add support for two server-controlled
timestamps that are already indexed as FAST i64 fields:

- internal_date (IMAP INTERNALDATE)
- ingest_at (Bichon's archival time)

EmailSearchFilter gains internal_date_since/before and ingest_since/before
range bounds, mirroring the existing `since`/`before` Date: handling.
SortBy gains InternalDate and IngestAt variants (wire values INTERNAL_DATE
and INGEST_AT), mirroring the existing DATE/SIZE sort handling.

The envelope and attachment Tantivy schemas already declare these fields
as INDEXED | STORED | FAST, so no re-index or migration is required.
Attachments carry no IMAP INTERNALDATE, so the attachment search maps the
InternalDate sort to the attachment's own date field as a defined fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:55:23 +02:00