fix(caldav): consistent UIDs and VTIMEZONE in iCalendar output#28115
fix(caldav): consistent UIDs and VTIMEZONE in iCalendar output#28115anikdhabal merged 5 commits intocalcom:mainfrom
Conversation
…tput Two remaining CalDAV interop issues from calcom#9485: 1. UID consistency: use the booking's canonical UID (event.uid) instead of always generating a new random UUID. CalDAV servers use UID as the event identifier — different UIDs cause duplicate calendar entries. 2. VTIMEZONE injection: the ics library generates UTC times with no VTIMEZONE block. CalDAV servers like Fastmail read this as UTC and send scheduling emails with wrong times. Per RFC 5545 §3.6.5, DTSTART with TZID requires a matching VTIMEZONE component. We now build a proper VTIMEZONE using binary-searched DST transitions for the event's year, handling Northern/Southern hemisphere correctly.
|
@anikdhabal here's the follow-up you asked for on #22434. 2 files changed, all 24 tests passing with TZ=UTC. for the UID fix — just for VTIMEZONE — instead of hardcoding US-specific DST rules, we binary-search the actual transition moments for the event's year using dayjs timezone data. this handles southern hemisphere zones (australia/sydney where DST polarity is reversed) and zones that changed rules post-2007 (US moved from 1st sunday in april to 2nd sunday in march). the VTIMEZONE block gets injected before BEGIN:VEVENT, and DTSTART/DTEND get rewritten from UTC to TZID-qualified local times. both fixes apply to createEvent and updateEvent. used #28112 as reference. |
Graphite Automations"Send notification to Community team when bounty PR opened" took an action on this PR • (02/21/26)2 teammates were notified to this PR based on Keith Williams's automation. |
There was a problem hiding this comment.
1 issue found across 2 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/lib/CalendarService.ts">
<violation number="1" location="packages/lib/CalendarService.ts:202">
P2: VTIMEZONE DTSTART is computed using the post-transition offset, so the generated onset time is shifted by the DST change (e.g., 03:00 instead of 02:00). RFC 5545 requires the DTSTART local time of the onset (interpreted with the pre-transition offset), so this produces incorrect DST boundaries in CalDAV clients.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
The DTSTART in VTIMEZONE components must represent the local time interpreted with the pre-transition offset (TZOFFSETFROM), not the post-transition offset. For example, US Eastern spring forward DTSTART should be 02:00 (EST), not 03:00 (EDT).
Removed comments about UID handling for calendar events.
Update injectVTimezone function documentation to clarify UTC handling.
Follow-up to #22434 — addresses the two remaining CalDAV interop issues flagged in #28112.
What changed
1. UID consistency
createEventwas always generating a freshuuidv4(). CalDAV servers use the UID as the canonical event identifier, so when cal.com's email invitation carried a different UID than the CalDAV object, recipients ended up with duplicate entries. Now we useevent.uid || uuidv4()so the booking's UID flows through to the.icsfile.2. VTIMEZONE injection
The
icslibrary outputs UTC times (DTSTART:20240115T140000Z) with noVTIMEZONEblock. RFC 5545 §3.6.5 requires aVTIMEZONEcomponent whenDTSTARTusesTZID. Without it, CalDAV servers like Fastmail fall back to UTC and send scheduling emails showing the wrong local time.We now:
DTSTART/DTENDfrom UTC toDTSTART;TZID=America/Chicago:20240115T080000(organizer's timezone)VTIMEZONEwithSTANDARD/DAYLIGHTcomponentsBYDAY/BYMONTHBoth fixes apply to
createEventandupdateEvent.Tests
10 new tests covering:
event.uidwhen provided, falls back touuidv4(), filename matches UIDVEVENT,DTSTARTusesTZID, correct UTC→local conversion, valid 8-digit dates in RRULE, Southern Hemisphere DST,updateEventparityAll 24 tests pass (
TZ=UTC yarn vitest run packages/lib/CalendarService.test.ts).Fixes #9485