Submissions say when DLP held the message #110

Merged
jcoffey-dev merged 1 commits from feature/submission-held-flag into main 2026-09-29 01:54:01 +00:00
3 changed files with 16 additions and 1 deletions
@@ -45,6 +45,9 @@ pub enum EmailSubmissionProperty {
// inbuxa: DLP (dlp-and-mail-flow-rules spec, §2.5): `{"reason": ...}`
// to send despite a warning
DlpOverride,
// inbuxa: in a create's response, true when DLP held the message for
// review (§2.6)
DlpHeld,
Pointer(JsonPointer<EmailSubmissionProperty>),
}
@@ -96,6 +99,7 @@ impl Property for EmailSubmissionProperty {
EmailSubmissionProperty::IdentityId => "identityId",
EmailSubmissionProperty::MdnBlobIds => "mdnBlobIds",
EmailSubmissionProperty::DlpOverride => "inbuxa:dlpOverride",
EmailSubmissionProperty::DlpHeld => "inbuxa:held",
EmailSubmissionProperty::SendAt => "sendAt",
EmailSubmissionProperty::ThreadId => "threadId",
EmailSubmissionProperty::UndoStatus => "undoStatus",
@@ -188,6 +192,7 @@ impl EmailSubmissionProperty {
"dsnBlobIds" => EmailSubmissionProperty::DsnBlobIds,
"mdnBlobIds" => EmailSubmissionProperty::MdnBlobIds,
"inbuxa:dlpOverride" => EmailSubmissionProperty::DlpOverride,
"inbuxa:held" => EmailSubmissionProperty::DlpHeld,
)
.or_else(|| {
if allow_patch && value.contains('/') {
+9 -1
View File
@@ -91,6 +91,13 @@ impl EmailSubmissionSet for Server {
);
let send_at = submission.send_at;
// inbuxa: DLP (§2.6): the sender learns it's held
let held = match submission.queue_id {
Some(queue_id) => {
inbuxa_features::mailflow::held::is_held(self.store(), queue_id).await?
}
None => false,
};
let undo_status = match submission.undo_status {
UndoStatus::Pending => email_submission::UndoStatus::Pending,
UndoStatus::Final => email_submission::UndoStatus::Final,
@@ -128,7 +135,8 @@ impl EmailSubmissionSet for Server {
.with_key_value(
EmailSubmissionProperty::UndoStatus,
Value::Element(EmailSubmissionValue::UndoStatus(undo_status)),
),
)
.with_key_value(EmailSubmissionProperty::DlpHeld, Value::Bool(held)),
),
);
}
+2
View File
@@ -312,6 +312,7 @@ pub async fn dlp(test: &mut TestServer) {
response["created"].get("s").is_some(),
"no rules: {response}"
);
assert_eq!(response["created"]["s"]["inbuxa:held"], false, "{response}");
// A warning: refused with the rule and its notice, then sent with a reason
let (_, response) = call(
@@ -833,6 +834,7 @@ pub async fn hold(test: &mut TestServer) {
.as_str()
.unwrap_or_else(|| panic!("held, not refused: {response}"))
.to_string();
assert_eq!(response["created"]["s"]["inbuxa:held"], true, "{response}");
let (_, response) = call(&admin, "inbuxa:HeldMessage/get", json!({"ids": null})).await;
let list = response["list"]
.as_array()