Journaling: capture at the queue, the built-in journal, retention
Phase 2 of the journaling spec. - A copy of each message is taken in MessageWrapper::queue, after DLP and transport rules, for every enabled journal that takes it (direction and scope: everyone, or accounts, groups, domains, tenants). If the copy can't be taken the message isn't queued (temporary failure). - The journal report: the envelope one field a line (sender, To, Cc, Bcc from the envelope, list members from their ORCPT, direction, held for review), then the queued message byte for byte as message/rfc822. - The built-in journal under J in the inbuxa subspace: one chain per node whose links name each entry by SHA-256, so entries can expire out of chain order; purge leaves a marker, and verify catches an entry changed or removed early and a report that doesn't match. - Retention per journal (30 to 3650 days); an entry keeps what it was written with. The daily maintenance purges what's due, keeping entries whose people a legal hold covers (deleted accounts a hold keeps too), and records the counts in the audit log. - inbuxa:Journal get/set, audited by the request layer. Permissions 680-683: administrators see and change journals; the Compliance Officer sees, searches and exports. Whoever changes journals may grant search and export without holding them, so officers can still be appointed. - Catalog entries (inbuxa:Journal, source "journal"); spec as-built notes. tests/src/system/journal.rs: validation, internal mail with a Bcc, outgoing into two journals, incoming over LMTP, the report and its original, tamper and early removal caught, hold-aware purge, retention changes leave entries alone, disabled and removed journals take nothing.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*
|
||||
* Modified by Coffey Labs in 2026 for INBUXA.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
@@ -453,6 +455,25 @@ impl MessageWrapper {
|
||||
return false;
|
||||
}
|
||||
|
||||
// inbuxa: journaling, JR-1: the copy is taken before the message is
|
||||
// queued; if it can't be, the message isn't queued either
|
||||
if let Err(err) = crate::queue::journal::capture(
|
||||
server,
|
||||
self.queue_id,
|
||||
&self.message,
|
||||
message.as_ref(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
trc::error!(
|
||||
err.details("Failed to journal a message.")
|
||||
.span_id(session_id)
|
||||
.caused_by(trc::location!())
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
Queue(event),
|
||||
SpanId = session_id,
|
||||
|
||||
Reference in New Issue
Block a user