github olivierlambert/calrs v1.13.0
v1.13.0: Exchange (EWS) + Google OAuth2 backends, meeting links, captcha, embeds

12 hours ago

calrs 1.13.0 is the provider-expansion release: connecting a calendar no longer means CalDAV with basic auth. Microsoft Exchange (EWS) joins as a second backend behind a new provider trait, Google Calendar connects via OAuth2 with encrypted token storage, confirmed bookings can auto-generate video meeting links (Jitsi pattern or bring-your-own webhook), booking pages gain an opt-in self-hosted proof-of-work captcha, and an embed system lets you put your booking page on any website. Two headline features are community contributions.

Added

  • Microsoft Exchange (EWS) backend (PR #103) — adds on-prem Exchange 2013/2016/2019 support via a minimal SOAP client in src/ews/ (autodiscover, GetFolder/FindItem/CreateItem/DeleteItem, iCal ↔ EWS field mapping). A new provider factory in src/providers/ abstracts CalDAV vs EWS behind a single CalendarProvider trait; the CalDAV path is unchanged. Source-add form gains a Backend dropdown with protocol-filtered presets. Migration 055 adds provider_type on caldav_sources (defaults to caldav, backward compatible)
  • Google Calendar (OAuth2) sources (PR #99) — admin configures the OAuth2 client ID/secret in the admin panel; users connect via "Add Google Calendar" on the sources page or calrs source add-google. Access and refresh tokens are stored AES-256-GCM encrypted and refreshed proactively five minutes before expiry. Migration 053
  • Auto-generated video meeting links (PR #128, phases 1+2 of #45) — new Jitsi (auto-generated room) location type: every confirmed booking gets a fresh URL built from WordPress-style pattern tokens ({username}, {event}, {date}, {random}; default {event}-{random}), with the pattern configurable org-wide and overridable per event type. Plus a Webhook (custom provider) location type for bring-your-own providers (Jitsi+JWT, Whereby, custom Meet): calrs POSTs booking details and uses the returned URL. Migration 056
  • Booking captcha (PR #122, contributed by @florian-SV) — opt-in Cap integration: self-hosted proof-of-work captcha on booking pages, no third-party tracking. Without configuration the booking flow is byte-for-byte unchanged. The Cap secret is encrypted at rest (same AES-256-GCM pattern as OIDC secrets), and the CSP is rebuilt in memory on every admin save, no restart needed, scoped to booking form pages only
  • Embed code generator (PR #125) — Cal.com-style embed system: a self-contained embed.js exposes Calrs.inline (auto-sizing iframe), Calrs.floatingButton (corner pill + modal), and Calrs.elementClick (data-attribute binding). ?embed=1 strips navigation chrome, autosizes via calrs:resize postMessages, accepts layout/theme/brand params, and switches the CSRF cookie to SameSite=None; Secure so cross-origin iframes work
  • calrs config dump (PR #112, contributed by @mvalois) — dumps the full instance configuration as JSON (--pretty supported): 18 sections covering auth, SMTP, users, sources, event types with availability rules/overrides, teams, weights, watchers and frequency limits, plus a top-level schema_version. Secrets and operational sync state are excluded by construction, with tests asserting they never appear
  • CALRS_ALLOW_PRIVATE_HOSTS (PR #124, closes #123) — opt-in, comma-separated, exact-match allowlist letting specific CalDAV/EWS hosts resolve to private/reserved IPs (docker-compose stacks, self-hosted Exchange behind private addressing). The SSRF guard stays active for every non-listed host; scheme checks still apply. Reported and verified by @aburg

Fixed

  • Google sync silently truncating the forward window (PR #99) — an unfiltered calendar-query REPORT left future events out of the local cache, making booked days look available. The full-fetch path now sends an RFC 4791 time-range filter with a 90-day lookback, falling back to the unfiltered REPORT for servers that reject it; orphan cleanup is scoped to the same window so pre-window history is preserved
  • CalDAV write-back no longer gated on SMTP (PR #99) — all four guest booking handlers previously wrapped the CalDAV push inside an SMTP-config check, so bookings on instances without SMTP never reached the host's calendar. Confirmed bookings now push unconditionally; only email sends remain gated on SMTP. A dashboard warning surfaces when sources are enabled but none have a write target
  • EWS: timed UTC events, all-day date offset, recurring series (PR #127) — follow-up correctness pass on the EWS backend
  • Friendly email validation on booking forms (PR #129) — incomplete addresses like user@domain (no TLD) pass HTML5 validation but failed server-side with a bare error page; guests now get a proper inline error

Internal

  • Migrations 053–056 (oauth2_caldav, captcha, provider_type, meeting_links)
  • Translation updates from Weblate (PR #131)
  • 758 tests, all green (up from 671 in 1.12.0)

Don't miss a new calrs release

NewReleases is sending notifications on new releases.