Masked email: rewrite to the owner at RCPT TO, create responses carry the address, admins query all masks (ME-4, ME-9, ME-13, ME-19)

Found by running system_tests, which masked email no longer stops:
- rcpt_resolve rewrites a live mask to its owner's address, so
  Delivered-To names the account; delivery recognizes the mask from the
  original recipient when it belongs to that account.
- x:MaskedEmail/set create responses carry the server-set email.
- x:MaskedEmail/query returns every mask to a server-level impersonate
  holder, and filters on accountId.
- The refusal for an unlinked emailDomain uses upstream's wording.
- The shared delivery test checks the fork's address format (ME-13).
- The masked email test's tenant domain uses manual DKIM, so its cleanup
  leaves nothing behind.
This commit is contained in:
2026-09-18 18:29:19 -07:00
parent f58aea000f
commit 4a9aa9c548
7 changed files with 160 additions and 35 deletions
+39
View File
@@ -105,6 +105,21 @@ pub async fn of_account(
Ok(masks)
}
/// Every mask on the server, for a server-level administrator (ME-19).
pub async fn all(data: &Store, registry: &RegistryStore) -> trc::Result<Vec<Mask>> {
let mut masks = Vec::new();
for id in registry
.query::<Vec<Id>>(RegistryQuery::new(ObjectType::MaskedEmail))
.await
.caused_by(trc::location!())?
{
if let Some(mask) = load(data, registry, id).await? {
masks.push(mask);
}
}
Ok(masks)
}
/// How many masks count against the account's limit (ME-14).
pub async fn live_count(
data: &Store,
@@ -440,6 +455,30 @@ pub async fn resolve_recipient(
Ok(None)
}
/// The mask a delivery came through, when the recipient was rewritten from
/// a mask to its owner's address at `RCPT TO`: the mask is the original
/// recipient (`ORCPT`, `rfc822;address`), and must belong to the recipient
/// account (ME-4, ME-9).
pub async fn resolve_original(
data: &Store,
registry: &RegistryStore,
orcpt: Option<&str>,
account_id: u32,
) -> trc::Result<Option<Mask>> {
let Some(original) = orcpt.map(|orcpt| {
orcpt
.split_once(';')
.map(|(_, address)| address)
.unwrap_or(orcpt)
.trim()
}) else {
return Ok(None);
};
Ok(resolve_recipient(data, registry, original)
.await?
.filter(|mask| mask.object.account_id.document_id() == account_id))
}
/// The message as delivered through a mask: an `X-Masked-Email` header
/// names the mask, so the user can tell even when it was only BCC'd (ME-9).
/// Nothing else in the message changes.