fix(dav): send reply email to organizer when attendee responds via invitation link#61213
Open
ndo84bw wants to merge 1 commit into
Open
fix(dav): send reply email to organizer when attendee responds via invitation link#61213ndo84bw wants to merge 1 commit into
ndo84bw wants to merge 1 commit into
Conversation
…vitation link Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Nico Donath <ndo84bw@gmx.de>
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.
Summary
When an attendee responds to a calendar invitation via the Accept/Decline links in the invitation email (
/apps/dav/invitation/{accept,decline}/{token}), the attendee's participation status is updated on the organizer's event, but the organizer is never notified by email. Responding to the same invitation through the Calendar web UI or through a CalDAV client does notify the organizer. nextcloud/calendar#7636 reports this inconsistency.Root cause
The invitation links are handled by
InvitationResponseController, which delivers the reply through a dedicated minimal DAV server,InvitationResponseServer. Delivering the reply to the attendee's calendar already triggers sabre's scheduling cascade (Sabre\CalDAV\Schedule\Plugin::scheduleLocalDelivery()→processICalendarChange()→deliver()): a second iTip REPLY addressed to the organizer is generated and emitted as ascheduleevent. This is how the organizer's copy of the event gets updated today.Sending the email is the responsibility of
IMipPlugin, which listens on that samescheduleevent. On the regular DAV server it is registered (apps/dav/lib/Server.php), onInvitationResponseServerit is not. The event that would produce the organizer email fires with nobody listening.Fix
Register
IMipPluginon theInvitationResponseServer, but only inhandleITipMessage(), which is exclusively used by the invitation-link controller. It must not be registered unconditionally in the constructor: the same server class is also used byCalendarImpl(e.g. iMIP processing for the Mail app) and byICreateFromString::createFromStringMinimal(), whose API documentation explicitly guarantees "no iMIP plugin, no invitation emails". Registering the plugin globally would cause duplicate emails in those flows.With this change, responding via the email links produces the same organizer notification as responding via the Calendar web UI, generated by the same broker/IMip machinery.
Known limitation (intentionally out of scope)
Attendees that are not users on the instance (external attendees) still do not trigger an organizer email when they use the links. Their reply takes a different path: it is delivered directly into the organizer's calendar via
scheduleLocalDelivery()without ever passing through thescheduleevent, and the token-built REPLY object lacks the event data (DTSTART,SUMMARY) needed to render the email. Supporting that case requires enriching the reply from the stored event first, which is a considerably larger change. I would prefer to address it in a follow-up PR so this fix is not blocked by that discussion. Whether nextcloud/calendar#7636 can be closed with this PR alone or only together with the follow-up is up to the maintainers.TODO
Manual tests
Performed on a Nextcloud 33.0.3 instance with this change applied (
handleITipMessage()is identical on master and stable33). User A (organizer) and user B (attendee) are users on the instance, user C is an external attendee invited by email address only.Checklist
InvitationResponseServerTestasserts that the constructor does not register the iMIP plugin (thecreateFromStringMinimal()guarantee) and thathandleITipMessage()does.3. to review, feature component)stable32)AI (if applicable)