idnits 2.17.1 draft-ietf-jmap-calendars-02.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 (March 10, 2020) is 1507 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-26 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: September 11, 2020 Spherical Cow Group 6 March 10, 2020 8 JMAP for Calendars 9 draft-ietf-jmap-calendars-02 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 September 11, 2020. 33 Copyright Notice 35 Copyright (c) 2020 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 . . . . . . . . . . . . . . . . . . . 4 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 . . . . . . . . . . . . . . . . . . . . . 7 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 . . . . . . . . . . . . . . . . . . . . . . . . . . 12 69 3.1. Per-user properties . . . . . . . . . . . . . . . . . . . 16 70 3.2. Calendar/get . . . . . . . . . . . . . . . . . . . . . . 16 71 3.3. Calendar/changes . . . . . . . . . . . . . . . . . . . . 17 72 3.4. Calendar/set . . . . . . . . . . . . . . . . . . . . . . 17 73 4. Calendar Share Notifications . . . . . . . . . . . . . . . . 18 74 4.1. Auto-deletion of Notifications . . . . . . . . . . . . . 18 75 4.2. Object Properties . . . . . . . . . . . . . . . . . . . . 18 76 4.3. CalendarShareNotification/get . . . . . . . . . . . . . . 19 77 4.4. CalendarShareNotification/changes . . . . . . . . . . . . 19 78 4.5. CalendarShareNotification/set . . . . . . . . . . . . . . 19 79 4.6. CalendarShareNotification/query . . . . . . . . . . . . . 20 80 4.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 20 81 4.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 20 82 4.7. CalendarShareNotification/queryChanges . . . . . . . . . 20 83 5. Calendar Events . . . . . . . . . . . . . . . . . . . . . . . 20 84 5.1. Attachments . . . . . . . . . . . . . . . . . . . . . . . 21 85 5.2. Per-user properties . . . . . . . . . . . . . . . . . . . 21 86 5.3. Recurring events . . . . . . . . . . . . . . . . . . . . 22 87 5.4. Updating for "this-and-future" . . . . . . . . . . . . . 22 88 5.4.1. Splitting an event . . . . . . . . . . . . . . . . . 23 89 5.4.2. Updating the master and overriding previous . . . . . 23 90 5.5. CalendarEvent/get . . . . . . . . . . . . . . . . . . . . 23 91 5.6. CalendarEvent/changes . . . . . . . . . . . . . . . . . . 24 92 5.7. CalendarEvent/set . . . . . . . . . . . . . . . . . . . . 24 93 5.7.1. Sending invitations and responses . . . . . . . . . . 26 94 5.8. CalendarEvent/copy . . . . . . . . . . . . . . . . . . . 29 95 5.9. CalendarEvent/query . . . . . . . . . . . . . . . . . . . 29 96 5.9.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 30 97 5.9.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 31 98 5.10. CalendarEvent/queryChanges . . . . . . . . . . . . . . . 32 99 5.11. Examples . . . . . . . . . . . . . . . . . . . . . . . . 32 100 6. Alerts . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 101 6.1. Push events . . . . . . . . . . . . . . . . . . . . . . . 32 102 6.2. Acknowledging an alert . . . . . . . . . . . . . . . . . 33 103 6.3. Snoozing an alert . . . . . . . . . . . . . . . . . . . . 33 104 7. Calendar Event Notifications . . . . . . . . . . . . . . . . 34 105 7.1. Auto-deletion of Notifications . . . . . . . . . . . . . 34 106 7.2. Object Properties . . . . . . . . . . . . . . . . . . . . 34 107 7.3. CalendarEventNotification/get . . . . . . . . . . . . . . 35 108 7.4. CalendarEventNotification/changes . . . . . . . . . . . . 35 109 7.5. CalendarEventNotification/set . . . . . . . . . . . . . . 35 110 7.6. CalendarEventNotification/query . . . . . . . . . . . . . 36 111 7.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 36 112 7.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 36 113 7.7. CalendarEventNotification/queryChanges . . . . . . . . . 36 114 8. Security Considerations . . . . . . . . . . . . . . . . . . . 36 115 8.1. Denial-of-service Expanding Recurrences . . . . . . . . . 36 116 8.2. Privacy . . . . . . . . . . . . . . . . . . . . . . . . . 37 117 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 37 118 9.1. JMAP Capability Registration for "calendars" . . . . . . 37 119 9.2. Reservation of JMAP attributes in JSCalendar Property 120 registry . . . . . . . . . . . . . . . . . . . . . . . . 37 121 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 37 122 10.1. Normative References . . . . . . . . . . . . . . . . . . 37 123 10.2. Informative References . . . . . . . . . . . . . . . . . 38 124 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 38 126 1. Introduction 128 JMAP ([RFC8620] - JSON Meta Application Protocol) is a generic 129 protocol for synchronizing data, such as mail, calendars or contacts, 130 between a client and a server. It is optimized for mobile and web 131 environments, and aims to provide a consistent interface to different 132 data types. 134 This specification defines a data model for synchronizing calendar 135 data between a client and a server using JMAP. The data model is 136 designed to allow a server to provide consistent access to the same 137 data via CalDAV [RFC4791] as well as JMAP, however the functionality 138 offered over the two protocols may differ. Unlike CalDAV, this 139 specification does not define access to tasks or journal entries 140 (VTODO or VJOURNAL iCalendar components in CalDAV). 142 1.1. Data Model Overview 144 A CalendarPrincipal (see Section XXX) represents an individual, team 145 or resource (e.g. a room or projector). The object contains 146 information about the entity being represented, such as a name, 147 description and time zone. A CalendarPrincipal has a 1:1 148 correspondence with an Account (see [RFC8620], Section 1.6.2) that 149 supports the "urn:ietf:params:jmap:calendars" capability. 151 Each such Account contains zero or more Calendar objects, which is a 152 named collection of CalendarEvents belonging to the 153 CalendarPrincipal. Sharing permissions are managed per calendar. 154 For example, an individual may have separate calendars for personal 155 and work activities, with both contributing to their free-busy 156 availability, but only the work calendar shared in its entirety with 157 colleagues. Calendars can also provide defaults, such as alerts and 158 a color to apply to events in the calendar. Clients commonly let 159 users toggle visibility of events belonging to a particular calendar 160 on/off. 162 A CalendarEvent is a representation of an event or recurring series 163 of events in JSEvent [I-D.ietf-calext-jscalendar] format. Simple 164 clients may ask the server to expand recurrences for them within a 165 specific time period, and optionally convert times into UTC so they 166 do not have to handle time zone conversion. More full-featured 167 clients will want to access the full event information and handle 168 recurrence expansion and time zone conversion locally. 170 CalendarEventNotification objects keep track of the history of 171 changes made to a calendar by other users, allowing calendar clients 172 to notify the user of changes to their schedule. Similarly, the 173 CalendarShareNotification type notifies the user when their access to 174 another user's calendar is granted or revoked. 176 1.2. Accounts, Push, and the Session Object 178 The JMAP Session object (see [RFC8620], Section 2) typically includes 179 an object in the "accounts" property for every account that the user 180 has access to. Calendaring systems may share data between a 181 (potentially very) large number of CalendarPrincipals, most of which 182 the user does not care about day-to-day but may occasionally need to 183 query when scheduling events. 185 Users can normally subscribe to any calendar to which they have 186 access (see Section XXX). This indicates the user wants this 187 calendar to appear in their regular list of calendars. The separate 188 "isVisible" property stores whether the user would currently like to 189 view the events in a subscribed calendar. 191 The Session object MUST only include Accounts where the user is 192 subscribed to at least one Calendar or they have access to some other 193 data type in the account. StateChange events for changes to 194 CalendarEvent data SHOULD only be sent for events in calendars the 195 user has subscribed to and MUST NOT be sent for any Account where the 196 user is not subscribed to at least one calendar. 198 The server MAY reject the user's attempt to subscribe to some 199 calendars, e.g. those representing resources. 201 A user may query the set of CalendarPrincipals they have access to 202 with "CalendarPrincipal/query" (see Section XXX). The 203 CalendarPrincipal object may have an "accountId" property that can be 204 used to then fetch calendars and events associated with that 205 principal, subject to appropriate permissions. 207 1.2.1. UIDs and CalendarEvent Ids 209 Each CalendarEvent has a "uid" property 210 ([I-D.ietf-calext-jscalendar], Section 4.1.2), which is a globally 211 unique identifier that identifies the same event in different 212 Accounts, or different instances of the same recurring event within 213 an Account. 215 An Account MUST NOT contain more than one CalendarEvent with the same 216 uid unless all of the CalendarEvent objects have distinct, non-null 217 values for their "recurrenceId" property. (This situation occurs if 218 the principal is added to one or more specific instances of a 219 recurring event without being invited to the whole series.) 221 Each CalendarEvent also has an id, which is scoped to the JMAP 222 Account and used for referencing it in JMAP methods. There is no 223 necessary link between the uid property and the CalendarEvent's id. 224 CalendarEvents with the same uid in different Accounts MAY have 225 different ids. 227 1.3. Notational Conventions 229 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 230 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 231 "OPTIONAL" in this document are to be interpreted as described in BCP 232 14 [RFC2119] [RFC8174] when, and only when, they appear in all 233 capitals, as shown here. 235 Type signatures, examples, and property descriptions in this document 236 follow the conventions established in Section 1.1 of [RFC8620]. Data 237 types defined in the core specification are also used in this 238 document. 240 1.4. The LocalDate Data Type 242 Where "LocalDate" is given as a type, it means a string in the same 243 format as "Date" (see [RFC8620], Section 1.4), but with the "time- 244 offset" omitted from the end. The interpretation in absolute time 245 depends upon the time zone for the event, which may not be a fixed 246 offset (for example when daylight saving time occurs). For example, 247 "2014-10-30T14:12:00". 249 1.5. Terminology 251 The same terminology is used in this document as in the core JMAP 252 specification, see [RFC8620], Section 1.6. 254 The terms CalendarPrincipal, Calendar, CalendarEvent, 255 CalendarEventNotification, and CalendarShareNotification (with these 256 specific capitalizations) are used to refer to the data types defined 257 in this document and instances of those data types. 259 1.6. Addition to the Capabilities Object 261 The capabilities object is returned as part of the JMAP Session 262 object; see [RFC8620], Section 2. This document defines two 263 additional capability URIs. 265 1.6.1. urn:ietf:params:jmap:calendars 267 This represents support for the Calendar, CalendarEvent, and 268 CalendarEventNotification data types and associated API methods. The 269 value of this property in the JMAP Session capabilities property is 270 an empty object. 272 The value of this property in an account's accountCapabilities 273 property is an object that MUST contain the following information on 274 server capabilities and permissions for that account: 276 o *accountIdForCalendarPrincipal*: "String|null" The id of an 277 account with the "urn:ietf:params:jmap:calendarprincipals" 278 capability that contains the corresponding CalendarPrincipal 279 object. This may be the same account id. This is null for 280 single-user systems that do not support the CalendarPrincipal data 281 type. 283 o *minDateTime*: "LocalDate" The earliest date-time the server is 284 willing to accept for any date stored in a CalendarEvent. 286 o *maxDateTime*: "LocalDate" The latest date-time the server is 287 willing to accept for any date stored in a CalendarEvent. 289 o *maxExpandedQueryDuration*: "Duration" The maximum duration the 290 user may query over when asking the server to expand recurrences. 292 o *maxParticipantsPerEvent*: "Number|null" The maximum number of 293 participants a single event may have, or null for no limit. 295 o *mayCreateCalendar*: "Boolean" If true, the user may create a 296 calendar in this account. 298 1.6.2. urn:ietf:params:jmap:calendarprincipals 300 Represents support for the CalendarPrincipal and 301 CalendarShareNotification data types and associated API methods. 302 Single user systems do not need this and MAY choose not to support 303 it. 305 The value of this property in the JMAP Session capabilities property 306 is an empty object. 308 The value of this property in an account's accountCapabilities 309 property is an object that MUST contain the following information on 310 server capabilities and permissions for that account: 312 o *currentUserPrincipalId*: "String|null" The id of the principal in 313 this account that corresponds to the user fetching this object, if 314 any. 316 o *maxAvailabilityDuration*: The maximum duration over which the 317 server is prepared to calculate availability in a single call (see 318 Section XXX). 320 2. Calendar Principals 322 A CalendarPrincipal represents an individual, group, schedulable 323 location (e.g. a room), bookable resource (e.g. a projector) or other 324 entity in the calendar system. In a shared calendar environment such 325 as a workplace, a user may have access to a large number of 326 principals. 328 In most systems the user will have access to a single Account 329 containing CalendarPrincipal objects, but they may have access to 330 multiple if, for example, aggregating calendar data from different 331 places. 333 A *CalendarPrincipal* object has the following properties: 335 o *id*: "Id" The id of the principal. 337 o *name*: "String" The name of the principal, e.g. "Jane Doe", or 338 "Room 4B". 340 o *description*: "String|null" A longer description of the 341 principal, for example details about the facilities of a resource, 342 or null if no description available. 344 o *email*: "String|null" An email address for the principal, or null 345 if no email is available. 347 o *type*: "String" This MUST be one of the following values: 349 * "individual": This represents a single person. 351 * "group": This represents a group of people. 353 * "resource": This represents some resource, e.g. a projector. 355 * "location": This represents a location. 357 * "other": This represents some other undefined principal. 359 o *timeZone*: "String" The time zone for this principal. The value 360 MUST be a time zone id from the IANA Time Zone Database. 362 o *mayGetAvailability*: "Boolean" May the user call the 363 "CalendarPrincipal/getAvailability" method with this 364 CalendarPrincipal? 366 o *accountId*: "Id|null" Id of Account with the 367 "urn:ietf:params:jmap:calendars" capability that contains the data 368 for this principal, or null if none (e.g. the CalendarPrincipal is 369 a group just used for permissions management), or the user does 370 not have access to any data in the account (with the exception of 371 free/busy, which is governed by the mayGetAvailability property). 373 o *account*: "Account|null" The JMAP Account object corresponding to 374 the accountId, null if none. 376 o *sendTo*: "String[String]|null" If this principal may be added as 377 a participant to an event, this is the map of methods for adding 378 it, in the same format as Participant#sendTo in JSEvent (see 379 [I-D.ietf-calext-jscalendar], Section 4.4.5). 381 2.1. CalendarPrincipal/get 383 This is a standard "/get" method as described in [RFC8620], 384 Section 5.1. 386 2.2. CalendarPrincipal/changes 388 This is a standard "/changes" method as described in [RFC8620], 389 Section 5.2. 391 2.3. CalendarPrincipal/set 393 This is a standard "/set" method as described in [RFC8620], 394 Section 5.3. However, the user may only update the "timeZone" 395 property of the CalendarPrincipal with the same id as the 396 "currentUserPrincipalId" in the Account capabilities. Any other 397 change MUST be rejected with a "forbidden" SetError. 399 Managing calendar principals is likely tied to a directory service or 400 some other vendor-specific solution, and occurs out-of-band, or via 401 an additional capability defined elsewhere. 403 2.4. CalendarPrincipal/query 405 This is a standard "/query" method as described in [RFC8620], 406 Section 5.5 408 2.4.1. Filtering 410 A *FilterCondition* object has the following properties: 412 o *accountIds*: "String[]" A list of account ids. The 413 CalendarPrincipal matches if the value for its accountId property 414 is in this list. 416 o *email*: "String" Looks for the text in the email property. 418 o *name*: "String" Looks for the text in the name property. 420 o *text* "String" Looks for the text in the name, email, and 421 description properties. 423 o *type*: "String" The type must be exactly as given to match the 424 condition. 426 o *timeZone*: "String" The timeZone must be exactly as given to 427 match the condition. 429 All conditions in the FilterCondition object must match for the 430 CalendarPrincipal to match. 432 2.5. CalendarPrincipal/queryChanges 434 This is a standard "/queryChanges" method as described in [RFC8620], 435 Section 5.6. 437 2.6. CalendarPrincipal/getAvailability 439 Calculates the availability of the principal for scheduling within a 440 requested time period. It takes the following arguments: 442 o *accountId*: "Id" The id of the account to use. 444 o *id*: "Id" The id of the CalendarPrincipal to calculate 445 availability for. 447 o *utcStart*: "UTCDate" The start time (inclusive) of the period for 448 which to return availability. 450 o *utcEnd*: "UTCDate" The end time (exclusive) of the period for 451 which to return availability. 453 o *showDetails*: "Boolean" If true, event details will be returned 454 if the user has permission to view them. 456 The server will first find all relevant events, expanding any 457 recurring events. Relevant events are ones where all of the 458 following is true: 460 o The principal is subscribed to the calendar. 462 o Either the calendar belongs to the principal or the "shareesActAs" 463 property of the calendar is "self". 465 o The "includeInAvailability" property of the calendar for the 466 principal is "all" or "attending". 468 o The user has the "mayReadFreeBusy" permission for the calendar. 470 o The event finishes after the "utcStart" argument and starts before 471 the "utcEnd" argument. 473 o The event's "privacy" property is not "secret". 475 o The "freeBusyStatus" property of the event is "busy" (or omitted, 476 as this is the default). 478 o The "status" property of the event is not "cancelled". 480 o If the "includeInAvailability" property of the calendar is 481 "attending", then the principal is a participant of the event, and 482 has a "participationStatus" of "accepted" or "tentative". 484 The server then generates a BusyPeriod object for each of these 485 events. A *BusyPeriod* object has the following properties: 487 o *utcStart*: "UTCDate" The start time (inclusive) of the period 488 this represents. 490 o *utcEnd*: "UTCDate" The end time (exclusive) of the period this 491 represents. 493 o *busyStatus*: "String" (optional, default "unavailable") This MUST 494 be one of 496 * "confirmed": The event status is "confirmed". 498 * "tentative": The event status is "tentative". 500 * "unavailable": The principal is not available for scheduling at 501 this time for any other reason. 503 o *event*: "JSEvent|null" The JSEvent representation of the event, 504 or null if any of the following are true: 506 * The "showDetails" argument is false. 508 * The "privacy" property of the event is "private". 510 * The user does not have the "mayReadItems" permission for the 511 calendar. 513 The server MAY also generate BusyPeriod objects based on other 514 information it has about the principal's availability, such as office 515 hours. 517 Finally, the server MUST merge and split BusyPeriod objects where the 518 "event" property is null, such that none of them overlap and either 519 there is a gap in time between any two objects (the utcEnd of one 520 does not equal the utcStart of another) or those objects have a 521 different busyStatus property. If there are overlapping BusyPeriod 522 time ranges with different "busyStatus" properties the server MUST 523 choose the value in the following order: confirmed > unavailable > 524 tentative. 526 The response has the following argument: 528 o *list*: "BusyPeriod[]" The list of BusyPeriod objects calculated 529 as described above. 531 The following additional errors may be returned instead of the 532 "CalendarPrincipal/getAvailability" response: 534 "notFound": No principal with this id exists, or the user does not 535 have permission to see that this principal exists. 537 "forbidden": The user does not have permission to query this 538 principal's availability. 540 "tooLarge": The duration between utcStart an utcEnd is longer than 541 the server is willing to calculate availability for. 543 "rateLimit": Too many availability requests have been made recently 544 and the user is being rate limited. It may work to try again later. 546 3. Calendars 548 A Calendar is a named collection of events. All events are 549 associated with one, and only one, calendar. 551 A *Calendar* object has the following properties: 553 o *id*: "Id" (immutable; server-set) The id of the calendar. 555 o *role*: "String|null" Denotes the calendar has a special purpose. 556 This MUST be one of the following: 558 * "inbox": This is the principal's default calendar; when the 559 principal is invited to an event, this is the calendar to which 560 it will be added by the server. There MUST NOT be more than 561 one calendar with this role in an account. 563 * "templates": This calendar holds templates for creating new 564 events. All events in this calendar MUST have the "isDraft" 565 property set to true. Clients should not show this as a 566 regular calendar to users, but may offer users to create new 567 events by copying one of the events in here. 569 o *name*: "String" The user-visible name of the calendar. This may 570 be any UTF-8 string of at least 1 character in length and maximum 571 255 octets in size. 573 o *description*: "String|null" An optional longer-form description 574 of the calendar, to provide context in shared environments where 575 users need more than just the name. 577 o *color*: "String" The color to be used when displaying events 578 associated with the calendar. The value MUST be a case- 579 insensitive color name taken from the CSS3 set of names, defined 580 in Section 4.3 of W3C.REC-css3-color-20110607, or a CSS3 RGB color 581 hex value. The color SHOULD have sufficient contrast to be used 582 as text on a white background. 584 o *sortOrder*: "UnsignedInt" (default: 0) Defines the sort order of 585 calendars when presented in the client's UI, so it is consistent 586 between devices. The number MUST be an integer in the range 0 <= 587 sortOrder < 2^31. A calendar with a lower order should be 588 displayed before a calendar with a higher order in any list of 589 calendars in the client's UI. Calendars with equal order SHOULD 590 be sorted in alphabetical order by name. The sorting should take 591 into account locale-specific character order convention. 593 o *isSubscribed*: "Boolean" Has the user indicated they wish to see 594 this Calendar in their client? This SHOULD default to false for 595 Calendars in shared accounts the user has access to and true for 596 any new Calendars created by the user themself. If false, the 597 calendar should only be displayed when the user explicitly 598 requests it or to offer it for the user to subscribe to. 600 o *isVisible*: "Boolean" (default: true) Should the calendar's 601 events be displayed to the user at the moment? Clients MUST 602 ignore this property if isSubscribed is false. 604 o *includeInAvailability*: "String" (default: all) Should the 605 calendar's events be used as part of availability calculation? 606 This MUST be one of: 608 * "all": all events are considered. 610 * "attending": events the user is a confirmed or tentative 611 participant of are considered. 613 * "none": all events are ignored. 615 o *defaultAlertsWithTime*: "Alert[]" The alerts to apply for events 616 where showWithoutTime is false that have "useDefaultAlerts" set. 617 See [I-D.ietf-calext-jscalendar], Section 4.5.2 for the definition 618 of an Alert object. 620 o *defaultAlertsWithoutTime*: "Alert[]" The alerts to apply for 621 events where showWithoutTime is true that have "useDefaultAlerts" 622 set. See [I-D.ietf-calext-jscalendar], Section 4.5.2 for the 623 definition of an Alert object. 625 o *timeZone*: "String|null" The time zone to use for events without 626 a time zone when the server needs to resolve them into absolute 627 time, e.g., for reminders, queries, or availability calculation. 628 The value MUST be a time zone id from the IANA Time Zone Database. 629 If "null", the timeZone of the account's associated 630 CalendarPrincipal will be used. Clients SHOULD use this as the 631 default for new events in this calendar if set. 633 o *participantIdentities*: "ParticipantIdentity[]|null" (server-set) 634 The identities that represent the user in this calendar. The 635 first item in the array is the default. A *ParticipantIdentity* 636 object has the following properties: 638 * *name*: "String" The display name of the participant to use 639 when adding this participant to an event, e.g. "Joe Bloggs". 641 * *type*: "String" The method for sending scheduling messages to 642 this identity, e.g. "imip" 644 * *uri*: "String" The URI for sending scheduling messages to this 645 identity, e.g. "mailto:foo@example.com" 647 The user is an *owner* for an event if the CalendarEvent object 648 has a "participants" property, and one of the Participant objects 649 has both: a) The "owner" role. b) A "sendTo" property that has 650 "type" and "uri" equal to one of the ParticipantIdentity objects 651 returned with the calendar. 653 o *shareWith*: "Id[CalendarRights]|null" A map of CalendarPrincipal 654 id to rights for principals this calendar is shared with. The 655 pricincipal to which this calendar belongs MUST NOT be in this 656 set. This is null if the user requesting the object does not have 657 the mayAdmin right, or if the calendar is not shared with anyone. 658 May be modified only if the user has the mayAdmin right. 660 o *shareesActAs*: "String" (immutable; default server-dependent) 661 This MUST be one of: 663 * "secretary" 665 * "self" 666 If "self", sharees act as themselves when using this calendar. If 667 "secretary", they act as the pricincipal to which this calendar 668 belongs (secretary mode). If omitted, the default is server 669 dependent. For example, it may be "self" if creating a calendar 670 in a CalendarPrincipal representing a group, and "secretary" if 671 creating a calendar for an individual. Users may attempt to set 672 this on creation, but the server may reject with an 673 "invalidProperties" error if the value is not permissible. 675 o *myRights*: "CalendarRights" (server-set) The set of access rights 676 the user has in relation to this Calendar. 678 A *CalendarRights* object has the following properties: 680 o *mayReadFreeBusy*: "Boolean" The user may read the free-busy 681 information for this calendar as part of a call to 682 CalendarPrincipal/getAvailability (see Section XXX). 684 o *mayReadItems*: "Boolean" The user may fetch the events in this 685 calendar. 687 o *mayAddItems*: "Boolean" The user may create new events on this 688 calendar or move events to this calendar. For recurring events, 689 they may add an override to add an occurrence, or remove an 690 existing override that is excluding an occurrence. 692 o *mayUpdatePrivate*: "Boolean" The user may modify the following 693 properties on all events in the calendar. If shareesActAs is 694 "self", these properties MUST all be stored per-user, and changes 695 do not affect any other user of the calendar. If shareesActAs is 696 "secretary", the values are shared between all users. 698 * keywords 700 * color 702 * freeBusyStatus 704 * useDefaultAlerts 706 * alerts 708 The user may also modify the above on a per-occurrence basis for 709 recurring events. 711 o *mayRSVP*: "Boolean" The user may modify the 712 "participationStatus", "participationComment", "expectReply" and 713 "scheduleAgent" properties of any Participant object that is 714 represented in the "participantIdentities" property of the 715 calendar. The user may also modify the above on a per-occurrence 716 basis for recurring events. 718 o *mayUpdateOwn*: "Boolean" The user may modify an existing event on 719 this calendar if either they are the owner of the event or the 720 event has no owner. 722 o *mayUpdateAll*: "Boolean" The user may modify all existing events 723 on this calendar. 725 o *mayRemoveOwn*: "Boolean" The user may delete an event or move it 726 to a different calendar if either they are the owner of the event 727 or the event has no owner. For recurring events, they may add an 728 override to remove an occurrence. 730 o *mayRemoveAll*: "Boolean" The user may delete any event or move it 731 to a different calendar. For recurring events, they may add an 732 override to remove an occurrence. 734 o *mayAdmin*: "Boolean" The user may modify sharing for this 735 calendar. 737 o *mayDelete*: "Boolean" (server-set) The user may delete the 738 calendar itself. This property MUST be false if the account to 739 which this calendar belongs has the _isReadOnly_ property set to 740 true. 742 3.1. Per-user properties 744 The following properties MUST be stored per-user: 746 o name 748 o color 750 o sortOrder 752 o isVisible 754 3.2. Calendar/get 756 This is a standard "/get" method as described in [RFC8620], 757 Section 5.1. The _ids_ argument may be "null" to fetch all at once. 759 If mayReadFreeBusy is the only permission the user has, the calendar 760 MUST NOT be returned in Calendar/get and Calendar/query; it must 761 behave as though it did not exist. The data is just used as part of 762 CalendarPrincipal/getAvailability. 764 3.3. Calendar/changes 766 This is a standard "/changes" method as described in [RFC8620], 767 Section 5.2. 769 3.4. Calendar/set 771 This is a standard "/set" method as described in [RFC8620], 772 Section 5.3 but with the following additional request argument: 774 o *onDestroyRemoveEvents*: "Boolean" (default: false) 776 If false, any attempt to destroy a Calendar that still has 777 CalendarEvents in it will be rejected with a "calendarHasEvents" 778 SetError. If true, any CalendarEvents that were in the Calendar will 779 be destroyed. This SHOULD NOT send scheduling messages to 780 participants or create CalendarEventNotification objects. 782 The "role" and "shareWith" properties may only be set by users that 783 have the mayAdmin right. The value is shared across all users, 784 although users without the mayAdmin right cannot see the value. 786 Users can subscribe or unsubscribe to a calendar by setting the 787 "isSubscribed" property. The server MAY forbid users from 788 subscribing to certain calendars even though they have permission to 789 see them, rejecting the update with a "forbidden" SetError. 791 The "timeZone", "includeInAvailability", "defaultAlertsWithoutTime" 792 and "defaultAlertsWithTime" properties are stored per-user if the 793 calendar "shareesActAs" value is "self", and may be set by any user 794 who is subscribed to the calendar. Otherwise, these properties are 795 shared, and may only be set by users that have the mayAdmin right. 797 The following properties may be set by anyone who is subscribed to 798 the calendar and are all stored per-user: 800 o name 802 o color 804 o sortOrder 806 o isVisible 807 These properties are initially inherited from the owner's copy of the 808 calendar, but if set by a sharee that user gets their own copy of the 809 property; it does not change for any other principals. If the value 810 of the property in the owner's calendar changes after this, it does 811 not overwrite the sharee's value. 813 The following extra SetError types are defined: 815 For "destroy": 817 o *calendarHasEvent*: The Calendar has at least one CalendarEvent 818 assigned to it, and the "onDestroyRemoveEvents" argument was 819 false. 821 4. Calendar Share Notifications 823 The CalendarShareNotification data type records when the user's 824 permissions to access a shared calendar changes. 825 CalendarShareNotification are only created by the server; users 826 cannot create them explicitly. Notifications are stored in the same 827 Account as the CalendarPrincipals. 829 Clients SHOULD present the list of notifications to the user and 830 allow them to dismiss them. To dismiss a notification you use a 831 standard "/set" call to destroy it. 833 The server SHOULD create a CalendarShareNotification whenever the 834 user's permissions change on a calendar. It SHOULD NOT create a 835 notification for permission changes to a group principal, even if the 836 user is in the group. 838 4.1. Auto-deletion of Notifications 840 The server MAY limit the maximum number of notifications it will 841 store for a user. When the limit is reached, any new notification 842 will cause the previously oldest notification to be automatically 843 deleted. 845 The server MAY coalesce events if appropriate, or remove events that 846 it deems are no longer relevant or after a certain period of time. 847 The server SHOULD automatically destroy a notification about a 848 calendar if the user subscribes to that calendar. 850 4.2. Object Properties 852 The *CalendarShareNotification* object has the following properties: 854 o *id*: "String" The id of the CalendarShareNotification. 856 o *created*: "UTCDate" The time this notification was created. 858 o *changedBy*: "Person" Who made the change. 860 * *name*: "String" The name of the person who made the change. 862 * *email*: "String|null" The email of the person who made the 863 change, or null if no email is available. 865 * *calendarPrincipalId*: "String|null" The id of the 866 CalendarPrincipal corresponding to the person who made the 867 change, or null if no associated princiapal. 869 o *calendarAccountId*: "String" The id of the account where this 870 Calendar exists. 872 o *calendarId*: "String" The id of the Calendar that this 873 notification is about. 875 o *calendarName*: "String" The name of the Calendar at the time the 876 notification was made. 878 o *oldRights*: "CalendarRights|null" The rights the user had before 879 the change. 881 o *newRights*: "CalendarRights|null" The rights the user has after 882 the change. 884 4.3. CalendarShareNotification/get 886 This is a standard "/get" method as described in [RFC8620], 887 Section 5.1. 889 4.4. CalendarShareNotification/changes 891 This is a standard "/changes" method as described in [RFC8620], 892 Section 5.2. 894 4.5. CalendarShareNotification/set 896 This is a standard "/changes" method as described in [RFC8620], 897 Section 5.3. 899 Only destroy is supported; any attempt to create/update MUST be 900 rejected with a "forbidden" SetError. 902 4.6. CalendarShareNotification/query 904 This is a standard "/query" method as described in [RFC8620], 905 Section 5.5. 907 4.6.1. Filtering 909 A *FilterCondition* object has the following properties: 911 o *after*: "UTCDate|null" The creation date must be on or after this 912 date to match the condition. 914 o *before*: "UTCDate|null" The creation date must be before this 915 date to match the condition. 917 4.6.2. Sorting 919 The "created" property MUST be supported for sorting. 921 4.7. CalendarShareNotification/queryChanges 923 This is a standard "/queryChanges" method as described in [RFC8620], 924 Section 5.6. 926 5. Calendar Events 928 A *CalendarEvent* object contains information about an event, or 929 recurring series of events, that takes place at a particular time. 930 It is a JSEvent object, as defined in [I-D.ietf-calext-jscalendar], 931 with the following additional properties: 933 o *id*: "Id" The id of the CalendarEvent. This property is 934 immutable. The id uniquely identifies a JSEvent with a particular 935 "uid" and "recurrenceId" within a particular account. 937 o *calendarId*: "Id" The id of the Calendar this event belongs to. 939 o *isDraft*: "Boolean" If true, this event is to be considered a 940 draft. The server will not send any scheduling messages to 941 participants or send push notifications for alerts. This may only 942 be set to true upon creation. Once set to false, the value cannot 943 be updated to true. This property MUST NOT appear in 944 "recurrenceOverrides". 946 o *utcStart*: "UTCDate" For simple clients that do not or cannot 947 implement time zone support. Clients should only use this if also 948 asking the server to expand recurrences, as you cannot accurately 949 expand a recurrence without the original time zone. This property 950 is calculated at fetch time by the server. Time zones are 951 political and they can and do change at any time. Fetching 952 exactly the same property again may return a different results if 953 the time zone data has been updated on the server. Time zone data 954 changes are not considered "updates" to the event. If set, server 955 will convert to the event's current time zone using its current 956 time zone data and store the local time. This is not included by 957 default and must be requested explicitly. Floating events will be 958 interpreted as per calendar's time zone property; or if not set, 959 the the principal's time zone property. Note that it is not 960 possible to accurately calculate the expansion of recurrence rules 961 or recurrence overrides with the utcStart property rather than the 962 local start time. Even simple recurrences such as "repeat weekly" 963 may cross a daylight-savings boundary and end up at a different 964 UTC time. Clients that wish to use "utcStart" are RECOMMENDED to 965 request the server expand recurrences (see Section XXX). 967 o *utcEnd*: "UTCDate" The server calculates the end time in UTC from 968 the start/timeZone/duration properties of the event. This is not 969 included by default and must be requested explicitly. Like 970 utcStart, this is calculated at fetch time if requested and may 971 change due to time zone data changes. 973 CalendarEvent objects MUST NOT have a "method" property as this is 974 only used when representing iTIP [RFC5546] scheduling messages, not 975 events in a data store. 977 5.1. Attachments 979 The Link object, as defined in [I-D.ietf-calext-jscalendar] 980 Section 4.2.7, with a "rel" property equal to "enclosure" is used to 981 represent attachments. Instead of mandating an "href" property, 982 clients may set a "blobId" property instead to reference a blob of 983 binary data in the account, as per [RFC8620] Section 6. 985 The server MUST translate this to an embedded "data:" URL [RFC2397] 986 when sending the event to a system that cannot access the blob. 987 Servers that support CalDAV access to the same data are recommended 988 to expose these files as managed attachments [?@RFC8607]. 990 5.2. Per-user properties 992 In shared calendars where "shareesActAs" is "self", the following 993 properties MUST be stored per-user: 995 o keywords 997 o color 998 o freeBusyStatus 1000 o useDefaultAlerts 1002 o alerts 1004 The user may also modify these properties on a per-occurrence basis 1005 for recurring events; again, these MUST be stored per-user. 1007 When writing per-user properties, the "updated" property MUST also be 1008 stored just for that user. When fetching the "updated" property, the 1009 value to return is whichever is later of the per-user updated time or 1010 the updated time of the master event. 1012 5.3. Recurring events 1014 Events may recur, in which case they represent multiple occurrences 1015 or instances. The data store will either contain a single master 1016 event, containing a recurrence rule and/or recurrence overrides; or, 1017 a set of individual instances (when invited to specific occurrences 1018 only). 1020 The client may ask the server to expand recurrences within a specific 1021 time range in "CalendarEvent/query". This will generate synthetic 1022 ids representing individual instances in the requested time range. 1023 The client can fetch and update the objects using these ids and the 1024 server will make the appropriate changes to the master event. 1025 Synthetic ids do not appear in "CalendarEvent/changes" responses; 1026 only the ids of events as actually stored on the server. 1028 If the user is invited to specific instances then later added to the 1029 master event, "CalendarEvent/changes" will show the ids of all the 1030 individual instances being destroyed and the id for the master event 1031 being created. 1033 5.4. Updating for "this-and-future" 1035 When editing a recurring event, you can either update the master 1036 event (affecting all instances unless overriden) or update an 1037 override for a specific occurrence. To update all occurrences from a 1038 specific point onwards, there are therefore two options: split the 1039 event, or update the master and override all occurrences before the 1040 split point back to their original values. 1042 5.4.1. Splitting an event 1044 If the event is not scheduled (has no participants), the simplest 1045 thing to do is to duplicate the event, modifying the recurrence rules 1046 of the original so it finishes before the split point, and the 1047 duplicate so it starts at the split point. As per JSCalendar 1048 {TODO:ref} Section 4.1.3, a "next" and "first" relation MUST be set 1049 on the new objects respectively. 1051 Splitting an event however is problematic in the case of a scheduled 1052 event, because the iTIP messages generated make it appear like two 1053 unrelated changes, which can be confusing. 1055 5.4.2. Updating the master and overriding previous 1057 For scheduled events, a better approach is to avoid splitting and 1058 instead update the master event with the new property value for "this 1059 and future", then create overrides for all occurrences before the 1060 split point to restore the property to its previous value. Indeed, 1061 this may be the only option the user has permission to do if not an 1062 owner of the event. 1064 Clients may choose to skip creating the overrides if the old data is 1065 not important, for example if the "alerts" property is being updated, 1066 it is probably not important to create overrides for events in the 1067 past with the alerts that have already fired. 1069 5.5. CalendarEvent/get 1071 This is a standard "/get" method as described in [RFC8620], 1072 Section 5.1, with three extra arguments: 1074 o *recurrenceOverridesBefore*: "UTCDate|null" If given, only 1075 recurrence overrides with a recurrence id on or after this date 1076 (when translated into UTC) will be returned. 1078 o *recurrenceOverridesAfter*: "UTCDate|null" If given, only 1079 recurrence overrides with a recurrence id before this date (when 1080 translated into UTC) will be returned. 1082 o *reduceParticipants*: "Boolean" (default: false) If true, only 1083 participants with the "owner" role or corresponding to the user's 1084 participant identities will be returned in the "participants" 1085 property of the master event and any recurrence overrides. If 1086 false, all participants will be returned. 1088 A CalendarEvent object is a JSEvent object so may have arbitrary 1089 properties. If the client makes a "CalendarEvent/get" call with a 1090 null or omitted "properties" argument, all properties defined on the 1091 JSEvent object in the store are returned, along with the "id", 1092 "calendarId", and "isDraft" properties. The "utcStart" and "utcEnd" 1093 computed properties are only returned if explicitly requested. If 1094 either are requested, the "recurrenceOverrides" property MUST NOT be 1095 requested (recurrence overrides cannot be interpreted accurately with 1096 just the UTC times). 1098 If specific properties are requested from the JSEvent and the 1099 property is not present on the object in the server's store, the 1100 server SHOULD return the default value if known for that property. 1102 A requested id may represent a single instance of a recurring event 1103 if the client asked the server to expand recurrences in 1104 "CalendarEvent/query". In such a case, the server will resolve any 1105 overrides and set the appropriate "start" and "recurrenceId" 1106 properties on the CalendarEvent object returned to the client. The 1107 "recurrenceRule" and "recurrenceOverrides" properties MUST be 1108 returned as null if requested for such an event. 1110 An event with the same uid/recurrenceId may appear in different 1111 accounts. Clients may coalesce the view of such events, but must be 1112 aware that the data may be different in the different accounts due to 1113 per-user properties, difference in permissions etc. 1115 The "privacy" property of a JSEvent object allows the owner to 1116 override how sharees of the calendar see the event. If this is set 1117 to "private", when a sharee fetches the event the server MUST only 1118 return the basic time and metadata properties of the JSEvent object 1119 as specified in [I-D.ietf-calext-jscalendar], Section 4.4.3. If set 1120 to "secret", the server MUST behave as though the event does not 1121 exist for all users other than the owner. 1123 5.6. CalendarEvent/changes 1125 This is a standard "/changes" method as described in [RFC8620], 1126 Section 5.2. 1128 5.7. CalendarEvent/set 1130 This is a standard "/set" method as described in [RFC8620], 1131 Section 5.3, with the following extra argument: 1133 o *sendSchedulingMessages*: "Boolean" (default: true) If true then 1134 any changes to scheduled events will be sent to all the 1135 participants (if the user is an owner of the event) or back to the 1136 owners (otherwise). If false, the changes only affect this 1137 calendar and no scheduling messages will be sent. 1139 For recurring events, an id may represent the master event or a 1140 specific instance. When the id for a specific instance is given, the 1141 server MUST process an update as an update to the recurrence override 1142 for that instance on the master event, and a destroy as removing just 1143 that instance. 1145 Clients MUST NOT send an update/destroy to both the master event and 1146 a specific instance in a single "/set" request; the result of this is 1147 undefined. 1149 Servers MUST enforce the user's permissions as returned in the 1150 "myRights" property of the Calendar object and reject changes with a 1151 "forbidden" SetError if not allowed. 1153 The "privacy" property MUST NOT be set to anything other than 1154 "public" (the default) for events in a calendar that does not belong 1155 to the user (e.g. a shared team calendar). The server MUST reject 1156 this with an "invalidProperties" SetError. 1158 The server MUST reject attempts to add events with a "participants" 1159 property where none of the participants correspond to one of the 1160 calendar's participant identities with a "forbidden" SetError. 1162 If omitted on create, the server MUST set the following properties to 1163 an appropriate value: 1165 o @type 1167 o uid 1169 o created 1171 o updated 1173 When modifying the event, the server MUST set the following 1174 properties if the server is the source of the event and the property 1175 is not explicitly set in the update: 1177 o updated: set to the current time. 1179 o sequence: increment by one, unless only per-user properties (see 1180 Section XXX) were changed. 1182 The "created" property MUST NOT be updated after creation. The 1183 "sequence" property MUST NOT be set to a lower number than its 1184 current value. The "method" property MUST NOT be set. Any attempt 1185 to do these is rejected with a standard "invalidProperties" SetError. 1187 If "utcStart" is set, this is translated into a "start" property 1188 using the server's current time zone information. It MUST NOT be set 1189 in addition to a "start" property and it cannot be set inside 1190 "recurrenceOverrides"; this MUST be rejected with an 1191 "invalidProperties" SetError. 1193 Similarly, the "utcEnd" property is translated into a "duration" 1194 property if set. It MUST NOT be set in addition to a "duration" 1195 property and it cannot be set inside "recurrenceOverrides"; this MUST 1196 be rejected with an "invalidProperties" SetError. 1198 The server does not automatically reset the "partipationStatus" or 1199 "expectReply" properties of a Participant if the event details 1200 change. Clients should either be intelligent about whether the 1201 change necessitates resending RSVP requests, or ask the user whether 1202 to send them. 1204 The server MAY enforce that all events have an owner, for example in 1205 team calendars. If the user tries to create an event without 1206 participants in such a calendar, the server MUST automatically add a 1207 participant with the "owner" role corresponding to one of the user's 1208 "participantIdentities" for the calendar. 1210 When creating an event with participants, or adding participants to 1211 an event that previously did not have participants, the server MUST 1212 set the "replyTo" property of the event if not present. Clients 1213 SHOULD NOT set the replyTo property for events when the user adds 1214 participants; the server is better positioned to add all the methods 1215 it supports to receive replies. 1217 5.7.1. Sending invitations and responses 1219 Unless "sendSchedulingMessages" is false, the server MUST send 1220 appropriate iTIP [RFC5546] scheduling messages after successfuly 1221 creating, updating or destroying a calendar event. 1223 When determining which scheduling messages to send, the server must 1224 first establish whether it is the _source_ of the event. The server 1225 is the source if it will receive messages sent to any of the methods 1226 specified in the "replyTo" property of the event. 1228 Messages are only sent to participants with a "scheduleAgent" 1229 property set to "server" or omitted. If the effective 1230 "scheduleAgent" property is changed: 1232 o to "server" from something else: send messages to this participant 1233 as though the event had just been created. 1235 o from "server" to something else: send messages to this participant 1236 as though the event had just been destroyed. 1238 o any other change: do not send any messages to this participant. 1240 The server may send the scheduling message via any of the methods 1241 defined on the sendTo property of a participant (if the server is the 1242 source) or the replyTo property of the event (otherwise) that it 1243 supports. If no supported methods are available, the server MUST 1244 reject the change with a "noSupportedScheduleMethods" SetError. 1246 If the server is the source of the event it MUST NOT send messages to 1247 any participant corresponding to the participantIdentities of the 1248 calendar it is in. 1250 If sending via iMIP [RFC6047], the server MAY choose to only send 1251 updates it deems "essential" to avoid flooding the recipient's email 1252 with changes they do not care about. For example, changes to the 1253 participationStatus of another participant, or changes to events 1254 solely in the past may be omitted. 1256 5.7.1.1. REQUEST 1258 When the server is the source for the event, a REQUEST message 1259 ([RFC5546], Section 3.2.2) is sent to all current participants if: 1261 o The event is being created. 1263 o Any non per-user property (see Section XXX) is updated on the 1264 event (including adding/removing participants), except if just 1265 modifying the recurrenceOverrides such that CANCEL messages are 1266 generated (see the next section). 1268 Note, if the only change is adding an additional instance (not 1269 generated by the event's recurrence rule) to the recurrenceOverrides, 1270 this MAY be handled via sending an ADD message ([RFC5546], 1271 Section 3.2.4) for the single instance rather than a REQUEST message 1272 for the master. However, for interoperability reasons this is not 1273 recommended due to poor support in the wild for this type of message. 1275 The server MUST ensure participants are only sent information about 1276 recurrence instances they are added to when sending scheduling 1277 messages for recurring events. If the participant is not invited to 1278 the master recurring event but only individual instances, scheduling 1279 messages MUST be sent for just those expanded occurrences 1280 individually. If a participant is invited to a recurring event, but 1281 removed via a recurrence override from a particular instance, any 1282 scheduling messages to this participant MUST return the instance as 1283 "excluded" (if it matches a recurrence rule for the event) or omit 1284 the instance entirely (otherwise). 1286 5.7.1.2. CANCEL 1288 When the server is the source for the event, a CANCEL message 1289 ([RFC5546], Section 3.2.5) is sent if: 1291 o A participant is removed from either the master event or a single 1292 instance (the message is only sent to this participant; remaining 1293 participants will get a REQUEST, as described above). 1295 o The event is destroyed. 1297 o An exclusion is added to recurrenceOverrides to remove an instance 1298 generated by the event's recurrence rule. 1300 o An additional instance (not generated by the event's recurrence 1301 rule) is removed from the recurrenceOverrides. 1303 In each of the latter 3 cases, the message is sent to all 1304 participants. 1306 5.7.1.3. REPLY 1308 When the server is _not_ the source for the event, a REPLY message 1309 ([RFC5546], Section 3.2.3) is sent for any participant corresponding 1310 to the participantIdentities of the calendar it is in if: 1312 o The "participationStatus" property of the participant is changed. 1314 o The event is destroyed and the participationStatus was not "needs- 1315 action". 1317 o The event is created and the participationStatus is not "needs- 1318 action". 1320 o An exclusion is added to recurrenceOverrides to remove an instance 1321 generated by the event's recurrence rule. 1323 o An exclusion is removed from recurrenceOverrides (this is presumed 1324 to be the client undoing the deletion of a single instance). 1326 o An instance not generated by the event's recurrence rule is 1327 removed from the recurrenceOverrides. 1329 o An instance not generated by the event's recurrence rule is added 1330 to the recurrenceOverrides (this is presumed to be the client 1331 undoing the deletion of a single instance). 1333 A reply is not sent when deleting an event where the current status 1334 is "needs-action" as if a junk calendar event gets added by an 1335 automated system, the user MUST be able to delete the event without 1336 sending a reply. 1338 5.8. CalendarEvent/copy 1340 This is a standard "/copy" method as described in [RFC8620], 1341 Section 5.4. 1343 5.9. CalendarEvent/query 1345 This is a standard "/query" method as described in [RFC8620], 1346 Section 5.5, with two extra arguments: 1348 o *expandRecurrences*: "Boolean" (default: false) If true, the 1349 server will expand any recurring event. If true, the filter MUST 1350 be just a FilterCondition (not a FilterOperator) and MUST include 1351 both a before and after property. This ensures the server is not 1352 asked to return an infinite number of results. 1354 o *timeZone*: "String" The time zone for before/after filter 1355 conditions (default: "Etc/UTC") 1357 If expandRecurrences is true, a separate id will be returned for each 1358 instance of a recurring event that matches the query. This synthetic 1359 id is opaque to the client, but allows the server to resolve the id + 1360 recurrence id for "/get" and "/set" operations. Otherwise, a single 1361 id will be returned for matching recurring events that represents the 1362 entire event. 1364 There is no necessary correspondence between the ids of different 1365 instances of the same expanded event. 1367 The following additional error may be returned instead of the 1368 "CalendarEvent/query" response: 1370 "cannotCalculateOccurrences": the server cannot expand a recurrence 1371 required to return the results for this query. 1373 5.9.1. Filtering 1375 A *FilterCondition* object has the following properties: 1377 o *inCalendars*: "Id[]|null" A list of calendar ids. An event must 1378 be in ANY of these calendars to match the condition. 1380 o *after*: "LocalDate|null" The end of the event, or any recurrence 1381 of the event, in the time zone given as the timeZone argument, 1382 must be after this date to match the condition. 1384 o *before*: "LocalDate|null" The start of the event, or any 1385 recurrence of the event, in the time zone given as the timeZone 1386 argument, must be before this date to match the condition. 1388 o *text*: "String|null" Looks for the text in the _title_, 1389 _description_, _locations_ (matching name/description), 1390 _participants_ (matching name/email) and any other textual 1391 properties of the event or any recurrence of the event. 1393 o *title*: "String|null" Looks for the text in the _title_ property 1394 of the event, or the overridden _title_ property of a recurrence. 1396 o *description*: "String|null" Looks for the text in the 1397 _description_ property of the event, or the overridden 1398 _description_ property of a recurrence. 1400 o *location*: "String|null" Looks for the text in the _locations_ 1401 property of the event (matching name/description of a location), 1402 or the overridden _locations_ property of a recurrence. 1404 o *owner*: "String|null" Looks for the text in the name or email 1405 fields of a participant in the _participants_ property of the 1406 event, or the overridden _participants_ property of a recurrence, 1407 where the participant has a role of "owner". 1409 o *attendee*: "String|null" Looks for the text in the name or email 1410 fields of a participant in the _participants_ property of the 1411 event, or the overridden _participants_ property of a recurrence, 1412 where the participant has a role of "attendee". 1414 o *participationStatus*: Must match. If owner/attendee condition, 1415 status must be of that participant. Otherwise any. 1417 o *uid*: "String" The uid of the event is exactly the given string. 1419 If expandRecurrences is true, all conditions must match against the 1420 same instance of a recurring event for the instance to match. If 1421 expandRecurrences is false, all conditions must match, but they may 1422 each match any instance of the event. 1424 If zero properties are specified on the FilterCondition, the 1425 condition MUST always evaluate to "true". If multiple properties are 1426 specified, ALL must apply for the condition to be "true" (it is 1427 equivalent to splitting the object into one-property conditions and 1428 making them all the child of an AND filter operator). 1430 The exact semantics for matching "String" fields is *deliberately not 1431 defined* to allow for flexibility in indexing implementation, subject 1432 to the following: 1434 o Text SHOULD be matched in a case-insensitive manner. 1436 o Text contained in either (but matched) single or double quotes 1437 SHOULD be treated as a *phrase search*, that is a match is 1438 required for that exact sequence of words, excluding the 1439 surrounding quotation marks. Use "\"", "\'" and "\\" to match a 1440 literal """, "'" and "\" respectively in a phrase. 1442 o Outside of a phrase, white-space SHOULD be treated as dividing 1443 separate tokens that may be searched for separately in the event, 1444 but MUST all be present for the event to match the filter. 1446 o Tokens MAY be matched on a whole-word basis using stemming (so for 1447 example a text search for "bus" would match "buses" but not 1448 "business"). 1450 5.9.2. Sorting 1452 The following properties MUST be supported for sorting: 1454 o start 1456 o uid 1458 o recurrenceId 1460 The following properties SHOULD be supported for sorting: 1462 o created 1464 o updated 1466 5.10. CalendarEvent/queryChanges 1468 This is a standard "/queryChanges" method as described in [RFC8620], 1469 Section 5.6. 1471 5.11. Examples 1473 TODO: Add example of how to get event by uid: query uid=foo and 1474 backref. Return multiple with recurrenceId set (user invited to 1475 specific instances of recurring event). 1477 6. Alerts 1479 Alerts may be specified on events as described in 1480 [I-D.ietf-calext-jscalendar], Section 4.5. If the "useDefaultAlerts" 1481 property is true, the alerts are taken from the Calendar 1482 "defaultAlertsWithTime" or "defaultAlertsWithoutTime" property, as 1483 described in Section XXX. Otherwise, the alerts are taken from the 1484 "alerts" property of the CalendarEvent. 1486 Alerts MUST only be triggered for events in calendars where the user 1487 is subscribed and either the user owns the calendar or the calendar's 1488 "shareesActAs" property is "self". 1490 When an alert with an "email" action is triggered, the server MUST 1491 send an email to the user to notify them of the event. The contents 1492 of the email is implementation specific. Clients MUST NOT perform an 1493 action for these alerts. 1495 When an alert with a "display" action is triggered, clients SHOULD 1496 display an alert in a platform-appropriate manner to the user to 1497 remind them of the event. Clients with a full offline cache of 1498 events may choose to calculate when alerts should trigger locally. 1499 Alternatively, they can subscribe to push events from the server. 1501 6.1. Push events 1503 Servers that support the "urn:ietf:params:jmap:calendars" capability 1504 MUST support registering for the pseudo-type "CalendarAlert" in push 1505 subscriptions and event source connections, as described in 1506 [RFC8620], Sections 7.2 and 7.3. 1508 If requested, a CalendarAlert notification will be pushed whenever an 1509 alert is triggered for the user. For Event Source connections, this 1510 notification is pushed as an event called "calendaralert". 1512 A *CalendarAlert* object has the following properties: 1514 o *@type*: "String" This MUST be the string "CalendarAlert". 1516 o *accountId*: "String" The account id for the calendar in which the 1517 alert triggered. 1519 o *calendarEventId*: "String" The CalendarEvent id for the alert 1520 that triggered. 1522 o *uid*: "String" The uid property of the CalendarEvent for the 1523 alert that triggered. 1525 o *recurrenceId*: "String|null" The recurrenceId for the instance of 1526 the event for which this alert is being triggered, or "null" if 1527 the event is not recurring. 1529 o *alertId*: "String" The id for the alert that triggered. 1531 6.2. Acknowledging an alert 1533 To dismiss an alert, clients set the "acknowledged" property of the 1534 Alert object to the current date-time. When other clients fetch the 1535 CalendarEvent with the updated Alert they SHOULD automatically 1536 dismiss or suppress duplicate alerts (alerts with the same alert id 1537 that triggered on or before this date-time). 1539 Setting the "acknowledged" property MUST NOT create a new recurrence 1540 override. For a recurring calendar object, the "acknowledged" 1541 property of the parent object MUST be updated, unless the alert is 1542 already overridden in the "recurrenceOverrides" property. 1544 6.3. Snoozing an alert 1546 Users may wish to dismiss an alert temporarily and have it come back 1547 after a specific period of time. To do this, clients MUST: 1549 1. Acknowledge the alert as described in Section XXX. 1551 2. Add a new alert with an "AbsoluteTrigger" for the date-time the 1552 alert has been snoozed until. Add a "relatedTo" property to the 1553 new alert, setting the "parent" relation to point to the original 1554 alert. This MUST NOT create a new recurrence override; it is 1555 added to the same "alerts" property that contains the alert being 1556 snoozed. 1558 When acknowledging a snoozed alert (i.e. one with a parent relatedTo 1559 pointing to the original alert), the client SHOULD delete the alert 1560 rather than setting the "acknowledged" property. 1562 7. Calendar Event Notifications 1564 The CalendarEventNotification data type records changes made by 1565 external entities to events in calendars the user is subscribed to. 1566 Notifications are stored in the same Account as the CalendarEvent 1567 that was changed. 1569 Notifications are only created by the server; users cannot create 1570 them directly. Clients SHOULD present the list of notifications to 1571 the user and allow them to dismiss them. To dismiss a notification 1572 you use a standard "/set" call to destroy it. 1574 The server SHOULD create a CalendarEventNotification whenever an 1575 event is added, updated or destroyed by another user or due to 1576 receiving an iTIP [RFC5546] or other scheduling message in a calendar 1577 this user is subscribed to. The server SHOULD NOT create 1578 notifications for events implicitly deleted due to the containing 1579 calendar being deleted. 1581 7.1. Auto-deletion of Notifications 1583 The server MAY limit the maximum number of notifications it will 1584 store for a user. When the limit is reached, any new notification 1585 will cause the previously oldest notification to be automatically 1586 deleted. 1588 The server MAY coalesce events if appropriate, or remove events that 1589 it deems are no longer relevant or after a certain period of time. 1590 The server SHOULD automatically destroy a notification about an event 1591 if the user updates or destroys that event (e.g. if the user sends an 1592 RSVP for the event). 1594 7.2. Object Properties 1596 The *CalendarEventNotification* object has the following properties: 1598 o *id*: "String" The id of the CalendarEventNotification. 1600 o *created*: "UTCDate" The time this notification was created. 1602 o *changedBy*: "Person" Who made the change. 1604 * *name*: "String" The name of the person who made the change. 1606 * *email*: "String" The email of the person who made the change, 1607 or null if no email is available. 1609 * *calendarPrincipalId*: "String|null" The id of the calendar 1610 principal corresponding to the person who made the change, if 1611 any. This will be null if the change was due to receving an 1612 iTIP message. 1614 o *comment*: "String|null" Comment sent along with the change by the 1615 user that made it. (e.g. COMMENT property in an iTIP message). 1617 o *type*: "String" This MUST be one of 1619 * created 1621 * updated 1623 * destroyed 1625 o *calendarEventId*: "String" The id of the CalendarEvent that this 1626 notification is about. 1628 o *isDraft*: "Boolean" (created/updated only) Is this event a draft? 1630 o *event*: "JSEvent" The data before the change (if updated or 1631 destroyed), or the data after creation (if created). 1633 o *eventPatch*: "PatchObject" (updated only) A patch encoding the 1634 change between the data in the event property, and the data after 1635 the update. 1637 To reduce data, if the change only affects a single instance of a 1638 recurring event, the server MAY set the event and eventPatch 1639 properties for the instance; the calendarEventId MUST still be for 1640 the master event. 1642 7.3. CalendarEventNotification/get 1644 This is a standard "/get" method as described in [RFC8620], 1645 Section 5.1. 1647 7.4. CalendarEventNotification/changes 1649 This is a standard "/changes" method as described in [RFC8620], 1650 Section 5.2. 1652 7.5. CalendarEventNotification/set 1654 This is a standard "/changes" method as described in [RFC8620], 1655 Section 5.3. 1657 Only destroy is supported; any attempt to create/update MUST be 1658 rejected with a "forbidden" SetError. 1660 7.6. CalendarEventNotification/query 1662 This is a standard "/query" method as described in [RFC8620], 1663 Section 5.5. 1665 7.6.1. Filtering 1667 A *FilterCondition* object has the following properties: 1669 o *after*: "UTCDate|null" The creation date must be on or after this 1670 date to match the condition. 1672 o *before*: "UTCDate|null" The creation date must be before this 1673 date to match the condition. 1675 o *type*: "String" The type property must be the same to match the 1676 condition. 1678 o *calendarEventIds*: "Id[]|null" A list of event ids. The 1679 calendarEventId property of the notification must be in this list 1680 to match the condition. 1682 7.6.2. Sorting 1684 The "created" property MUST be supported for sorting. 1686 7.7. CalendarEventNotification/queryChanges 1688 This is a standard "/queryChanges" method as described in [RFC8620], 1689 Section 5.6. 1691 8. Security Considerations 1693 All security considerations of JMAP [RFC8620] and JSCalendar 1694 [I-D.ietf-calext-jscalendar] apply to this specification. Additional 1695 considerations specific to the data types and functionality 1696 introduced by this document are described in the following 1697 subsections. 1699 8.1. Denial-of-service Expanding Recurrences 1701 Recurrence rules can be crafted to occur as frequently as every 1702 second. Servers MUST be careful to not allow resources to be 1703 exhausted when expanding. Equally, rules can be generated that never 1704 create any occurrences at all. Servers MUST be careful to limit the 1705 work spent iterating in search of the next occurrence. 1707 8.2. Privacy 1709 TODO. 1711 9. IANA Considerations 1713 9.1. JMAP Capability Registration for "calendars" 1715 IANA will register the "calendars" JMAP Capability as follows: 1717 Capability Name: "urn:ietf:params:jmap:calendars" 1719 Specification document: this document 1721 Intended use: common 1723 Change Controller: IETF 1725 Security and privacy considerations: this document, Section XXX 1727 9.2. Reservation of JMAP attributes in JSCalendar Property registry 1729 TODO. 1731 10. References 1733 10.1. Normative References 1735 [I-D.ietf-calext-jscalendar] 1736 Jenkins, N. and R. Stepanek, "JSCalendar: A JSON 1737 representation of calendar data", draft-ietf-calext- 1738 jscalendar-26 (work in progress), March 2020. 1740 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1741 Requirement Levels", BCP 14, RFC 2119, 1742 DOI 10.17487/RFC2119, March 1997, 1743 . 1745 [RFC2397] Masinter, L., "The "data" URL scheme", RFC 2397, 1746 DOI 10.17487/RFC2397, August 1998, 1747 . 1749 [RFC5546] Daboo, C., Ed., "iCalendar Transport-Independent 1750 Interoperability Protocol (iTIP)", RFC 5546, 1751 DOI 10.17487/RFC5546, December 2009, 1752 . 1754 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1755 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1756 May 2017, . 1758 [RFC8620] Jenkins, N. and C. Newman, "The JSON Meta Application 1759 Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, July 1760 2019, . 1762 10.2. Informative References 1764 [RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault, 1765 "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791, 1766 DOI 10.17487/RFC4791, March 2007, 1767 . 1769 [RFC6047] Melnikov, A., Ed., "iCalendar Message-Based 1770 Interoperability Protocol (iMIP)", RFC 6047, 1771 DOI 10.17487/RFC6047, December 2010, 1772 . 1774 Authors' Addresses 1776 Neil Jenkins 1777 Fastmail 1778 PO Box 234, Collins St West 1779 Melbourne VIC 8007 1780 Australia 1782 Email: neilj@fastmailteam.com 1783 URI: https://www.fastmail.com 1785 Michael Douglass 1786 Spherical Cow Group 1787 226 3rd Street 1788 Troy NY 12180 1789 United States of America 1791 Email: mdouglass@sphericalcowgroup.com 1792 URI: http://sphericalcowgroup.com