iMIP: Notification subjects and bodies omit the event start date, time and timezone for recurring events

This commit is contained in:
Maurus Decimus committed 2026-09-10 19:22:00 +01:00
1 parent 4f7a73a423
commit 9064735363
3 files changed
+103 -9

No files matched your search

+1
View File
@@ -13,6 +13,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
## Fixed
- WebDAV: `PROPFIND` responses do not declare the namespace of every requested property on the `DAV:multistatus` element.
- MTA: SMTP session state obtained before `STARTTLS` is discarded once the TLS handshake completes, as required by RFC 3207.
- iMIP: Notification subjects and bodies omit the event start date, time and timezone for recurring events.
## [0.16.21] - 2026-09-06
+39 -9
View File
@@ -414,13 +414,13 @@ pub async fn build_itip_template(
}
};
let mut has_rrule = false;
let mut details = Vec::with_capacity(4);
let mut when_detail: Option<(usize, &ItipValue)> = None;
let mut details: Vec<AHashMap<CalendarTemplateVariable, String>> = Vec::with_capacity(4);
for field in [
ICalendarProperty::Summary,
ICalendarProperty::Description,
ICalendarProperty::Rrule,
ICalendarProperty::Dtstart,
ICalendarProperty::Rrule,
ICalendarProperty::Location,
ICalendarProperty::Conference,
] {
@@ -430,11 +430,7 @@ pub async fn build_itip_template(
let field_name = match &field {
ICalendarProperty::Summary => locale.calendar_summary,
ICalendarProperty::Description => locale.calendar_description,
ICalendarProperty::Rrule => {
has_rrule = true;
locale.calendar_when
}
ICalendarProperty::Dtstart if !has_rrule => locale.calendar_when,
ICalendarProperty::Dtstart | ICalendarProperty::Rrule => locale.calendar_when,
ICalendarProperty::Location => locale.calendar_location,
ICalendarProperty::Conference => locale.calendar_conference,
_ => continue,
@@ -447,7 +443,11 @@ pub async fn build_itip_template(
ICalendarProperty::Summary => {
subject.push_str(&value);
}
ICalendarProperty::Dtstart | ICalendarProperty::Rrule => {
ICalendarProperty::Dtstart => {
subject.push_str(" @ ");
subject.push_str(&value);
}
ICalendarProperty::Rrule if when_detail.is_none() => {
subject.push_str(" @ ");
subject.push_str(&value);
}
@@ -468,6 +468,33 @@ pub async fn build_itip_template(
variables.insert_single(variable, value.clone());
}
if matches!(field, ICalendarProperty::Rrule)
&& let Some((index, start_value)) = when_detail
&& let Some(detail) = details.get_mut(index)
{
if let Some(when_value) = detail.get_mut(&CalendarTemplateVariable::Value) {
when_value.push_str(", ");
when_value.push_str(&value);
}
if let Some(old_entry) = old_entry {
detail.insert(
CalendarTemplateVariable::Changed,
locale.calendar_changed.to_string(),
);
let old_value = detail
.entry(CalendarTemplateVariable::OldValue)
.or_insert_with(|| {
formatter.field_to_string(start_value, DateStyle::Short)
});
old_value.push_str(", ");
old_value
.push_str(&formatter.field_to_string(&old_entry.value, DateStyle::Short));
}
continue;
}
let mut detail = AHashMap::with_capacity(4);
detail.insert(CalendarTemplateVariable::Key, field_name.to_string());
if matches!(field, ICalendarProperty::Conference)
@@ -486,6 +513,9 @@ pub async fn build_itip_template(
formatter.field_to_string(&old_entry.value, DateStyle::Short),
);
}
if matches!(field, ICalendarProperty::Dtstart) && when_detail.is_none() {
when_detail = Some((details.len(), &entry.value));
}
details.push(detail);
}
}
+63
View File
@@ -1038,6 +1038,17 @@ pub async fn test_build_itip_templates(test: &TestServer) {
tz_id: Tz::from_str("New Zealand").unwrap().as_id(),
}),
},
ItipField {
name: ICalendarProperty::Rrule,
value: ItipValue::Rrule(Box::new(ICalendarRecurrenceRule {
freq: ICalendarFrequency::Weekly,
byday: vec![ICalendarDay {
ordwk: None,
weekday: ICalendarWeekday::Tuesday,
}],
..Default::default()
})),
},
ItipField {
name: ICalendarProperty::Attendee,
value: ItipValue::Participants(vec![
@@ -1170,6 +1181,17 @@ pub async fn test_build_itip_templates(test: &TestServer) {
tz_id: Tz::from_str("New Zealand").unwrap().as_id(),
}),
},
ItipField {
name: ICalendarProperty::Rrule,
value: ItipValue::Rrule(Box::new(ICalendarRecurrenceRule {
freq: ICalendarFrequency::Weekly,
byday: vec![ICalendarDay {
ordwk: None,
weekday: ICalendarWeekday::Tuesday,
}],
..Default::default()
})),
},
ItipField {
name: ICalendarProperty::Attendee,
value: ItipValue::Participants(vec![
@@ -1206,8 +1228,49 @@ pub async fn test_build_itip_templates(test: &TestServer) {
tz_id: Tz::from_str("New Zealand").unwrap().as_id(),
}),
},
ItipField {
name: ICalendarProperty::Rrule,
value: ItipValue::Rrule(Box::new(ICalendarRecurrenceRule {
freq: ICalendarFrequency::Daily,
..Default::default()
})),
},
],
},
ItipSummary::Update {
method: ICalendarMethod::Request,
current: vec![
ItipField {
name: ICalendarProperty::Summary,
value: ItipValue::Text("Standup".to_string()),
},
ItipField {
name: ICalendarProperty::Dtstart,
value: ItipValue::Time(ItipTime {
start: 1750616068,
tz_id: Tz::from_str("New Zealand").unwrap().as_id(),
}),
},
ItipField {
name: ICalendarProperty::Rrule,
value: ItipValue::Rrule(Box::new(ICalendarRecurrenceRule {
freq: ICalendarFrequency::Weekly,
byday: vec![ICalendarDay {
ordwk: None,
weekday: ICalendarWeekday::Tuesday,
}],
..Default::default()
})),
},
],
previous: vec![ItipField {
name: ICalendarProperty::Rrule,
value: ItipValue::Rrule(Box::new(ICalendarRecurrenceRule {
freq: ICalendarFrequency::Daily,
..Default::default()
})),
}],
},
]
.into_iter()
.enumerate()