Fix CalDAV: calendar-query REPORT returns empty calendar-data for JMAP-created events

This commit is contained in:
Maurus Decimus
2026-07-19 21:27:01 +02:00
parent 2bce0d22fd
commit c105cff8fb
4 changed files with 294 additions and 262 deletions

View File

@@ -20,6 +20,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
- `PushSubscription/set` rejects the unpadded base64url keys the W3C Push API produces.
- `Email/import` does not send push notifications for imported messages.
- `CalendarEvent/set` silently ignores `ifInState`.
- CalDAV: `calendar-query` REPORT returns empty calendar-data for JMAP-created events.
- MTA: DMARC is skipped when MAIL FROM SPF is unavailable.
- Calendar:
- Uppercase `MAILTO` calendar addresses become invalid SMTP recipients.

505
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -562,7 +562,10 @@ impl CalendarQueryHandler {
let _ = write!(&mut out, "END:{component_name}\r\n");
}
}
} else if entries.peek().is_some() {
} else if entries.peek().is_some()
|| (component.component_type == ICalendarComponentType::VCalendar
&& !component.component_ids.is_empty())
{
let _ = write!(&mut out, "BEGIN:{component_name}\r\n");
match data.limit_freebusy {

View File

@@ -176,6 +176,22 @@ pub async fn test(test: &TestServer) {
remove_dtstamp(REPORT_11_RESPONSE)
);
// Test 12: JMAP-style event stored with an entry-less VCALENDAR wrapper
client
.request("PUT", &rfc_file_name(9), ICAL_JMAP_NO_VERSION)
.await
.with_status(StatusCode::CREATED);
let response = client
.request("REPORT", &cal_path, REPORT_12)
.await
.with_status(StatusCode::MULTI_STATUS)
.with_hrefs([rfc_file_name(9).as_str()])
.into_propfind_response(None);
response
.properties(&rfc_file_name(9))
.calendar_data()
.is_not_empty();
client.delete_default_containers().await;
test.assert_is_empty().await;
}
@@ -737,6 +753,35 @@ const REPORT_9: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
</C:calendar-query>
"#;
const REPORT_12: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop xmlns:D="DAV:">
<D:getetag/>
<C:calendar-data/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:prop-filter name="UID">
<C:text-match collation="i;octet"
>JMAP-NO-VERSION-EVENT@example.com</C:text-match>
</C:prop-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
"#;
const ICAL_JMAP_NO_VERSION: &str = r#"BEGIN:VCALENDAR
BEGIN:VEVENT
UID:JMAP-NO-VERSION-EVENT@example.com
SUMMARY:JMAP created event
DTSTART:20060107T120000Z
DTEND:20060107T130000Z
END:VEVENT
END:VCALENDAR
"#;
const REPORT_10: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
<C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
<C:time-range start="20060104T140000Z"