iTIP: Do not send a REPLY when deleting an event that was not accepted

This commit is contained in:
mdecimus
2025-09-08 10:13:00 +02:00
parent 68d02a6df7
commit 751cb16a8b
5 changed files with 28 additions and 17 deletions

View File

@@ -391,7 +391,7 @@ impl DestroyArchive<Archive<&ArchivedCalendarEvent>> {
.caused_by(trc::location!())?;
if let Ok(messages) =
itip_cancel(&event.data.event, access_token.emails.as_slice())
itip_cancel(&event.data.event, access_token.emails.as_slice(), true)
{
ItipMessages::new(vec![messages])
.queue(batch)

View File

@@ -59,6 +59,7 @@ pub(crate) fn attendee_handle_update(
old_instance,
&dt_stamp,
&mut email_rcpt,
false,
) {
// Add EXDATE as RECURRENCE-ID
cancel_comp
@@ -207,6 +208,7 @@ pub(crate) fn attendee_handle_update(
old_instance,
&dt_stamp,
&mut email_rcpt,
false,
) {
// Add cancel component
let comp_id = message.components.len() as u16;
@@ -269,6 +271,7 @@ pub(crate) fn attendee_decline<'x>(
comp: &'x ItipSnapshot<'x>,
dt_stamp: &'x PartialDateTime,
email_rcpt: &mut AHashSet<&'x str>,
skip_needs_action: bool,
) -> Option<(ICalendarComponent, &'x Email)> {
let component = comp.comp;
let mut cancel_comp = ICalendarComponent {
@@ -284,14 +287,14 @@ pub(crate) fn attendee_decline<'x>(
if attendee.email.is_local {
if attendee.is_server_scheduling
&& attendee.rsvp.is_none_or(|rsvp| rsvp)
&& (attendee.force_send.is_some()
|| !matches!(
attendee.part_stat,
Some(
ICalendarParticipationStatus::Declined
| ICalendarParticipationStatus::Delegated
)
))
&& match attendee.part_stat {
Some(
ICalendarParticipationStatus::Declined
| ICalendarParticipationStatus::Delegated,
) => attendee.force_send.is_some(),
Some(ICalendarParticipationStatus::NeedsAction) => !skip_needs_action,
_ => true,
}
{
local_attendee = Some(attendee);
}

View File

@@ -22,6 +22,7 @@ use calcard::{
pub fn itip_cancel(
ical: &ICalendar,
account_emails: &[String],
is_deletion: bool,
) -> Result<ItipMessage<ICalendar>, ItipError> {
// Prepare iTIP message
let itip = itip_snapshot(ical, account_emails, false)?;
@@ -88,9 +89,14 @@ pub fn itip_cancel(
let mut mail_from = None;
let mut email_rcpt = AHashSet::new();
for (instance_id, comp) in &itip.components {
if let Some((cancel_comp, attendee_email)) =
attendee_decline(instance_id, &itip, comp, &dt_stamp, &mut email_rcpt)
{
if let Some((cancel_comp, attendee_email)) = attendee_decline(
instance_id,
&itip,
comp,
&dt_stamp,
&mut email_rcpt,
is_deletion,
) {
// Add cancel component
let comp_id = message.components.len() as u16;
message.components[0].component_ids.push(comp_id);

View File

@@ -39,7 +39,7 @@ pub fn itip_update(
| ItipError::OtherSchedulingAgent => {
if old_itip.organizer.email.is_local {
// RFC 6638 does not support replacing the organizer, so we cancel the event
itip_cancel(old_ical, account_emails).map(|message| vec![message])
itip_cancel(old_ical, account_emails, false).map(|message| vec![message])
} else {
Err(ItipError::CannotModifyAddress)
}