feat: complete CalDAV (RFC 4791) and CardDAV (RFC 6352) implementation

- CalDAV: MKCALENDAR, PROPFIND, PUT/GET/DELETE events, REPORT calendar-query
- CardDAV: MKCOL, PROPFIND, PUT/GET/DELETE vCards, REPORT addressbook-query
- Fix routing: move CalDAV/CardDAV to top-level merge() with explicit routes
- Fix DB schema: VARCHAR(36) -> UUID for entity IDs, vcard_data -> vcard
- Fix 15 repository stub methods that returned empty results
- Fix vCard parser in ContactStorageAdapter (was hardcoded stub)
- All operations tested end-to-end in Docker (201/207/200/204 as expected)
This commit is contained in:
Dionisio
2026-02-10 18:46:59 +01:00
parent 5bd505ccd7
commit ef9ed2cc31
22 changed files with 3479 additions and 1125 deletions
+18
View File
@@ -94,6 +94,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut app;
// Build CalDAV / CardDAV protocol routers (merged at top-level, not under /api)
use oxicloud::interfaces::api::handlers::caldav_handler;
use oxicloud::interfaces::api::handlers::carddav_handler;
let caldav_router = caldav_handler::caldav_routes();
let carddav_router = carddav_handler::carddav_routes();
// Apply auth middleware to protected API routes when auth is enabled
if config.features.enable_auth && app_state.auth_service.is_some() {
use interfaces::api::handlers::auth_handler::auth_routes;
@@ -104,6 +110,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Protected API routes — require valid JWT token
let protected_api = api_routes
.layer(axum::middleware::from_fn_with_state(app_state_arc.clone(), auth_middleware));
// CalDAV/CardDAV with auth middleware (merged, not nested)
let caldav_protected = caldav_router
.layer(axum::middleware::from_fn_with_state(app_state_arc.clone(), auth_middleware));
let carddav_protected = carddav_router
.layer(axum::middleware::from_fn_with_state(app_state_arc, auth_middleware));
app = Router::new()
@@ -113,6 +125,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.nest("/api", public_api_routes)
// All other API routes are protected by auth middleware
.nest("/api", protected_api)
// CalDAV/CardDAV protocols merged at top-level for client compatibility
.merge(caldav_protected)
.merge(carddav_protected)
.merge(web_routes)
.layer(TraceLayer::new_for_http());
} else {
@@ -121,6 +136,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
app = Router::new()
.nest("/api", public_api_routes)
.nest("/api", api_routes)
// CalDAV/CardDAV protocols merged at top-level
.merge(caldav_router)
.merge(carddav_router)
.merge(web_routes)
.layer(TraceLayer::new_for_http());
}