500 Commits

Author SHA1 Message Date
rustmailer
de871225ae update 2026-08-26 01:11:49 +08:00
rustmailer
388773bd2e update 2026-08-25 17:26:31 +08:00
rustmailer
a0d69f43b6 update 2026-08-25 17:03:25 +08:00
rustmailer
c4a1e36c61 bump to v2.0.2 2.0.2 2026-08-19 17:34:54 +08:00
rustmailer
02b8741725 fix(imap): downgrade empty tail-fetch from error to info #342 2026-08-19 17:31:47 +08:00
rustmailer
d9097f85cf refactor: rename cache module to archive 2026-08-19 17:02:55 +08:00
rustmailer
704678234b Update index.tsx 2026-08-19 15:33:05 +08:00
rustmailer
0d800a48bb Merge pull request #350 from sripwoud/fix/dedup-duplicates-count
fix(core): count deduplicated imports as duplicates, not successes
2026-08-19 15:25:17 +08:00
rustmailer
eaba876de5 refactor: reorder import UI flow to select files before folder 2026-08-19 15:00:06 +08:00
sripwoud
f357d45235 feat(web): reassure on hover that duplicates are already archived
The anxiety behind a surprise duplicates count is "did I lose
something?" — a native title tooltip on the counter answers it:
these messages are already in the archive. Key added to all 18
locales.
2026-08-19 08:45:21 +02:00
sripwoud
46eeab8100 fix(web): localize duplicates counter and hoist processed math
duplicateCount existed only in en.json, so 17 locales fell back to
English inside an otherwise localized panel. The processed count,
percentage and progress bar computed success+failed+duplicates
inline three times; hoist it once so the three can never disagree.
2026-08-19 08:45:21 +02:00
sripwoud
fa98f161c6 fix(core): carry duplicates through the import audit event
success no longer includes dedup-skipped mail, so without a
duplicates field ImportPerformed consumers could not tell an
all-duplicates batch from one that silently lost everything. Also
documents that ExtractOutcome::Imported covers mail dropped by
archive rules, which has always counted as a success.
2026-08-19 08:45:21 +02:00
sripwoud
8eac80e15c style(core): format files touched by the dedup fix
rustfmt +nightly (imports_granularity, group_imports per
.rustfmt.toml) over the five files the fix touched, plus trailing
whitespace cleanup. No behavior change.
2026-08-19 08:45:21 +02:00
sripwoud
e72a53a4d0 fix(web): restore duplicates display in import progress
Reapplies what c067655 reverted: the duplicates counter next to
success/failed and duplicates included in the processed count and
percentage. The server now reports real duplicate counts on every
upload-import path, so the display no longer renders dead zeros.
2026-08-19 08:45:21 +02:00
sripwoud
0899aafbb3 fix(core): count deduplicated imports as duplicates, not successes
A BLAKE3 content-hash hit in extract_envelope_core returned the same
Ok(()) as a real import, so every import surface counted silently
skipped messages as successes and the documented duplicates field
stayed 0 forever.

Make the outcome explicit: extract_envelope_core now returns
ExtractOutcome::{Imported, Duplicate} and every import loop (batch
/import, upload EML, MBOX, PST) counts Duplicate into duplicates
instead of success. total = success + duplicates + failed holds on
every path; duplicates produce no failed_details entries and an
all-duplicates run reports Completed. The batch endpoint status check
treats duplicates as processed work so a duplicates-plus-failures run
keeps reporting Completed as before. The SMTP receiver and IMAP sync
ignore the outcome.
2026-08-19 08:45:21 +02:00
rustmailer
1b2952a6b0 fix: resolve React hooks order violations in account dialogs 2026-08-19 13:54:13 +08:00
rustmailer
ae7a681751 Merge pull request #347 from sripwoud/fix/web-multi-file-import
fix(web): import all selected files, not just the first
2026-08-19 13:38:12 +08:00
rustmailer
2d61f5b555 fix: Dangerous text in migration to 2.x #349 2026-08-19 13:24:12 +08:00
sripwoud
c067655171 revert(web): drop duplicates display until the server reports them
The upload-import path never increments duplicates (a dedup hit
returns Ok and counts as success), so the counter and the progress
math addition could only ever render dead zeros. The display returns
together with the server-side fix; the client-side aggregation of the
duplicates field stays, as issue #2 specifies.
2026-08-18 18:34:02 +02:00
sripwoud
350ec8da1e feat(web): clarify batch import copy and surface duplicates
The import footer showed 'Will import to: X' with no sign that the
whole selection lands in that one folder, and the detected-folder
badge never said which file the hint came from (only the first valid
file is consulted). Multi-file selections now show the file count in
the footer and the hint's source file in the badge.

The results card now renders the aggregated duplicates count and the
processed math includes it. The upload-import path currently always
reports duplicates as 0 (duplicates return Ok and count as success
server-side), so this only becomes visible once the server reports
them, but the aggregate and display are ready.

Header unfolding in extractFolderHint matched any whitespace-led line
in the remaining 64 KB, so body text could be glued onto the folder
name; it now stops at the first non-continuation line per RFC 5322.
2026-08-18 18:23:35 +02:00
sripwoud
9a5816a458 fix(web): import all selected files, not just the first
The file picker allows multi-select but the import mutation only ever
uploaded files[0], silently dropping the rest. upload-import is
one-file-per-call and async: it returns Pending immediately and the
real counts only exist at /import-progress/:id, so summing upload
responses would aggregate zeros.

importFiles() loops the selection sequentially: upload, poll to a
terminal status, merge counts and failed_details into an aggregate.
A file that fails upload or polling becomes a synthetic failure entry
(labelled with the file name) instead of aborting the remaining
uploads; only when every upload transport-fails does it throw so the
existing toast-and-reset path still handles total failure. Upload
progress is byte-weighted across the whole selection so the bar never
resets between files. An AbortSignal wired to component unmount
replaces the deleted setInterval cleanup so polling cannot outlive
the page.

Fixes #2
2026-08-18 17:53:19 +02:00
rustmailer
9e0755c9ed bump to v2.0.1 2.0.1 2026-08-09 17:52:33 +08:00
rustmailer
d27b0f274f update 2026-08-09 17:44:23 +08:00
rustmailer
6e1c75bba8 update 2026-08-09 17:42:49 +08:00
rustmailer
17750e9b80 update 2026-08-09 17:33:02 +08:00
rustmailer
4809f298e9 update 2026-08-09 16:45:00 +08:00
rustmailer
a07e8b3a78 Merge pull request #340 from rustmailer/fix/imap-uid-search-truncation
fix(imap): stop silent mail loss from truncated UID SEARCH enumeration
2026-08-09 16:27:43 +08:00
rustmailer
eb2e4b5393 fix(imap): stop silent mail loss from truncated UID SEARCH enumeration 2026-08-07 19:20:42 +08:00
rustmailer
adb94263c0 feat(audit): audit log page, full event coverage, retention cleanup, and duplicate-view dedup 2026-08-07 00:50:13 +08:00
rustmailer
2d278f956c bump to 2.0.0 2.0.0 2026-08-06 01:25:10 +08:00
rustmailer
ed02c642c8 feat(imap): gap-fill missing-mail repair with live progress UI 2026-08-06 01:18:20 +08:00
rustmailer
75d345b742 feat(imap): resilient batched sync, stale-session cleanup, and live progress UI
- Add SyncFull trigger and configurable IMAP socket read timeout
  - Replace streaming UID FETCH with UID SEARCH ALL + batched fetch so per-message progress stays responsive and throttling servers can retry with reconnection
  - Finalize stale Running sessions on startup so interrupted syncs no longer show a phantom "syncing" state
  - Show a live syncing pill on the account row; add elapsed time, current folder, and slow-server warning styling in the dialog
2026-08-04 17:47:42 +08:00
rustmailer
9b1f6cae8c update 2026-08-03 00:17:00 +08:00
rustmailer
e57d1e41e0 fix(web): consume OIDC access_token and add dual SSO sign-out 2026-08-03 00:04:51 +08:00
rustmailer
409370be4b bump version 2.0.1-alpha.1 2026-07-31 22:50:46 +08:00
rustmailer
657371c669 update 2026-07-31 18:23:42 +08:00
rustmailer
8ab549c27c Merge branch 'main' of https://github.com/rustmailer/bichon 2026-07-31 18:03:07 +08:00
rustmailer
1b7daff10d fix: Proxy field shows error when editing an account #335 2026-07-31 18:03:05 +08:00
rustmailer
7c7a490091 Merge pull request #325 from hammaschlach/feature/imap-poll-interval
Allow IMAP sync intervals as low as 1 minute
2026-07-29 17:07:49 +08:00
rustmailer
57a3c3c519 Update README.md 2026-07-29 00:24:09 +08:00
rustmailer
a280fb6198 feat(server): auto-build web frontend in build.rs 2026-07-29 00:24:06 +08:00
rustmailer
022813a17c Update account-settings-page.tsx 2.0.0-alpha.1 2026-07-28 23:37:06 +08:00
rustmailer
281a256582 Update release.yml 2026-07-28 23:32:06 +08:00
rustmailer
02e9864343 Merge remote-tracking branch 'origin/main' into replace-fjall-with-blob 2026-07-28 21:38:44 +08:00
rustmailer
eae26d3e97 perf(blob): batch blob writes during migration to avoid per-blob fsync overhead 2026-07-28 21:13:16 +08:00
rustmailer
de2a2b5d47 fix: healthcheck with macvlan #329 2026-07-28 14:11:46 +08:00
rustmailer
664ac2fe55 fix: can't set proxy for email account (IMAP) #326 2026-07-20 23:00:36 +08:00
rustmailer
c468f8be41 fix(admin): skip oversized blobs during migration instead of aborting 2026-07-16 05:22:10 +08:00
misolau
b4972d81f0 Allow IMAP sync intervals as low as 1 minute 2026-07-15 08:35:22 +00:00
rustmailer
a88b5c84f3 Merge remote-tracking branch 'origin/main' into replace-fjall-with-blob 2026-07-15 10:48:51 +08:00