CalDAV - Working#343
Open
cjroth wants to merge 4 commits into
Open
Conversation
cjroth
commented
Jun 5, 2026
- Based on @zCri's PR - CalDAV support #282
- This is fully working for me.
- This is AI-generated code - I did a light review.
- Creating events with attendees is working but adding them retroactively is not.
Squashes PR emersion#282 (zCri's CalDAV support) plus our fixes onto current master, replacing the stale go-webdav v0.5.1 base. Ports the backend to the go-webdav v0.7.0 caldav.Backend interface: - PutCalendarObject now returns (*caldav.CalendarObject, error) - implement CreateCalendar (MKCALENDAR) as 501 Not Implemented (Proton calendar provisioning is not supported yet; create via the web app) Carries the three correctness fixes from the original port: 1. event create detection via errors.As (wrapped APIError, code 2061) 2. read-back of own events when Author is empty (fall back to user keyring) 3. time-range calendar-query filtering via go-webdav's caldav.Match Tests: protonmail/calendar_test.go (unit) + test/caldav_e2e.py (full create/read/update/delete/query lifecycle, 12/12 against live API).
The CalDAV backend registered an events channel but never read it (empty receiveEvents stub). events.Receiver dispatches each event to every registered channel while holding its lock, over UNBUFFERED channels — so the first real Proton event blocked the dispatcher forever with the lock held. That in turn deadlocked the next events.Manager.Register call, i.e. the first CardDAV request for the same account (manifesting as CardDAV PROPFINDs hanging indefinitely once any calendar/mail event had fired). Drain the channel so the shared receiver stays healthy.
Implements the PR's biggest deferred TODO. Outgoing: parse ATTENDEE props, derive the Proton attendee token (SHA1(UID+normalized email)), build an encrypted attendee card with the event's shared session key, populate the Attendees clear list, and wrap the shared session key to each internal Proton attendee's address key (AddedProtonAttendees) so they can decrypt the event. Read-back: decode the AttendeesEvents card so clients see invitees + RSVP status (and preserve multiple ATTENDEE props on merge). Refactors makeUpdateData to generate the shared session key once up front so the shared part and attendee card share it. Adds a unit test pinning the token derivation.
hydroxide never signed attachments (two TODOs), so Proton rejected any outgoing message with an attachment: [2011] One or more attachments are missing a signature. Add Attachment.Sign (binary detached signature of the plaintext, matching go-proton-api's GetBinary()) and upload it as the Signature multipart field. smtp buffers the part, signs, then encrypts. Unblocks sending attachments generally (and iMIP calendar invitations).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.