Merge upstream v0.16.23

Five conflicts, resolved:

- crates/common/src/auth/authentication.rs: upstream's get_directory_for_token
  and JwtClaims replace extract_jwt_domain; the per-domain directory code
  (DIR-1, DIR-5 to DIR-7) is kept, and the token lookup routes through it.
  The release's one new Enterprise snippet was the body of
  get_directory_for_issuer, which stays returning None: a token naming no
  address gets the server default, as DIR-2 specifies and as v0.16.22 did.
- crates/common/src/manager/application.rs: upstream's rewrite of the tests,
  with the temp directory names renamed again, and the 5(a) notice the
  name-purge change should have added.
- crates/common/src/network/mta.rs: both sides' imports.
- crates/main/Cargo.toml: the AGPL-only license kept, version 0.16.23.
- Cargo.lock: upstream's, with the fork's crates added by Cargo.
This commit is contained in:
2026-09-22 16:57:06 -07:00
82 changed files with 1527 additions and 611 deletions
+123 -15
View File
@@ -592,14 +592,7 @@ END:VCARD
})
.await;
let bill_messages = test
.server
.get_cached_messages(bill.id().document_id())
.await
.unwrap()
.emails
.items
.len();
let bill_messages = inbox_count(&test.server, &bill).await;
lmtp.ingest(
"[email protected]",
@@ -617,17 +610,122 @@ END:VCARD
tokio::time::sleep(Duration::from_millis(200)).await;
assert_eq!(
test.server
.get_cached_messages(bill.id().document_id())
.await
.unwrap()
.emails
.items
.len(),
inbox_count(&test.server, &bill).await,
bill_messages + 1,
"sub-addressed mailing list member was not delivered"
);
// Lists nested within lists must be expanded recursively
admin
.registry_create_object(MailingList {
name: "engineering".to_string(),
recipients: Map::new(vec!["[email protected]".to_string()]),
domain_id,
..Default::default()
})
.await;
admin
.registry_create_object(MailingList {
name: "all-staff".to_string(),
recipients: Map::new(vec![
"[email protected]".to_string(),
"[email protected]".to_string(),
]),
domain_id,
..Default::default()
})
.await;
let jane_messages = inbox_count(&test.server, &jane).await;
let bill_messages = inbox_count(&test.server, &bill).await;
lmtp.ingest(
"[email protected]",
&["[email protected]"],
concat!(
"From: [email protected]\r\n",
"To: [email protected]\r\n",
"Subject: Company picnic\r\n",
"\r\n",
"Bring your own stapler."
),
)
.await;
tokio::time::sleep(Duration::from_millis(200)).await;
assert_eq!(
inbox_count(&test.server, &jane).await,
jane_messages + 1,
"nested mailing list member was not delivered"
);
assert_eq!(
inbox_count(&test.server, &bill).await,
bill_messages + 1,
"direct mailing list member was not delivered"
);
// Lists that reference each other must terminate and deliver exactly once
admin
.registry_create_object(MailingList {
name: "ouroboros-head".to_string(),
recipients: Map::new(vec![
"[email protected]".to_string(),
"[email protected]".to_string(),
"[email protected]".to_string(),
]),
domain_id,
..Default::default()
})
.await;
admin
.registry_create_object(MailingList {
name: "ouroboros-tail".to_string(),
recipients: Map::new(vec![
"[email protected]".to_string(),
"[email protected]".to_string(),
"[email protected]".to_string(),
]),
domain_id,
..Default::default()
})
.await;
let john_messages = inbox_count(&test.server, &john).await;
let jane_messages = inbox_count(&test.server, &jane).await;
let bill_messages = inbox_count(&test.server, &bill).await;
lmtp.ingest(
"[email protected]",
&["[email protected]"],
concat!(
"From: [email protected]\r\n",
"To: [email protected]\r\n",
"Subject: Going in circles\r\n",
"\r\n",
"Please advise."
),
)
.await;
tokio::time::sleep(Duration::from_millis(200)).await;
assert_eq!(
inbox_count(&test.server, &john).await,
john_messages + 1,
"cyclic mailing list did not deliver exactly once"
);
assert_eq!(
inbox_count(&test.server, &jane).await,
jane_messages + 1,
"cyclic mailing list did not deliver exactly once"
);
assert_eq!(
inbox_count(&test.server, &bill).await,
bill_messages + 1,
"member shared by two nested lists was delivered more than once"
);
// Remove test data
john.registry_destroy(
ObjectType::MaskedEmail,
@@ -708,3 +806,13 @@ async fn message_metadata(server: &Server, account_id: u32, document_id: u32) ->
.deserialize::<MessageMetadata>()
.unwrap()
}
async fn inbox_count(server: &Server, account: &Account) -> usize {
server
.get_cached_messages(account.id().document_id())
.await
.unwrap()
.emails
.items
.len()
}