diff --git a/knot2/crates/knot-server/Cargo.toml b/knot2/crates/knot-server/Cargo.toml index 31c4a3816..ccb46e038 100644 --- a/knot2/crates/knot-server/Cargo.toml +++ b/knot2/crates/knot-server/Cargo.toml @@ -28,7 +28,7 @@ knot-maintenance = { workspace = true } knot-postreceive = { workspace = true } knot-messages = { workspace = true } axum = { workspace = true } -tower-http = { workspace = true, features = ["fs"] } +tower-http = { workspace = true, features = ["fs", "cors"] } tokio = { workspace = true } tokio-util = { workspace = true } anyhow = { workspace = true } diff --git a/knot2/crates/knot-server/src/main.rs b/knot2/crates/knot-server/src/main.rs index 1183bb92f..3d7e82147 100644 --- a/knot2/crates/knot-server/src/main.rs +++ b/knot2/crates/knot-server/src/main.rs @@ -18,6 +18,7 @@ use tokio_util::sync::CancellationToken; use anyhow::Context; use axum::Json; +use axum::http::{Method, header}; use axum::response::Html; use axum::routing::get; use base64::Engine; @@ -28,6 +29,7 @@ use knot_runtime::{Clock, HttpTransport, OsEntropy, ReqwestHttp, SystemClock}; use knot_secrets::{MasterKey, SealedStore}; use knot_types::{ActorId, AuthorName, BranchName, CiLogsAddr, Email, KnotHostname, ObjectCount}; use knot_xrpc::XrpcState; +use tower_http::cors::{Any, CorsLayer}; use tower_http::services::ServeFile; const MAINTENANCE_SHUTDOWN_DRAIN: Duration = Duration::from_secs(30); @@ -645,6 +647,12 @@ async fn main() -> anyhow::Result<()> { HomepageSource::Default => base_router.route("/", get(|| async { Html(DEFAULT_HOMEPAGE) })), HomepageSource::File(path) => base_router.route_service("/", ServeFile::new(path)), }; + let base_router = base_router.layer( + CorsLayer::new() + .allow_origin(Any) + .allow_methods([Method::GET, Method::POST, Method::OPTIONS]) + .allow_headers([header::AUTHORIZATION, header::CONTENT_TYPE]), + ); let app = knot_edge::RequiresFullHandshake::new(base_router); let scheme = if tls_setup.is_some() { "https" } else { "http" }; let edge_config = knot_edge::EdgeConfig {