/claim #5756
What does this PR do?
Adds a standalone Proton Calendar app (app.cal.com/apps/proton-calendar) that handles Proton-specific ICS feed nuances, separate from the generic ICS feed app.
This follows the approach suggested by @PeerRich and @alishaz-polymath — a Proton-specific app based on the ICS feed app where we can handle Proton quirks without breaking the generic ICS app for other providers.
Key improvements over the base ICS app:
- Fix ghost events: Filters
STATUS:CANCELLED events that Proton includes in its ICS feeds, which were blocking availability incorrectly
- Fix cancelled recurring occurrences: Tracks cancelled occurrences by UID + recurrence-id so phantom busy slots from cancelled instances of recurring events are properly skipped
- Proton URL validation: Only accepts
proton.me / protonmail.com domains (prevents SSRF, ensures correct app usage)
- Proton branding: Dedicated app with Proton Calendar icon, description, and setup instructions
- Default calendar name fallback: Uses “Proton Calendar” when
x-wr-calname is missing from the feed
Architecture
The app follows the exact same patterns as the existing ICS feed app:
_metadata.ts for app registration
api/add.ts for credential setup (with Proton domain validation)
lib/CalendarService.ts — based on ICS feed service with Proton-specific fixes
- Read-only by design (Proton does not support third-party writes due to E2E encryption)
How to test
- Install the Proton Calendar app from the app store
- In Proton Calendar → Settings → Calendars → Share → create a “Link to calendar” (ICS feed)
- Paste the URL into the app setup
- Verify:
- Cancelled events no longer block availability (ghost events fixed)
- Recurring events expand correctly within the availability window
- Non-Proton URLs are rejected
Mandatory Tasks
- I have self-reviewed the code
- N/A — no developer docs changes needed
- Automated tests — happy to add if requested; the CalendarService logic mirrors the existing ICS feed app with targeted Proton fixes
Fixes #5756