diff --git a/crates/dav/src/resource/axum_service.rs b/crates/dav/src/resource/axum_service.rs index 22dcf0e..5bfa98f 100644 --- a/crates/dav/src/resource/axum_service.rs +++ b/crates/dav/src/resource/axum_service.rs @@ -114,6 +114,9 @@ where } async fn route_options() -> Response { + // Semantically NO_CONTENT would also make sense, + // but GNOME Accounts only works when returning OK + // https://gitlab.gnome.org/GNOME/gnome-online-accounts/-/blob/master/src/goabackend/goadavclient.c#L289 let mut resp = Response::builder().status(StatusCode::OK); let headers = resp.headers_mut().unwrap(); headers.insert("DAV", HeaderValue::from_static(RS::DAV_HEADER)); diff --git a/src/app.rs b/src/app.rs index ce6b042..d0b9bd7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,9 +1,11 @@ use crate::config::NextcloudLoginConfig; use axum::Router; +use axum::body::Body; use axum::extract::Request; -use axum::response::Response; +use axum::response::{IntoResponse, Response}; +use axum::routing::options; use headers::{HeaderMapExt, UserAgent}; -use http::StatusCode; +use http::{HeaderValue, StatusCode}; use rustical_caldav::caldav_router; use rustical_carddav::carddav_router; use rustical_frontend::nextcloud_login::nextcloud_login_router; @@ -46,6 +48,24 @@ pub fn make_app( subscription_store.clone(), )); + // GNOME Accounts needs to discover a WebDAV Files endpoint to complete the setup + // It looks at / as well as /remote.php/dav (Nextcloud) + // This is not nice but we offer this as a sacrificial route to ensure the CalDAV/CardDAV setup + // works. + // See: + // https://github.com/GNOME/gnome-online-accounts/blob/master/src/goabackend/goadavclient.c + // https://github.com/GNOME/gnome-online-accounts/blob/master/src/goabackend/goawebdavprovider.c + router = router.route( + "/remote.php/dav", + options(async || { + let mut resp = Response::builder().status(StatusCode::OK); + resp.headers_mut() + .unwrap() + .insert("DAV", HeaderValue::from_static("1")); + resp.body(Body::empty()).unwrap() + }), + ); + let session_store = MemoryStore::default(); if frontend_config.enabled { router = router.merge(frontend_router(