fetchCalendars: accept calendars without supported-calendar-component-set#276
fetchCalendars: accept calendars without supported-calendar-component-set#276ilyasturki wants to merge 1 commit intonatelindev:mainfrom
Conversation
…t is absent Some CalDAV servers (notably Purelymail) violate RFC 4791 § 5.2.3 by failing to return the supported-calendar-component-set property in PROPFIND responses, even on real calendar collections. The current filter rejects every such calendar, breaking discovery against otherwise functional servers. Treat the absence of declared components as "unknown, accept" rather than "reject". The earlier resourcetype filter has already confirmed the resource declares <calendar/>, so we have independent evidence it's a calendar; the component-set filter only meaningfully discriminates between iCal-style and non-iCal calendars when a server actually populates the property. Tolerant clients like Thunderbird and Evolution-DS accept these servers today; this brings tsdav in line with their behavior. The added regression test covers both an empty <supported-calendar-component-set/> element (Purelymail's actual response shape) and the property being entirely absent from the response.
|
@ilyasturki is attempting to deploy a commit to the llldar's projects Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
Updates fetchCalendars to be more tolerant of real-world CalDAV servers that omit or return an empty supported-calendar-component-set, while keeping existing filtering behavior when components are explicitly declared.
Changes:
- Adjust calendar filtering to accept calendars when
supported-calendar-component-setyields no component names. - Add unit test coverage for calendars where
supported-calendar-component-setis empty or absent.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/calendar.ts |
Relaxes iCal component filtering to treat empty/missing component-set as “accept”. |
src/__tests__/unit/calendar.test.ts |
Adds regression test for empty and missing supported-calendar-component-set. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| it('should accept calendars when supported-calendar-component-set is missing', async () => { | ||
| // Some servers (e.g. Purelymail) violate RFC 4791 § 5.2.3 by not returning the | ||
| // supported-calendar-component-set property. The previous resourcetype filter has | ||
| // already confirmed these are calendar collections, so they should pass through. | ||
| mockedPropfind.mockResolvedValue([ |
There was a problem hiding this comment.
Test name says "supported-calendar-component-set is missing" but the fixture also covers the "present but empty" case (supportedCalendarComponentSet: {}); consider renaming the test to mention both (e.g. "missing or empty") or splitting into two tests to make the intent explicit.
Summary
fetchCalendarscurrently filters out any calendar whosesupported-calendar-component-setproperty is empty or absent. Real-world CalDAV servers do this in violation of RFC 4791 § 5.2.3 — most notably Purelymail, which returns an empty<supported-calendar-component-set/>element on every calendar collection.The earlier filter (
Object.keys(resourcetype).includes('calendar')) has already confirmed the resource is a calendar by the time we reach the component-set check, so the second filter is acting as belt-and-suspenders defense rather than primary identification. When the property is absent, falling back to "accept" matches what tolerant clients like Thunderbird/Lightning, Evolution-DS, and DAVx5 do in practice.Reproduction (against Purelymail)
DEBUG=tsdav:*confirms the full discovery chain succeeds (well-known redirect → principal → calendar-home-set) — onlyfetchCalendarsswallows the actual calendar.Diff summary
src/calendar.ts: whenextractComponentNamesreturns an empty array, accept the calendar instead of rejecting it.src/__tests__/unit/calendar.test.ts: regression test with two fixtures — emptysupported-calendar-component-setelement (Purelymail's actual shape) and the property being entirely absent.Verification
pnpm test— 186/186 unit tests pass (12 files), including 2 new fixtures.pnpm typecheck— clean.pnpm lint— clean for changed files (2 pre-existing errors insrc/account.tsare unrelated to this PR).fetchCalendars()now returns theDefaultcalendar correctly; downstreamfetchCalendarObjectsandfreeBusyQueryalso work.Compatibility
UNKNOWN_TYPE) still get filtered out. Only the absent/empty case changes behavior.