Skip to content

Implement attendee counter-proposal storage#168

Merged
TDannhauer merged 3 commits into
FRAMEWORK_6_0from
feat/polish_EAS16.1
Jun 19, 2026
Merged

Implement attendee counter-proposal storage#168
TDannhauer merged 3 commits into
FRAMEWORK_6_0from
feat/polish_EAS16.1

Conversation

@TDannhauer

@TDannhauer TDannhauer commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Persist attendee counter-proposals from EAS 16.1 MeetingResponse commands onto the Kronolith calendar via calendar/storeAttendeeProposal.

Motivation

When an iOS client proposes a new meeting time, Horde already parses ProposedStartTime/ProposedEndTime, validates disallow-counter flags, and sends METHOD=COUNTER mail to the organizer. Without storing the proposal on the server-side calendar event, Kronolith cannot:

  • export proposed times on the next calendar Sync (so the device shows the proposal), or
  • clear them later when the organizer declines (via ActiveSync empty proposed-time tags).

This change closes the inbound path: device → server storage → sync / clear on decline.

Changes

lib/Horde/Core/ActiveSync/Driver.php

In _meetingResponse(), after proposal validation and before sending COUNTER iTip mail:

  • Call calendar/storeAttendeeProposal with event UID, attendee email, and proposed start/end.
  • On failure: log a warning and continue with the existing reply/COUNTER flow (MeetingResponse does not fail hard).

test/Unit/ActiveSync/DriverMeetingResponseTest.php

Add targeted unit coverage for attendee proposal persistence in meetingResponse():

  • assert the registry call is made when both ProposedStartTime and ProposedEndTime are present
  • assert the registry call is skipped when counter-proposals are disallowed
  • assert the registry call is skipped when the proposed start time is invalid

Dependencies

Requires horde/kronolith (storeAttendeeProposal and related counter-proposal APIs). Works together with horde/activesync (WBXML export/clear) and horde/imp (organizer accept/decline in webmail).

Test plan

  • EAS 16.1: attendee proposes new time on iOS → proposal stored on server → calendar Sync includes ProposedStartTime/ProposedEndTime for attendee
  • Organizer declines in IMP → attendee iOS calendar clears proposal after sync
  • Proposal ignored when event has disallow-counter iCal property (unchanged)
  • Accept/decline/tentative MeetingResponse without proposed times still works
  • Add unit coverage for meetingResponse() proposal storage and skip paths

Add functionality to store attendee counter-proposals in the calendar.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds server-side persistence of EAS 16.1 attendee counter-proposals during MeetingResponse handling, by calling into Kronolith’s calendar API so proposed times can be re-synced to devices and later cleared when declined.

Changes:

  • In meetingResponse(), store ProposedStartTime/ProposedEndTime on the calendar event via calendar/storeAttendeeProposal.
  • On storage failure, log a warning and continue with the existing reply/COUNTER email flow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/Horde/Core/ActiveSync/Driver.php Outdated

if (!empty($proposedStart)) {
try {
$this->_registry->call('calendar/storeAttendeeProposal', [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 5351198.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@TDannhauer TDannhauer merged commit 2faa3fa into FRAMEWORK_6_0 Jun 19, 2026
0 of 4 checks passed
ralflang added a commit that referenced this pull request Jun 24, 2026
Release version 3.0.0-RC10

fix: Ensure absolute URLs from registry are used correctly in withAppWebroot & friends
fix(core): popup CSRF without SID in URL query
fix(core): add CSRF token to HordePopup.popup at click time
fix(core): honor FILTERTYPE_INCOMPLETETASKS in task sync
fix(core): honor FILTERTYPE_INCOMPLETETASKS in task sync
feat(core): pass ActiveSync sync config to driver
feat(core): pass ActiveSync sync config to driver
Merge pull request #168 from horde/feat/polish_EAS16.1
Potential fix for pull request finding
Merge pull request #169 from horde/fix/portal-layout-csrf-token
refactor(core): inject session for portal layout CSRF check
Add meeting response proposal tests
fix(core): validate portal layout CSRF with session checkToken
Implement attendee counter-proposal storage
Merge pull request #167 from horde/fix/redbox-autocompleter-dialog-reopen
Delete doc/pr directory
fix(core): harden RedBox and autocompleter dialog DOM handling
fix(activesync): honor per-user EAS 16.1 permission in versionCallback
feat(core): add EAS 16.1 meeting proposal handling in MeetingResponse
fix(session): guard session_destroy() when no active PHP session
Merge pull request #164 from horde/fix/map_OSM
Update js/map/osm.js
Update js/map/ocm.js
Update js/map/owm.js
Merge pull request #163 from horde/feat/finish_EAS16.0
fix(maps): allow OSM tile Referer and use HTTPS tile URLs
feat(activesync): EAS 16.0 draft sync and calendar initial-sync in core driver
refactor: shrink base factory class to accept "Injector" (of which Horde_Injector is a duck type)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants