idnits 2.17.1 draft-ietf-jmap-calendars-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (October 28, 2019) is 1636 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Outdated reference: A later version (-32) exists of draft-ietf-calext-jscalendar-20 Summary: 0 errors (**), 0 flaws (~~), 2 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 JMAP N. Jenkins 3 Internet-Draft Fastmail 4 Intended status: Standards Track M. Douglass 5 Expires: April 30, 2020 Spherical Cow Group 6 October 28, 2019 8 JMAP for Calendars 9 draft-ietf-jmap-calendars-01 11 Abstract 13 This document specifies a data model for synchronizing calendar data 14 with a server using JMAP. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at https://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on April 30, 2020. 33 Copyright Notice 35 Copyright (c) 2019 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents 40 (https://trustee.ietf.org/license-info) in effect on the date of 41 publication of this document. Please review these documents 42 carefully, as they describe your rights and restrictions with respect 43 to this document. Code Components extracted from this document must 44 include Simplified BSD License text as described in Section 4.e of 45 the Trust Legal Provisions and are provided without warranty as 46 described in the Simplified BSD License. 48 Table of Contents 50 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 51 1.1. Data Model Overview . . . . . . . . . . . . . . . . . . . 3 52 1.2. Accounts, Push, and the Session Object . . . . . . . . . 4 53 1.2.1. UIDs and CalendarEvent Ids . . . . . . . . . . . . . 5 54 1.3. Notational Conventions . . . . . . . . . . . . . . . . . 5 55 1.4. The LocalDate Data Type . . . . . . . . . . . . . . . . . 6 56 1.5. Terminology . . . . . . . . . . . . . . . . . . . . . . . 6 57 1.6. Addition to the Capabilities Object . . . . . . . . . . . 6 58 1.6.1. urn:ietf:params:jmap:calendars . . . . . . . . . . . 6 59 1.6.2. urn:ietf:params:jmap:calendarprincipals . . . . . . . 7 60 2. Calendar Principals . . . . . . . . . . . . . . . . . . . . . 8 61 2.1. CalendarPrincipal/get . . . . . . . . . . . . . . . . . . 9 62 2.2. CalendarPrincipal/changes . . . . . . . . . . . . . . . . 9 63 2.3. CalendarPrincipal/set . . . . . . . . . . . . . . . . . . 9 64 2.4. CalendarPrincipal/query . . . . . . . . . . . . . . . . . 9 65 2.4.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 9 66 2.5. CalendarPrincipal/queryChanges . . . . . . . . . . . . . 10 67 2.6. CalendarPrincipal/getAvailability . . . . . . . . . . . . 10 68 3. Calendars . . . . . . . . . . . . . . . . . . . . . . . . . . 13 69 3.1. Calendar/get . . . . . . . . . . . . . . . . . . . . . . 17 70 3.2. Calendar/changes . . . . . . . . . . . . . . . . . . . . 17 71 3.3. Calendar/set . . . . . . . . . . . . . . . . . . . . . . 17 72 4. Calendar Share Notifications . . . . . . . . . . . . . . . . 18 73 4.1. Auto-deletion of Notifications . . . . . . . . . . . . . 19 74 4.2. Object Properties . . . . . . . . . . . . . . . . . . . . 19 75 4.3. CalendarShareNotification/get . . . . . . . . . . . . . . 20 76 4.4. CalendarShareNotification/changes . . . . . . . . . . . . 20 77 4.5. CalendarShareNotification/set . . . . . . . . . . . . . . 20 78 4.6. CalendarShareNotification/query . . . . . . . . . . . . . 20 79 4.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 20 80 4.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 20 81 4.7. CalendarShareNotification/queryChanges . . . . . . . . . 20 82 5. Calendar Events . . . . . . . . . . . . . . . . . . . . . . . 20 83 5.1. Attachments . . . . . . . . . . . . . . . . . . . . . . . 21 84 5.2. Per-user properties . . . . . . . . . . . . . . . . . . . 22 85 5.3. Recurring events . . . . . . . . . . . . . . . . . . . . 22 86 5.4. CalendarEvent/get . . . . . . . . . . . . . . . . . . . . 23 87 5.5. CalendarEvent/changes . . . . . . . . . . . . . . . . . . 24 88 5.6. CalendarEvent/set . . . . . . . . . . . . . . . . . . . . 24 89 5.6.1. Sending invitations and responses . . . . . . . . . . 25 90 5.7. CalendarEvent/copy . . . . . . . . . . . . . . . . . . . 28 91 5.8. CalendarEvent/query . . . . . . . . . . . . . . . . . . . 28 92 5.8.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 29 93 5.8.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 30 94 5.9. CalendarEvent/queryChanges . . . . . . . . . . . . . . . 31 95 5.10. Examples . . . . . . . . . . . . . . . . . . . . . . . . 31 97 6. Alerts . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 98 6.1. Push events . . . . . . . . . . . . . . . . . . . . . . . 31 99 6.2. Acknowledging an alert . . . . . . . . . . . . . . . . . 32 100 6.3. Snoozing an alert . . . . . . . . . . . . . . . . . . . . 32 101 7. Calendar Event Notifications . . . . . . . . . . . . . . . . 33 102 7.1. Auto-deletion of Notifications . . . . . . . . . . . . . 33 103 7.2. Object Properties . . . . . . . . . . . . . . . . . . . . 33 104 7.3. CalendarEventNotification/get . . . . . . . . . . . . . . 34 105 7.4. CalendarEventNotification/changes . . . . . . . . . . . . 34 106 7.5. CalendarEventNotification/set . . . . . . . . . . . . . . 34 107 7.6. CalendarEventNotification/query . . . . . . . . . . . . . 35 108 7.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 35 109 7.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 35 110 7.7. CalendarEventNotification/queryChanges . . . . . . . . . 35 111 8. Security Considerations . . . . . . . . . . . . . . . . . . . 35 112 8.1. Denial-of-service Expanding Recurrences . . . . . . . . . 35 113 8.2. Privacy . . . . . . . . . . . . . . . . . . . . . . . . . 36 114 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 36 115 9.1. JMAP Capability Registration for "calendars" . . . . . . 36 116 9.2. Reservation of JMAP attributes in JSCalendar Property 117 registry . . . . . . . . . . . . . . . . . . . . . . . . 36 118 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 36 119 10.1. Normative References . . . . . . . . . . . . . . . . . . 36 120 10.2. Informative References . . . . . . . . . . . . . . . . . 37 121 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 37 123 1. Introduction 125 JMAP ([RFC8620] - JSON Meta Application Protocol) is a generic 126 protocol for synchronizing data, such as mail, calendars or contacts, 127 between a client and a server. It is optimized for mobile and web 128 environments, and aims to provide a consistent interface to different 129 data types. 131 This specification defines a data model for synchronizing calendar 132 data between a client and a server using JMAP. The data model is 133 designed to allow a server to provide consistent access to the same 134 data via CalDAV [RFC4791] as well as JMAP, however the functionality 135 offered over the two protocols may differ. Unlike CalDAV, this 136 specification does not define access to tasks or journal entries 137 (VTODO or VJOURNAL iCalendar components in CalDAV). 139 1.1. Data Model Overview 141 A CalendarPrincipal (see Section XXX) represents an individual, team 142 or resource (e.g. a room or projector). The object contains 143 information about the entity being represented, such as a name, 144 description and time zone. A CalendarPrincipal has a 1:1 145 correspondence with an Account (see [RFC8620], Section 1.6.2) that 146 supports the "urn:ietf:params:jmap:calendars" capability. 148 Each such Account contains zero or more Calendar objects, which is a 149 named collection of CalendarEvents belonging to the 150 CalendarPrincipal. Sharing permissions are managed per calendar. 151 For example, an individual may have separate calendars for personal 152 and work activities, with both contributing to their free-busy 153 availability, but only the work calendar shared in its entirety with 154 colleagues. Calendars can also provide defaults, such as alerts and 155 a color to apply to events in the calendar. Clients commonly let 156 users toggle visibility of events belonging to a particular calendar 157 on/off. 159 A CalendarEvent is a representation of an event or recurring series 160 of events in JSEvent [I-D.ietf-calext-jscalendar] format. Simple 161 clients may ask the server to expand recurrences for them within a 162 specific time period, and optionally convert times into UTC so they 163 do not have to handle time zone conversion. More full-featured 164 clients will want to access the full event information and handle 165 recurrence expansion and time zone conversion locally. 167 CalendarEventNotification objects keep track of the history of 168 changes made to a calendar by other users, allowing calendar clients 169 to notify the user of changes to their schedule. Similarly, the 170 CalendarShareNotification type notifies the user when their access to 171 another user's calendar is granted or revoked. 173 1.2. Accounts, Push, and the Session Object 175 The JMAP Session object (see [RFC8620], Section 2) typically includes 176 an object in the "accounts" property for every account that the user 177 has access to. Calendaring systems may share data between a 178 (potentially very) large number of CalendarPrincipals, most of which 179 the user does not care about day-to-day but may occasionally need to 180 query when scheduling events. 182 Users can normally subscribe to any calendar to which they have 183 access (see Section XXX). This indicates the user wants this 184 calendar to appear in their regular list of calendars. The separate 185 "isVisible" property stores whether the user would currently like to 186 view the events in a subscribed calendar. 188 The Session object MUST only include Accounts where the user is 189 subscribed to at least one Calendar or they have access to some other 190 data type in the account. StateChange events for changes to 191 CalendarEvent data SHOULD only be sent for events in calendars the 192 user has subscribed to and MUST NOT be sent for any Account where the 193 user is not subscribed to at least one calendar. 195 The server MAY reject the user's attempt to subscribe to some 196 calendars, e.g. those representing resources. 198 A user may query the set of CalendarPrincipals they have access to 199 with "CalendarPrincipal/query" (see Section XXX). The 200 CalendarPrincipal object may have an "accountId" property that can be 201 used to then fetch calendars and events associated with that 202 principal, subject to appropriate permissions. 204 1.2.1. UIDs and CalendarEvent Ids 206 Each CalendarEvent has a "uid" property 207 ([I-D.ietf-calext-jscalendar], Section 4.1.2), which is a globally 208 unique identifier that identifies the same event in different 209 Accounts, or different instances of the same recurring event within 210 an Account. 212 An Account MUST NOT contain more than one CalendarEvent with the same 213 uid unless all of the CalendarEvent objects have distinct, non-null 214 values for their "recurrenceId" property. (This situation occurs if 215 the principal is added to one or more specific instances of a 216 recurring event without being invited to the whole series.) 218 Each CalendarEvent also has an id, which is scoped to the JMAP 219 Account and used for referencing it in JMAP methods. There is no 220 necessary link between the uid property and the CalendarEvent's id. 221 CalendarEvents with the same uid in different Accounts MAY have 222 different ids. 224 1.3. Notational Conventions 226 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 227 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 228 "OPTIONAL" in this document are to be interpreted as described in BCP 229 14 [RFC2119] [RFC8174] when, and only when, they appear in all 230 capitals, as shown here. 232 Type signatures, examples, and property descriptions in this document 233 follow the conventions established in Section 1.1 of [RFC8620]. Data 234 types defined in the core specification are also used in this 235 document. 237 1.4. The LocalDate Data Type 239 Where "LocalDate" is given as a type, it means a string in the same 240 format as "Date" (see [RFC8620], Section 1.4), but with the "time- 241 offset" omitted from the end. The interpretation in absolute time 242 depends upon the time zone for the event, which may not be a fixed 243 offset (for example when daylight saving time occurs). For example, 244 "2014-10-30T14:12:00". 246 1.5. Terminology 248 The same terminology is used in this document as in the core JMAP 249 specification, see [RFC8620], Section 1.6. 251 The terms CalendarPrincipal, Calendar, CalendarEvent, 252 CalendarEventNotification, and CalendarShareNotification (with these 253 specific capitalizations) are used to refer to the data types defined 254 in this document and instances of those data types. 256 1.6. Addition to the Capabilities Object 258 The capabilities object is returned as part of the JMAP Session 259 object; see [RFC8620], Section 2. This document defines two 260 additional capability URIs. 262 1.6.1. urn:ietf:params:jmap:calendars 264 This represents support for the Calendar, CalendarEvent, and 265 CalendarEventNotification data types and associated API methods. The 266 value of this property in the JMAP Session capabilities property is 267 an empty object. 269 The value of this property in an account's accountCapabilities 270 property is an object that MUST contain the following information on 271 server capabilities and permissions for that account: 273 o *accountIdForCalendarPrincipal*: "String|null" The id of an 274 account with the "urn:ietf:params:jmap:calendarprincipals" 275 capability that contains the corresponding CalendarPrincipal 276 object. This may be the same account id. This is null for 277 single-user systems that do not support the CalendarPrincipal data 278 type. 280 o *maxSizeCalendarEvent*: "UnsignedInt" The maximum size in octets 281 of the largest CalendarEvent the server is willing to store. 282 TODO: How can you relate this to what the client knows? 284 o *minDateTime*: "LocalDate" The earliest date-time the server is 285 willing to accept for any date stored in a CalendarEvent. 287 o *maxDateTime*: "LocalDate" The latest date-time the server is 288 willing to accept for any date stored in a CalendarEvent. 290 o *maxExpandedQueryDuration*: "Duration" The maximum duration the 291 user may query over when asking the server to expand recurrences. 293 o *maxParticipantsPerEvent*: "Number|null" The maximum number of 294 participants a single event may have, or null for no limit. 296 o *maxNumberEventNotifications*: "UnsignedInt" The maximum number of 297 CalendarEventNotification objects the server will store for this 298 account. If new notifications are added in excess of this number, 299 older notifications will be automatically deleted by the server. 301 o *mayCreateCalendar*: "Boolean" If true, the user may create a 302 calendar in this account. 304 1.6.2. urn:ietf:params:jmap:calendarprincipals 306 Represents support for the CalendarPrincipal and 307 CalendarShareNotification data types and associated API methods. 308 Single user systems do not need this and MAY choose not to support 309 it. 311 The value of this property in the JMAP Session capabilities property 312 is an empty object. 314 The value of this property in an account's accountCapabilities 315 property is an object that MUST contain the following information on 316 server capabilities and permissions for that account: 318 o *currentUserPrincipalId*: "String|null" The id of the principal in 319 this account that corresponds to the user fetching this object, if 320 any. 322 o *maxAvailabilityDuration*: The maximum duration over which the 323 server is prepared to calculate availability in a single call (see 324 Section XXX). 326 o *maxNumberShareNotifications*: "UnsignedInt" The maximum number of 327 CalendarShareNotification objects the server will store for a 328 principal in this account. If new notifications are added in 329 excess of this number, older notifications will be automatically 330 deleted by the server. 332 2. Calendar Principals 334 A CalendarPrincipal represents an individual, group, schedulable 335 location (e.g. a room), bookable resource (e.g. a projector) or other 336 entity in the calendar system. In a shared calendar environment such 337 as a workplace, a user may have access to a large number of 338 principals. 340 In most systems the user will have access to a single Account 341 containing CalendarPrincipal objects, but they may have access to 342 multiple if, for example, aggregating calendar data from different 343 places. 345 A *CalendarPrincipal* object has the following properties: 347 o *id*: "Id" The id of the principal. 349 o *name*: "String" The name of the principal, e.g. "Jane Doe", or 350 "Room 4B". 352 o *description*: "String|null" A longer description of the 353 principal, for example details about the facilities of a resource, 354 or null if no description available. 356 o *email*: "String|null" An email address for the principal, or null 357 if no email is available. 359 o *type*: "String" This MUST be one of the following values: 361 * "individual": This represents a single person. 363 * "group": This represents a group of people. 365 * "resource": This represents some resource, e.g. a projector. 367 * "location": This represents a location. 369 * "other": This represents some other undefined principal. 371 o *timeZone*: "String" The time zone for this principal. The value 372 MUST be a time zone id from the IANA Time Zone Database. 374 o *mayGetAvailability*: "Boolean" May the user call the 375 "CalendarPrincipal/getAvailability" method with this 376 CalendarPrincipal? 378 o *accountId*: "Id|null" Id of Account with the 379 "urn:ietf:params:jmap:calendars" capability that contains the data 380 for this principal, or null if none (e.g. the CalendarPrincipal is 381 a group just used for permissions management), or the user does 382 not have access to any data in the account (with the exception of 383 free/busy, which is governed by the mayGetAvailability property). 385 o *account*: "Account|null" The JMAP Account object corresponding to 386 the accountId, null if none. 388 o *sendTo*: "String[String]|null" If this principal may be added as 389 a participant to an event, this is the map of methods for adding 390 it, in the same format as Participant#sendTo in JSEvent (see 391 [I-D.ietf-calext-jscalendar], Section 4.4.5). 393 2.1. CalendarPrincipal/get 395 This is a standard "/get" method as described in [RFC8620], 396 Section 5.1. 398 2.2. CalendarPrincipal/changes 400 This is a standard "/changes" method as described in [RFC8620], 401 Section 5.2. 403 2.3. CalendarPrincipal/set 405 This is a standard "/set" method as described in [RFC8620], 406 Section 5.3. However, the user may only update the "timeZone" 407 property of the CalendarPrincipal with the same id as the 408 "currentUserPrincipalId" in the Account capabilities. Any other 409 change MUST be rejected with a "forbidden" SetError. 411 Managing calendar principals is likely tied to a directory service or 412 some other vendor-specific solution, and occurs out-of-band, or via 413 an additional capability defined elsewhere. 415 2.4. CalendarPrincipal/query 417 This is a standard "/query" method as described in [RFC8620], 418 Section 5.5 420 2.4.1. Filtering 422 A *FilterCondition* object has the following properties: 424 o *accountIds*: "String[]" A list of account ids. The 425 CalendarPrincipal matches if the value for its accountId property 426 is in this list. 428 o *email*: "String" Looks for the text in the email property. 430 o *name*: "String" Looks for the text in the name property. 432 o *text* "String" Looks for the text in the name, email, and 433 description properties. 435 o *type*: "String" The type must be exactly as given to match the 436 condition. 438 o *timeZone*: "String" The timeZone must be exactly as given to 439 match the condition. 441 All conditions in the FilterCondition object must match for the 442 CalendarPrincipal to match. 444 2.5. CalendarPrincipal/queryChanges 446 This is a standard "/queryChanges" method as described in [RFC8620], 447 Section 5.6. 449 2.6. CalendarPrincipal/getAvailability 451 Calculates the availability of the principal for scheduling within a 452 requested time period. It takes the following arguments: 454 o *accountId*: "Id" The id of the account to use. 456 o *id*: "Id" The id of the CalendarPrincipal to calculate 457 availability for. 459 o *utcStart*: "UTCDate" The start time (inclusive) of the period for 460 which to return availability. 462 o *utcEnd*: "UTCDate" The end time (exclusive) of the period for 463 which to return availability. 465 o *showDetails*: "Boolean" If true, event details will be returned 466 if the user has permission to view them. 468 The server will first find all relevant events, expanding any 469 recurring events. Relevant events are ones where all of the 470 following is true: 472 o The principal is subscribed to the calendar. 474 o Either the calendar belongs to the principal or the "shareesActAs" 475 property of the calendar is "self". 477 o The "includeInAvailability" property of the calendar for the 478 principal is "all" or "attending". 480 o The user has the "mayReadFreeBusy" permission for the calendar. 482 o The event finishes after the "utcStart" argument and starts before 483 the "utcEnd" argument. 485 o The event's "privacy" property is not "secret". 487 o The "freeBusyStatus" property of the event is "busy" (or omitted, 488 as this is the default). 490 o The "status" property of the event is not "cancelled". 492 o If the "includeInAvailability" property of the calendar is 493 "attending", then the principal is a participant of the event, and 494 has a "participationStatus" of "accepted" or "tentative". 496 The server then generates a BusyPeriod object for each of these 497 events. A *BusyPeriod* object has the following properties: 499 o *utcStart*: "UTCDate" The start time (inclusive) of the period 500 this represents. 502 o *utcEnd*: "UTCDate" The end time (exclusive) of the period this 503 represents. 505 o *busyStatus*: "String" (optional, default "unavailable") This MUST 506 be one of 508 * "confirmed": The event status is "confirmed". 510 * "tentative": The event status is "tentative". 512 * "unavailable": The principal is not available for scheduling at 513 this time for any other reason. 515 o *event*: "JSEvent|null" The JSEvent representation of the event, 516 or null if any of the following are true: 518 * The "showDetails" argument is false. 520 * The "privacy" property of the event is "private". 522 * The user does not have the "mayReadItems" permission for the 523 calendar. 525 The server MAY also generate BusyPeriod objects based on other 526 information it has about the principal's availability, such as office 527 hours. 529 Finally, the server MUST merge and split BusyPeriod objects where the 530 "event" property is null, such that none of them overlap and either 531 there is a gap in time between any two objects (the utcEnd of one 532 does not equal the utcStart of another) or those objects have a 533 different busyStatus property. If there are overlapping BusyPeriod 534 time ranges with different "busyStatus" properties the server MUST 535 choose the value in the following order: confirmed > unavailable > 536 tentative. 538 The response has the following arguments: 540 o *accountId*: "Id" The id of the account used for the call. 542 o *id*: "Id" The id of the CalendarPrincipal availability is being 543 returned for. 545 o *utcStart*: "UTCDate" The start time (inclusive) of the period for 546 which availability is being returned. 548 o *utcEnd*: "UTCDate" The end time (exclusive) of the period for 549 which availability is being returned. 551 o *list*: "BusyPeriod[]" The list of BusyPeriod objects calculated 552 as described above. 554 The following additional errors may be returned instead of the 555 "CalendarPrincipal/getAvailability" response: 557 "notFound": No principal with this id exists, or the user does not 558 have permission to see that this principal exists. 560 "forbidden": The user does not have permission to query this 561 principal's availability. 563 "tooLarge": The duration between utcStart an utcEnd is longer than 564 the server is willing to calculate availability for. 566 "rateLimit": Too many availability requests have been made recently 567 and the user is being rate limited. It may work to try again later. 569 3. Calendars 571 A Calendar is a named collection of events. All events are 572 associated with one, and only one, calendar. 574 A *Calendar* object has the following properties: 576 o *id*: "Id" (immutable; server-set) The id of the calendar. 578 o *role*: "String|null" Denotes the calendar has a special purpose. 579 This MUST be one of the following: 581 * "inbox": This is the principal's default calendar; when the 582 principal is invited to an event, this is the calendar to which 583 it will be added by the server. There MUST NOT be more than 584 one calendar with this role in an account. 586 * "templates": This calendar holds templates for creating new 587 events. All events in this calendar MUST have the "isDraft" 588 property set to true. Clients should not show this as a 589 regular calendar to users, but may offer users to create new 590 events by copying one of the events in here. 592 o *name*: "String" The user-visible name of the calendar. This may 593 be any UTF-8 string of at least 1 character in length and maximum 594 255 octets in size. 596 o *description*: "String|null" An optional longer-form description 597 of the calendar, to provide context in shared environments where 598 users need more than just the name. 600 o *color*: "String" The color to be used when displaying events 601 associated with the calendar. The value MUST be a case- 602 insensitive color name taken from the CSS3 set of names, defined 603 in Section 4.3 of W3C.REC-css3-color-20110607, or a CSS3 RGB color 604 hex value. The color SHOULD have sufficient contrast to be used 605 as text on a white background. 607 o *sortOrder*: "UnsignedInt" (default: 0) Defines the sort order of 608 calendars when presented in the client's UI, so it is consistent 609 between devices. The number MUST be an integer in the range 0 <= 610 sortOrder < 2^31. A calendar with a lower order should be 611 displayed before a calendar with a higher order in any list of 612 calendars in the client's UI. Calendars with equal order SHOULD 613 be sorted in alphabetical order by name. The sorting should take 614 into account locale-specific character order convention. 616 o *isSubscribed*: "Boolean" Has the user indicated they wish to see 617 this Calendar in their client? This SHOULD default to false for 618 Calendars in shared accounts the user has access to and true for 619 any new Calendars created by the user themself. If false, the 620 calendar should only be displayed when the user explicitly 621 requests it or to offer it for the user to subscribe to. 623 o *isVisible*: "Boolean" (default: true) Should the calendar's 624 events be displayed to the user at the moment? Clients MUST 625 ignore this property if isSubscribed is false. 627 o *includeInAvailability*: "String" (default: all) Should the 628 calendar's events be used as part of availability calculation? 629 This MUST be one of: 631 * "all": all events are considered. 633 * "attending": events the user is a confirmed or tentative 634 participant of are considered. 636 * "none": all events are ignored. 638 o *defaultAlertsWithTime*: "Alert[]" The alerts to apply for events 639 where showWithoutTime is false that have "useDefaultAlerts" set. 640 See [I-D.ietf-calext-jscalendar], Section 4.5.2 for the definition 641 of an Alert object. 643 o *defaultAlertsWithoutTime*: "Alert[]" The alerts to apply for 644 events where showWithoutTime is true that have "useDefaultAlerts" 645 set. See [I-D.ietf-calext-jscalendar], Section 4.5.2 for the 646 definition of an Alert object. 648 o *timeZone*: "String|null" The time zone to use for events without 649 a time zone when the server needs to resolve them into absolute 650 time, e.g., for reminders, queries, or availability calculation. 651 The value MUST be a time zone id from the IANA Time Zone Database. 652 If "null", the timeZone of the account's associated 653 CalendarPrincipal will be used. Clients SHOULD use this as the 654 default for new events in this calendar if set. 656 o *participantIdentities*: "ParticipantIdentity[]|null" (server-set) 657 The identities that represent the user in this calendar. The 658 first item in the array is the default. A *ParticipantIdentity* 659 object has the following properties: 661 * *name*: "String" The display name of the participant to use 662 when adding this participant to an event, e.g. "Joe Bloggs". 664 * *type*: "String" The method for sending scheduling messages to 665 this identity, e.g. "imip" 667 * *uri*: "String" The URI for sending scheduling messages to this 668 identity, e.g. "mailto:foo@example.com" 670 The user is an *owner* for an event if the CalendarEvent object 671 has a "participants" property, and one of the Participant objects 672 has both: a) The "owner" role. b) A "sendTo" property that has 673 "type" and "uri" equal to one of the ParticipantIdentity objects 674 returned with the calendar. 676 o *shareWith*: "Id[CalendarRights]|null" A map of CalendarPrincipal 677 id to rights for principals this calendar is shared with. The 678 pricincipal to which this calendar belongs MUST NOT be in this 679 set. This is null if the user requesting the object does not have 680 the mayAdmin right, or if the calendar is not shared with anyone. 681 May be modified only if the user has the mayAdmin right. 683 o *shareesActAs*: "String" (immutable; default server-dependent) 684 This MUST be one of: 686 * "owner" 688 * "self" 690 If "self", sharees act as themselves when using this calendar. If 691 "owner", they act as the pricincipal to which this calendar 692 belongs (secretary mode). If omitted, the default is server 693 dependent. For example, it may be "self" if creating a calendar 694 in a CalendarPrincipal representing a group, and "owner" if 695 creating a calendar for an individual. Users may attempt to set 696 this on creation, but the server may reject with an 697 "invalidProperties" error if the value is not permissible. 699 o *myRights*: "CalendarRights" (server-set) The set of access rights 700 the user has in relation to this Calendar. 702 A *CalendarRights* object has the following properties: 704 o *mayReadFreeBusy*: "Boolean" The user may read the free-busy 705 information for this calendar as part of a call to 706 CalendarPrincipal/getAvailability (see Section XXX). 708 o *mayReadItems*: "Boolean" The user may fetch the events in this 709 calendar. 711 o *mayAddItems*: "Boolean" The user may create new events on this 712 calendar or move events to this calendar. For recurring events, 713 they may add an override to add an occurrence, or remove an 714 existing override that is excluding an occurrence. 716 o *mayUpdatePrivate*: "Boolean" The user may modify the following 717 properties on all events in the calendar. If shareesActAs is 718 "self", these properties MUST all be stored per-user, and changes 719 do not affect any other user of the calendar. If shareesActAs is 720 "owner", the values are shared between all users. 722 * keywords 724 * color 726 * freeBusyStatus 728 * useDefaultAlerts 730 * alerts 732 The user may also modify the above on a per-occurrence basis for 733 recurring events. 735 o *mayRSVP*: "Boolean" The user may modify the 736 "participationStatus", "participationComment", "expectReply" and 737 "scheduleAgent" properties of any Participant object that is 738 represented in the "participantIdentities" property of the 739 calendar. The user may also modify the above on a per-occurrence 740 basis for recurring events. 742 o *mayUpdateOwn*: "Boolean" The user may modify an existing event on 743 this calendar if either they are the owner of the event or the 744 event has no owner. 746 o *mayUpdateAll*: "Boolean" The user may modify all existing events 747 on this calendar. 749 o *mayRemoveOwn*: "Boolean" The user may delete an event or move it 750 to a different calendar if either they are the owner of the event 751 or the event has no owner. For recurring events, they may add an 752 override to remove an occurrence. 754 o *mayRemoveAll*: "Boolean" The user may delete any event or move it 755 to a different calendar. For recurring events, they may add an 756 override to remove an occurrence. 758 o *mayAdmin*: "Boolean" The user may modify sharing for this 759 calendar. 761 o *mayDelete*: "Boolean" (server-set) The user may delete the 762 calendar itself. This property MUST be false if the account to 763 which this calendar belongs has the _isReadOnly_ property set to 764 true. 766 3.1. Calendar/get 768 This is a standard "/get" method as described in [RFC8620], 769 Section 5.1. The _ids_ argument may be "null" to fetch all at once. 771 If mayReadFreeBusy is the only permission the user has, the calendar 772 MUST NOT be returned in Calendar/get and Calendar/query; it must 773 behave as though it did not exist. The data is just used as part of 774 CalendarPrincipal/getAvailability. 776 3.2. Calendar/changes 778 This is a standard "/changes" method as described in [RFC8620], 779 Section 5.2. 781 3.3. Calendar/set 783 This is a standard "/set" method as described in [RFC8620], 784 Section 5.3 but with the following additional request argument: 786 o *onDestroyRemoveEvents*: "Boolean" (default: false) 788 If false, any attempt to destroy a Calendar that still has 789 CalendarEvents in it will be rejected with a "calendarHasEvents" 790 SetError. If true, any CalendarEvents that were in the Calendar will 791 be destroyed. This SHOULD NOT send scheduling messages to 792 participants or create CalendarEventNotification objects. 794 The role and shareWith properties may only be set by users that have 795 the mayAdmin right. The value is shared across all users, although 796 users without the mayAdmin right cannot see the value. 798 Users can subscribe or unsubscribe to a calendar by setting the 799 isSubscribed property. The server MAY forbid users from subscribing 800 to certain calendars even though they haver permission to see them, 801 rejecting the update with a "forbidden" SetError. 803 The timeZone, includeInAvailability, defaultAlertsWithoutTime and 804 defaultAlertsWithTime properties are stored per-user if the calendar 805 shareesActAs is "self" and may be set by any user who is subscribed 806 to the calendar. Otherwise, these properties are shared, and may 807 only be set by users that have the mayAdmin right. 809 The following properties may be set by anyone who is subscribed to 810 the calendar and are all stored per-user: 812 o name 814 o description 816 o color 818 o sortOrder 820 o isVisible 822 These properties are initially inherited from the owner's copy of the 823 calendar, but if set by a sharee that user gets their own copy of the 824 property; it does not change for any other principals. If the value 825 of the property in the owner's calendar changes after this, it does 826 not overwrite the sharee's value. 828 The following extra SetError types are defined: 830 For "destroy": 832 o *calendarHasEvent*: The Calendar has at least one CalendarEvent 833 assigned to it, and the "onDestroyRemoveEvents" argument was 834 false. 836 4. Calendar Share Notifications 838 The CalendarShareNotification data type records when the user's 839 permissions to access a shared calendar changes. 840 CalendarShareNotification are only created by the server; users 841 cannot create them explicitly. Notifications are stored in the same 842 Account as the CalendarPrincipals. 844 Clients SHOULD present the list of notifications to the user and 845 allow them to dismiss them. To dismiss a notification you use a 846 standard "/set" call to destroy it. 848 The server SHOULD create a CalendarShareNotification whenever the 849 user's permissions change on a calendar. It SHOULD NOT create a 850 notification for permission changes to a group principal, even if the 851 user is in the group. 853 4.1. Auto-deletion of Notifications 855 The server MAY limit the maximum number of notifications it will 856 store for a user. When the limit is reached, any new notification 857 will cause the previously oldest notification to be automatically 858 deleted. 860 The server MAY coalesce events if appropriate, or remove events that 861 it deems are no longer relevant or after a certain period of time. 862 The server SHOULD automatically destroy a notification about a 863 calendar if the user subscribes to that calendar. 865 4.2. Object Properties 867 The *CalendarShareNotification* object has the following properties: 869 o *id*: "String" The id of the CalendarShareNotification. 871 o *created*: "UTCDate" The time this notification was created. 873 o *changedBy*: "Person" Who made the change. 875 * *name*: "String" The name of the person who made the change. 877 * *email*: "String" The email of the person who made the change. 879 * *calendarPrincipalId*: "String|null" The id of the calendar 880 principal corresponding to the person who made the change. 882 o *calendarAccountId*: "String" The id of the account where this 883 calendar exists. 885 o *calendarId*: "String" The id of the CalendarEvent that this 886 notification is about. 888 o *calendarName*: "String" The name of the calendar at the time the 889 notification was made. 891 o *oldRights*: "CalendarRights|null" The rights the user had before 892 the change. 894 o *newRights*: "CalendarRights|null" The rights the user has after 895 the change. 897 4.3. CalendarShareNotification/get 899 This is a standard "/get" method as described in [RFC8620], 900 Section 5.1. 902 4.4. CalendarShareNotification/changes 904 This is a standard "/changes" method as described in [RFC8620], 905 Section 5.2. 907 4.5. CalendarShareNotification/set 909 This is a standard "/changes" method as described in [RFC8620], 910 Section 5.3. 912 Only destroy is supported; any attempt to create/update MUST be 913 rejected with a "forbidden" SetError. 915 4.6. CalendarShareNotification/query 917 This is a standard "/query" method as described in [RFC8620], 918 Section 5.5. 920 4.6.1. Filtering 922 A *FilterCondition* object has the following properties: 924 o *after*: "UTCDate|null" The creation date must be on or after this 925 date to match the condition. 927 o *before*: "UTCDate|null" The creation date must be before this 928 date to match the condition. 930 4.6.2. Sorting 932 The "created" property MUST be supported for sorting. 934 4.7. CalendarShareNotification/queryChanges 936 This is a standard "/queryChanges" method as described in [RFC8620], 937 Section 5.6. 939 5. Calendar Events 941 A *CalendarEvent* object contains information about an event, or 942 recurring series of events, that takes place at a particular time. 943 It is a JSEvent object, as defined in [I-D.ietf-calext-jscalendar], 944 with the following additional properties: 946 o *id*: "Id" The id of the CalendarEvent. This property is 947 immutable. The id uniquely identifies a JSEvent with a particular 948 "uid" and "recurrenceId" within a particular account. 950 o *calendarId*: "Id" The id of the Calendar this event belongs to. 952 o *isDraft*: "Boolean" If true, this event is to be considered a 953 draft; the server will not send any scheduling messages to 954 participants while this is true. To use, this must be set on 955 creation. Once set to false, the value cannot be updated to true. 957 o *utcStart*: "UTCDate" For simple clients that do not or cannot 958 implement time zone support. Clients should only use this if also 959 asking the server to expand recurrences, as you cannot accurately 960 expand a recurrence without the original time zone. This property 961 is calculated at fetch time by the server. Time zones are 962 political and they can and do change at any time. Fetching 963 exactly the same property again may return a different results if 964 the time zone data has been updated on the server. Time zone data 965 changes are not considered "updates" to the event. If set, server 966 will convert to the event's current time zone using its current 967 time zone data and store the local time. This is not included by 968 default and must be requested explicitly. Floating events will be 969 interpreted as per calendar's time zone property; or if not set, 970 the the principal's time zone property. 972 o *utcEnd*: "UTCDate" The server calculates the end time in UTC from 973 the start/timeZone/duration properties of the event. This is not 974 included by default and must be requested explicitly. Like 975 utcStart, this is calculated at fetch time if requested and may 976 change due to time zone data changes. 978 CalendarEvent objects MUST NOT have a "method" property as this is 979 only used when representing iTIP [RFC5546] scheduling messages, not 980 events in a data store. 982 5.1. Attachments 984 The Link object, as defined in [I-D.ietf-calext-jscalendar] 985 Section 4.2.7, with a "rel" property equal to "enclosure" is used to 986 represent attachments. Instead of mandating an "href" property, 987 clients may set a "blobId" property instead to reference a blob of 988 binary data in the account, as per [RFC8620] Section 6. 990 The server MUST translate this to an embedded "data:" URL [RFC2397] 991 when sending the event to a system that cannot access the blob. 992 Servers that support CalDAV access to the same data are recommended 993 to expose these files as managed attachments [?@RFC8607]. 995 5.2. Per-user properties 997 In shared calendars where "shareesActAs" is "self", the following 998 properties MUST be stored per-user: 1000 o keywords 1002 o color 1004 o freeBusyStatus 1006 o useDefaultAlerts 1008 o alerts 1010 The user may also modify the above on a per-occurrence basis for 1011 recurring events; again, these MUST be stored per-user. 1013 When writing per-user properties, the "updated" property MUST also be 1014 stored just for that user. When fetching the "updated" property, the 1015 value to return is whichever is later of the per-user updated time or 1016 the updated time of the master event. 1018 5.3. Recurring events 1020 Events may recur, in which case they represent multiple occurrences 1021 or instances. The data store will either contain a single master 1022 event, containing a recurrence rule and/or recurrence overrides; or, 1023 a set of individual instances (when invited to specific occurrences 1024 only). 1026 The client may ask the server to expand recurrences within a specific 1027 time range in "CalendarEvent/query". This will generate synthetic 1028 ids representing individual instances in the requested time range. 1029 The client can fetch and update the objects using these ids and the 1030 server will make the appropriate changes to the master event. 1031 Synthetic ids do not appear in "CalendarEvent/changes" responses; 1032 only the ids of events as actually stored on the server. 1034 If the user is invited to specific instances then later added to the 1035 master event, "CalendarEvent/changes" will show the ids of all the 1036 individual instances being destroyed and the id for the master event 1037 being created. 1039 5.4. CalendarEvent/get 1041 This is a standard "/get" method as described in [RFC8620], 1042 Section 5.1, with three extra arguments: 1044 o *recurrenceOverridesBefore*: "UTCDate|null" If given, only 1045 recurrence overrides with a recurrence id on or after this date 1046 (when translated into UTC) will be returned. 1048 o *recurrenceOverridesAfter*: "UTCDate|null" If given, only 1049 recurrence overrides with a recurrence id before this date (when 1050 translated into UTC) will be returned. 1052 o *reduceParticipants*: "Boolean" (default: false) If true, only 1053 participants with the "owner" role or corresponding to the user's 1054 participant identities will be returned in the "participants" 1055 property of the master event and any recurrence overrides. If 1056 false, all participants will be returned. 1058 A CalendarEvent object is a JSEvent object so may have arbitrary 1059 properties. If the client makes a "CalendarEvent/get" call with a 1060 null or omitted "properties" argument, all properties defined on the 1061 JSEvent object in the store are returned, along with the "id", 1062 "calendarId", and "isDraft" properties. The "utcStart" and "utcEnd" 1063 computed properties are only returned if explicitly requested. 1065 If specific properties are requested from the JSEvent and the 1066 property is not present on the object in the server's store, the 1067 server SHOULD return the default value if known for that property. 1069 An id requested by the server may represent a single instance of a 1070 recurring event if the client asked the server to expand recurrences 1071 in "CalendarEvent/query". In such a case, the server will resolve 1072 any overrides and set the appropriate "start" and "recurrenceId" 1073 properties on the CalendarEvent object returned to the client. The 1074 "recurrenceRule" and "recurrenceOverrides" properties MUST be 1075 returned as null if requested for such an event. 1077 An event with the same uid/recurrenceId may appear in different 1078 accounts. Clients may coalesce the view of such events, but must be 1079 aware that the data may be different in the different accounts due to 1080 per-user properties, difference in permissions etc. 1082 The "privacy" property of a JSEvent object allows the owner to 1083 override how sharees of the calendar see the event. If this is set 1084 to "private", when a sharee fetches the event the server MUST only 1085 return the basic time and metadata properties of the JSEvent object 1086 as specified in [I-D.ietf-calext-jscalendar], Section 4.4.3. If set 1087 to "secret", the server MUST behave as though the event does not 1088 exist for all users other than the owner. 1090 5.5. CalendarEvent/changes 1092 This is a standard "/changes" method as described in [RFC8620], 1093 Section 5.2. 1095 5.6. CalendarEvent/set 1097 This is a standard "/set" method as described in [RFC8620], 1098 Section 5.3, with the following extra argument: 1100 o *sendSchedulingMessages*: "Boolean" (default: true) If true then 1101 any changes to scheduled events will be sent to all the 1102 participants (if the user is an owner of the event) or back to the 1103 owners (otherwise). If false, the changes only affect this 1104 calendar and no scheduling messages will be sent. 1106 For recurring events, an id may represent the master event or a 1107 specific instance. When the id for a specific instance is given, the 1108 server MUST process an update as an update to the recurrence override 1109 for that instance on the master event, and a destroy as removing just 1110 that instance. 1112 Clients MUST NOT send an update/destroy to both the master event and 1113 a specific instance in a single "/set" request; the result of this is 1114 undefined. 1116 Servers MUST enforce the user's permissions as returned in the 1117 "myRights" property of the Calendar object and reject changes with a 1118 "forbidden" SetError if not allowed. 1120 The "privacy" property MUST NOT be set to anything other than 1121 "public" (the default) for events in a calendar that does not belong 1122 to the user (e.g. a shared team calendar). The server MUST reject 1123 this with an _invalidProperties_ SetError. 1125 The server MUST reject attempts to add events with a "participants" 1126 property where none of the participants correspond to one of the 1127 calendar's participant identities with a "forbidden" SetError. 1129 If omitted on create, the server MUST set the following properties to 1130 an appropriate value: 1132 o @type 1134 o uid 1135 o created 1137 o updated 1139 When modifying the event, the server MUST set the following 1140 properties if not explicitly set in the update: 1142 o updated: set to the current time. 1144 o sequence: increment by one, unless only per-user properties (see 1145 Section XXX) were changed. 1147 The "created" property MUST NOT be updated after creation. The 1148 "sequence" property MUST NOT be set to a lower number than its 1149 current value. The "method" property MUST NOT be set. Any attempt 1150 to do these is rejected with a standard "invalidProperties" SetError. 1152 The server does not automatically reset the "partipationStatus" or 1153 "expectReply" properties of a Participant if the event details 1154 change. Clients should either be intelligent about whether the 1155 change necessitates resending RSVP requests, or ask the user whether 1156 to send them. 1158 The server MAY enforce that all events have an owner, for example in 1159 team calendars. If the user tries to create an event without 1160 participants in such a calendar, the server MUST automatically add a 1161 participant with the "owner" role corresponding to one of the user's 1162 "participantIdentities" for the calendar. 1164 When creating an event with participants, or adding participants to 1165 an event that previously did not have participants, the server MUST 1166 set the "replyTo" property of the event if not present. Clients 1167 SHOULD NOT set the replyTo property for events when the user adds 1168 participants; the server is better positioned to add all the methods 1169 it supports to receive replies. 1171 5.6.1. Sending invitations and responses 1173 Unless "sendSchedulingMessages" is false, the server MUST send 1174 appropriate iTIP [RFC5546] scheduling messages after successfuly 1175 creating, updating or destroying a calendar event. 1177 When determining which scheduling messages to send, the server must 1178 first establish whether it is the _source_ of the event. The server 1179 is the source if it will receive messages sent to any of the methods 1180 specified in the "replyTo" property of the event. 1182 Messages are only sent to participants with a "scheduleAgent" 1183 property set to "server" or omitted. If the effective 1184 "scheduleAgent" property is changed: 1186 o to "server" from something else: send messages to this participant 1187 as though the event had just been created. 1189 o from "server" to something else: send messages to this participant 1190 as though the event had just been destroyed. 1192 o any other change: do not send any messages to this participant. 1194 The server may send the scheduling message via any of the methods 1195 defined on the sendTo property of a participant (if the server is the 1196 source) or the replyTo property of the event (otherwise) that it 1197 supports. If no supported methods are available, the server MUST 1198 reject the change with a "noSupportedScheduleMethods" SetError. 1200 If the server is the source of the event it MUST NOT send messages to 1201 any participant corresponding to the participantIdentities of the 1202 calendar it is in. 1204 If sending via iMIP [RFC6047], the server MAY choose to only send 1205 updates it deems "essential" to avoid flooding the recipient's email 1206 with changes they do not care about. For example, changes to the 1207 participationStatus of another participant, or changes to events 1208 solely in the past may be omitted. 1210 5.6.1.1. REQUEST 1212 When the server is the source for the event, a REQUEST message 1213 ([RFC5546], Section 3.2.2) is sent to all current participants if: 1215 o The event is being created. 1217 o Any non per-user property (see Section XXX) is updated on the 1218 event (including adding/removing participants), except if just 1219 modifying the recurrenceOverrides such that CANCEL messages are 1220 generated (see the next section). 1222 Note, if the only change is adding an additional instance (not 1223 generated by the event's recurrence rule) to the recurrenceOverrides, 1224 this could be handled via sending an ADD message ([RFC5546], 1225 Section 3.2.4) for the single instance rather than a REQUEST message 1226 for the master. However, for interoperability reasons this is not 1227 recommended due to poor support in the wild for this type of message. 1229 The server MUST ensure participants are only sent information about 1230 recurrence instances they are added to when sending scheduling 1231 messages for recurring events. If the participant is not invited to 1232 the master recurring event but only individual instances, scheduling 1233 messages MUST be sent for just those expanded occurrences 1234 individually. If a participant is invited to a recurring event, but 1235 removed via a recurrence override from a particular instance, any 1236 scheduling messages to this participant MUST return the instance as 1237 "excluded" (if it matches a recurrence rule for the event) or omit 1238 the instance entirely (otherwise). 1240 5.6.1.2. CANCEL 1242 When the server is the source for the event, a CANCEL message 1243 ([RFC5546], Section 3.2.5) is sent if: 1245 o A participant is removed from either the master event or a single 1246 instance (the message is only sent to this participant; remaining 1247 participants will get a REQUEST, as described above). 1249 o The event is destroyed. 1251 o An exclusion is added to recurrenceOverrides to remove an instance 1252 generated by the event's recurrence rule. 1254 o An additional instance (not generated by the event's recurrence 1255 rule) is removed from the recurrenceOverrides. 1257 In each of the latter 3 cases, the message is sent to all 1258 participants. 1260 5.6.1.3. REPLY 1262 When the server is _not_ the source for the event, a REPLY message 1263 ([RFC5546], Section 3.2.3) is sent for any participant corresponding 1264 to the participantIdentities of the calendar it is in if: 1266 o The "participationStatus" property of the participant is changed. 1268 o The event is destroyed and the participationStatus was not "needs- 1269 action". 1271 o The event is created and the participationStatus is not "needs- 1272 action". 1274 o An exclusion is added to recurrenceOverrides to remove an instance 1275 generated by the event's recurrence rule. 1277 o An exclusion is removed from recurrenceOverrides (this is presumed 1278 to be the client undoing the deletion of a single instance). 1280 o An instance not generated by the event's recurrence rule is 1281 removed from the recurrenceOverrides. 1283 o An instance not generated by the event's recurrence rule is added 1284 to the recurrenceOverrides (this is presumed to be the client 1285 undoing the deletion of a single instance). 1287 A reply is not sent when deleting an event where the current status 1288 is "needs-action" as if a junk calendar event gets added by an 1289 automated system, the user MUST be able to delete the event without 1290 sending a reply. 1292 5.7. CalendarEvent/copy 1294 This is a standard "/copy" method as described in [RFC8620], 1295 Section 5.4. 1297 5.8. CalendarEvent/query 1299 This is a standard "/query" method as described in [RFC8620], 1300 Section 5.5, with two extra arguments: 1302 o *expandRecurrences*: "Boolean" (default: false) If true, the 1303 server will expand any recurring event. If true, the filter MUST 1304 be just a FilterCondition (not a FilterOperator) and MUST include 1305 both a before and after property. This ensures the server is not 1306 asked to return an infinite number of results. 1308 o *timeZone*: "String" The time zone for before/after filter 1309 conditions (default: "Etc/UTC") 1311 If expandRecurrences is true, a separate id will be returned for each 1312 instance of a recurring event that matches the query. Otherwise, a 1313 single id will be returned for matching recurring events that 1314 represents the entire event. 1316 There is no necessary correspondence between the ids of different 1317 instances of the same expanded event. 1319 The following additional error may be returned instead of the 1320 "CalendarEvent/query" response: 1322 "cannotCalculateOccurrences": the server cannot expand a recurrence 1323 required to return the results for this query. 1325 5.8.1. Filtering 1327 A *FilterCondition* object has the following properties: 1329 o *inCalendars*: "Id[]|null" A list of calendar ids. An event must 1330 be in ANY of these calendars to match the condition. 1332 o *after*: "LocalDate|null" The end of the event, or any recurrence 1333 of the event, in the time zone given as the timeZone argument, 1334 must be after this date to match the condition. 1336 o *before*: "LocalDate|null" The start of the event, or any 1337 recurrence of the event, in the time zone given as the timeZone 1338 argument, must be before this date to match the condition. 1340 o *text*: "String|null" Looks for the text in the _title_, 1341 _description_, _locations_ (matching name/description), 1342 _participants_ (matching name/email) and any other textual 1343 properties of the event or any recurrence of the event. 1345 o *title*: "String|null" Looks for the text in the _title_ property 1346 of the event, or the overridden _title_ property of a recurrence. 1348 o *description*: "String|null" Looks for the text in the 1349 _description_ property of the event, or the overridden 1350 _description_ property of a recurrence. 1352 o *location*: "String|null" Looks for the text in the _locations_ 1353 property of the event (matching name/description of a location), 1354 or the overridden _locations_ property of a recurrence. 1356 o *owner*: "String|null" Looks for the text in the name or email 1357 fields of a participant in the _participants_ property of the 1358 event, or the overridden _participants_ property of a recurrence, 1359 where the participant has a role of "owner". 1361 o *attendee*: "String|null" Looks for the text in the name or email 1362 fields of a participant in the _participants_ property of the 1363 event, or the overridden _participants_ property of a recurrence, 1364 where the participant has a role of "attendee". 1366 o *participationStatus*: Must match. If owner/attendee condition, 1367 status must be of that participant. Otherwise any. 1369 o *uid*: "String" The uid of the event is exactly the given string. 1371 If expandRecurrences is true, all conditions must match against the 1372 same instance of a recurring event for the instance to match. If 1373 expandRecurrences is false, all conditions must match, but they may 1374 each match any instance of the event. 1376 If zero properties are specified on the FilterCondition, the 1377 condition MUST always evaluate to "true". If multiple properties are 1378 specified, ALL must apply for the condition to be "true" (it is 1379 equivalent to splitting the object into one-property conditions and 1380 making them all the child of an AND filter operator). 1382 The exact semantics for matching "String" fields is *deliberately not 1383 defined* to allow for flexibility in indexing implementation, subject 1384 to the following: 1386 o Text SHOULD be matched in a case-insensitive manner. 1388 o Text contained in either (but matched) single or double quotes 1389 SHOULD be treated as a *phrase search*, that is a match is 1390 required for that exact sequence of words, excluding the 1391 surrounding quotation marks. Use "\"", "\'" and "\\" to match a 1392 literal """, "'" and "\" respectively in a phrase. 1394 o Outside of a phrase, white-space SHOULD be treated as dividing 1395 separate tokens that may be searched for separately in the event, 1396 but MUST all be present for the event to match the filter. 1398 o Tokens MAY be matched on a whole-word basis using stemming (so for 1399 example a text search for "bus" would match "buses" but not 1400 "business"). 1402 5.8.2. Sorting 1404 The following properties MUST be supported for sorting: 1406 o start 1408 o uid 1410 o recurrenceId 1412 The following properties SHOULD be supported for sorting: 1414 o created 1416 o updated 1418 5.9. CalendarEvent/queryChanges 1420 This is a standard "/queryChanges" method as described in [RFC8620], 1421 Section 5.6. 1423 5.10. Examples 1425 TODO: Add example of how to get event by uid: query uid=foo and 1426 backref. Return multiple with recurrenceId set (user invited to 1427 specific instances of recurring event). 1429 6. Alerts 1431 Alerts may be specified on events as described in 1432 [I-D.ietf-calext-jscalendar], Section 4.5. If the "useDefaultAlerts" 1433 property is true, the alerts are taken from the Calendar 1434 "defaultAlertsWithTime" or "defaultAlertsWithoutTime" property, as 1435 described in Section XXX. Otherwise, the alerts are taken from the 1436 "alerts" property of the CalendarEvent. 1438 Alerts MUST only be triggered for events in calendars where the user 1439 is subscribed and either the user owns the calendar or the calendar's 1440 "shareesActAs" property is "self". 1442 When an alert with an "email" action is triggered, the server MUST 1443 send an email to the user to notify them of the event. The contents 1444 of the email is implementation specific. Clients MUST NOT perform an 1445 action for these alerts. 1447 When an alert with a "display" action is triggered, clients SHOULD 1448 display an alert in a platform-appropriate manner to the user to 1449 remind them of the event. Clients with a full offline cache of 1450 events may choose to calculate when alerts should trigger locally. 1451 Alternatively, they can subscribe to push events from the server. 1453 6.1. Push events 1455 Servers that support the "urn:ietf:params:jmap:calendars" capability 1456 MUST support registering for the pseudo-type "CalendarAlert" in push 1457 subscriptions and event source connections, as described in 1458 [RFC8620], Sections 7.2 and 7.3. 1460 If requested, a CalendarAlert notification will be pushed whenever an 1461 alert is triggered for the user. For Event Source connections, this 1462 notification is pushed as an event called "calendaralert". 1464 A *CalendarAlert* object has the following properties: 1466 o *@type*: "String" This MUST be the string "CalendarAlert". 1468 o *accountId*: "String" The account id for the calendar in which the 1469 alert triggered. 1471 o *calendarEventId*: "String" The CalendarEvent id for the alert 1472 that triggered. 1474 o *uid*: "String" The uid property of the CalendarEvent for the 1475 alert that triggered. 1477 o *recurrenceId*: "String|null" The recurrenceId for the instance of 1478 the event for which this alert is being triggered, or "null" if 1479 the event is not recurring. 1481 o *alertId*: "String" The id for the alert that triggered. 1483 6.2. Acknowledging an alert 1485 To dismiss an alert, clients set the "acknowledged" property of the 1486 Alert object to the current date-time. When other clients fetch the 1487 CalendarEvent with the updated Alert they SHOULD automatically 1488 dismiss or suppress duplicate alerts (alerts with the same alert id 1489 that triggered on or before this date-time). 1491 Setting the "acknowledged" property MUST NOT create a new recurrence 1492 override. For a recurring calendar object, the "acknowledged" 1493 property of the parent object MUST be updated, unless the alert is 1494 already overridden in the "recurrenceOverrides" property. 1496 6.3. Snoozing an alert 1498 Users may wish to dismiss an alert temporarily and have it come back 1499 after a specific period of time. To do this, clients MUST: 1501 1. Acknowledge the alert as described in Section XXX. 1503 2. Add a new alert with an "AbsoluteTrigger" for the date-time the 1504 alert has been snoozed until. Add a "relatedTo" property to the 1505 new alert, setting the "parent" relation to point to the original 1506 alert. This MUST NOT create a new recurrence override; it is 1507 added to the same "alerts" property that contains the alert being 1508 snoozed. 1510 When acknowledging a snoozed alert (i.e. one with a parent relatedTo 1511 pointing to the original alert), the client SHOULD delete the alert 1512 rather than setting the "acknowledged" property. 1514 7. Calendar Event Notifications 1516 The CalendarEventNotification data type records changes made by 1517 external entities to events in calendars the user is subscribed to. 1518 Notifications are stored in the same Account as the CalendarEvent 1519 that was changed. 1521 Notifications are only created by the server; users cannot create 1522 them directly. Clients SHOULD present the list of notifications to 1523 the user and allow them to dismiss them. To dismiss a notification 1524 you use a standard "/set" call to destroy it. 1526 The server SHOULD create a CalendarEventNotification whenever an 1527 event is added, updated or destroyed by another user or due to 1528 receiving an iTIP [RFC5546] or other scheduling message in a calendar 1529 this user is subscribed to. The server SHOULD NOT create 1530 notifications for events implicitly deleted due to the containing 1531 calendar being deleted. 1533 7.1. Auto-deletion of Notifications 1535 The server MAY limit the maximum number of notifications it will 1536 store for a user. When the limit is reached, any new notification 1537 will cause the previously oldest notification to be automatically 1538 deleted. 1540 The server MAY coalesce events if appropriate, or remove events that 1541 it deems are no longer relevant or after a certain period of time. 1542 The server SHOULD automatically destroy a notification about an event 1543 if the user updates or destroys that event (e.g. if the user sends an 1544 RSVP for the event). 1546 7.2. Object Properties 1548 The *CalendarEventNotification* object has the following properties: 1550 o *id*: "String" The id of the CalendarEventNotification. 1552 o *created*: "UTCDate" The time this notification was created. 1554 o *changedBy*: "Person" Who made the change. 1556 * *name*: "String" The name of the person who made the change. 1558 * *email*: "String" The email of the person who made the change. 1560 * *calendarPrincipalId*: "String|null" The id of the calendar 1561 principal corresponding to the person who made the change, if 1562 any. This will be null if the change was due to receving an 1563 iTIP message. 1565 o *comment*: "String|null" Comment sent along with the change by the 1566 user that made it. (e.g. COMMENT property in an iTIP message). 1568 o *type*: "String" This MUST be one of 1570 * created 1572 * updated 1574 * destroyed 1576 o *calendarEventId*: "String" The id of the CalendarEvent that this 1577 notification is about. 1579 o *isDraft*: "Boolean" (created/updated only) Is this event a draft? 1581 o *event*: "JSEvent" The data before the change (if updated or 1582 destroyed), or the data after creation (if created). 1584 o *eventPatch*: "PatchObject" (updated only) A patch encoding the 1585 change between the data in the event property, and the data after 1586 the update. 1588 To reduce data, if the change only affects a single instance of a 1589 recurring event, the server MAY set the event and eventPatch 1590 properties for the instance; the calendarEventId MUST still be for 1591 the master event. 1593 7.3. CalendarEventNotification/get 1595 This is a standard "/get" method as described in [RFC8620], 1596 Section 5.1. 1598 7.4. CalendarEventNotification/changes 1600 This is a standard "/changes" method as described in [RFC8620], 1601 Section 5.2. 1603 7.5. CalendarEventNotification/set 1605 This is a standard "/changes" method as described in [RFC8620], 1606 Section 5.3. 1608 Only destroy is supported; any attempt to create/update MUST be 1609 rejected with a "forbidden" SetError. 1611 7.6. CalendarEventNotification/query 1613 This is a standard "/query" method as described in [RFC8620], 1614 Section 5.5. 1616 7.6.1. Filtering 1618 A *FilterCondition* object has the following properties: 1620 o *after*: "UTCDate|null" The creation date must be on or after this 1621 date to match the condition. 1623 o *before*: "UTCDate|null" The creation date must be before this 1624 date to match the condition. 1626 o *type*: "String" The type property must be the same to match the 1627 condition. 1629 o *calendarEventIds*: "Id[]|null" A list of event ids. The 1630 calendarEventId property of the notification must be in this list 1631 to match the condition. 1633 7.6.2. Sorting 1635 The "created" property MUST be supported for sorting. 1637 7.7. CalendarEventNotification/queryChanges 1639 This is a standard "/queryChanges" method as described in [RFC8620], 1640 Section 5.6. 1642 8. Security Considerations 1644 All security considerations of JMAP [RFC8620] and JSCalendar 1645 [I-D.ietf-calext-jscalendar] apply to this specification. Additional 1646 considerations specific to the data types and functionality 1647 introduced by this document are described in the following 1648 subsections. 1650 8.1. Denial-of-service Expanding Recurrences 1652 Recurrence rules can be crafted to occur as frequently as every 1653 second. Servers MUST be careful to not allow resources to be 1654 exhausted when expanding. Equally, rules can be generated that never 1655 create any occurrences at all. Servers MUST be careful to limit the 1656 work spent iterating in search of the next occurrence. 1658 8.2. Privacy 1660 TODO. 1662 9. IANA Considerations 1664 9.1. JMAP Capability Registration for "calendars" 1666 IANA will register the "calendars" JMAP Capability as follows: 1668 Capability Name: "urn:ietf:params:jmap:calendars" 1670 Specification document: this document 1672 Intended use: common 1674 Change Controller: IETF 1676 Security and privacy considerations: this document, Section XXX 1678 9.2. Reservation of JMAP attributes in JSCalendar Property registry 1680 TODO. 1682 10. References 1684 10.1. Normative References 1686 [I-D.ietf-calext-jscalendar] 1687 Jenkins, N. and R. Stepanek, "JSCalendar: A JSON 1688 representation of calendar data", draft-ietf-calext- 1689 jscalendar-20 (work in progress), October 2019. 1691 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1692 Requirement Levels", BCP 14, RFC 2119, 1693 DOI 10.17487/RFC2119, March 1997, 1694 . 1696 [RFC2397] Masinter, L., "The "data" URL scheme", RFC 2397, 1697 DOI 10.17487/RFC2397, August 1998, 1698 . 1700 [RFC5546] Daboo, C., Ed., "iCalendar Transport-Independent 1701 Interoperability Protocol (iTIP)", RFC 5546, 1702 DOI 10.17487/RFC5546, December 2009, 1703 . 1705 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1706 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1707 May 2017, . 1709 [RFC8620] Jenkins, N. and C. Newman, "The JSON Meta Application 1710 Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, July 1711 2019, . 1713 10.2. Informative References 1715 [RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault, 1716 "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791, 1717 DOI 10.17487/RFC4791, March 2007, 1718 . 1720 [RFC6047] Melnikov, A., Ed., "iCalendar Message-Based 1721 Interoperability Protocol (iMIP)", RFC 6047, 1722 DOI 10.17487/RFC6047, December 2010, 1723 . 1725 Authors' Addresses 1727 Neil Jenkins 1728 Fastmail 1729 PO Box 234, Collins St West 1730 Melbourne VIC 8007 1731 Australia 1733 Email: neilj@fastmailteam.com 1734 URI: https://www.fastmail.com 1736 Michael Douglass 1737 Spherical Cow Group 1738 226 3rd Street 1739 Troy NY 12180 1740 United States of America 1742 Email: mdouglass@sphericalcowgroup.com 1743 URI: http://sphericalcowgroup.com