draft-ietf-jmap-calendars-04.txt   draft-ietf-jmap-calendars-05.txt 
JMAP N. Jenkins JMAP N.M. Jenkins, Ed.
Internet-Draft Fastmail Internet-Draft Fastmail
Intended status: Standards Track M. Douglass Intended status: Standards Track M. Douglass, Ed.
Expires: January 28, 2021 Spherical Cow Group Expires: 29 July 2021 Spherical Cow Group
July 27, 2020 25 January 2021
JMAP for Calendars JMAP for Calendars
draft-ietf-jmap-calendars-04 draft-ietf-jmap-calendars-05
Abstract Abstract
This document specifies a data model for synchronizing calendar data This document specifies a data model for synchronizing calendar data
with a server using JMAP. with a server using JMAP.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
skipping to change at page 1, line 32 skipping to change at page 1, line 32
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on January 28, 2021. This Internet-Draft will expire on 29 July 2021.
Copyright Notice Copyright Notice
Copyright (c) 2020 IETF Trust and the persons identified as the Copyright (c) 2021 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents (https://trustee.ietf.org/
(https://trustee.ietf.org/license-info) in effect on the date of license-info) in effect on the date of publication of this document.
publication of this document. Please review these documents Please review these documents carefully, as they describe your rights
carefully, as they describe your rights and restrictions with respect and restrictions with respect to this document. Code Components
to this document. Code Components extracted from this document must extracted from this document must include Simplified BSD License text
include Simplified BSD License text as described in Section 4.e of as described in Section 4.e of the Trust Legal Provisions and are
the Trust Legal Provisions and are provided without warranty as provided without warranty as described in the Simplified BSD License.
described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Data Model Overview . . . . . . . . . . . . . . . . . . . 4 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4
1.2. Accounts, Push, and the Session Object . . . . . . . . . 5 1.2. The LocalDate Data Type . . . . . . . . . . . . . . . . . 4
1.2.1. UIDs and CalendarEvent Ids . . . . . . . . . . . . . 5 1.3. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4
1.3. Notational Conventions . . . . . . . . . . . . . . . . . 6 1.4. Data Model Overview . . . . . . . . . . . . . . . . . . . 4
1.4. The LocalDate Data Type . . . . . . . . . . . . . . . . . 6 1.4.1. UIDs and CalendarEvent Ids . . . . . . . . . . . . . 5
1.5. Terminology . . . . . . . . . . . . . . . . . . . . . . . 6 1.5. Addition to the Capabilities Object . . . . . . . . . . . 6
1.6. Addition to the Capabilities Object . . . . . . . . . . . 6 1.5.1. urn:ietf:params:jmap:calendars . . . . . . . . . . . 6
1.6.1. urn:ietf:params:jmap:calendars . . . . . . . . . . . 6 1.5.2. urn:ietf:params:jmap:principals:availability . . . . 7
1.6.2. urn:ietf:params:jmap:calendarprincipals . . . . . . . 7 2. Principals and Sharing . . . . . . . . . . . . . . . . . . . 7
2. Calendar Principals . . . . . . . . . . . . . . . . . . . . . 8 2.1. Principal Capability urn:ietf:params:jmap:calendars . . . 7
2.1. CalendarPrincipal/get . . . . . . . . . . . . . . . . . . 9 2.2. Principal/getAvailability . . . . . . . . . . . . . . . . 8
2.2. CalendarPrincipal/changes . . . . . . . . . . . . . . . . 9 3. Participant Identities . . . . . . . . . . . . . . . . . . . 10
2.3. CalendarPrincipal/set . . . . . . . . . . . . . . . . . . 9 3.1. ParticipantIdentity/get . . . . . . . . . . . . . . . . . 11
2.4. CalendarPrincipal/query . . . . . . . . . . . . . . . . . 9 3.2. ParticipantIdentity/changes . . . . . . . . . . . . . . . 11
2.4.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 9 3.3. ParticipantIdentity/set . . . . . . . . . . . . . . . . . 11
2.5. CalendarPrincipal/queryChanges . . . . . . . . . . . . . 10 4. Calendars . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6. CalendarPrincipal/getAvailability . . . . . . . . . . . . 10 4.1. Calendar/get . . . . . . . . . . . . . . . . . . . . . . 16
3. Calendars . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.2. Calendar/changes . . . . . . . . . . . . . . . . . . . . 16
3.1. Calendar/get . . . . . . . . . . . . . . . . . . . . . . 17 4.3. Calendar/set . . . . . . . . . . . . . . . . . . . . . . 16
3.2. Calendar/changes . . . . . . . . . . . . . . . . . . . . 17 5. Calendar Events . . . . . . . . . . . . . . . . . . . . . . . 17
3.3. Calendar/set . . . . . . . . . . . . . . . . . . . . . . 17 5.1. Additional JSCalendar properties . . . . . . . . . . . . 19
4. Calendar Share Notifications . . . . . . . . . . . . . . . . 18 5.1.1. mayInviteSelf . . . . . . . . . . . . . . . . . . . . 19
4.1. Auto-deletion of Notifications . . . . . . . . . . . . . 18 5.1.2. mayInviteOthers . . . . . . . . . . . . . . . . . . . 19
4.2. Object Properties . . . . . . . . . . . . . . . . . . . . 19 5.1.3. hideAttendees . . . . . . . . . . . . . . . . . . . . 19
4.3. CalendarShareNotification/get . . . . . . . . . . . . . . 19 5.2. Attachments . . . . . . . . . . . . . . . . . . . . . . . 19
4.4. CalendarShareNotification/changes . . . . . . . . . . . . 20 5.3. Per-user properties . . . . . . . . . . . . . . . . . . . 19
4.5. CalendarShareNotification/set . . . . . . . . . . . . . . 20 5.4. Recurring events . . . . . . . . . . . . . . . . . . . . 20
4.6. CalendarShareNotification/query . . . . . . . . . . . . . 20 5.5. Updating for "this-and-future" . . . . . . . . . . . . . 20
4.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 20 5.5.1. Splitting an event . . . . . . . . . . . . . . . . . 21
4.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 20 5.5.2. Updating the master and overriding previous . . . . . 21
4.7. CalendarShareNotification/queryChanges . . . . . . . . . 20 5.6. CalendarEvent/get . . . . . . . . . . . . . . . . . . . . 21
5. Calendar Events . . . . . . . . . . . . . . . . . . . . . . . 20 5.7. CalendarEvent/changes . . . . . . . . . . . . . . . . . . 23
5.1. Additional JSCalendar properties . . . . . . . . . . . . 21 5.8. CalendarEvent/set . . . . . . . . . . . . . . . . . . . . 23
5.1.1. mayInviteSelf . . . . . . . . . . . . . . . . . . . . 22 5.8.1. Patching . . . . . . . . . . . . . . . . . . . . . . 25
5.1.2. mayInviteOthers . . . . . . . . . . . . . . . . . . . 22 5.8.2. Sending invitations and responses . . . . . . . . . . 28
5.1.3. hideAttendees . . . . . . . . . . . . . . . . . . . . 22 5.9. CalendarEvent/copy . . . . . . . . . . . . . . . . . . . 31
5.2. Attachments . . . . . . . . . . . . . . . . . . . . . . . 22 5.10. CalendarEvent/query . . . . . . . . . . . . . . . . . . . 31
5.3. Per-user properties . . . . . . . . . . . . . . . . . . . 22 5.10.1. Filtering . . . . . . . . . . . . . . . . . . . . . 32
5.4. Recurring events . . . . . . . . . . . . . . . . . . . . 23 5.10.2. Sorting . . . . . . . . . . . . . . . . . . . . . . 33
5.5. Updating for "this-and-future" . . . . . . . . . . . . . 23 5.11. CalendarEvent/queryChanges . . . . . . . . . . . . . . . 34
5.5.1. Splitting an event . . . . . . . . . . . . . . . . . 24 5.12. Examples . . . . . . . . . . . . . . . . . . . . . . . . 34
5.5.2. Updating the master and overriding previous . . . . . 24 6. Alerts . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.6. CalendarEvent/get . . . . . . . . . . . . . . . . . . . . 24 6.1. Default alerts . . . . . . . . . . . . . . . . . . . . . 34
5.7. CalendarEvent/changes . . . . . . . . . . . . . . . . . . 25 6.2. Acknowledging an alert . . . . . . . . . . . . . . . . . 35
5.8. CalendarEvent/set . . . . . . . . . . . . . . . . . . . . 26 6.3. Snoozing an alert . . . . . . . . . . . . . . . . . . . . 35
5.8.1. Patching . . . . . . . . . . . . . . . . . . . . . . 27 6.4. Push events . . . . . . . . . . . . . . . . . . . . . . . 36
5.8.2. Sending invitations and responses . . . . . . . . . . 31 7. Calendar Event Notifications . . . . . . . . . . . . . . . . 36
5.9. CalendarEvent/copy . . . . . . . . . . . . . . . . . . . 34 7.1. Auto-deletion of Notifications . . . . . . . . . . . . . 37
5.10. CalendarEvent/query . . . . . . . . . . . . . . . . . . . 34 7.2. Object Properties . . . . . . . . . . . . . . . . . . . . 37
5.10.1. Filtering . . . . . . . . . . . . . . . . . . . . . 35 7.3. CalendarEventNotification/get . . . . . . . . . . . . . . 38
5.10.2. Sorting . . . . . . . . . . . . . . . . . . . . . . 36 7.4. CalendarEventNotification/changes . . . . . . . . . . . . 38
5.11. CalendarEvent/queryChanges . . . . . . . . . . . . . . . 37 7.5. CalendarEventNotification/set . . . . . . . . . . . . . . 38
5.12. Examples . . . . . . . . . . . . . . . . . . . . . . . . 37 7.6. CalendarEventNotification/query . . . . . . . . . . . . . 38
6. Alerts . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 7.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 38
6.1. Push events . . . . . . . . . . . . . . . . . . . . . . . 37 7.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 39
6.2. Acknowledging an alert . . . . . . . . . . . . . . . . . 38 7.7. CalendarEventNotification/queryChanges . . . . . . . . . 39
6.3. Snoozing an alert . . . . . . . . . . . . . . . . . . . . 38 8. Security Considerations . . . . . . . . . . . . . . . . . . . 39
7. Calendar Event Notifications . . . . . . . . . . . . . . . . 39 8.1. Denial-of-service Expanding Recurrences . . . . . . . . . 39
7.1. Auto-deletion of Notifications . . . . . . . . . . . . . 39 8.2. Privacy . . . . . . . . . . . . . . . . . . . . . . . . . 39
7.2. Object Properties . . . . . . . . . . . . . . . . . . . . 39 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 39
7.3. CalendarEventNotification/get . . . . . . . . . . . . . . 40 9.1. JMAP Capability Registration for "calendars" . . . . . . 39
7.4. CalendarEventNotification/changes . . . . . . . . . . . . 40 9.2. JSCalendar Property Registrations . . . . . . . . . . . . 40
7.5. CalendarEventNotification/set . . . . . . . . . . . . . . 40 9.2.1. id . . . . . . . . . . . . . . . . . . . . . . . . . 40
7.6. CalendarEventNotification/query . . . . . . . . . . . . . 41 9.2.2. calendarIds . . . . . . . . . . . . . . . . . . . . . 40
7.6.1. Filtering . . . . . . . . . . . . . . . . . . . . . . 41 9.2.3. isDraft . . . . . . . . . . . . . . . . . . . . . . . 40
7.6.2. Sorting . . . . . . . . . . . . . . . . . . . . . . . 41 9.2.4. utcStart . . . . . . . . . . . . . . . . . . . . . . 40
7.7. CalendarEventNotification/queryChanges . . . . . . . . . 41 9.2.5. utcEnd . . . . . . . . . . . . . . . . . . . . . . . 41
8. Security Considerations . . . . . . . . . . . . . . . . . . . 41 9.2.6. mayInviteSelf . . . . . . . . . . . . . . . . . . . . 41
8.1. Denial-of-service Expanding Recurrences . . . . . . . . . 41 9.2.7. mayInviteOthers . . . . . . . . . . . . . . . . . . . 41
8.2. Privacy . . . . . . . . . . . . . . . . . . . . . . . . . 42 9.2.8. hideAttendees . . . . . . . . . . . . . . . . . . . . 41
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 42 10. Normative References . . . . . . . . . . . . . . . . . . . . 42
9.1. JMAP Capability Registration for "calendars" . . . . . . 42 11. Informative References . . . . . . . . . . . . . . . . . . . 42
9.2. JSCalendar Property Registrations . . . . . . . . . . . . 42 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42
9.2.1. id . . . . . . . . . . . . . . . . . . . . . . . . . 42
9.2.2. calendarId . . . . . . . . . . . . . . . . . . . . . 42
9.2.3. isDraft . . . . . . . . . . . . . . . . . . . . . . . 43
9.2.4. utcStart . . . . . . . . . . . . . . . . . . . . . . 43
9.2.5. utcEnd . . . . . . . . . . . . . . . . . . . . . . . 43
9.2.6. mayInviteSelf . . . . . . . . . . . . . . . . . . . . 43
9.2.7. mayInviteOthers . . . . . . . . . . . . . . . . . . . 43
9.2.8. hideAttendees . . . . . . . . . . . . . . . . . . . . 44
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 44
10.1. Normative References . . . . . . . . . . . . . . . . . . 44
10.2. Informative References . . . . . . . . . . . . . . . . . 45
10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 45
1. Introduction 1. Introduction
JMAP ([RFC8620] - JSON Meta Application Protocol) is a generic JMAP ([RFC8620] - JSON Meta Application Protocol) is a generic
protocol for synchronizing data, such as mail, calendars or contacts, protocol for synchronizing data, such as mail, calendars or contacts,
between a client and a server. It is optimized for mobile and web between a client and a server. It is optimized for mobile and web
environments, and aims to provide a consistent interface to different environments, and aims to provide a consistent interface to different
data types. data types.
This specification defines a data model for synchronizing calendar This specification defines a data model for synchronizing calendar
data between a client and a server using JMAP. The data model is data between a client and a server using JMAP. The data model is
designed to allow a server to provide consistent access to the same designed to allow a server to provide consistent access to the same
data via CalDAV [RFC4791] as well as JMAP, however the functionality data via CalDAV [RFC4791] as well as JMAP, however the functionality
offered over the two protocols may differ. Unlike CalDAV, this offered over the two protocols may differ. Unlike CalDAV, this
specification does not define access to tasks or journal entries specification does not define access to tasks or journal entries
(VTODO or VJOURNAL iCalendar components in CalDAV). (VTODO or VJOURNAL iCalendar components in CalDAV).
1.1. Data Model Overview 1.1. Notational Conventions
A CalendarPrincipal (see Section XXX) represents an individual, team The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
or resource (e.g. a room or projector). The object contains "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
information about the entity being represented, such as a name, "OPTIONAL" in this document are to be interpreted as described in BCP
description and time zone. A CalendarPrincipal has a 1:1 14 [RFC2119] [RFC8174] when, and only when, they appear in all
correspondence with an Account (see [RFC8620], Section 1.6.2) that capitals, as shown here.
supports the "urn:ietf:params:jmap:calendars" capability.
Each such Account contains zero or more Calendar objects, which is a Type signatures, examples, and property descriptions in this document
named collection of CalendarEvents belonging to the follow the conventions established in Section 1.1 of [RFC8620]. Data
CalendarPrincipal. Sharing permissions are managed per calendar. types defined in the core specification are also used in this
For example, an individual may have separate calendars for personal document.
and work activities, with both contributing to their free-busy
availability, but only the work calendar shared in its entirety with 1.2. The LocalDate Data Type
colleagues. Calendars can also provide defaults, such as alerts and
a color to apply to events in the calendar. Clients commonly let Where "LocalDate" is given as a type, it means a string in the same
users toggle visibility of events belonging to a particular calendar format as "Date" (see [RFC8620], Section 1.4), but with the "time-
on/off. offset" omitted from the end. The interpretation in absolute time
depends upon the time zone for the event, which may not be a fixed
offset (for example when daylight saving time occurs). For example,
"2014-10-30T14:12:00".
1.3. Terminology
The same terminology is used in this document as in the core JMAP
specification, see [RFC8620], Section 1.6.
The terms ParticipantIdentity, Calendar, CalendarEvent, and
CalendarEventNotification (with these specific capitalizations) are
used to refer to the data types defined in this document and
instances of those data types.
1.4. Data Model Overview
An Account (see [RFC8620], Section 1.6.2) with support for the
calendar data model contains zero or more Calendar objects, which is
a named collection of CalendarEvents. Calendars can also provide
defaults, such as alerts and a color to apply to events in the
calendar. Clients commonly let users toggle visibility of events
belonging to a particular calendar on/off. Servers may allow an
event to belong to multiple Calendars within an account.
A CalendarEvent is a representation of an event or recurring series A CalendarEvent is a representation of an event or recurring series
of events in JSEvent [I-D.ietf-calext-jscalendar] format. Simple of events in JSEvent [I-D.ietf-calext-jscalendar] format. Simple
clients may ask the server to expand recurrences for them within a clients may ask the server to expand recurrences for them within a
specific time period, and optionally convert times into UTC so they specific time period, and optionally convert times into UTC so they
do not have to handle time zone conversion. More full-featured do not have to handle time zone conversion. More full-featured
clients will want to access the full event information and handle clients will want to access the full event information and handle
recurrence expansion and time zone conversion locally. recurrence expansion and time zone conversion locally.
CalendarEventNotification objects keep track of the history of CalendarEventNotification objects keep track of the history of
changes made to a calendar by other users, allowing calendar clients changes made to a calendar by other users, allowing calendar clients
to notify the user of changes to their schedule. Similarly, the to notify the user of changes to their schedule.
CalendarShareNotification type notifies the user when their access to
another user's calendar is granted or revoked.
1.2. Accounts, Push, and the Session Object The ParticipantIdentity data type represents the identities of the
current user within an Account, which determines which events the
user is a participant of and possibly their permissions related to
that event.
The JMAP Session object (see [RFC8620], Section 2) typically includes In servers with support for JMAP Sharing [RFC XXX], data may be
an object in the "accounts" property for every account that the user shared with other users. Sharing permissions are managed per
has access to. Calendaring systems may share data between a calendar. For example, an individual may have separate calendars for
(potentially very) large number of CalendarPrincipals, most of which personal and work activities, with both contributing to their free-
the user does not care about day-to-day but may occasionally need to busy availability, but only the work calendar shared in its entirety
query when scheduling events. with colleagues. Principals may also represent schedulable entities,
such as a meeting room.
Users can normally subscribe to any calendar to which they have Users can normally subscribe to any calendar to which they have
access (see Section XXX). This indicates the user wants this access. This indicates the user wants this calendar to appear in
calendar to appear in their regular list of calendars. The separate their regular list of calendars. The separate "isVisible" property
"isVisible" property stores whether the user would currently like to stores whether the user would currently like to view the events in a
view the events in a subscribed calendar. subscribed calendar.
The Session object MUST only include Accounts where the user is
subscribed to at least one Calendar or they have access to some other
data type in the account. StateChange events for changes to
CalendarEvent data SHOULD only be sent for events in calendars the
user has subscribed to and MUST NOT be sent for any Account where the
user is not subscribed to at least one calendar.
The server MAY reject the user's attempt to subscribe to some
calendars, e.g. those representing resources.
A user may query the set of CalendarPrincipals they have access to
with "CalendarPrincipal/query" (see Section XXX). The
CalendarPrincipal object may have an "accountId" property that can be
used to then fetch calendars and events associated with that
principal, subject to appropriate permissions.
1.2.1. UIDs and CalendarEvent Ids 1.4.1. UIDs and CalendarEvent Ids
Each CalendarEvent has a "uid" property Each CalendarEvent has a "uid" property
([I-D.ietf-calext-jscalendar], Section 4.1.2), which is a globally ([I-D.ietf-calext-jscalendar], Section 4.1.2), which is a globally
unique identifier that identifies the same event in different unique identifier that identifies the same event in different
Accounts, or different instances of the same recurring event within Accounts, or different instances of the same recurring event within
an Account. an Account.
An Account MUST NOT contain more than one CalendarEvent with the same An Account MUST NOT contain more than one CalendarEvent with the same
uid unless all of the CalendarEvent objects have distinct, non-null uid unless all of the CalendarEvent objects have distinct, non-null
values for their "recurrenceId" property. (This situation occurs if values for their "recurrenceId" property. (This situation occurs if
skipping to change at page 5, line 49 skipping to change at page 6, line 4
([I-D.ietf-calext-jscalendar], Section 4.1.2), which is a globally ([I-D.ietf-calext-jscalendar], Section 4.1.2), which is a globally
unique identifier that identifies the same event in different unique identifier that identifies the same event in different
Accounts, or different instances of the same recurring event within Accounts, or different instances of the same recurring event within
an Account. an Account.
An Account MUST NOT contain more than one CalendarEvent with the same An Account MUST NOT contain more than one CalendarEvent with the same
uid unless all of the CalendarEvent objects have distinct, non-null uid unless all of the CalendarEvent objects have distinct, non-null
values for their "recurrenceId" property. (This situation occurs if values for their "recurrenceId" property. (This situation occurs if
the principal is added to one or more specific instances of a the principal is added to one or more specific instances of a
recurring event without being invited to the whole series.) recurring event without being invited to the whole series.)
Each CalendarEvent also has an id, which is scoped to the JMAP Each CalendarEvent also has an id, which is scoped to the JMAP
Account and used for referencing it in JMAP methods. There is no Account and used for referencing it in JMAP methods. There is no
necessary link between the uid property and the CalendarEvent's id. necessary link between the uid property and the CalendarEvent's id.
CalendarEvents with the same uid in different Accounts MAY have CalendarEvents with the same uid in different Accounts MAY have
different ids. different ids.
1.3. Notational Conventions 1.5. Addition to the Capabilities Object
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
Type signatures, examples, and property descriptions in this document
follow the conventions established in Section 1.1 of [RFC8620]. Data
types defined in the core specification are also used in this
document.
1.4. The LocalDate Data Type
Where "LocalDate" is given as a type, it means a string in the same
format as "Date" (see [RFC8620], Section 1.4), but with the "time-
offset" omitted from the end. The interpretation in absolute time
depends upon the time zone for the event, which may not be a fixed
offset (for example when daylight saving time occurs). For example,
"2014-10-30T14:12:00".
1.5. Terminology
The same terminology is used in this document as in the core JMAP
specification, see [RFC8620], Section 1.6.
The terms CalendarPrincipal, Calendar, CalendarEvent,
CalendarEventNotification, and CalendarShareNotification (with these
specific capitalizations) are used to refer to the data types defined
in this document and instances of those data types.
1.6. Addition to the Capabilities Object
The capabilities object is returned as part of the JMAP Session The capabilities object is returned as part of the JMAP Session
object; see [RFC8620], Section 2. This document defines two object; see [RFC8620], Section 2. This document defines two
additional capability URIs. additional capability URIs.
1.6.1. urn:ietf:params:jmap:calendars 1.5.1. urn:ietf:params:jmap:calendars
This represents support for the Calendar, CalendarEvent, and This represents support for the Calendar, CalendarEvent,
CalendarEventNotification data types and associated API methods. The CalendarEventNotification, and ParticipantIdentity data types and
value of this property in the JMAP Session capabilities property is associated API methods. The value of this property in the JMAP
an empty object. Session capabilities property is an empty object.
The value of this property in an account's accountCapabilities The value of this property in an account's accountCapabilities
property is an object that MUST contain the following information on property is an object that MUST contain the following information on
server capabilities and permissions for that account: server capabilities and permissions for that account:
o *accountIdForCalendarPrincipal*: "String|null" The id of an * *shareesActAs*: "String" This MUST be one of:
account with the "urn:ietf:params:jmap:calendarprincipals"
capability that contains the corresponding CalendarPrincipal
object. This may be the same account id. This is null for
single-user systems that do not support the CalendarPrincipal data
type.
o *minDateTime*: "LocalDate" The earliest date-time the server is - "self" - sharees act as themselves when using calendars in this
account.
- "secretary"- sharees act as the principal to which this account
belongs.
* *maxCalendarsPerEvent*: "UnsignedInt|null" The maximum number of
Calendars (see Section XXX) that can be can assigned to a single
CalendarEvent object (see Section XXX). This MUST be an integer
>= 1, or null for no limit (or rather, the limit is always the
number of Calendars in the account).
* *minDateTime*: "LocalDate" The earliest date-time the server is
willing to accept for any date stored in a CalendarEvent. willing to accept for any date stored in a CalendarEvent.
o *maxDateTime*: "LocalDate" The latest date-time the server is * *maxDateTime*: "LocalDate" The latest date-time the server is
willing to accept for any date stored in a CalendarEvent. willing to accept for any date stored in a CalendarEvent.
o *maxExpandedQueryDuration*: "Duration" The maximum duration the * *maxExpandedQueryDuration*: "Duration" The maximum duration the
user may query over when asking the server to expand recurrences. user may query over when asking the server to expand recurrences.
o *maxParticipantsPerEvent*: "Number|null" The maximum number of * *maxParticipantsPerEvent*: "Number|null" The maximum number of
participants a single event may have, or null for no limit. participants a single event may have, or null for no limit.
o *mayCreateCalendar*: "Boolean" If true, the user may create a * *mayCreateCalendar*: "Boolean" If true, the user may create a
calendar in this account. calendar in this account.
1.6.2. urn:ietf:params:jmap:calendarprincipals 1.5.2. urn:ietf:params:jmap:principals:availability
Represents support for the CalendarPrincipal and Represents support for the Principal/getAvailability method. Any
CalendarShareNotification data types and associated API methods. account with this capability MUST also have the
Single user systems do not need this and MAY choose not to support "urn:ietf:params:jmap:principals" capability (see [RFC XXX]).
it.
The value of this property in the JMAP Session capabilities property The value of this property in the JMAP Session capabilities property
is an empty object. is an empty object.
The value of this property in an account's accountCapabilities The value of this property in an account's accountCapabilities
property is an object that MUST contain the following information on property is an object that MUST contain the following information on
server capabilities and permissions for that account: server capabilities and permissions for that account:
o *currentUserPrincipalId*: "String|null" The id of the principal in * *maxAvailabilityDuration*: The maximum duration over which the
this account that corresponds to the user fetching this object, if
any.
o *maxAvailabilityDuration*: The maximum duration over which the
server is prepared to calculate availability in a single call (see server is prepared to calculate availability in a single call (see
Section XXX). Section XXX).
2. Calendar Principals 2. Principals and Sharing
A CalendarPrincipal represents an individual, group, schedulable
location (e.g. a room), bookable resource (e.g. a projector) or other
entity in the calendar system. In a shared calendar environment such
as a workplace, a user may have access to a large number of
principals.
In most systems the user will have access to a single Account
containing CalendarPrincipal objects, but they may have access to
multiple if, for example, aggregating calendar data from different
places.
A *CalendarPrincipal* object has the following properties:
o *id*: "Id" The id of the principal.
o *name*: "String" The name of the principal, e.g. "Jane Doe", or
"Room 4B".
o *description*: "String|null" A longer description of the
principal, for example details about the facilities of a resource,
or null if no description available.
o *email*: "String|null" An email address for the principal, or null
if no email is available.
o *type*: "String" This MUST be one of the following values:
* "individual": This represents a single person.
* "group": This represents a group of people.
* "resource": This represents some resource, e.g. a projector.
* "location": This represents a location.
* "other": This represents some other undefined principal. For systems that also support JMAP Sharing [RFC XXX], the calendars
capability is used to indicate that this principal may be used with
calendaring. A new method is defined to allow users to query
availability when scehduling events.
o *timeZone*: "String" The time zone for this principal. The value 2.1. Principal Capability urn:ietf:params:jmap:calendars
MUST be a time zone id from the IANA Time Zone Database TZDB [1].
o *mayGetAvailability*: "Boolean" May the user call the A "urn:ietf:params:jmap:calendars" property is added to the Principal
"CalendarPrincipal/getAvailability" method with this "capabilities" object, the value of which is an object with the
CalendarPrincipal? following properties:
o *accountId*: "Id|null" Id of Account with the * *accountId*: "Id|null" Id of Account with the
"urn:ietf:params:jmap:calendars" capability that contains the data "urn:ietf:params:jmap:calendars" capability that contains the
for this principal, or null if none (e.g. the CalendarPrincipal is calendar data for this principal, or null if none (e.g. the
a group just used for permissions management), or the user does Principal is a group just used for permissions management), or the
not have access to any data in the account (with the exception of user does not have access to any data in the account (with the
free/busy, which is governed by the mayGetAvailability property). exception of free/busy, which is governed by the
mayGetAvailability property).
o *account*: "Account|null" The JMAP Account object corresponding to * *account*: "Account|null" The JMAP Account object corresponding to
the accountId, null if none. the accountId, null if none.
o *sendTo*: "String[String]|null" If this principal may be added as * *mayGetAvailability*: "Boolean" May the user call the "Principal/
getAvailability" method with this Principal?
* *sendTo*: "String[String]|null" If this principal may be added as
a participant to an event, this is the map of methods for adding a participant to an event, this is the map of methods for adding
it, in the same format as Participant#sendTo in JSEvent (see it, in the same format as Participant#sendTo in JSEvent (see
[I-D.ietf-calext-jscalendar], Section 4.4.5). [I-D.ietf-calext-jscalendar], Section 4.4.5).
2.1. CalendarPrincipal/get 2.2. Principal/getAvailability
This is a standard "/get" method as described in [RFC8620],
Section 5.1.
2.2. CalendarPrincipal/changes
This is a standard "/changes" method as described in [RFC8620],
Section 5.2.
2.3. CalendarPrincipal/set
This is a standard "/set" method as described in [RFC8620],
Section 5.3. However, the user may only update the "timeZone"
property of the CalendarPrincipal with the same id as the
"currentUserPrincipalId" in the Account capabilities. Any other
change MUST be rejected with a "forbidden" SetError.
Managing calendar principals is likely tied to a directory service or
some other vendor-specific solution, and occurs out-of-band, or via
an additional capability defined elsewhere.
2.4. CalendarPrincipal/query
This is a standard "/query" method as described in [RFC8620],
Section 5.5
2.4.1. Filtering
A *FilterCondition* object has the following properties:
o *accountIds*: "String[]" A list of account ids. The
CalendarPrincipal matches if the value for its accountId property
is in this list.
o *email*: "String" Looks for the text in the email property.
o *name*: "String" Looks for the text in the name property.
o *text* "String" Looks for the text in the name, email, and
description properties.
o *type*: "String" The type must be exactly as given to match the
condition.
o *timeZone*: "String" The timeZone must be exactly as given to
match the condition.
All conditions in the FilterCondition object must match for the
CalendarPrincipal to match.
2.5. CalendarPrincipal/queryChanges
This is a standard "/queryChanges" method as described in [RFC8620],
Section 5.6.
2.6. CalendarPrincipal/getAvailability
Calculates the availability of the principal for scheduling within a This method calculates the availability of the principal for
requested time period. It takes the following arguments: scheduling within a requested time period. It takes the following
arguments:
o *accountId*: "Id" The id of the account to use. * *accountId*: "Id" The id of the account to use.
o *id*: "Id" The id of the CalendarPrincipal to calculate * *id*: "Id" The id of the Principal to calculate availability for.
availability for.
o *utcStart*: "UTCDate" The start time (inclusive) of the period for * *utcStart*: "UTCDate" The start time (inclusive) of the period for
which to return availability. which to return availability.
o *utcEnd*: "UTCDate" The end time (exclusive) of the period for * *utcEnd*: "UTCDate" The end time (exclusive) of the period for
which to return availability. which to return availability.
o *showDetails*: "Boolean" If true, event details will be returned * *showDetails*: "Boolean" If true, event details will be returned
if the user has permission to view them. if the user has permission to view them.
* *eventProperties*: "String[]|null" A list of properties to include
in any JSEvent object returned. If "null", all properties of the
event will be returned. Otherwise, only properties with names in
the given list will be returned.
The server will first find all relevant events, expanding any The server will first find all relevant events, expanding any
recurring events. Relevant events are ones where all of the recurring events. Relevant events are ones where all of the
following is true: following is true:
o The principal is subscribed to the calendar. * The principal is subscribed to the calendar.
o Either the calendar belongs to the principal or the "shareesActAs" * Either the calendar belongs to the principal or the calendar
property of the calendar is "self". account's "shareesActAs" property is "self".
o The "includeInAvailability" property of the calendar for the * The "includeInAvailability" property of the calendar for the
principal is "all" or "attending". principal is "all" or "attending".
o The user has the "mayReadFreeBusy" permission for the calendar. * The user has the "mayReadFreeBusy" permission for the calendar.
o The event finishes after the "utcStart" argument and starts before * The event finishes after the "utcStart" argument and starts before
the "utcEnd" argument. the "utcEnd" argument.
o The event's "privacy" property is not "secret". * The event's "privacy" property is not "secret".
o The "freeBusyStatus" property of the event is "busy" (or omitted, * The "freeBusyStatus" property of the event is "busy" (or omitted,
as this is the default). as this is the default).
o The "status" property of the event is not "cancelled". * The "status" property of the event is not "cancelled".
o If the "includeInAvailability" property of the calendar is * If the "includeInAvailability" property of the calendar is
"attending", then the principal is a participant of the event, and "attending", then the principal is a participant of the event, and
has a "participationStatus" of "accepted" or "tentative". has a "participationStatus" of "accepted" or "tentative".
If an event is in more than one calendar, it is relevant if all of
the above are true for any one calendar that it is in.
The server then generates a BusyPeriod object for each of these The server then generates a BusyPeriod object for each of these
events. A *BusyPeriod* object has the following properties: events. A *BusyPeriod* object has the following properties:
o *utcStart*: "UTCDate" The start time (inclusive) of the period * *utcStart*: "UTCDate" The start time (inclusive) of the period
this represents. this represents.
o *utcEnd*: "UTCDate" The end time (exclusive) of the period this * *utcEnd*: "UTCDate" The end time (exclusive) of the period this
represents. represents.
o *busyStatus*: "String" (optional, default "unavailable") This MUST * *busyStatus*: "String" (optional, default "unavailable") This MUST
be one of be one of
* "confirmed": The event status is "confirmed". - "confirmed": The event status is "confirmed".
* "tentative": The event status is "tentative". - "tentative": The event status is "tentative".
* "unavailable": The principal is not available for scheduling at - "unavailable": The principal is not available for scheduling at
this time for any other reason. this time for any other reason.
o *event*: "JSEvent|null" The JSEvent representation of the event, * *event*: "JSEvent|null" The JSEvent representation of the event,
or null if any of the following are true: or null if any of the following are true:
* The "showDetails" argument is false. - The "showDetails" argument is false.
* The "privacy" property of the event is "private". - The "privacy" property of the event is "private".
* The user does not have the "mayReadItems" permission for the - The user does not have the "mayReadItems" permission for any of
calendar. the calendars the event is in.
If an eventProperties argument was given, any properties in the
JSEvent that are not in the eventProperties list are removed from
the returned representation.
The server MAY also generate BusyPeriod objects based on other The server MAY also generate BusyPeriod objects based on other
information it has about the principal's availability, such as office information it has about the principal's availability, such as office
hours. hours.
Finally, the server MUST merge and split BusyPeriod objects where the Finally, the server MUST merge and split BusyPeriod objects where the
"event" property is null, such that none of them overlap and either "event" property is null, such that none of them overlap and either
there is a gap in time between any two objects (the utcEnd of one there is a gap in time between any two objects (the utcEnd of one
does not equal the utcStart of another) or those objects have a does not equal the utcStart of another) or those objects have a
different busyStatus property. If there are overlapping BusyPeriod different busyStatus property. If there are overlapping BusyPeriod
time ranges with different "busyStatus" properties the server MUST time ranges with different "busyStatus" properties the server MUST
choose the value in the following order: confirmed > unavailable > choose the value in the following order: confirmed > unavailable >
tentative. tentative.
The response has the following argument: The response has the following argument:
o *list*: "BusyPeriod[]" The list of BusyPeriod objects calculated * *list*: "BusyPeriod[]" The list of BusyPeriod objects calculated
as described above. as described above.
The following additional errors may be returned instead of the The following additional errors may be returned instead of the
"CalendarPrincipal/getAvailability" response: "Principal/getAvailability" response:
"notFound": No principal with this id exists, or the user does not "notFound": No principal with this id exists, or the user does not
have permission to see that this principal exists. have permission to see that this principal exists.
"forbidden": The user does not have permission to query this "forbidden": The user does not have permission to query this
principal's availability. principal's availability.
"tooLarge": The duration between utcStart an utcEnd is longer than "tooLarge": The duration between utcStart an utcEnd is longer than
the server is willing to calculate availability for. the server is willing to calculate availability for.
"rateLimit": Too many availability requests have been made recently "rateLimit": Too many availability requests have been made recently
and the user is being rate limited. It may work to try again later. and the user is being rate limited. It may work to try again later.
3. Calendars 3. Participant Identities
A ParticipantIdentity stores information about a URI that represents
the user within that account in an event's participants. It has the
following properties:
* *id*: "Id" (immutable; server-set) The id of the
ParticipantIdentity.
* *name*: "String" (default: "") The display name of the participant
to use when adding this participant to an event, e.g. "Joe
Bloggs".
* *sendTo*: "String[String]" Represents methods by which the
participant may receive invitations and updates to an event.
The keys in the property value are the available methods and MUST
only contain ASCII alphanumeric characters (A-Za-z0-9). The value
is a URI for the method specified in the key.
A participant in an event corresponds to a ParticipantIdentity if any
of the method/uri pairs in the sendTo property of the participant are
identical to a method/uri pair in the sendTo property of the
identity.
The following JMAP methods are supported.
3.1. ParticipantIdentity/get
This is a standard "/get" method as described in [RFC8620],
Section 5.1. The _ids_ argument may be "null" to fetch all at once.
3.2. ParticipantIdentity/changes
This is a standard "/changes" method as described in [RFC8620],
Section 5.2.
3.3. ParticipantIdentity/set
This is a standard "/set" method as described in [RFC8620],
Section 5.3. The server MAY restrict the uri values the user may
claim, for example only allowing "mailto:" URIs with email addresses
that belong to the user. A standard "forbidden" error is returned to
reject non-permissible changes.
4. Calendars
A Calendar is a named collection of events. All events are A Calendar is a named collection of events. All events are
associated with one, and only one, calendar. associated with one, and only one, calendar.
A *Calendar* object has the following properties: A *Calendar* object has the following properties:
o *id*: "Id" (immutable; server-set) The id of the calendar. * *id*: "Id" (immutable; server-set) The id of the calendar.
o *role*: "String|null" (default: null) Denotes the calendar has a * *role*: "String|null" (default: null) Denotes the calendar has a
special purpose. This MUST be one of the following: special purpose. This MUST be one of the following:
* "inbox": This is the principal's default calendar; when the - "inbox": This is the principal's default calendar; when the
principal is invited to an event, this is the calendar to which principal is invited to an event, this is the calendar to which
it will be added by the server. There MUST NOT be more than it will be added by the server. There MUST NOT be more than
one calendar with this role in an account. one calendar with this role in an account.
* "templates": This calendar holds templates for creating new - "templates": This calendar holds templates for creating new
events. All events in this calendar MUST have the "isDraft" events. All events in this calendar MUST have the "isDraft"
property set to true. Clients should not show this as a property set to true. Clients should not show this as a
regular calendar to users, but may offer users to create new regular calendar to users, but may offer users to create new
events by copying one of the events in here. events by copying one of the events in here.
o *name*: "String" The user-visible name of the calendar. This may * *name*: "String" The user-visible name of the calendar. This may
be any UTF-8 string of at least 1 character in length and maximum be any UTF-8 string of at least 1 character in length and maximum
255 octets in size. 255 octets in size.
o *description*: "String|null" (default: null) An optional longer- * *description*: "String|null" (default: null) An optional longer-
form description of the calendar, to provide context in shared form description of the calendar, to provide context in shared
environments where users need more than just the name. environments where users need more than just the name.
o *color*: "String|null" (default: null) The color to be used when * *color*: "String|null" (default: null) A color to be used when
displaying events associated with the calendar. displaying events associated with the calendar.
If not null, the value MUST be a case-insensitive color name taken If not null, the value MUST be a case-insensitive color name taken
from the set of names defined in Section 4.3 of CSS Color Module from the set of names defined in Section 4.3 of CSS Color Module
Level 3 COLORS [2], or an RGB value in hexadecimal notation, as Level 3 COLORS (https://www.w3.org/TR/css-color-3/), or an RGB value
defined in Section 4.2.1 of CSS Color Module Level 3. in hexadecimal notation, as defined in Section 4.2.1 of CSS Color
Module Level 3.
The color SHOULD have sufficient contrast to be used as text on a white background. The color SHOULD have sufficient contrast to be used as text on a white background.
o *sortOrder*: "UnsignedInt" (default: 0) Defines the sort order of * *sortOrder*: "UnsignedInt" (default: 0) Defines the sort order of
calendars when presented in the client's UI, so it is consistent calendars when presented in the client's UI, so it is consistent
between devices. The number MUST be an integer in the range 0 <= between devices. The number MUST be an integer in the range 0 <=
sortOrder < 2^31. A calendar with a lower order should be sortOrder < 2^(31.)
displayed before a calendar with a higher order in any list of
calendars in the client's UI. Calendars with equal order SHOULD
be sorted in alphabetical order by name. The sorting should take
into account locale-specific character order convention.
o *isSubscribed*: "Boolean" Has the user indicated they wish to see A calendar with a lower order should be displayed before a
calendar with a higher order in any list of calendars in the
client's UI. Calendars with equal order SHOULD be sorted in
alphabetical order by name. The sorting should take into account
locale-specific character order convention.
* *isSubscribed*: "Boolean" Has the user indicated they wish to see
this Calendar in their client? This SHOULD default to false for this Calendar in their client? This SHOULD default to false for
Calendars in shared accounts the user has access to and true for Calendars in shared accounts the user has access to and true for
any new Calendars created by the user themself. If false, the any new Calendars created by the user themself.
calendar should only be displayed when the user explicitly
requests it or to offer it for the user to subscribe to.
o *isVisible*: "Boolean" (default: true) Should the calendar's If false, the calendar should only be displayed when the user
explicitly requests it or to offer it for the user to subscribe
to.
* *isVisible*: "Boolean" (default: true) Should the calendar's
events be displayed to the user at the moment? Clients MUST events be displayed to the user at the moment? Clients MUST
ignore this property if isSubscribed is false. ignore this property if isSubscribed is false. If an event is in
multiple calendars, it should be displayed if isVisible is true
for any of those calendars.
o *includeInAvailability*: "String" (default: all) Should the * *includeInAvailability*: "String" (default: all) Should the
calendar's events be used as part of availability calculation? calendar's events be used as part of availability calculation?
This MUST be one of: This MUST be one of:
* "all": all events are considered. - "all": all events are considered.
* "attending": events the user is a confirmed or tentative - "attending": events the user is a confirmed or tentative
participant of are considered. participant of are considered.
* "none": all events are ignored. - "none": all events are ignored (but may be considered if also
in another calendar).
o *defaultAlertsWithTime*: "Alert[]|null" (default: null) The alerts * *defaultAlertsWithTime*: "Id[Alert]|null" (default: null) A map of
to apply for events where showWithoutTime is false that have alert ids to Alert objects (see [I-D.ietf-calext-jscalendar],
"useDefaultAlerts" set. See [I-D.ietf-calext-jscalendar], Section 4.5.2) to apply for events where "showWithoutTime" is
Section 4.5.2 for the definition of an Alert object. false and "useDefaultAlerts" is true. Ids MUST be unique across
all default alerts in the account, including those in other
calendars; a UUID is recommended.
o *defaultAlertsWithoutTime*: "Alert[]|null" (default: null) The * *defaultAlertsWithoutTime*: "Id[Alert]|null" (default: null) A map
alerts to apply for events where showWithoutTime is true that have of alert ids to Alert objects (see [I-D.ietf-calext-jscalendar],
"useDefaultAlerts" set. See [I-D.ietf-calext-jscalendar], Section 4.5.2) to apply for events where "showWithoutTime" is true
Section 4.5.2 for the definition of an Alert object. and "useDefaultAlerts" is true. Ids MUST be unique across all
default alerts in the account, including those in other calendars;
a UUID is recommended.
o *timeZone*: "String|null" (default: null) The time zone to use for * *timeZone*: "String|null" (default: null) The time zone to use for
events without a time zone when the server needs to resolve them events without a time zone when the server needs to resolve them
into absolute time, e.g., for reminders, queries, or availability into absolute time, e.g., for alerts or availability calculation.
calculation. The value MUST be a time zone id from the IANA Time The value MUST be a time zone id from the IANA Time Zone Database
Zone Database TZDB [3]. If "null", the timeZone of the account's TZDB (https://www.iana.org/time-zones). If "null", the timeZone
associated CalendarPrincipal will be used. Clients SHOULD use of the account's associated Principal will be used. Clients
this as the default for new events in this calendar if set. SHOULD use this as the default for new events in this calendar if
set.
o *participantIdentities*: "ParticipantIdentity[]|null" (server-set)
The identities that represent the user in this calendar. The
first item in the array is the default. A *ParticipantIdentity*
object has the following properties:
* *name*: "String" The display name of the participant to use
when adding this participant to an event, e.g. "Joe Bloggs".
* *type*: "String" The method for sending scheduling messages to
this identity, e.g. "imip"
* *uri*: "String" The URI for sending scheduling messages to this
identity, e.g. "mailto:foo@example.com"
The user is an *owner* for an event if the CalendarEvent object
has a "participants" property, and one of the Participant objects
has both: a) The "owner" role. b) A "sendTo" property that has
"type" and "uri" equal to one of the ParticipantIdentity objects
returned with the calendar.
o *shareWith*: "Id[CalendarRights]|null" (default: null) A map of
CalendarPrincipal id to rights for principals this calendar is
shared with. The pricincipal to which this calendar belongs MUST
NOT be in this set. This is null if the user requesting the
object does not have the mayAdmin right, or if the calendar is not
shared with anyone. May be modified only if the user has the
mayAdmin right.
o *shareesActAs*: "String" (immutable; default server-dependent) * *shareWith*: "Id[CalendarRights]|null" (default: null) A map of
This MUST be one of: Principal id to rights for principals this calendar is shared
with. The principal to which this calendar belongs MUST NOT be in
this set. This is null if the user requesting the object does not
have the mayAdmin right, or if the calendar is not shared with
anyone. May be modified only if the user has the mayAdmin right.
The account id for the principals may be found in the
"urn:ietf:params:jmap:principals:owner" capability of the Account
to which the calendar belongs.
* "secretary" * *myRights*: "CalendarRights" (server-set) The set of access rights
the user has in relation to this Calendar. If any event is in
multiple calendars, the user has the following rights:
* "self" - The user may fetch the event if they have the mayReadItems
right on any calendar the event is in.
If "self", sharees act as themselves when using this calendar. If - The user may remove an event from a calendar (by modifying the
"secretary", they act as the pricincipal to which this calendar event's "calendarIds" property) if the user has the appropriate
belongs (secretary mode). If omitted, the default is server permission for that calendar.
dependent. For example, it may be "self" if creating a calendar
in a CalendarPrincipal representing a group, and "secretary" if
creating a calendar for an individual. Users may attempt to set
this on creation, but the server may reject with an
"invalidProperties" error if the value is not permissible.
o *myRights*: "CalendarRights" (server-set) The set of access rights - The user may make other changes to the event if they have the
the user has in relation to this Calendar. right to do so in _all_ calendars to which the event belongs.
A *CalendarRights* object has the following properties: A *CalendarRights* object has the following properties:
o *mayReadFreeBusy*: "Boolean" The user may read the free-busy * *mayReadFreeBusy*: "Boolean" The user may read the free-busy
information for this calendar as part of a call to information for this calendar as part of a call to Principal/
CalendarPrincipal/getAvailability (see Section XXX). getAvailability (see Section XXX).
o *mayReadItems*: "Boolean" The user may fetch the events in this * *mayReadItems*: "Boolean" The user may fetch the events in this
calendar. calendar.
o *mayAddItems*: "Boolean" The user may create new events on this * *mayAddItems*: "Boolean" The user may create new events on this
calendar or move events to this calendar. For recurring events, calendar or move events to this calendar. For recurring events,
they may add an override to add an occurrence, or remove an they may add an override to add an occurrence, or remove an
existing override that is excluding an occurrence. existing override that is excluding an occurrence.
o *mayUpdatePrivate*: "Boolean" The user may modify the following * *mayUpdatePrivate*: "Boolean" The user may modify the following
properties on all events in the calendar. If shareesActAs is properties on all events in the calendar. If the shareesActAs
"self", these properties MUST all be stored per-user, and changes account capability is "self", these properties MUST all be stored
do not affect any other user of the calendar. If shareesActAs is per-user, and changes do not affect any other user of the
"secretary", the values are shared between all users. calendar. If shareesActAs is "secretary", the values are shared
between all users.
* keywords - keywords
* color
* freeBusyStatus - color
* useDefaultAlerts - freeBusyStatus
* alerts - useDefaultAlerts
- alerts
The user may also modify the above on a per-occurrence basis for The user may also modify the above on a per-occurrence basis for
recurring events. recurring events.
o *mayRSVP*: "Boolean" The user may modify the * *mayRSVP*: "Boolean" The user may modify the
"participationStatus", "participationComment", "expectReply", "participationStatus", "participationComment", "expectReply",
"scheduleAgent", "scheduleSequence", and "scheduleUpdated" "scheduleAgent", "scheduleSequence", and "scheduleUpdated"
properties of any Participant object where the sendTo property properties of any Participant object that corresponds to one of
matches a ParticipantIdentity of the calendar. If the event has the user's ParticipantIdentity objects in the account.
its "mayInviteSelf" property set to true (see Section XXX), then
the user may also add a new Participant to the event with a sendTo If the event has its "mayInviteSelf" property set to true (see
property that matches a ParticipantIdentity of the calendar. The Section XXX), then the user may also add a new Participant to the
roles property of the participant MUST only contain "attendee". event with a sendTo property that is the same as the sendTo
property of one of the user's ParticipantIdentity objects in the
account. The roles property of the participant MUST only contain
"attendee".
If the event has its "mayInviteOthers" property set to true (see If the event has its "mayInviteOthers" property set to true (see
Section XXX) and there is an existing Participant in the event Section XXX) and there is an existing Participant in the event
where the sendTo property matches a ParticipantIdentity of the corresponding to one of the user's ParticipantIdentity objects in
calendar, then the user may also add new participants. The roles the account, then the user may also add new participants. The
property of any new participant MUST only contain "attendee". The roles property of any new participant MUST only contain
user may also do all of the above on a per-occurrence basis for "attendee".
recurring events.
o *mayUpdateOwn*: "Boolean" The user may modify an existing event on The user may also do all of the above on a per-occurrence basis
for recurring events.
* *mayUpdateOwn*: "Boolean" The user may modify an existing event on
this calendar if either they are the owner of the event or the this calendar if either they are the owner of the event or the
event has no owner. event has no owner.
o *mayUpdateAll*: "Boolean" The user may modify all existing events * *mayUpdateAll*: "Boolean" The user may modify all existing events
on this calendar. on this calendar.
o *mayRemoveOwn*: "Boolean" The user may delete an event or move it * *mayRemoveOwn*: "Boolean" The user may delete an event or remove
to a different calendar if either they are the owner of the event it from this calendar if either they are the owner of the event or
or the event has no owner. For recurring events, they may add an the event has no owner. For recurring events, they may add an
override to remove an occurrence. override to remove an occurrence.
o *mayRemoveAll*: "Boolean" The user may delete any event or move it * *mayRemoveAll*: "Boolean" The user may delete any event or remove
to a different calendar. For recurring events, they may add an it from this calendar. For recurring events, they may add an
override to remove an occurrence. override to remove an occurrence.
o *mayAdmin*: "Boolean" The user may modify sharing for this * *mayAdmin*: "Boolean" The user may modify sharing for this
calendar. calendar.
o *mayDelete*: "Boolean" (server-set) The user may delete the * *mayDelete*: "Boolean" (server-set) The user may delete the
calendar itself. This property MUST be false if the account to calendar itself. This property MUST be false if the account to
which this calendar belongs has the _isReadOnly_ property set to which this calendar belongs has the _isReadOnly_ property set to
true. true.
3.1. Calendar/get The user is an *owner* for an event if the CalendarEvent object has a
"participants" property, and one of the Participant objects both:
a) Has the "owner" role.
b) Corresponds to one of the user's ParticipantIdentity objects in the account.
An event has no owner if its participants property is null or
omitted.
4.1. Calendar/get
This is a standard "/get" method as described in [RFC8620], This is a standard "/get" method as described in [RFC8620],
Section 5.1. The _ids_ argument may be "null" to fetch all at once. Section 5.1. The _ids_ argument may be "null" to fetch all at once.
If mayReadFreeBusy is the only permission the user has, the calendar If mayReadFreeBusy is the only permission the user has, the calendar
MUST NOT be returned in Calendar/get and Calendar/query; it must MUST NOT be returned in Calendar/get and Calendar/query; it must
behave as though it did not exist. The data is just used as part of behave as though it did not exist. The data is just used as part of
CalendarPrincipal/getAvailability. Principal/getAvailability.
3.2. Calendar/changes 4.2. Calendar/changes
This is a standard "/changes" method as described in [RFC8620], This is a standard "/changes" method as described in [RFC8620],
Section 5.2. Section 5.2.
3.3. Calendar/set 4.3. Calendar/set
This is a standard "/set" method as described in [RFC8620], This is a standard "/set" method as described in [RFC8620],
Section 5.3 but with the following additional request argument: Section 5.3 but with the following additional request argument:
o *onDestroyRemoveEvents*: "Boolean" (default: false) * *onDestroyRemoveEvents*: "Boolean" (default: false)
If false, any attempt to destroy a Calendar that still has If false, any attempt to destroy a Calendar that still has
CalendarEvents in it will be rejected with a "calendarHasEvent" CalendarEvents in it will be rejected with a "calendarHasEvent"
SetError. If true, any CalendarEvents that were in the Calendar will SetError. If true, any CalendarEvents that were in the Calendar will
be destroyed. This SHOULD NOT send scheduling messages to be removed from it, and if in no other Calendars they will be
participants or create CalendarEventNotification objects. destroyed. This SHOULD NOT send scheduling messages to participants
or create CalendarEventNotification objects.
The "role" and "shareWith" properties may only be set by users that The "role" and "shareWith" properties may only be set by users that
have the mayAdmin right. The value is shared across all users, have the mayAdmin right. The value is shared across all users,
although users without the mayAdmin right cannot see the value. although users without the mayAdmin right cannot see the value.
When modifying the shareWith property, the user cannot give a right
to a principal if the principal did not already have that right and
the user making the change also does not have that right. Any
attempt to do so must be rejected with a "forbidden" SetError.
Users can subscribe or unsubscribe to a calendar by setting the Users can subscribe or unsubscribe to a calendar by setting the
"isSubscribed" property. The server MAY forbid users from "isSubscribed" property. The server MAY forbid users from
subscribing to certain calendars even though they have permission to subscribing to certain calendars even though they have permission to
see them, rejecting the update with a "forbidden" SetError. see them, rejecting the update with a "forbidden" SetError.
The "timeZone", "includeInAvailability", "defaultAlertsWithoutTime" The "timeZone", "includeInAvailability", "defaultAlertsWithoutTime"
and "defaultAlertsWithTime" properties are stored per-user if the and "defaultAlertsWithTime" properties are stored per-user if the
calendar "shareesActAs" value is "self", and may be set by any user calendar account's "shareesActAs" capability is "self", and may be
who is subscribed to the calendar. Otherwise, these properties are set by any user who is subscribed to the calendar. Otherwise, these
shared, and may only be set by users that have the mayAdmin right. properties are shared, and may only be set by users that have the
mayAdmin right.
The following properties may be set by anyone who is subscribed to The following properties may be set by anyone who is subscribed to
the calendar and are all stored per-user: the calendar and are all stored per-user:
o name * name
o color * color
o sortOrder * sortOrder
o isVisible * isVisible
These properties are initially inherited from the owner's copy of the These properties are initially inherited from the owner's copy of the
calendar, but if set by a sharee that user gets their own copy of the calendar, but if set by a sharee that user gets their own copy of the
property; it does not change for any other principals. If the value property; it does not change for any other principals. If the value
of the property in the owner's calendar changes after this, it does of the property in the owner's calendar changes after this, it does
not overwrite the sharee's value. not overwrite the sharee's value.
The following extra SetError types are defined: The following extra SetError types are defined:
For "destroy": For "destroy":
o *calendarHasEvent*: The Calendar has at least one CalendarEvent * *calendarHasEvent*: The Calendar has at least one CalendarEvent
assigned to it, and the "onDestroyRemoveEvents" argument was assigned to it, and the "onDestroyRemoveEvents" argument was
false. false.
4. Calendar Share Notifications
The CalendarShareNotification data type records when the user's
permissions to access a shared calendar changes.
CalendarShareNotification are only created by the server; users
cannot create them explicitly. Notifications are stored in the same
Account as the CalendarPrincipals.
Clients SHOULD present the list of notifications to the user and
allow them to dismiss them. To dismiss a notification you use a
standard "/set" call to destroy it.
The server SHOULD create a CalendarShareNotification whenever the
user's permissions change on a calendar. It SHOULD NOT create a
notification for permission changes to a group principal, even if the
user is in the group.
4.1. Auto-deletion of Notifications
The server MAY limit the maximum number of notifications it will
store for a user. When the limit is reached, any new notification
will cause the previously oldest notification to be automatically
deleted.
The server MAY coalesce events if appropriate, or remove events that
it deems are no longer relevant or after a certain period of time.
The server SHOULD automatically destroy a notification about a
calendar if the user subscribes to that calendar.
4.2. Object Properties
The *CalendarShareNotification* object has the following properties:
o *id*: "String" The id of the CalendarShareNotification.
o *created*: "UTCDate" The time this notification was created.
o *changedBy*: "Person" Who made the change.
* *name*: "String" The name of the person who made the change.
* *email*: "String|null" The email of the person who made the
change, or null if no email is available.
* *calendarPrincipalId*: "String|null" The id of the
CalendarPrincipal corresponding to the person who made the
change, or null if no associated princiapal.
o *calendarAccountId*: "String" The id of the account where this
Calendar exists.
o *calendarId*: "String" The id of the Calendar that this
notification is about.
o *calendarName*: "String" The name of the Calendar at the time the
notification was made.
o *oldRights*: "CalendarRights|null" The rights the user had before
the change.
o *newRights*: "CalendarRights|null" The rights the user has after
the change.
4.3. CalendarShareNotification/get
This is a standard "/get" method as described in [RFC8620],
Section 5.1.
4.4. CalendarShareNotification/changes
This is a standard "/changes" method as described in [RFC8620],
Section 5.2.
4.5. CalendarShareNotification/set
This is a standard "/set" method as described in [RFC8620],
Section 5.3.
Only destroy is supported; any attempt to create/update MUST be
rejected with a "forbidden" SetError.
4.6. CalendarShareNotification/query
This is a standard "/query" method as described in [RFC8620],
Section 5.5.
4.6.1. Filtering
A *FilterCondition* object has the following properties:
o *after*: "UTCDate|null" The creation date must be on or after this
date to match the condition.
o *before*: "UTCDate|null" The creation date must be before this
date to match the condition.
4.6.2. Sorting
The "created" property MUST be supported for sorting.
4.7. CalendarShareNotification/queryChanges
This is a standard "/queryChanges" method as described in [RFC8620],
Section 5.6.
5. Calendar Events 5. Calendar Events
A *CalendarEvent* object contains information about an event, or A *CalendarEvent* object contains information about an event, or
recurring series of events, that takes place at a particular time. recurring series of events, that takes place at a particular time.
It is a JSEvent object, as defined in [I-D.ietf-calext-jscalendar], It is a JSEvent object, as defined in [I-D.ietf-calext-jscalendar],
with the following additional properties: with the following additional properties:
o *id*: "Id" The id of the CalendarEvent. This property is * *id*: "Id" The id of the CalendarEvent. This property is
immutable. The id uniquely identifies a JSEvent with a particular immutable. The id uniquely identifies a JSEvent with a particular
"uid" and "recurrenceId" within a particular account. "uid" and "recurrenceId" within a particular account.
o *calendarId*: "Id" The id of the Calendar this event belongs to. * *calendarIds*: "Id[Boolean]" The set of Calendar ids this event
belongs to. An event MUST belong to one or more Calendars at all
times (until it is destroyed). The set is represented as an
object, with each key being a _Calendar id_. The value for each
key in the object MUST be "true".
o *isDraft*: "Boolean" If true, this event is to be considered a * *isDraft*: "Boolean" If true, this event is to be considered a
draft. The server will not send any scheduling messages to draft. The server will not send any scheduling messages to
participants or send push notifications for alerts. This may only participants or send push notifications for alerts. This may only
be set to true upon creation. Once set to false, the value cannot be set to true upon creation. Once set to false, the value cannot
be updated to true. This property MUST NOT appear in be updated to true. This property MUST NOT appear in
"recurrenceOverrides". "recurrenceOverrides".
o *utcStart*: "UTCDate" For simple clients that do not or cannot * *utcStart*: "UTCDate" For simple clients that do not or cannot
implement time zone support. Clients should only use this if also implement time zone support. Clients should only use this if also
asking the server to expand recurrences, as you cannot accurately asking the server to expand recurrences, as you cannot accurately
expand a recurrence without the original time zone. This property expand a recurrence without the original time zone.
is calculated at fetch time by the server. Time zones are
political and they can and do change at any time. Fetching
exactly the same property again may return a different results if
the time zone data has been updated on the server. Time zone data
changes are not considered "updates" to the event. If set, server
will convert to the event's current time zone using its current
time zone data and store the local time. This is not included by
default and must be requested explicitly. Floating events will be
interpreted as per calendar's time zone property; or if not set,
the the principal's time zone property. Note that it is not
possible to accurately calculate the expansion of recurrence rules
or recurrence overrides with the utcStart property rather than the
local start time. Even simple recurrences such as "repeat weekly"
may cross a daylight-savings boundary and end up at a different
UTC time. Clients that wish to use "utcStart" are RECOMMENDED to
request the server expand recurrences (see Section XXX).
o *utcEnd*: "UTCDate" The server calculates the end time in UTC from This property is calculated at fetch time by the server. Time
zones are political and they can and do change at any time.
Fetching exactly the same property again may return a different
results if the time zone data has been updated on the server.
Time zone data changes are not considered "updates" to the event.
If set, server will convert to the event's current time zone using
its current time zone data and store the local time.
This is not included by default and must be requested explicitly.
Floating events (events without a time zone) will be interpreted
as per the time zone given as a CalendarEvent/get argument.
Note that it is not possible to accurately calculate the expansion
of recurrence rules or recurrence overrides with the utcStart
property rather than the local start time. Even simple
recurrences such as "repeat weekly" may cross a daylight-savings
boundary and end up at a different UTC time. Clients that wish to
use "utcStart" are RECOMMENDED to request the server expand
recurrences (see Section XXX).
* *utcEnd*: "UTCDate" The server calculates the end time in UTC from
the start/timeZone/duration properties of the event. This is not the start/timeZone/duration properties of the event. This is not
included by default and must be requested explicitly. Like included by default and must be requested explicitly. Like
utcStart, this is calculated at fetch time if requested and may utcStart, this is calculated at fetch time if requested and may
change due to time zone data changes. change due to time zone data changes. Floating events will be
interpreted as per the time zone given as a CalendarEvent/get
argument.
CalendarEvent objects MUST NOT have a "method" property as this is CalendarEvent objects MUST NOT have a "method" property as this is
only used when representing iTIP [RFC5546] scheduling messages, not only used when representing iTIP [RFC5546] scheduling messages, not
events in a data store. events in a data store.
5.1. Additional JSCalendar properties 5.1. Additional JSCalendar properties
This document defines three new JSCalendar properties. This document defines three new JSCalendar properties.
5.1.1. mayInviteSelf 5.1.1. mayInviteSelf
skipping to change at page 22, line 47 skipping to change at page 19, line 51
clients may set a "blobId" property instead to reference a blob of clients may set a "blobId" property instead to reference a blob of
binary data in the account, as per [RFC8620] Section 6. binary data in the account, as per [RFC8620] Section 6.
The server MUST translate this to an embedded "data:" URL [RFC2397] The server MUST translate this to an embedded "data:" URL [RFC2397]
when sending the event to a system that cannot access the blob. when sending the event to a system that cannot access the blob.
Servers that support CalDAV access to the same data are recommended Servers that support CalDAV access to the same data are recommended
to expose these files as managed attachments [?@RFC8607]. to expose these files as managed attachments [?@RFC8607].
5.3. Per-user properties 5.3. Per-user properties
In shared calendars where "shareesActAs" is "self", the following In shared calendars where the account's "shareesActAs" capability is
properties MUST be stored per-user: "self", the following properties MUST be stored per-user:
o keywords * keywords
o color * color
o freeBusyStatus
o useDefaultAlerts * freeBusyStatus
o alerts * useDefaultAlerts
* alerts
The user may also modify these properties on a per-occurrence basis The user may also modify these properties on a per-occurrence basis
for recurring events; again, these MUST be stored per-user. for recurring events; again, these MUST be stored per-user.
When writing only per-user properties, the "updated" property MUST When writing only per-user properties, the "updated" property MUST
also be stored just for that user. When fetching the "updated" also be stored just for that user. When fetching the "updated"
property, the value to return is whichever is later of the per-user property, the value to return is whichever is later of the per-user
updated time or the updated time of the master event. updated time or the updated time of the master event.
5.4. Recurring events 5.4. Recurring events
skipping to change at page 24, line 37 skipping to change at page 21, line 37
Clients may choose to skip creating the overrides if the old data is Clients may choose to skip creating the overrides if the old data is
not important, for example if the "alerts" property is being updated, not important, for example if the "alerts" property is being updated,
it is probably not important to create overrides for events in the it is probably not important to create overrides for events in the
past with the alerts that have already fired. past with the alerts that have already fired.
5.6. CalendarEvent/get 5.6. CalendarEvent/get
This is a standard "/get" method as described in [RFC8620], This is a standard "/get" method as described in [RFC8620],
Section 5.1, with three extra arguments: Section 5.1, with three extra arguments:
o *recurrenceOverridesBefore*: "UTCDate|null" If given, only * *recurrenceOverridesBefore*: "UTCDate|null" If given, only
recurrence overrides with a recurrence id before this date (when recurrence overrides with a recurrence id before this date (when
translated into UTC) will be returned. translated into UTC) will be returned.
o *recurrenceOverridesAfter*: "UTCDate|null" If given, only * *recurrenceOverridesAfter*: "UTCDate|null" If given, only
recurrence overrides with a recurrence id on or after this date recurrence overrides with a recurrence id on or after this date
(when translated into UTC) will be returned. (when translated into UTC) will be returned.
o *reduceParticipants*: "Boolean" (default: false) If true, only * *reduceParticipants*: "Boolean" (default: false) If true, only
participants with the "owner" role or corresponding to the user's participants with the "owner" role or corresponding to the user's
participant identities will be returned in the "participants" participant identities will be returned in the "participants"
property of the master event and any recurrence overrides. If property of the master event and any recurrence overrides. If
false, all participants will be returned. false, all participants will be returned.
* *timeZone*: "String" (default "Etc/UTC") The time zone to use when
calculating the utcStart/utcEnd property of floating events. This
argument has no effect if those properties are not requested.
A CalendarEvent object is a JSEvent object so may have arbitrary A CalendarEvent object is a JSEvent object so may have arbitrary
properties. If the client makes a "CalendarEvent/get" call with a properties. If the client makes a "CalendarEvent/get" call with a
null or omitted "properties" argument, all properties defined on the null or omitted "properties" argument, all properties defined on the
JSEvent object in the store are returned, along with the "id", JSEvent object in the store are returned, along with the "id",
"calendarId", and "isDraft" properties. The "utcStart" and "utcEnd" "calendarIds", and "isDraft" properties. The "utcStart" and "utcEnd"
computed properties are only returned if explicitly requested. If computed properties are only returned if explicitly requested. If
either are requested, the "recurrenceOverrides" property MUST NOT be either are requested, the "recurrenceOverrides" property MUST NOT be
requested (recurrence overrides cannot be interpreted accurately with requested (recurrence overrides cannot be interpreted accurately with
just the UTC times). just the UTC times).
If specific properties are requested from the JSEvent and the If specific properties are requested from the JSEvent and the
property is not present on the object in the server's store, the property is not present on the object in the server's store, the
server SHOULD return the default value if known for that property. server SHOULD return the default value if known for that property.
A requested id may represent a single instance of a recurring event A requested id may represent a single instance of a recurring event
skipping to change at page 26, line 10 skipping to change at page 23, line 15
5.7. CalendarEvent/changes 5.7. CalendarEvent/changes
This is a standard "/changes" method as described in [RFC8620], This is a standard "/changes" method as described in [RFC8620],
Section 5.2. Section 5.2.
5.8. CalendarEvent/set 5.8. CalendarEvent/set
This is a standard "/set" method as described in [RFC8620], This is a standard "/set" method as described in [RFC8620],
Section 5.3, with the following extra argument: Section 5.3, with the following extra argument:
o *sendSchedulingMessages*: "Boolean" (default: false) If true then * *sendSchedulingMessages*: "Boolean" (default: false) If true then
any changes to scheduled events will be sent to all the any changes to scheduled events will be sent to all the
participants (if the user is an owner of the event) or back to the participants (if the user is an owner of the event) or back to the
owners (otherwise). If false, the changes only affect this owners (otherwise). If false, the changes only affect this
calendar and no scheduling messages will be sent. account and no scheduling messages will be sent.
For recurring events, an id may represent the master event or a For recurring events, an id may represent the master event or a
specific instance. When the id for a specific instance is given, the specific instance. When the id for a specific instance is given, the
server MUST process an update as an update to the recurrence override server MUST process an update as an update to the recurrence override
for that instance on the master event, and a destroy as removing just for that instance on the master event, and a destroy as removing just
that instance. that instance.
Clients MUST NOT send an update/destroy to both the master event and Clients MUST NOT send an update/destroy to both the master event and
a specific instance in a single "/set" request; the result of this is a specific instance in a single "/set" request; the result of this is
undefined. undefined.
Servers MUST enforce the user's permissions as returned in the Servers MUST enforce the user's permissions as returned in the
"myRights" property of the Calendar object and reject changes with a "myRights" property of the Calendar objects and reject changes with a
"forbidden" SetError if not allowed. "forbidden" SetError if not allowed.
The "privacy" property MUST NOT be set to anything other than The "privacy" property MUST NOT be set to anything other than
"public" (the default) for events in a calendar that does not belong "public" (the default) for events in a calendar that does not belong
to the user (e.g. a shared team calendar). The server MUST reject to the user (e.g. a shared team calendar). The server MUST reject
this with an "invalidProperties" SetError. this with an "invalidProperties" SetError.
The server MUST reject attempts to add events with a "participants" The server MUST reject attempts to add events with a "participants"
property where none of the participants correspond to one of the property where none of the participants correspond to one of the
calendar's participant identities with a "forbidden" SetError. calendar's participant identities with a "forbidden" SetError.
If omitted on create, the server MUST set the following properties to If omitted on create, the server MUST set the following properties to
an appropriate value: an appropriate value:
o @type * @type
o uid
o created * uid
* created
The "updated" property MUST be set to the current time by the server The "updated" property MUST be set to the current time by the server
whenever an event is created or updated. If the client tries to set whenever an event is created or updated. If the client tries to set
a value for this property it is not an error, but it MUST be a value for this property it is not an error, but it MUST be
overridden and replaced with the server's time. overridden and replaced with the server's time.
When updating an event, if all of: * a non per-user property has been When updating an event, if all of: * a non per-user property has been
changed; and * the server is the source of the event (see changed; and * the server is the source of the event (see
Section XXX); and * the "sequence" property is not explicitly set in Section XXX); and * the "sequence" property is not explicitly set in
the update, or the given value is less than or equal to the current the update, or the given value is less than or equal to the current
"sequence" value on the server; then the server MUST increment the "sequence" value on the server; then the server MUST increment the
skipping to change at page 27, line 37 skipping to change at page 24, line 41
The server does not automatically reset the "partipationStatus" or The server does not automatically reset the "partipationStatus" or
"expectReply" properties of a Participant when changing other event "expectReply" properties of a Participant when changing other event
details. Clients should either be intelligent about whether the details. Clients should either be intelligent about whether the
change necessitates resending RSVP requests, or ask the user whether change necessitates resending RSVP requests, or ask the user whether
to send them. to send them.
The server MAY enforce that all events have an owner, for example in The server MAY enforce that all events have an owner, for example in
team calendars. If the user tries to create an event without team calendars. If the user tries to create an event without
participants in such a calendar, the server MUST automatically add a participants in such a calendar, the server MUST automatically add a
participant with the "owner" role corresponding to one of the user's participant with the "owner" role corresponding to one of the user's
"participantIdentities" for the calendar. ParticipantIdentities (see Section XXX).
When creating an event with participants, or adding participants to When creating an event with participants, or adding participants to
an event that previously did not have participants, the server MUST an event that previously did not have participants, the server MUST
set the "replyTo" property of the event if not present. Clients set the "replyTo" property of the event if not present. Clients
SHOULD NOT set the replyTo property for events when the user adds SHOULD NOT set the replyTo property for events when the user adds
participants; the server is better positioned to add all the methods participants; the server is better positioned to add all the methods
it supports to receive replies. it supports to receive replies.
5.8.1. Patching 5.8.1. Patching
skipping to change at page 30, line 23 skipping to change at page 27, line 23
"recurrenceOverrides/2018-03-08T09:00:00/ "recurrenceOverrides/2018-03-08T09:00:00/
participants~1em9lQGZvb2GFtcGxlLmNvbQ~1participationStatus": participants~1em9lQGZvb2GFtcGxlLmNvbQ~1participationStatus":
"declined" "declined"
} }
} }
}, "0" ]] }, "0" ]]
This patches the "2018-03-08T09:00:00" PatchObject in This patches the "2018-03-08T09:00:00" PatchObject in
recurrenceOverrides so that it ends up like this: recurrenceOverrides so that it ends up like this:
"recurrenceOverrides": { "recurrenceOverrides": {
"2018-03-08T09:00:00": { "2018-03-08T09:00:00": {
"start": "2018-03-08T10:00:00", "start": "2018-03-08T10:00:00",
"participants/dG9tQGZvb2Jhci5xlLmNvbQ/participationStatus": "participants/dG9tQGZvb2Jhci5xlLmNvbQ/participationStatus":
"declined", "declined",
"participants/em9lQGZvb2GFtcGxlLmNvbQ/participationStatus": "participants/em9lQGZvb2GFtcGxlLmNvbQ/participationStatus":
"declined" "declined"
} }
} }
Now if Tom were to change his mind and remove his declined status Now if Tom were to change his mind and remove his declined status
override (thus meaning he is attending, as inherited from the top- override (thus meaning he is attending, as inherited from the top-
level event), he might remove his patch from the overrides like so: level event), he might remove his patch from the overrides like so:
[[ "CalendarEvent/set", { [[ "CalendarEvent/set", {
"accountId": "ue150411c", "accountId": "ue150411c",
"update": { "update": {
"123": { "123": {
"recurrenceOverrides/2018-03-08T09:00:00/ "recurrenceOverrides/2018-03-08T09:00:00/
participants~1dG9tQGZvb2Jhci5xlLmNvbQ~1participationStatus": null participants~1dG9tQGZvb2Jhci5xlLmNvbQ~1participationStatus": null
} }
} }
}, "0" ]] }, "0" ]]
However, if you instead want to remove Tom from this instance However, if you instead want to remove Tom from this instance
altogether, you could not send this patch: altogether, you could not send this patch:
[[ "CalendarEvent/set", { [[ "CalendarEvent/set", {
"accountId": "ue150411c", "accountId": "ue150411c",
"update": { "update": {
"123": { "123": {
"recurrenceOverrides/2018-03-08T09:00:00/ "recurrenceOverrides/2018-03-08T09:00:00/
participants~1dG9tQGZvb2Jhci5xlLmNvbQ": null participants~1dG9tQGZvb2Jhci5xlLmNvbQ": null
} }
} }
}, "0" ]] }, "0" ]]
This would mean remove the "participants/dG9tQGZvb2Jhci5xlLmNvbQ" This would mean remove the "participants/dG9tQGZvb2Jhci5xlLmNvbQ"
property at path "recurrenceOverrides" -> "2018-03-08T09:00:00" property at path "recurrenceOverrides" -> "2018-03-08T09:00:00"
inside the object; but this doesn't exist. We actually we want to inside the object; but this doesn't exist. We actually we want to
add this property and make it map to "null". The client must instead add this property and make it map to "null". The client must instead
send the full object that contains the property mapping to "null", send the full object that contains the property mapping to "null",
like so: like so:
[[ "CalendarEvent/set", { [[ "CalendarEvent/set", {
"accountId": "ue150411c", "accountId": "ue150411c",
"update": { "update": {
"123": { "123": {
"recurrenceOverrides/2018-03-08T09:00:00": { "recurrenceOverrides/2018-03-08T09:00:00": {
"start": "2018-03-08T10:00:00", "start": "2018-03-08T10:00:00",
"participants/em9lQGZvb2GFtcGxlLmNvbQ/participationStatus": "participants/em9lQGZvb2GFtcGxlLmNvbQ/participationStatus":
"declined" "declined"
"participants/dG9tQGZvb2Jhci5xlLmNvbQ": null "participants/dG9tQGZvb2Jhci5xlLmNvbQ": null
} }
} }
} }
}, "0" ]] }, "0" ]]
5.8.2. Sending invitations and responses 5.8.2. Sending invitations and responses
If "sendSchedulingMessages" is true, the server MUST send appropriate If "sendSchedulingMessages" is true, the server MUST send appropriate
iTIP [RFC5546] scheduling messages after successfuly creating, iTIP [RFC5546] scheduling messages after successfuly creating,
updating or destroying a calendar event. updating or destroying a calendar event.
When determining which scheduling messages to send, the server must When determining which scheduling messages to send, the server must
first establish whether it is the _source_ of the event. The server first establish whether it is the _source_ of the event. The server
is the source if it will receive messages sent to any of the methods is the source if it will receive messages sent to any of the methods
specified in the "replyTo" property of the event. specified in the "replyTo" property of the event.
Messages are only sent to participants with a "scheduleAgent" Messages are only sent to participants with a "scheduleAgent"
property set to "server" or omitted. If the effective property set to "server" or omitted. If the effective
"scheduleAgent" property is changed: "scheduleAgent" property is changed:
o to "server" from something else: send messages to this participant * to "server" from something else: send messages to this participant
as though the event had just been created. as though the event had just been created.
o from "server" to something else: send messages to this participant * from "server" to something else: send messages to this participant
as though the event had just been destroyed. as though the event had just been destroyed.
o any other change: do not send any messages to this participant. * any other change: do not send any messages to this participant.
The server may send the scheduling message via any of the methods The server may send the scheduling message via any of the methods
defined on the sendTo property of a participant (if the server is the defined on the sendTo property of a participant (if the server is the
source) or the replyTo property of the event (otherwise) that it source) or the replyTo property of the event (otherwise) that it
supports. If no supported methods are available, the server MUST supports. If no supported methods are available, the server MUST
reject the change with a "noSupportedScheduleMethods" SetError. reject the change with a "noSupportedScheduleMethods" SetError.
If the server is the source of the event it MUST NOT send messages to If the server is the source of the event it MUST NOT send messages to
any participant corresponding to the participantIdentities of the any participant corresponding to a ParticipantIdentitity in that
calendar it is in. account (see Section XXX).
If sending via iMIP [RFC6047], the server MAY choose to only send If sending via iMIP [RFC6047], the server MAY choose to only send
updates it deems "essential" to avoid flooding the recipient's email updates it deems "essential" to avoid flooding the recipient's email
with changes they do not care about. For example, changes to the with changes they do not care about. For example, changes to the
participationStatus of another participant, or changes to events participationStatus of another participant, or changes to events
solely in the past may be omitted. solely in the past may be omitted.
5.8.2.1. REQUEST 5.8.2.1. REQUEST
When the server is the source for the event, a REQUEST message When the server is the source for the event, a REQUEST message
([RFC5546], Section 3.2.2) is sent to all current participants if: ([RFC5546], Section 3.2.2) is sent to all current participants if:
o The event is being created. * The event is being created.
o Any non per-user property (see Section XXX) is updated on the * Any non per-user property (see Section XXX) is updated on the
event (including adding/removing participants), except if just event (including adding/removing participants), except if just
modifying the recurrenceOverrides such that CANCEL messages are modifying the recurrenceOverrides such that CANCEL messages are
generated (see the next section). generated (see the next section).
Note, if the only change is adding an additional instance (not Note, if the only change is adding an additional instance (not
generated by the event's recurrence rule) to the recurrenceOverrides, generated by the event's recurrence rule) to the recurrenceOverrides,
this MAY be handled via sending an ADD message ([RFC5546], this MAY be handled via sending an ADD message ([RFC5546],
Section 3.2.4) for the single instance rather than a REQUEST message Section 3.2.4) for the single instance rather than a REQUEST message
for the master. However, for interoperability reasons this is not for the master. However, for interoperability reasons this is not
recommended due to poor support in the wild for this type of message. recommended due to poor support in the wild for this type of message.
skipping to change at page 33, line 16 skipping to change at page 30, line 25
If the event's "hideAttendees" property is set to "true", the If the event's "hideAttendees" property is set to "true", the
recipient MUST be the only attendee in the message; all others are recipient MUST be the only attendee in the message; all others are
omitted. omitted.
5.8.2.2. CANCEL 5.8.2.2. CANCEL
When the server is the source for the event, a CANCEL message When the server is the source for the event, a CANCEL message
([RFC5546], Section 3.2.5) is sent if: ([RFC5546], Section 3.2.5) is sent if:
o A participant is removed from either the master event or a single * A participant is removed from either the master event or a single
instance (the message is only sent to this participant; remaining instance (the message is only sent to this participant; remaining
participants will get a REQUEST, as described above). participants will get a REQUEST, as described above).
o The event is destroyed. * The event is destroyed.
o An exclusion is added to recurrenceOverrides to remove an instance * An exclusion is added to recurrenceOverrides to remove an instance
generated by the event's recurrence rule. generated by the event's recurrence rule.
o An additional instance (not generated by the event's recurrence * An additional instance (not generated by the event's recurrence
rule) is removed from the recurrenceOverrides. rule) is removed from the recurrenceOverrides.
In each of the latter 3 cases, the message is sent to all In each of the latter 3 cases, the message is sent to all
participants. participants.
5.8.2.3. REPLY 5.8.2.3. REPLY
When the server is _not_ the source for the event, a REPLY message When the server is _not_ the source for the event, a REPLY message
([RFC5546], Section 3.2.3) is sent for any participant corresponding ([RFC5546], Section 3.2.3) is sent for any participant corresponding
to the participantIdentities of the calendar it is in if: to one of the user's ParticipantIdentitities in the account if:
o The "participationStatus" property of the participant is changed. * The "participationStatus" property of the participant is changed.
o The event is destroyed and the participationStatus was not "needs- * The event is destroyed and the participationStatus was not "needs-
action". action".
o The event is created and the participationStatus is not "needs- * The event is created and the participationStatus is not "needs-
action". action".
o An exclusion is added to recurrenceOverrides to remove an instance * An exclusion is added to recurrenceOverrides to remove an instance
generated by the event's recurrence rule. generated by the event's recurrence rule.
o An exclusion is removed from recurrenceOverrides (this is presumed * An exclusion is removed from recurrenceOverrides (this is presumed
to be the client undoing the deletion of a single instance). to be the client undoing the deletion of a single instance).
o An instance not generated by the event's recurrence rule is * An instance not generated by the event's recurrence rule is
removed from the recurrenceOverrides. removed from the recurrenceOverrides.
o An instance not generated by the event's recurrence rule is added * An instance not generated by the event's recurrence rule is added
to the recurrenceOverrides (this is presumed to be the client to the recurrenceOverrides (this is presumed to be the client
undoing the deletion of a single instance). undoing the deletion of a single instance).
A reply is not sent when deleting an event where the current status A reply is not sent when deleting an event where the current status
is "needs-action" as if a junk calendar event gets added by an is "needs-action" as if a junk calendar event gets added by an
automated system, the user MUST be able to delete the event without automated system, the user MUST be able to delete the event without
sending a reply. sending a reply.
5.9. CalendarEvent/copy 5.9. CalendarEvent/copy
This is a standard "/copy" method as described in [RFC8620], This is a standard "/copy" method as described in [RFC8620],
Section 5.4. Section 5.4.
5.10. CalendarEvent/query 5.10. CalendarEvent/query
This is a standard "/query" method as described in [RFC8620], This is a standard "/query" method as described in [RFC8620],
Section 5.5, with two extra arguments: Section 5.5, with two extra arguments:
o *expandRecurrences*: "Boolean" (default: false) If true, the * *expandRecurrences*: "Boolean" (default: false) If true, the
server will expand any recurring event. If true, the filter MUST server will expand any recurring event. If true, the filter MUST
be just a FilterCondition (not a FilterOperator) and MUST include be just a FilterCondition (not a FilterOperator) and MUST include
both a before and after property. This ensures the server is not both a before and after property. This ensures the server is not
asked to return an infinite number of results. asked to return an infinite number of results.
o *timeZone*: "String" The time zone for before/after filter * *timeZone*: "String" The time zone for before/after filter
conditions (default: "Etc/UTC") conditions (default: "Etc/UTC")
If expandRecurrences is true, a separate id will be returned for each If expandRecurrences is true, a separate id will be returned for each
instance of a recurring event that matches the query. This synthetic instance of a recurring event that matches the query. This synthetic
id is opaque to the client, but allows the server to resolve the id + id is opaque to the client, but allows the server to resolve the id +
recurrence id for "/get" and "/set" operations. Otherwise, a single recurrence id for "/get" and "/set" operations. Otherwise, a single
id will be returned for matching recurring events that represents the id will be returned for matching recurring events that represents the
entire event. entire event.
There is no necessary correspondence between the ids of different There is no necessary correspondence between the ids of different
skipping to change at page 35, line 9 skipping to change at page 32, line 15
The following additional error may be returned instead of the The following additional error may be returned instead of the
"CalendarEvent/query" response: "CalendarEvent/query" response:
"cannotCalculateOccurrences": the server cannot expand a recurrence "cannotCalculateOccurrences": the server cannot expand a recurrence
required to return the results for this query. required to return the results for this query.
5.10.1. Filtering 5.10.1. Filtering
A *FilterCondition* object has the following properties: A *FilterCondition* object has the following properties:
o *inCalendars*: "Id[]|null" A list of calendar ids. An event must * *inCalendars*: "Id[]|null" A list of calendar ids. An event must
be in ANY of these calendars to match the condition. be in ANY of these calendars to match the condition.
o *after*: "LocalDate|null" The end of the event, or any recurrence * *after*: "LocalDate|null" The end of the event, or any recurrence
of the event, in the time zone given as the timeZone argument, of the event, in the time zone given as the timeZone argument,
must be after this date to match the condition. must be after this date to match the condition.
o *before*: "LocalDate|null" The start of the event, or any * *before*: "LocalDate|null" The start of the event, or any
recurrence of the event, in the time zone given as the timeZone recurrence of the event, in the time zone given as the timeZone
argument, must be before this date to match the condition. argument, must be before this date to match the condition.
o *text*: "String|null" Looks for the text in the _title_, * *text*: "String|null" Looks for the text in the _title_,
_description_, _locations_ (matching name/description), _description_, _locations_ (matching name/description),
_participants_ (matching name/email) and any other textual _participants_ (matching name/email) and any other textual
properties of the event or any recurrence of the event. properties of the event or any recurrence of the event.
o *title*: "String|null" Looks for the text in the _title_ property * *title*: "String|null" Looks for the text in the _title_ property
of the event, or the overridden _title_ property of a recurrence. of the event, or the overridden _title_ property of a recurrence.
o *description*: "String|null" Looks for the text in the * *description*: "String|null" Looks for the text in the
_description_ property of the event, or the overridden _description_ property of the event, or the overridden
_description_ property of a recurrence. _description_ property of a recurrence.
o *location*: "String|null" Looks for the text in the _locations_ * *location*: "String|null" Looks for the text in the _locations_
property of the event (matching name/description of a location), property of the event (matching name/description of a location),
or the overridden _locations_ property of a recurrence. or the overridden _locations_ property of a recurrence.
o *owner*: "String|null" Looks for the text in the name or email * *owner*: "String|null" Looks for the text in the name or email
fields of a participant in the _participants_ property of the fields of a participant in the _participants_ property of the
event, or the overridden _participants_ property of a recurrence, event, or the overridden _participants_ property of a recurrence,
where the participant has a role of "owner". where the participant has a role of "owner".
o *attendee*: "String|null" Looks for the text in the name or email * *attendee*: "String|null" Looks for the text in the name or email
fields of a participant in the _participants_ property of the fields of a participant in the _participants_ property of the
event, or the overridden _participants_ property of a recurrence, event, or the overridden _participants_ property of a recurrence,
where the participant has a role of "attendee". where the participant has a role of "attendee".
o *participationStatus*: Must match. If owner/attendee condition, * *participationStatus*: Must match. If owner/attendee condition,
status must be of that participant. Otherwise any. status must be of that participant. Otherwise any.
o *uid*: "String" The uid of the event is exactly the given string. * *uid*: "String" The uid of the event is exactly the given string.
If expandRecurrences is true, all conditions must match against the If expandRecurrences is true, all conditions must match against the
same instance of a recurring event for the instance to match. If same instance of a recurring event for the instance to match. If
expandRecurrences is false, all conditions must match, but they may expandRecurrences is false, all conditions must match, but they may
each match any instance of the event. each match any instance of the event.
If zero properties are specified on the FilterCondition, the If zero properties are specified on the FilterCondition, the
condition MUST always evaluate to "true". If multiple properties are condition MUST always evaluate to "true". If multiple properties are
specified, ALL must apply for the condition to be "true" (it is specified, ALL must apply for the condition to be "true" (it is
equivalent to splitting the object into one-property conditions and equivalent to splitting the object into one-property conditions and
making them all the child of an AND filter operator). making them all the child of an AND filter operator).
The exact semantics for matching "String" fields is *deliberately not The exact semantics for matching "String" fields is *deliberately not
defined* to allow for flexibility in indexing implementation, subject defined* to allow for flexibility in indexing implementation, subject
to the following: to the following:
o Text SHOULD be matched in a case-insensitive manner. * Text SHOULD be matched in a case-insensitive manner.
o Text contained in either (but matched) single or double quotes * Text contained in either (but matched) single or double quotes
SHOULD be treated as a *phrase search*, that is a match is SHOULD be treated as a *phrase search*, that is a match is
required for that exact sequence of words, excluding the required for that exact sequence of words, excluding the
surrounding quotation marks. Use "\"", "\'" and "\\" to match a surrounding quotation marks. Use "\"", "\'" and "\\" to match a
literal """, "'" and "\" respectively in a phrase. literal """, "'" and "\" respectively in a phrase.
o Outside of a phrase, white-space SHOULD be treated as dividing * Outside of a phrase, white-space SHOULD be treated as dividing
separate tokens that may be searched for separately in the event, separate tokens that may be searched for separately in the event,
but MUST all be present for the event to match the filter. but MUST all be present for the event to match the filter.
o Tokens MAY be matched on a whole-word basis using stemming (so for * Tokens MAY be matched on a whole-word basis using stemming (so for
example a text search for "bus" would match "buses" but not example a text search for "bus" would match "buses" but not
"business"). "business").
5.10.2. Sorting 5.10.2. Sorting
The following properties MUST be supported for sorting: The following properties MUST be supported for sorting:
o start * start
o uid * uid
o recurrenceId * recurrenceId
The following properties SHOULD be supported for sorting: The following properties SHOULD be supported for sorting:
o created * created
o updated * updated
5.11. CalendarEvent/queryChanges 5.11. CalendarEvent/queryChanges
This is a standard "/queryChanges" method as described in [RFC8620], This is a standard "/queryChanges" method as described in [RFC8620],
Section 5.6. Section 5.6.
5.12. Examples 5.12. Examples
TODO: Add example of how to get event by uid: query uid=foo and TODO: Add example of how to get event by uid: query uid=foo and
backref. Return multiple with recurrenceId set (user invited to backref. Return multiple with recurrenceId set (user invited to
specific instances of recurring event). specific instances of recurring event).
6. Alerts 6. Alerts
Alerts may be specified on events as described in Alerts may be specified on events as described in
[I-D.ietf-calext-jscalendar], Section 4.5. If the "useDefaultAlerts" [I-D.ietf-calext-jscalendar], Section 4.5.
property is true, the alerts are taken from the Calendar
"defaultAlertsWithTime" or "defaultAlertsWithoutTime" property, as
described in Section XXX. Otherwise, the alerts are taken from the
"alerts" property of the CalendarEvent.
Alerts MUST only be triggered for events in calendars where the user Alerts MUST only be triggered for events in calendars where the user
is subscribed and either the user owns the calendar or the calendar's is subscribed and either the user owns the calendar or the calendar
"shareesActAs" property is "self". account's "shareesActAs" capability is "self".
When an alert with an "email" action is triggered, the server MUST When an alert with an "email" action is triggered, the server MUST
send an email to the user to notify them of the event. The contents send an email to the user to notify them of the event. The contents
of the email is implementation specific. Clients MUST NOT perform an of the email is implementation specific. Clients MUST NOT perform an
action for these alerts. action for these alerts.
When an alert with a "display" action is triggered, clients SHOULD When an alert with a "display" action is triggered, clients SHOULD
display an alert in a platform-appropriate manner to the user to display an alert in a platform-appropriate manner to the user to
remind them of the event. Clients with a full offline cache of remind them of the event. Clients with a full offline cache of
events may choose to calculate when alerts should trigger locally. events may choose to calculate when alerts should trigger locally.
Alternatively, they can subscribe to push events from the server. Alternatively, they can subscribe to push events from the server.
6.1. Push events 6.1. Default alerts
Servers that support the "urn:ietf:params:jmap:calendars" capability
MUST support registering for the pseudo-type "CalendarAlert" in push
subscriptions and event source connections, as described in
[RFC8620], Sections 7.2 and 7.3.
If requested, a CalendarAlert notification will be pushed whenever an
alert is triggered for the user. For Event Source connections, this
notification is pushed as an event called "calendaralert".
A *CalendarAlert* object has the following properties:
o *@type*: "String" This MUST be the string "CalendarAlert".
o *accountId*: "String" The account id for the calendar in which the
alert triggered.
o *calendarEventId*: "String" The CalendarEvent id for the alert If the "useDefaultAlerts" property of an event is true, the alerts
that triggered. are taken from the "defaultAlertsWithTime" or
"defaultAlertsWithoutTime" property of all Calendars the event is in,
as described in Section XXX, rather than the "alerts" property of the
CalendarEvent.
o *uid*: "String" The uid property of the CalendarEvent for the When using default alerts, the "alerts" property of the event is
alert that triggered. ignored except for the following:
o *recurrenceId*: "String|null" The recurrenceId for the instance of * The "acknowledged" time for an alert is stored here when a default
the event for which this alert is being triggered, or "null" if alert for the event is dismissed. The id of the alert MUST be the
the event is not recurring. same as the id of the default alert in the calendar. See
Section XXX on acknowledging alerts.
o *alertId*: "String" The id for the alert that triggered. * If an alert has a relatedTo property where the parent is the id of
one of the calendar default alerts, it is processed as normal and
not ignored. This is to support snoozing default alerts; see
Section XXX.
6.2. Acknowledging an alert 6.2. Acknowledging an alert
To dismiss an alert, clients set the "acknowledged" property of the To dismiss an alert, clients set the "acknowledged" property of the
Alert object to the current date-time. When other clients fetch the Alert object to the current date-time. If the alert was a calendar
CalendarEvent with the updated Alert they SHOULD automatically default, it may need to be added to the event at this point in order
dismiss or suppress duplicate alerts (alerts with the same alert id to acknowledge it. When other clients fetch the updated
that triggered on or before this date-time). CalendarEvent they SHOULD automatically dismiss or suppress duplicate
alerts (alerts with the same alert id that triggered on or before the
"acknowledged" date-time) and alerts that have been removed from the
event.
Setting the "acknowledged" property MUST NOT create a new recurrence Setting the "acknowledged" property MUST NOT create a new recurrence
override. For a recurring calendar object, the "acknowledged" override. For a recurring calendar object, the "acknowledged"
property of the parent object MUST be updated, unless the alert is property of the parent object MUST be updated, unless the alert is
already overridden in the "recurrenceOverrides" property. already overridden in the "recurrenceOverrides" property.
6.3. Snoozing an alert 6.3. Snoozing an alert
Users may wish to dismiss an alert temporarily and have it come back Users may wish to dismiss an alert temporarily and have it come back
after a specific period of time. To do this, clients MUST: after a specific period of time. To do this, clients MUST:
1. Acknowledge the alert as described in Section XXX. 1. Acknowledge the alert as described in Section XXX.
2. Add a new alert with an "AbsoluteTrigger" for the date-time the 2. Add a new alert to the event with an "AbsoluteTrigger" for the
alert has been snoozed until. Add a "relatedTo" property to the date-time the alert has been snoozed until. Add a "relatedTo"
new alert, setting the "parent" relation to point to the original property to the new alert, setting the "parent" relation to point
alert. This MUST NOT create a new recurrence override; it is to the original alert. This MUST NOT create a new recurrence
added to the same "alerts" property that contains the alert being override; it is added to the same "alerts" property that contains
snoozed. the alert that was acknowledged in step 1.
When acknowledging a snoozed alert (i.e. one with a parent relatedTo When acknowledging a snoozed alert (i.e. one with a parent relatedTo
pointing to the original alert), the client SHOULD delete the alert pointing to the original alert), the client SHOULD delete the alert
rather than setting the "acknowledged" property. rather than setting the "acknowledged" property.
6.4. Push events
Servers that support the "urn:ietf:params:jmap:calendars" capability
MUST support registering for the pseudo-type "CalendarAlert" in push
subscriptions and event source connections, as described in
[RFC8620], Sections 7.2 and 7.3.
If requested, a CalendarAlert notification will be pushed whenever an
alert is triggered for the user. For Event Source connections, this
notification is pushed as an event called "calendarAlert".
A *CalendarAlert* object has the following properties:
* *@type*: "String" This MUST be the string "CalendarAlert".
* *accountId*: "String" The account id for the calendar in which the
alert triggered.
* *calendarEventId*: "String" The CalendarEvent id for the alert
that triggered.
* *uid*: "String" The uid property of the CalendarEvent for the
alert that triggered.
* *recurrenceId*: "String|null" The recurrenceId for the instance of
the event for which this alert is being triggered, or "null" if
the event is not recurring.
* *alertId*: "String" The id for the alert that triggered.
7. Calendar Event Notifications 7. Calendar Event Notifications
The CalendarEventNotification data type records changes made by The CalendarEventNotification data type records changes made by
external entities to events in calendars the user is subscribed to. external entities to events in calendars the user is subscribed to.
Notifications are stored in the same Account as the CalendarEvent Notifications are stored in the same Account as the CalendarEvent
that was changed. that was changed.
Notifications are only created by the server; users cannot create Notifications are only created by the server; users cannot create
them directly. Clients SHOULD present the list of notifications to them directly. Clients SHOULD present the list of notifications to
the user and allow them to dismiss them. To dismiss a notification the user and allow them to dismiss them. To dismiss a notification
you use a standard "/set" call to destroy it. you use a standard "/set" call to destroy it.
The server SHOULD create a CalendarEventNotification whenever an The server SHOULD create a CalendarEventNotification whenever an
event is added, updated or destroyed by another user or due to event is added, updated or destroyed by another user or due to
receiving an iTIP [RFC5546] or other scheduling message in a calendar receiving an iTIP [RFC5546] or other scheduling message in a calendar
this user is subscribed to. The server SHOULD NOT create this user is subscribed to. The server SHOULD NOT create
notifications for events implicitly deleted due to the containing notifications for events implicitly deleted due to the containing
calendar being deleted. calendar being deleted.
The CalendarEventNotification does not have any per-user data. A
single instance may therefore be maintained on the server for all
sharees of the notification. The server need only keep track of
which users have yet to destroy the notification.
7.1. Auto-deletion of Notifications 7.1. Auto-deletion of Notifications
The server MAY limit the maximum number of notifications it will The server MAY limit the maximum number of notifications it will
store for a user. When the limit is reached, any new notification store for a user. When the limit is reached, any new notification
will cause the previously oldest notification to be automatically will cause the previously oldest notification to be automatically
deleted. deleted.
The server MAY coalesce events if appropriate, or remove events that The server MAY coalesce events if appropriate, or remove events that
it deems are no longer relevant or after a certain period of time. it deems are no longer relevant or after a certain period of time.
The server SHOULD automatically destroy a notification about an event The server SHOULD automatically destroy a notification about an event
if the user updates or destroys that event (e.g. if the user sends an if the user updates or destroys that event (e.g. if the user sends an
RSVP for the event). RSVP for the event).
7.2. Object Properties 7.2. Object Properties
The *CalendarEventNotification* object has the following properties: The *CalendarEventNotification* object has the following properties:
o *id*: "String" The id of the CalendarEventNotification. * *id*: "String" The id of the CalendarEventNotification.
o *created*: "UTCDate" The time this notification was created. * *created*: "UTCDate" The time this notification was created.
o *changedBy*: "Person" Who made the change. * *changedBy*: "Person" Who made the change.
* *name*: "String" The name of the person who made the change. - *name*: "String" The name of the person who made the change.
* *email*: "String" The email of the person who made the change, - *email*: "String" The email of the person who made the change,
or null if no email is available. or null if no email is available.
* *calendarPrincipalId*: "String|null" The id of the calendar - *principalId*: "String|null" The id of the calendar principal
principal corresponding to the person who made the change, if corresponding to the person who made the change, if any. This
any. This will be null if the change was due to receving an will be null if the change was due to receving an iTIP message.
iTIP message.
o *comment*: "String|null" Comment sent along with the change by the * *comment*: "String|null" Comment sent along with the change by the
user that made it. (e.g. COMMENT property in an iTIP message). user that made it. (e.g. COMMENT property in an iTIP message).
o *type*: "String" This MUST be one of * *type*: "String" This MUST be one of
* created - created
* updated - updated
* destroyed - destroyed
o *calendarEventId*: "String" The id of the CalendarEvent that this * *calendarEventId*: "String" The id of the CalendarEvent that this
notification is about. notification is about.
o *isDraft*: "Boolean" (created/updated only) Is this event a draft? * *isDraft*: "Boolean" (created/updated only) Is this event a draft?
o *event*: "JSEvent" The data before the change (if updated or * *event*: "JSEvent" The data before the change (if updated or
destroyed), or the data after creation (if created). destroyed), or the data after creation (if created).
o *eventPatch*: "PatchObject" (updated only) A patch encoding the * *eventPatch*: "PatchObject" (updated only) A patch encoding the
change between the data in the event property, and the data after change between the data in the event property, and the data after
the update. the update.
To reduce data, if the change only affects a single instance of a To reduce data, if the change only affects a single instance of a
recurring event, the server MAY set the event and eventPatch recurring event, the server MAY set the event and eventPatch
properties for the instance; the calendarEventId MUST still be for properties for the instance; the calendarEventId MUST still be for
the master event. the master event.
7.3. CalendarEventNotification/get 7.3. CalendarEventNotification/get
skipping to change at page 41, line 17 skipping to change at page 38, line 49
7.6. CalendarEventNotification/query 7.6. CalendarEventNotification/query
This is a standard "/query" method as described in [RFC8620], This is a standard "/query" method as described in [RFC8620],
Section 5.5. Section 5.5.
7.6.1. Filtering 7.6.1. Filtering
A *FilterCondition* object has the following properties: A *FilterCondition* object has the following properties:
o *after*: "UTCDate|null" The creation date must be on or after this * *after*: "UTCDate|null" The creation date must be on or after this
date to match the condition. date to match the condition.
o *before*: "UTCDate|null" The creation date must be before this * *before*: "UTCDate|null" The creation date must be before this
date to match the condition. date to match the condition.
o *type*: "String" The type property must be the same to match the * *type*: "String" The type property must be the same to match the
condition. condition.
o *calendarEventIds*: "Id[]|null" A list of event ids. The * *calendarEventIds*: "Id[]|null" A list of event ids. The
calendarEventId property of the notification must be in this list calendarEventId property of the notification must be in this list
to match the condition. to match the condition.
7.6.2. Sorting 7.6.2. Sorting
The "created" property MUST be supported for sorting. The "created" property MUST be supported for sorting.
7.7. CalendarEventNotification/queryChanges 7.7. CalendarEventNotification/queryChanges
This is a standard "/queryChanges" method as described in [RFC8620], This is a standard "/queryChanges" method as described in [RFC8620],
skipping to change at page 42, line 42 skipping to change at page 40, line 25
9.2.1. id 9.2.1. id
Property Name: id Property Name: id
Property Type: "Id" Property Type: "Id"
Property Context: JSEvent, JSTask Property Context: JSEvent, JSTask
Intended Use: Reserved Intended Use: Reserved
9.2.2. calendarId 9.2.2. calendarIds
Property Name: calendarId Property Name: calendarIds
Property Type: "Id" Property Type: "Id[Boolean]"
Property Context: JSEvent, JSTask Property Context: JSEvent, JSTask
Intended Use: Reserved Intended Use: Reserved
9.2.3. isDraft 9.2.3. isDraft
Property Name: isDraft Property Name: isDraft
Property Type: "Boolean" Property Type: "Boolean"
skipping to change at page 44, line 22 skipping to change at page 42, line 5
Property Name: hideAttendees Property Name: hideAttendees
Property Type: "Boolean" (default: false) Property Type: "Boolean" (default: false)
Property Context: JSEvent, JSTask Property Context: JSEvent, JSTask
Reference: This document, Section XXX. Reference: This document, Section XXX.
Intended Use: Common Intended Use: Common
10. References 10. Normative References
10.1. Normative References
[I-D.ietf-calext-jscalendar] [I-D.ietf-calext-jscalendar]
Jenkins, N. and R. Stepanek, "JSCalendar: A JSON Jenkins, N. and R. Stepanek, "JSCalendar: A JSON
representation of calendar data", draft-ietf-calext- representation of calendar data", Work in Progress,
jscalendar-27 (work in progress), June 2020. Internet-Draft, draft-ietf-calext-jscalendar-32, 15
October 2020, <https://tools.ietf.org/html/draft-ietf-
calext-jscalendar-32>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
[RFC2397] Masinter, L., "The "data" URL scheme", RFC 2397, [RFC2397] Masinter, L., "The "data" URL scheme", RFC 2397,
DOI 10.17487/RFC2397, August 1998, DOI 10.17487/RFC2397, August 1998,
<https://www.rfc-editor.org/info/rfc2397>. <https://www.rfc-editor.org/info/rfc2397>.
[RFC5546] Daboo, C., Ed., "iCalendar Transport-Independent
Interoperability Protocol (iTIP)", RFC 5546,
DOI 10.17487/RFC5546, December 2009,
<https://www.rfc-editor.org/info/rfc5546>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>. May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8620] Jenkins, N. and C. Newman, "The JSON Meta Application [RFC8620] Jenkins, N. and C. Newman, "The JSON Meta Application
Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, July Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, July
2019, <https://www.rfc-editor.org/info/rfc8620>. 2019, <https://www.rfc-editor.org/info/rfc8620>.
10.2. Informative References 11. Informative References
[RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault, [RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault,
"Calendaring Extensions to WebDAV (CalDAV)", RFC 4791, "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
DOI 10.17487/RFC4791, March 2007, DOI 10.17487/RFC4791, March 2007,
<https://www.rfc-editor.org/info/rfc4791>. <https://www.rfc-editor.org/info/rfc4791>.
[RFC5546] Daboo, C., Ed., "iCalendar Transport-Independent
Interoperability Protocol (iTIP)", RFC 5546,
DOI 10.17487/RFC5546, December 2009,
<https://www.rfc-editor.org/info/rfc5546>.
[RFC6047] Melnikov, A., Ed., "iCalendar Message-Based [RFC6047] Melnikov, A., Ed., "iCalendar Message-Based
Interoperability Protocol (iMIP)", RFC 6047, Interoperability Protocol (iMIP)", RFC 6047,
DOI 10.17487/RFC6047, December 2010, DOI 10.17487/RFC6047, December 2010,
<https://www.rfc-editor.org/info/rfc6047>. <https://www.rfc-editor.org/info/rfc6047>.
10.3. URIs
[1] https://www.iana.org/time-zones
[2] https://www.w3.org/TR/css-color-3/
[3] https://www.iana.org/time-zones
Authors' Addresses Authors' Addresses
Neil Jenkins Neil Jenkins (editor)
Fastmail Fastmail
PO Box 234, Collins St West PO Box 234, Collins St West
Melbourne VIC 8007 Melbourne VIC 8007
Australia Australia
Email: neilj@fastmailteam.com Email: neilj@fastmailteam.com
URI: https://www.fastmail.com URI: https://www.fastmail.com
Michael Douglass Michael Douglass (editor)
Spherical Cow Group Spherical Cow Group
226 3rd Street 226 3rd Street
Troy NY 12180 Troy, NY 12180
United States of America United States of America
Email: mdouglass@sphericalcowgroup.com Email: mdouglass@sphericalcowgroup.com
URI: http://sphericalcowgroup.com URI: http://sphericalcowgroup.com
 End of changes. 234 change blocks. 
789 lines changed or deleted 664 lines changed or added

This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/