diff --git a/CHANGELOG.md b/CHANGELOG.md index 21d4a905..3782536e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This version includes **multiple breaking changes**. If you are upgrading from v - Sorting order issues when emails lack `receivedAt` headers. - IMAP: Fix `BINARY` fetch responses (#2940). - ACME: Allow requesting apex domain certificates. +- Bootstrap: Accept RFC 6761 reserved TLDs during bootstrap. - Reverse proxy issues. - OSS builds. - DNS Updater: diff --git a/crates/jmap/src/registry/mapping/bootstrap.rs b/crates/jmap/src/registry/mapping/bootstrap.rs index c5a7b257..44636157 100644 --- a/crates/jmap/src/registry/mapping/bootstrap.rs +++ b/crates/jmap/src/registry/mapping/bootstrap.rs @@ -121,7 +121,7 @@ pub(crate) async fn bootstrap_set( // Validate domain name and hostname let server_hostname = bootstrap.server_hostname.trim().to_lowercase(); let domain_name = bootstrap.default_domain.trim().to_lowercase(); - if psl::domain_str(&server_hostname).is_none() && !server_hostname.ends_with(".test") { + if !is_valid_domain(&server_hostname) { set.response.not_updated.append( id, SetError::invalid_properties() @@ -130,7 +130,7 @@ pub(crate) async fn bootstrap_set( ); break; } - if psl::domain_str(&domain_name).is_none() && !domain_name.ends_with(".test") { + if !is_valid_domain(&domain_name) { set.response.not_updated.append( id, SetError::invalid_properties() @@ -505,6 +505,15 @@ pub(crate) async fn bootstrap_set( Ok(set) } +fn is_valid_domain(hostname: &str) -> bool { + const RESERVED_TLDS: &[&str] = &["test", "localhost", "local"]; + psl::domain_str(hostname).is_some() + || RESERVED_TLDS.contains(&hostname) + || hostname + .rsplit_once('.') + .is_some_and(|(_, tld)| RESERVED_TLDS.contains(&tld)) +} + async fn write_object(registry: &RegistryStore, object: &Object) -> Result> { match registry.write(RegistryWrite::insert(object)).await { Ok(RegistryWriteResult::Success(id)) => Ok(id),