Commit Graph
3 Commits
Author SHA1 Message Date
wrycu 3a3ebc9155 fix: rsvp controls
* adds "canRSVP" in addition to the existing "getEventEditability"
* wires calendar to leverage "canRSVP" before editability checks
* adds tests for RSVP
2026-09-03 22:12:15 -07:00
Stefan Hildebrandt 06784581aa fix(calendar): exclude subscription/read-only calendars from event creation (#762)
The rights-first resolver already made EXISTING events in subscription /
read-only calendars read-only, but the create path still offered them:
event-modal's calendar dropdown listed every calendar. iCal subscriptions are
real Stalwart calendars (client-side feed written into a created calendar) with
writable myRights, so they appeared as selectable create destinations.

- canCreateEventsIn(calendar, isSubscriptionCalendar): writable AND not a
  subscription. Exported from lib/calendar-editability.
- event-modal: the calendar picker now lists only creatable calendars (plus the
  event's own calendar when editing), and new events never default into a
  subscription / read-only calendar.

+4 unit tests. tsc + eslint clean; calendar-editability suite 30 green.
2026-08-10 12:05:44 +02:00
Stefan Hildebrandt 3898d0c1cb fix(calendar): rights-first event editability, incl. alias organizers
Event editability was inferred from identity (isOrigin + organizer match)
and never from the calendar's write rights. That opened events in read-only
shared / iCal-subscription calendars for editing, and once the address list
was widened with account aliases any alias-organized event became editable -
even in calendars the user cannot write.

- lib/calendar-editability.ts: getEventEditability() -> editable | rsvp-only
  | read-only, gating on the calendar's myRights (mayWriteAll / mayWriteOwn /
  mayRSVP) first, then organizer/participant identity. Subscriptions are
  read-only. Aliases now only refine the write-own / RSVP branches, so they
  can no longer over-open events (Stalwart: organizer identity does not
  confer calendar write; the ACL does).
- collectUserCalendarAddresses(): merge identities + account aliases so an
  alias organizer is recognised as the user's own; calendar-app fetches the
  principal aliases and passes isSubscriptionCalendar through.
- event-detail-popover / event-modal: derive Edit/Delete/RSVP/read-only from
  the resolver (three render states); read-only is new - no edit, no RSVP.

Tests: calendar-editability (26 cases over rights x role x subscription x
origin, incl. the alias-in-read-only regression) + calendar-participants.
tsc + eslint clean.
2026-08-10 09:09:55 +02:00