From af583c19c1ca2ce9288cfcc4a9a5620aca8839b8 Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Fri, 8 May 2026 08:06:18 +0200 Subject: [PATCH] Fix HTTP: Use permissive CORS headers for `.well-known` endpoints --- CHANGELOG.md | 1 + README.md | 4 ++-- crates/http-proto/src/response.rs | 15 +++++++++++++++ crates/http/src/auth/oauth/auth.rs | 3 ++- crates/http/src/auth/oauth/openid.rs | 3 ++- crates/http/src/request.rs | 7 ++++--- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 566aab6bb..7f230ff61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If - SQL directory: Return `Failed` instead of `Error` when the query returns no results. - Network: Attempt binding to IPv4 when binding to IPv6 fails with `EAFNOSUPPORT` error. - Bootstrap: Timeout after 30 seconds when probing the data store. +- HTTP: Use permissive CORS headers for `.well-known` endpoints. - ACME: - Include apex domains when requesting certificates for subdomains. - Use the public suffix list to determine the zone name when no origin is provided. diff --git a/README.md b/README.md index 948da46a8..e347df811 100644 --- a/README.md +++ b/README.md @@ -142,8 +142,8 @@ All documentation is available at [stalw.art/docs](https://stalw.art/docs/instal ## Support -If you are having problems running Stalwart, you found a bug or just have a question, do not hesitate to reach us on [GitHub Discussions](https://github.com/stalwartlabs/stalwart/discussions), [Reddit](https://www.reddit.com/r/stalwartlabs) or [Discord](https://discord.com/servers/stalwart-923615863037390889). -Additionally you may purchase an [Enterprise License](https://stalw.art/enterprise) to obtain priority support from Stalwart Labs LLC. +If you are having problems running Stalwart, found a bug, or just have a question, please head to the [Stalwart Support Portal](https://support.stalw.art) at [support.stalw.art](https://support.stalw.art). +Additionally, you may purchase an [Enterprise License](https://stalw.art/enterprise) to obtain priority support from Stalwart Labs LLC, including response-time commitments and a private Priority Support area on the portal. ## Roadmap diff --git a/crates/http-proto/src/response.rs b/crates/http-proto/src/response.rs index 1707dc783..52cacd944 100644 --- a/crates/http-proto/src/response.rs +++ b/crates/http-proto/src/response.rs @@ -179,6 +179,21 @@ impl HttpResponse { self } + pub fn with_cors_unrestricted(mut self) -> Self { + self.builder = self + .builder + .header(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*") + .header( + header::ACCESS_CONTROL_ALLOW_HEADERS, + "Authorization, Content-Type, Accept, X-Requested-With", + ) + .header( + header::ACCESS_CONTROL_ALLOW_METHODS, + "POST, GET, PATCH, PUT, DELETE, HEAD, OPTIONS", + ); + self + } + pub fn size(&self) -> usize { match &self.body { HttpResponseBody::Text(value) => value.len(), diff --git a/crates/http/src/auth/oauth/auth.rs b/crates/http/src/auth/oauth/auth.rs index 2b4b2346c..ca448e1c3 100644 --- a/crates/http/src/auth/oauth/auth.rs +++ b/crates/http/src/auth/oauth/auth.rs @@ -456,6 +456,7 @@ impl OAuthApiHandler for Server { code_challenge_methods_supported: &["S256"], issuer: base_url.to_string(), }) - .into_http_response()) + .into_http_response() + .with_cors_unrestricted()) } } diff --git a/crates/http/src/auth/oauth/openid.rs b/crates/http/src/auth/oauth/openid.rs index 14cbecaf3..f8a32e538 100644 --- a/crates/http/src/auth/oauth/openid.rs +++ b/crates/http/src/auth/oauth/openid.rs @@ -99,6 +99,7 @@ impl OpenIdHandler for Server { code_challenge_methods_supported: &["S256"], issuer: base_url.to_string(), }) - .into_http_response()) + .into_http_response() + .with_cors_unrestricted()) } } diff --git a/crates/http/src/request.rs b/crates/http/src/request.rs index 6de1f5c78..f80517769 100644 --- a/crates/http/src/request.rs +++ b/crates/http/src/request.rs @@ -321,7 +321,8 @@ impl ParseHttp for Server { .await? .into_bytes(), ) - .into_http_response()); + .into_http_response() + .with_cors_unrestricted()); } ("mail-v1.xml", &Method::GET) => { // Limit anonymous requests @@ -344,10 +345,10 @@ impl ParseHttp for Server { return self .handle_autoconfig_request(req.uri().query()) .await - .map(|resource| resource.into_http_response()); + .map(|resource| resource.into_http_response().with_cors_unrestricted()); } (_, &Method::OPTIONS) => { - return Ok(HttpResponse::new(StatusCode::NO_CONTENT)); + return Ok(HttpResponse::new(StatusCode::NO_CONTENT).with_cors_unrestricted()); } _ => (), },