rfc9670.original.xml | rfc9670.xml | |||
---|---|---|---|---|
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="UTF-8"?> | |||
<rfc version="3" ipr="trust200902" docName="draft-ietf-jmap-sharing-09" submissi | ||||
onType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInc | ||||
lude" indexInclude="true" consensus="true" updates="8620"> | ||||
<front> | <!DOCTYPE rfc [ | |||
<title abbrev="JMAP Sharing">JMAP Sharing</title> | <!ENTITY nbsp " "> | |||
<seriesInfo value="draft-ietf-jmap-sharing-09" stream="IETF" status="standard" n | <!ENTITY zwsp "​"> | |||
ame="Internet-Draft"></seriesInfo> | <!ENTITY nbhy "‑"> | |||
<author role="editor" initials="N.M." surname="Jenkins" fullname="Neil Jenkins"> | <!ENTITY wj "⁠"> | |||
]> | ||||
<rfc version="3" ipr="trust200902" docName="draft-ietf-jmap-sharing-09" number=" | ||||
9670" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3 | ||||
.org/2001/XInclude" tocInclude="true" consensus="true" updates="8620" obsoletes= | ||||
"" symRefs="true" sortRefs="true"> | ||||
<front> | ||||
<title abbrev="JMAP Sharing">JSON Meta Application Protocol (JMAP) Sharing</ | ||||
title> | ||||
<seriesInfo name="RFC" value="9670"/> | ||||
<author role="editor" initials="N." surname="Jenkins" fullname="Neil Jenkins | ||||
"> | ||||
<organization>Fastmail</organization> | <organization>Fastmail</organization> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street>PO Box 234, Collins St West</street> | <street>PO Box 234, Collins St West</street> | |||
<city>Melbourne</city> | <city>Melbourne</city> | |||
<code>VIC 8007</code> | <region>VIC</region> | |||
<code>8007</code> | ||||
<country>Australia</country> | <country>Australia</country> | |||
</postal> | </postal> | |||
<email>neilj@fastmailteam.com</email> | <email>neilj@fastmailteam.com</email> | |||
<uri>https://www.fastmail.com</uri> | <uri>https://www.fastmail.com</uri> | |||
</address> | </address> | |||
</author> | </author> | |||
<date year="2024" month="April" day="18"></date> | <date year="2024" month="November"/> | |||
<area>Applications</area> | <area>ART</area> | |||
<workgroup>JMAP</workgroup> | <workgroup>jmap</workgroup> | |||
<keyword>JMAP</keyword> | <keyword>JMAP</keyword> | |||
<keyword>JSON</keyword> | <keyword>JSON</keyword> | |||
<keyword>sharing</keyword> | <keyword>sharing</keyword> | |||
<abstract> | <abstract> | |||
<t>This document specifies a data model for sharing data between users using JMA P. Future documents can reference this document when defining data types to supp ort a consistent model of sharing.</t> | <t>This document specifies a data model for sharing data between users using the JSON Meta Application Protocol (JMAP). Future documents can reference this docu ment when defining data types to support a consistent model of sharing.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<middle> | <middle> | |||
<section anchor="introduction"><name>Introduction</name> | <section anchor="introduction"><name>Introduction</name> | |||
<t>JMAP (<xref target="RFC8620"></xref> JSON Meta Application Protocol) is a gen | <t>The JSON Meta Application Protocol (JMAP) <xref target="RFC8620"/> is a gener | |||
eric protocol for synchronizing data, such as mail, calendars or contacts, betwe | ic protocol for synchronizing data, such as mail, calendars, or contacts, betwee | |||
en a client and a server. It is optimized for mobile and web environments, and p | n a client and a server. It is optimized for mobile and web environments and pro | |||
rovides a consistent interface to query, read, and modify different data types, | vides a consistent interface to query, read, and modify different data types, in | |||
including comprehensive error handling.</t> | cluding comprehensive error handling.</t> | |||
<t>This specification defines a data model to represent entities in a collaborat | <t>This specification defines a data model to represent entities in a collaborat | |||
ive environment, and a framework for sharing data between them that can be used | ive environment and a framework for sharing data between them that can be used t | |||
to provide a consistent sharing model for different data types. It does not defi | o provide a consistent sharing model for different data types. It does not defin | |||
ne <em>what</em> may be shared, or the granularity of permissions, as this will | e <em>what</em> may be shared or the granularity of permissions, as this will de | |||
depend on the data in question.</t> | pend on the data in question.</t> | |||
<section anchor="notational-conventions"><name>Notational Conventions</name> | <section anchor="notational-conventions"><name>Notational Conventions</name> | |||
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||||
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this d | <t> | |||
ocument are to be interpreted as described in BCP 14 <xref target="RFC2119"></xr | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU | |||
ef> <xref target="RFC8174"></xref> when, and only when, they appear in all capit | IRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | |||
als, as shown here.</t> | NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14> | |||
RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | ||||
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to | ||||
be interpreted as | ||||
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | ||||
when, and only when, they appear in all capitals, as shown here. | ||||
</t> | ||||
<t>Type signatures, examples, and property descriptions in this document follow the conventions established in <xref target="RFC8620" section="1.1" sectionForma t="of"></xref>. Data types defined in the core specification are also used in t his document.</t> | <t>Type signatures, examples, and property descriptions in this document follow the conventions established in <xref target="RFC8620" section="1.1" sectionForma t="of"></xref>. Data types defined in the core specification are also used in t his document.</t> | |||
<t>Examples of API exchanges only show the methodCalls array of the Request obje ct or the methodResponses array of the Response object. For compactness, the res t of the Request/Response object is omitted.</t> | <t>Examples of API exchanges only show the methodCalls array of the Request obje ct or the methodResponses array of the Response object. For compactness, the res t of the Request/Response object is omitted.</t> | |||
</section> | </section> | |||
<section anchor="terminology"><name>Terminology</name> | <section anchor="terminology"><name>Terminology</name> | |||
<t>The same terminology is used in this document as in the core JMAP specificati | <t>The same terminology is used in this document as in the core JMAP specificati | |||
on, see <xref target="RFC8620" section="1.6" sectionFormat="comma"></xref>.</t> | on. See <xref target="RFC8620" section="1.6" sectionFormat="comma"></xref>.</t> | |||
<t>The terms Principal, and ShareNotification (with these specific capitalizatio | <t>The terms "Principal" and "ShareNotification" (with this specific capitalizat | |||
ns) are used to refer to the data types defined in this document and instances o | ion) are used to refer to the data types defined in this document and instances | |||
f those data types.</t> | of those data types.</t> | |||
</section> | </section> | |||
<section anchor="data-model-overview"><name>Data Model Overview</name> | <section anchor="data-model-overview"><name>Data Model Overview</name> | |||
<t>A Principal (see <xref target="principals"/>) represents an individual, team, or resource (e.g., a room or projector). The object contains information about the entity being represented, such as a name, description, and time zone. It may also hold domain-specific information. A Principal may be associated with zero or more Accounts (see <xref target="RFC8620" section="1.6.2" sectionFormat="comm a"></xref>) containing data belonging to the Principal. Managing the set of Prin cipals within a system is out of scope for this specification, as it is highly d omain specific. It is likely to map directly from a directory service or other u ser management system.</t> | <t>A Principal (see <xref target="principals"/>) represents an individual, team, or resource (e.g., a room or projector). The object contains information about the entity being represented, such as a name, description, and time zone. It may also hold domain-specific information. A Principal may be associated with zero or more Accounts (see <xref target="RFC8620" section="1.6.2" sectionFormat="comm a"></xref>) containing data belonging to the Principal. Managing the set of Prin cipals within a system is out of scope for this specification, as it is highly d omain specific. It is likely to map directly from a directory service or other u ser management system.</t> | |||
<t>Data types may allow users to share data with others by assigning permissions to Principals. When a user's permissions are changed, a ShareNotification objec t is created for them so a client can inform the user of the changes.</t> | <t>Data types may allow users to share data with others by assigning permissions to Principals. When a user's permissions are changed, a ShareNotification objec t is created for them so a client can inform the user of the changes.</t> | |||
</section> | </section> | |||
<section anchor="subscriptions"><name>Subscribing to Shared Data</name> | <section anchor="subscriptions"><name>Subscribing to Shared Data</name> | |||
<t>Permissions determine whether a user <em>may</em> access data, but not whethe | <t>Permissions determine whether a user <em>may</em> access data but not whether | |||
r they <em>want</em> to. Some shared data is of equal importance as the user's o | they <em>want</em> to. Some shared data is of equal importance as the user's ow | |||
wn, while other data is just there should the user wish to explicitly go find it | n, while other data is just there should the user wish to explicitly go find it. | |||
. Clients will often want to differentiate the two. For example, a company may s | Clients will often want to differentiate the two. For example, a company may sh | |||
hare mailing list archives for all departments with all employees, but a user ma | are mailing list archives for all departments with all employees, but a user may | |||
y only generally be interested in the few they belong to. They would have <em>pe | only generally be interested in the few they belong to. They would have <em>per | |||
rmission</em> to access many mailboxes, but can <em>subscribe</em> to just the o | mission</em> to access many mailboxes but can <em>subscribe</em> to just the one | |||
nes they care about. The client would provide separate interfaces for reading ma | s they care about. The client would provide separate interfaces for reading mail | |||
il in subscribed mailboxes and browsing all mailboxes they have permission to ac | in subscribed mailboxes and browsing all mailboxes they have permission to acce | |||
cess in order to manage which they are subscribed to.</t> | ss in order to manage those that they are subscribed to.</t> | |||
<t>The JMAP Session object (see <xref target="RFC8620" section="2" sectionFormat | <t>The JMAP Session object (see <xref target="RFC8620" section="2" sectionFormat | |||
="comma"></xref>) is defined to include an object in the <tt>accounts</tt> prope | ="comma"></xref>) is defined to include an object in the "accounts" property for | |||
rty for every account that the user has access to. Collaborative systems may sha | every Account that the user has access to. Collaborative systems may share data | |||
re data between a very large number of Principals, most of which the user does n | between a very large number of Principals, most of which the user does not care | |||
ot care about day-to-day. For servers implementing this specification, the Sessi | about day to day. For servers implementing this specification, the Session obje | |||
on object <bcp14>MUST</bcp14> only include Accounts where either the user is sub | ct <bcp14>MUST</bcp14> only include Accounts where either the user is subscribed | |||
scribed to at least one record (see <xref target="RFC8620" section="1.6.3" secti | to at least one record (see <xref target="RFC8620" section="1.6.3" sectionForma | |||
onFormat="comma"></xref>) in the account, or the account belongs to the user. St | t="comma"></xref>) in the Account or the Account belongs to the user. StateChang | |||
ateChange events (<xref target="RFC8620" section="7.1" sectionFormat="comma"></x | e events (<xref target="RFC8620" section="7.1" sectionFormat="comma"></xref>) fo | |||
ref>) for changes to data <bcp14>SHOULD</bcp14> only be sent for data the user h | r changes to data <bcp14>SHOULD</bcp14> only be sent for data the user has subsc | |||
as subscribed to and <bcp14>MUST NOT</bcp14> be sent for any account where the u | ribed to and <bcp14>MUST NOT</bcp14> be sent for any Account where the user is n | |||
ser is not subscribed to any records in the account, except where that account b | ot subscribed to any records in the Account, except where that Account belongs t | |||
elongs to the user.</t> | o the user.</t> | |||
<t>The server <bcp14>MAY</bcp14> reject the user's attempt to subscribe to some resources even if they have permission to access them (e.g., a calendar represen ting a location).</t> | <t>The server <bcp14>MAY</bcp14> reject the user's attempt to subscribe to some resources even if they have permission to access them (e.g., a calendar represen ting a location).</t> | |||
<t>A user can query the set of Principals they have access to with "Principal/qu ery" (see <xref target="principal-query"/>). The Principal object will contain a n Account object for all accounts where the user has permission to access data f or that Principal, even if they are not yet subscribed.</t> | <t>A user can query the set of Principals they have access to with "Principal/qu ery" (see <xref target="principal-query"/>). The Principal object will contain a n Account object for all Accounts where the user has permission to access data f or that Principal, even if they are not yet subscribed.</t> | |||
</section> | </section> | |||
<section anchor="addition-to-the-capabilities-object"><name>Addition to the Capa bilities Object</name> | <section anchor="addition-to-the-capabilities-object"><name>Addition to the Capa bilities Object</name> | |||
<t>The capabilities object is returned as part of the JMAP Session object; see < xref target="RFC8620" section="2" sectionFormat="comma"></xref>. This document d efines two additional capability URIs.</t> | <t>The capabilities object is returned as part of the JMAP Session object; see < xref target="RFC8620" section="2" sectionFormat="comma"></xref>. This document d efines two additional capability URIs.</t> | |||
<section anchor="urn-ietf-params-jmap-principals"><name>urn:ietf:params:jmap:pri ncipals</name> | <section anchor="urn-ietf-params-jmap-principals"><name>urn:ietf:params:jmap:pri ncipals</name> | |||
<t>The <tt>urn:ietf:params:jmap:principals</tt> capability represents support fo r the Principal and ShareNotification data types and associated API methods.</t> | <t>The <tt>urn:ietf:params:jmap:principals</tt> capability represents support fo r the Principal and ShareNotification data types and associated API methods.</t> | |||
<t>The value of this property in the JMAP Session capabilities property is an em | <t>The value of this property in the JMAP Session "capabilities" property is an | |||
pty object.</t> | empty object.</t> | |||
<t>The value of this property in an account’s accountCapabilities property is an | <t>The value of this property in an Account's "accountCapabilities" property is | |||
object that <bcp14>MUST</bcp14> contain the following information on server cap | an object that <bcp14>MUST</bcp14> contain the following information on server c | |||
abilities and permissions for that account:</t> | apabilities and permissions for that Account:</t> | |||
<ul spacing="compact"> | <dl newline="true" spacing="normal"> | |||
<li><t><strong>currentUserPrincipalId</strong>: <tt>Id|null</tt></t> | <dt><strong>currentUserPrincipalId</strong>: <tt>Id|null</tt></dt> | |||
<t>The id of the Principal in this account that corresponds to the user fetching | <dd>The id of the Principal in this Account that corresponds to the user fetchin | |||
this object, if any.</t></li> | g this object, if any.</dd> | |||
</ul> | </dl> | |||
</section> | </section> | |||
<section anchor="urn-ietf-params-jmap-principals-owner"><name>urn:ietf:params:jm ap:principals:owner</name> | <section anchor="urn-ietf-params-jmap-principals-owner"><name>urn:ietf:params:jm ap:principals:owner</name> | |||
<t>The URI <tt>urn:ietf:params:jmap:principals:owner</tt> is solely used as a ke | <t>The URI <tt>urn:ietf:params:jmap:principals:owner</tt> is solely used as a ke | |||
y in an account’s accountCapabilities property. It does not appear in the JMAP S | y in an Account's "accountCapabilities" property. It does not appear in the JMAP | |||
ession capabilities — support is indicated by the <tt>urn:ietf:params:jmap:princ | Session capabilities -- support is indicated by the <tt>urn:ietf:params:jmap:pr | |||
ipals</tt> URI being present in the session capabilities.</t> | incipals</tt> URI being present in the session capabilities.</t> | |||
<t>If <tt>urn:ietf:params:jmap:principals:owner</tt> is a key in an account’s ac | <t>If <tt>urn:ietf:params:jmap:principals:owner</tt> is a key in an Account's "a | |||
countCapabilities, that account (and data therein) is owned by a Principal. Some | ccountCapabilities" property, that Account (and the data therein) is owned by a | |||
accounts may not be owned by a Principal (e.g., the account that contains the d | Principal. Some Accounts may not be owned by a Principal (e.g., the Account that | |||
ata for the Principals themselves), in which case this property is omitted.</t> | contains the data for the Principals themselves), in which case this property i | |||
s omitted.</t> | ||||
<t>The value of this property is an object with the following properties:</t> | <t>The value of this property is an object with the following properties:</t> | |||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>accountIdForPrincipal</strong>: <tt>Id</tt></t> | <dt><strong>accountIdForPrincipal</strong>: <tt>Id</tt></dt><dd> | |||
<t>The id of an account with the <tt>urn:ietf:params:jmap:principals</tt> | The id of an Account with the <tt>urn:ietf:params:jmap:principals</tt> | |||
capability that contains the corresponding Principal object.</t></li> | capability that contains the corresponding Principal object.</dd> | |||
<li><t><strong>principalId</strong>: <tt>Id</tt></t> | <dt><strong>principalId</strong>:<tt>Id</tt></dt><dd> The id of the Principal th | |||
<t>The id of the Principal that owns this account.</t></li> | at owns this Account.</dd> | |||
</ul> | </dl> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="principals"><name>Principals</name> | <section anchor="principals"><name>Principals</name> | |||
<t>A Principal represents an individual, group, location (e.g., a room), resourc | <t>A Principal represents an individual, a group, a location (e.g., a room), a r | |||
e (e.g., a projector) or other entity in a collaborative environment. Sharing in | esource (e.g., a projector), or another entity in a collaborative environment. S | |||
JMAP is generally configured by assigning rights to certain data within an acco | haring in JMAP is generally configured by assigning rights to certain data withi | |||
unt to other Principals. For example, a user may assign permission to read their | n an Account to other Principals. For example, a user may assign permission to r | |||
calendar to a Principal representing another user or their team.</t> | ead their calendar to a Principal representing another user or their team.</t> | |||
<t>In a shared environment such as a workplace, a user may have access to a larg | <t>In a shared environment, such as a workplace, a user may have access to a lar | |||
e number of Principals.</t> | ge number of Principals.</t> | |||
<t>In most systems, the user will have access to a single Account containing Pri | <t>In most systems, the user will have access to a single Account containing Pri | |||
ncipal objects. In some situations, for example when aggregating data from diffe | ncipal objects. In some situations, for example, when aggregating data from diff | |||
rent places, there may be multiple Accounts containing Principal objects.</t> | erent places, there may be multiple Accounts containing Principal objects.</t> | |||
<t>A <strong>Principal</strong> object has the following properties:</t> | <t>A <strong>Principal</strong> object has the following properties:</t> | |||
<dl spacing="normal" newline="true"> | ||||
<dt><strong>id</strong>: <tt>Id</tt> (immutable; server-set)</dt> | ||||
<dd>The id of the Principal.</dd> | ||||
<dt><strong>type</strong>: <tt>String</tt></dt> | ||||
<dd><t>This <bcp14>MUST</bcp14> be one of the following values:</t> | ||||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li><t><strong>id</strong>: <tt>Id</tt> (immutable; server-set)</t> | <li><tt>"individual"</tt>: This represents a single person.</li> | |||
<t>The id of the Principal.</t></li> | <li><tt>"group"</tt>: This represents a group of other Principals.</li> | |||
<li><t><strong>type</strong>: <tt>String</tt></t> | <li><tt>"resource"</tt>: This represents some resource, e.g., a projector.</li> | |||
<t>This <bcp14>MUST</bcp14> be one of the following values:</t> | <li><tt>"location"</tt>: This represents a location.</li> | |||
<li><tt>"other"</tt>: This represents some other undefined Principal.</li> | ||||
<ul spacing="compact"> | </ul></dd> | |||
<li><tt>individual</tt>: This represents a single person.</li> | <dt><strong>name</strong>: <tt>String</tt></dt> | |||
<li><tt>group</tt>: This represents a group of other Principals.</li> | <dd>The name of the Principal, e.g., "Jane Doe" or "Room 4B".</dd> | |||
<li><tt>resource</tt>: This represents some resource, e.g., a projector.</li> | <dt><strong>description</strong>: <tt>String|null</tt></dt> | |||
<li><tt>location</tt>: This represents a location.</li> | <dd>A longer description of the Principal, for example, details about the facili | |||
<li><tt>other</tt>: This represents some other undefined Principal.</li> | ties of a resource, or null if no description is available.</dd> | |||
</ul></li> | <dt><strong>email</strong>: <tt>String|null</tt></dt> | |||
<li><t><strong>name</strong>: <tt>String</tt></t> | <dd>An email address for the Principal, or <tt>null</tt> if no email is availabl | |||
<t>The name of the Principal, e.g., "Jane Doe", or "Room 4B".</t></li> | e. If given, the value <bcp14>MUST</bcp14> conform to the "addr-spec" syntax, as | |||
<li><t><strong>description</strong>: <tt>String|null</tt></t> | defined in <xref target="RFC5322" section="3.4.1" sectionFormat="comma" />.</dd | |||
<t>A longer description of the Principal, for example details about the faciliti | > | |||
es of a resource, or null if no description available.</t></li> | <dt><strong>timeZone</strong>: <tt>String|null</tt></dt> | |||
<li><t><strong>email</strong>: <tt>String|null</tt></t> | <dd>The time zone for this Principal, if known. If not <tt>null</tt>, the value | |||
<t>An email address for the Principal, or null if no email is available. If give | <bcp14>MUST</bcp14> be a time zone name from the IANA Time Zone Database <xref t | |||
n, the value MUST conform to the "addr-spec" syntax, as defined in <xref target= | arget="IANA-TZDB" />.</dd> | |||
"RFC5322" section="3.4.1" sectionFormat="comma" />.</t></li> | <dt><strong>capabilities</strong>: <tt>String[Object]</tt> (server-set)</dt> | |||
<li><t><strong>timeZone</strong>: <tt>String|null</tt></t> | <dd>A map of JMAP capability URIs to domain-specific information about the Princ | |||
<t>The time zone for this Principal, if known. If not null, the value <bcp14>MUS | ipal in relation to that capability, as defined in the document that registered | |||
T</bcp14> be a time zone name from the IANA Time Zone Database <eref target="htt | the capability.</dd> | |||
ps://www.iana.org/time-zones">TZDB</eref>.</t></li> | <dt><strong>accounts</strong>: <tt>Id[Account]|null</tt> (server-set)</dt> | |||
<li><t><strong>capabilities</strong>: <tt>String[Object]</tt> (server-set)</t> | <dd>A map of Account id to Account object for each JMAP Account containing data | |||
<t>A map of JMAP capability URIs to domain specific information about the Princi | for this Principal that the user has access to, or <tt>null</tt> if none.</dd> | |||
pal in relation to that capability, as defined in the document that registered t | </dl> | |||
he capability.</t></li> | ||||
<li><t><strong>accounts</strong>: <tt>Id[Account]|null</tt> (server-set)</t> | ||||
<t>A map of account id to Account object for each JMAP Account containing data | ||||
for this Principal that the user has access to, or null if none.</t></li> | ||||
</ul> | ||||
<section anchor="principal-get"><name>Principal/get</name> | <section anchor="principal-get"><name>Principal/get</name> | |||
<t>This is a standard "/get" method as described in <xref target="RFC8620" secti on="5.1" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/get" method as described in <xref target="RFC8620" secti on="5.1" sectionFormat="comma"></xref>.</t> | |||
</section> | </section> | |||
<section anchor="principal-changes"><name>Principal/changes</name> | <section anchor="principal-changes"><name>Principal/changes</name> | |||
<t>This is a standard "/changes" method as described in <xref target="RFC8620" s | <t>This is a standard "/changes" method as described in <xref target="RFC8620" s | |||
ection="5.2" sectionFormat="comma"></xref>. Note: implementations backed by an e | ection="5.2" sectionFormat="comma"></xref>.</t> | |||
xternal directory may be unable to calculate changes. In this case, they will al | ||||
ways return a "cannotCalculateChanges" error as described in the core JMAP speci | <aside><t>Note: Implementations backed by an external directory may be unable to | |||
fication.</t> | calculate changes. In this case, they will always return a "cannotCalculateChan | |||
ges" error as described in the core JMAP specification.</t></aside> | ||||
</section> | </section> | |||
<section anchor="principal-set"><name>Principal/set</name> | <section anchor="principal-set"><name>Principal/set</name> | |||
<t>This is a standard "/set" method as described in <xref target="RFC8620" secti on="5.3" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/set" method as described in <xref target="RFC8620" secti on="5.3" sectionFormat="comma"></xref>.</t> | |||
<t>Managing Principals is likely tied to a directory service or some other vendo | <t>Managing Principals is likely tied to a directory service or some other vendo | |||
r-specific solution. This management may occur out-of-band, or via an additional | r-specific solution. This management may occur out of band or via an additional | |||
capability defined elsewhere. Allowing direct user modification of properties h | capability defined elsewhere. Allowing direct user modification of properties ha | |||
as security considerations, as noted in <xref target="security-considerations" / | s security considerations, as noted in <xref target="security-considerations" /> | |||
>. Servers MUST reject any change it doesn’t allow with a <tt>forbidden</tt> Set | . A server <bcp14>MUST</bcp14> reject any change it doesn't allow with a "forbid | |||
Error.</t> | den" SetError.</t> | |||
<t>Where a server does support changes via this API, it <bcp14>SHOULD</bcp14> al | <t>Where a server does support changes via this API, it <bcp14>SHOULD</bcp14> al | |||
low an update to the "name", "description" and "timeZone" properties of the Prin | low an update to the "name", "description", and "timeZone" properties of the Pri | |||
cipal with the same id as the "currentUserPrincipalId" in the Account capabiliti | ncipal with the same id as the "currentUserPrincipalId" in the Account capabilit | |||
es. This allows the user to update their own details.</t> | ies. This allows the user to update their own details.</t> | |||
</section> | </section> | |||
<section anchor="principal-query"><name>Principal/query</name> | <section anchor="principal-query"><name>Principal/query</name> | |||
<t>This is a standard "/query" method as described in <xref target="RFC8620" sec tion="5.5" sectionFormat="comma"></xref></t> | <t>This is a standard "/query" method as described in <xref target="RFC8620" sec tion="5.5" sectionFormat="comma"></xref>.</t> | |||
<section anchor="filtering"><name>Filtering</name> | <section anchor="filtering"><name>Filtering</name> | |||
<t>A <strong>FilterCondition</strong> object has the following properties, all o f which are optional:</t> | <t>A <strong>FilterCondition</strong> object has the following properties, all o f which are optional:</t> | |||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>accountIds</strong>: <tt>String[]</tt></t> | <dt><strong>accountIds</strong>: <tt>String[]</tt></dt> | |||
<t>A list of account ids. The Principal matches if any of the ids in this list a | <dd>A list of Account ids. The Principal matches if any of the ids in this list | |||
re keys in the Principal's "accounts" property (i.e., if any of the account ids | are keys in the Principal's "accounts" property (i.e., if any of the Account ids | |||
belong to the Principal).</t></li> | belong to the Principal).</dd> | |||
<li><t><strong>email</strong>: <tt>String</tt></t> | <dt><strong>email</strong>: <tt>String</tt></dt> | |||
<t>The email property of the Principal contains the given string.</t></li> | <dd>The email property of the Principal contains the given string.</dd> | |||
<li><t><strong>name</strong>: <tt>String</tt></t> | <dt><strong>name</strong>: <tt>String</tt></dt> | |||
<t>The name property of the Principal contains the given string.</t></li> | <dd>The name property of the Principal contains the given string.</dd> | |||
<li><t><strong>text</strong> <tt>String</tt></t> | <dt><strong>text</strong>: <tt>String</tt></dt> | |||
<t>The name, email, or description property of the Principal contains the given | <dd>The name, email, or description property of the Principal contains the given | |||
string.</t></li> | string.</dd> | |||
<li><t><strong>type</strong>: <tt>String</tt></t> | <dt><strong>type</strong>: <tt>String</tt></dt> | |||
<t>The type must be exactly as given to match the condition.</t></li> | <dd>The type must be exactly as given to match the condition.</dd> | |||
<li><t><strong>timeZone</strong>: <tt>String</tt></t> | <dt><strong>timeZone</strong>: <tt>String</tt></dt> | |||
<t>The timeZone must be exactly as given to match the condition.</t></li> | <dd>The timeZone must be exactly as given to match the condition.</dd> | |||
</ul> | </dl> | |||
<t>All given conditions in the FilterCondition object must match for the Princip al to match.</t> | <t>All given conditions in the FilterCondition object must match for the Princip al to match.</t> | |||
<t>Text matches for "contains" SHOULD be simple substring matches.</t> | <t>Text matches for "contains" <bcp14>SHOULD</bcp14> be simple substring matches .</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="principal-querychanges"><name>Principal/queryChanges</name> | <section anchor="principal-querychanges"><name>Principal/queryChanges</name> | |||
<t>This is a standard "/queryChanges" method as described in <xref target="RFC86 | <t>This is a standard "/queryChanges" method as described in <xref target="RFC86 | |||
20" section="5.6" sectionFormat="comma"></xref>. Note: implementations backed by | 20" section="5.6" sectionFormat="comma"></xref>.</t> | |||
an external directory may be unable to calculate changes. In this case, they wi | <aside><t>Note: Implementations backed by an external directory may be unable to | |||
ll always return a "cannotCalculateChanges" error as described in the core JMAP | calculate changes. In this case, they will always return a "cannotCalculateChan | |||
specification.</t> | ges" error as described in the core JMAP specification.</t></aside> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="share-notifications"><name>Share Notifications</name> | <section anchor="share-notifications"><name>ShareNotifications</name> | |||
<t>The ShareNotification data type records when the user's permissions to access | <t>The ShareNotification data type records when the user's permissions to access | |||
a shared object changes. ShareNotification are only created by the server; user | a shared object changes. ShareNotifications are only created by the server; use | |||
s cannot create them explicitly. Notifications are stored in the same Account as | rs cannot create them explicitly. They are stored in the same Account as the Pri | |||
the Principals.</t> | ncipals.</t> | |||
<t>Clients may present the list of notifications to the user and allow them to d | <t>Clients may present the list of notifications to the user and allow the user | |||
ismiss them. To dismiss a notification you use a standard "/set" call to destroy | to dismiss them. To dismiss a notification, use a standard "/set" call to destro | |||
it.</t> | y it.</t> | |||
<t>The server <bcp14>SHOULD</bcp14> create a ShareNotification whenever the user | <t>The server <bcp14>SHOULD</bcp14> create a ShareNotification whenever the user | |||
's permissions change on an object. It <bcp14>MAY</bcp14> choose not to create a | 's permissions change on an object. It <bcp14>MAY</bcp14> choose not to create a | |||
notification for permission changes to a group Principal, even if the user is i | notification for permission changes to a group Principal, even if the user is i | |||
n the group, if this is more likely to be overwhelming than helpful, or would cr | n the group, if this is more likely to be overwhelming than helpful, or if it wo | |||
eate excessive notifications within the system.</t> | uld create excessive notifications within the system.</t> | |||
<section anchor="auto-deletion-of-notifications"><name>Auto-deletion of Notifica tions</name> | ||||
<t>The server <bcp14>MAY</bcp14> limit the maximum number of notifications it wi ll store for a user. When the limit is reached, any new notification will cause the previously oldest notification to be automatically deleted.</t> | <t>The server <bcp14>MAY</bcp14> limit the maximum number of notifications it wi ll store for a user. When the limit is reached, any new notification will cause the previously oldest notification to be automatically deleted.</t> | |||
<t>The server <bcp14>MAY</bcp14> coalesce notifications if appropriate, or remov | <t>The server <bcp14>MAY</bcp14> coalesce notifications if appropriate or remove | |||
e notifications that it deems are no longer relevant or after a certain period o | notifications after a certain period of time or that it deems are no longer rel | |||
f time.</t> | evant.</t> | |||
</section> | ||||
<section anchor="object-properties"><name>Object Properties</name> | <t>A <strong>ShareNotification</strong> object has the following properties:</t> | |||
<t>The <strong>ShareNotification</strong> object has the following properties:</ | ||||
t> | ||||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>id</strong>: <tt>String</tt> (immutable; server-set)</t> | <dt><strong>id</strong>: <tt>String</tt> (immutable; server-set)</dt> | |||
<t>The id of the ShareNotification.</t></li> | <dd>The id of the ShareNotification.</dd> | |||
<li><t><strong>created</strong>: <tt>UTCDate</tt> (immutable; server-set)</t> | <dt><strong>created</strong>: <tt>UTCDate</tt> (immutable; server-set)</dt> | |||
<t>The time this notification was created.</t></li> | <dd>The time this notification was created.</dd> | |||
<li><t><strong>changedBy</strong>: <tt>Entity</tt> (immutable; server-set)</t> | <dt><strong>changedBy</strong>: <tt>Entity</tt> (immutable; server-set)</dt> | |||
<t>Who made the change.</t> | <dd><t>Who made the change. An <strong>Entity</strong> object has the following | |||
properties:</t> | ||||
<dl spacing="compact" newline="true"> | ||||
<dt><strong>name</strong>: <tt>String</tt></dt> | ||||
<dd>The name of the entity who made the change.</dd> | ||||
<dt><strong>email</strong>: <tt>String|null</tt></dt> | ||||
<dd>The email of the entity who made the change, or <tt>null</tt> if no email is | ||||
available.</dd> | ||||
<dt><strong>principalId</strong>: <tt>Id|null</tt></dt> | ||||
<dd>The id of the Principal corresponding to the entity who made the change, or | ||||
<tt>null</tt> if no associated Principal.</dd> | ||||
</dl></dd> | ||||
<dt><strong>objectType</strong>: <tt>String</tt> (immutable; server-set)</dt> | ||||
<dd>The name of the data type for the object whose permissions have changed, as | ||||
registered in the IANA "JMAP Data Types" registry <xref target="IANA-JMAP" />, e | ||||
.g., "Calendar" or "Mailbox".</dd> | ||||
<dt><strong>objectAccountId</strong>: <tt>Id</tt> (immutable; server-set)</dt> | ||||
<dd>The id of the Account where this object exists.</dd> | ||||
<dt><strong>objectId</strong>: <tt>Id</tt> (immutable; server-set)</dt> | ||||
<dd>The id of the object that this notification is about.</dd> | ||||
<dt><strong>oldRights</strong>: <tt>String[Boolean]|null</tt> (immutable; server | ||||
-set)</dt> | ||||
<dd>The "myRights" property of the object for the user before the change.</dd> | ||||
<dt><strong>newRights</strong>: <tt>String[Boolean]|null</tt> (immutable; server | ||||
-set)</dt> | ||||
<dd>The "myRights" property of the object for the user after the change.</dd> | ||||
<dt><strong>name</strong>: <tt>String</tt> (immutable; server-set)</dt> | ||||
<dd>The name of the object at the time the notification was made. Determining th | ||||
e name will depend on the data type in question. For example, it might be the "t | ||||
itle" property of a CalendarEvent or the "name" of a Mailbox. The name is to sho | ||||
w users who have had their access rights to the object removed what it is that t | ||||
hey can no longer access. | ||||
<ul spacing="compact"> | </dd> | |||
<li><t><strong>name</strong>: <tt>String</tt></t> | </dl> | |||
<t>The name of the entity who made the change.</t></li> | ||||
<li><t><strong>email</strong>: <tt>String|null</tt></t> | ||||
<t>The email of the entity who made the change, or null if no email is available | ||||
.</t></li> | ||||
<li><t><strong>principalId</strong>: <tt>Id|null</tt></t> | ||||
<t>The id of the Principal corresponding to the entity who made the change, or n | ||||
ull if no associated Principal.</t></li> | ||||
</ul></li> | ||||
<li><t><strong>objectType</strong>: <tt>String</tt> (immutable; server-set)</t> | ||||
<t>The name of the data type for the object whose permissions have changed, as r | ||||
egistered in the <eref target="https://www.iana.org/assignments/jmap/jmap.xhtml# | ||||
jmap-data-types">IANA JMAP Data Types registry</eref>. e.g., "Calendar" or "Mail | ||||
box".</t></li> | ||||
<li><t><strong>objectAccountId</strong>: <tt>Id</tt> (immutable; server-set)</t> | ||||
<t>The id of the account where this object exists.</t></li> | ||||
<li><t><strong>objectId</strong>: <tt>Id</tt> (immutable; server-set)</t> | ||||
<t>The id of the object that this notification is about.</t></li> | ||||
<li><t><strong>oldRights</strong>: <tt>String[Boolean]|null</tt> (immutable; ser | ||||
ver-set)</t> | ||||
<t>The "myRights" property of the object for the user before the change.</t></li | ||||
> | ||||
<li><t><strong>newRights</strong>: <tt>String[Boolean]|null</tt> (immutable; ser | ||||
ver-set)</t> | ||||
<t>The "myRights" property of the object for the user after the change.</t></li> | ||||
<li><t><strong>name</strong>: <tt>String</tt> (immutable; server-set)</t> | ||||
<t>The name of the object at the time the notification was made. Determining the | ||||
name will depend on the data type in question. For example, it might be the "ti | ||||
tle" property of a CalendarEvent or the "name" of a Mailbox. The name is to show | ||||
to users who have had their access rights to the object removed, so that these | ||||
users know what it is they can no longer access.</t></li> | ||||
</ul> | ||||
</section> | ||||
<section anchor="sharenotification-get"><name>ShareNotification/get</name> | <section anchor="sharenotification-get"><name>ShareNotification/get</name> | |||
<t>This is a standard "/get" method as described in <xref target="RFC8620" secti on="5.1" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/get" method as described in <xref target="RFC8620" secti on="5.1" sectionFormat="comma"></xref>.</t> | |||
</section> | </section> | |||
<section anchor="sharenotification-changes"><name>ShareNotification/changes</nam e> | <section anchor="sharenotification-changes"><name>ShareNotification/changes</nam e> | |||
<t>This is a standard "/changes" method as described in <xref target="RFC8620" s ection="5.2" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/changes" method as described in <xref target="RFC8620" s ection="5.2" sectionFormat="comma"></xref>.</t> | |||
</section> | </section> | |||
<section anchor="sharenotification-set"><name>ShareNotification/set</name> | <section anchor="sharenotification-set"><name>ShareNotification/set</name> | |||
<t>This is a standard "/set" method as described in <xref target="RFC8620" secti on="5.3" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/set" method as described in <xref target="RFC8620" secti on="5.3" sectionFormat="comma"></xref>.</t> | |||
<t>Only destroy is supported; any attempt to create/update <bcp14>MUST</bcp14> b | <t>Only destroy is supported; any attempt to create/update <bcp14>MUST</bcp14> b | |||
e rejected with a | e rejected with a "forbidden" SetError.</t> | |||
<tt>forbidden</tt> SetError.</t> | ||||
</section> | </section> | |||
<section anchor="sharenotification-query"><name>ShareNotification/query</name> | <section anchor="sharenotification-query"><name>ShareNotification/query</name> | |||
<t>This is a standard "/query" method as described in <xref target="RFC8620" sec tion="5.5" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/query" method as described in <xref target="RFC8620" sec tion="5.5" sectionFormat="comma"></xref>.</t> | |||
<section anchor="filtering-1"><name>Filtering</name> | <section anchor="filtering-1"><name>Filtering</name> | |||
<t>A <strong>FilterCondition</strong> object has the following properties, all o f which are optional:</t> | <t>A <strong>FilterCondition</strong> object has the following properties, all o f which are optional:</t> | |||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>after</strong>: <tt>UTCDate|null</tt></t> | <dt><strong>after</strong>: <tt>UTCDate|null</tt></dt> | |||
<t>The creation date must be on or after this date to match the condition.</t></ | <dd>The creation date must be on or after this date to match the condition.</dd> | |||
li> | <dt><strong>before</strong>: <tt>UTCDate|null</tt></dt> | |||
<li><t><strong>before</strong>: <tt>UTCDate|null</tt></t> | <dd>The creation date must be before this date to match the condition.</dd> | |||
<t>The creation date must be before this date to match the condition.</t></li> | <dt><strong>objectType</strong>: <tt>String</tt></dt> | |||
<li><t><strong>objectType</strong>: <tt>String</tt></t> | <dd>The objectType value must be identical to the given value to match the condi | |||
<t>The objectType value must be identical to the given value to match the condit | tion.</dd> | |||
ion.</t></li> | <dt><strong>objectAccountId</strong>: <tt>Id</tt></dt> | |||
<li><t><strong>objectAccountId</strong>: <tt>Id</tt></t> | <dd>The objectAccountId value must be identical to the given value to match the | |||
<t>The objectAccountId value must be identical to the given value to match the c | condition.</dd> | |||
ondition.</t></li> | </dl> | |||
</ul> | ||||
<t>All given conditions in the FilterCondition object must match for the ShareNo tification to match.</t> | <t>All given conditions in the FilterCondition object must match for the ShareNo tification to match.</t> | |||
</section> | </section> | |||
<section anchor="sorting"><name>Sorting</name> | <section anchor="sorting"><name>Sorting</name> | |||
<t>The "created" property <bcp14>MUST</bcp14> be supported for sorting.</t> | <t>The "created" property <bcp14>MUST</bcp14> be supported for sorting.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="sharenotification-querychanges"><name>ShareNotification/queryCh anges</name> | <section anchor="sharenotification-querychanges"><name>ShareNotification/queryCh anges</name> | |||
<t>This is a standard "/queryChanges" method as described in <xref target="RFC86 20" section="5.6" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/queryChanges" method as described in <xref target="RFC86 20" section="5.6" sectionFormat="comma"></xref>.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="framework-for-shared-data"><name>Framework for Shared Data</nam e> | <section anchor="framework-for-shared-data"><name>Framework for Shared Data</nam e> | |||
<t>Shareable data types <bcp14>MUST</bcp14> define the following three propertie s:</t> | <t>Shareable data types <bcp14>MUST</bcp14> define the following three propertie s:</t> | |||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>isSubscribed</strong>: <tt>Boolean</tt></t> | <dt><strong>isSubscribed</strong>: <tt>Boolean</tt></dt> | |||
<t>> The value true indicates the user wishes to subscribe to see this data. The | <dd>The value <tt>true</tt> indicates that the user wishes to subscribe to see t | |||
value false indicates the user does not wish to subscribe to see this data. The | his data. The value <tt>false</tt> indicates that the user does not wish to subs | |||
initial value for this property when data is shared by another user is implemen | cribe to see this data. The initial value for this property when data is shared | |||
tation dependent, although data types may give advice on appropriate defaults.</ | by another user is implementation dependent, although data types may give advice | |||
t></li> | on appropriate defaults.</dd> | |||
<li><t><strong>myRights</strong>: <tt>String[Boolean]</tt></t> | <dt><strong>myRights</strong>: <tt>String[Boolean]</tt></dt> | |||
<t>The set of permissions the user currently has. Appropriate permissions are do | <dd>The set of permissions the user currently has. Appropriate permissions are d | |||
main specific and must be defined per data type. Each key is the name of a permi | omain specific and must be defined per data type. Each key is the name of a perm | |||
ssion defined for that data type. The value for the key is <tt>true</tt> if the | ission defined for that data type. The value for the key is <tt>true</tt> if the | |||
user has the permission, or <tt>false</tt> if they do not.</t></li> | user has the permission or <tt>false</tt> if they do not.</dd> | |||
<li><t><strong>shareWith</strong>: <tt>Id[String[Boolean]]|null</tt></t> | <dt><strong>shareWith</strong>: <tt>Id[String[Boolean]]|null</tt></dt> | |||
<t>The value of this property is null if the data is not shared with anyone. Oth | <dd><t>The value of this property is <tt>null</tt> if the data is not shared wit | |||
erwise, it is a map where each key is the id of a Principal with which this data | h anyone. Otherwise, it is a map where each key is the id of a Principal with wh | |||
is shared, and the value associated with that key is the rights to give that Pr | ich this data is shared, and the value associated with that key is the rights to | |||
incipal, in the same format as the <tt>myRights</tt> property. The account id fo | give that Principal, in the same format as the "myRights" property. The Account | |||
r the Principal id can be found in the capabilities of the Account this object i | id for the Principal id can be found in the capabilities of the Account this ob | |||
s in (see <xref target="urn-ietf-params-jmap-principals-owner"/>). </t> | ject is in (see <xref target="urn-ietf-params-jmap-principals-owner"/>).</t> | |||
<t>Users with appropriate permission may set this property to modify who the dat | <t>Users with appropriate permission may set this property to modify who the dat | |||
a is shared with. The Principal that owns the account this data is in <bcp14>MUS | a is shared with. The Principal that owns the Account that this data is in <bcp1 | |||
T NOT</bcp14> be in the set of sharees since the owner's rights are implicit.</t | 4>MUST NOT</bcp14> be in the map, since the owner's rights are implicit.</t></dd | |||
></li> | > | |||
</ul> | </dl> | |||
<section anchor="example"><name>Example</name> | <section anchor="example"><name>Example</name> | |||
<t>Suppose we are designing a data model for a very simple todo list. There is a Todo data type representing a single item to do, each of which belongs to a sin gle TodoList. The specification makes the lists shareable by referencing this do cument and defining the common properties.</t> | <t>Suppose we are designing a data model for a very simple to-do list. There is a Todo data type representing a single item to do, each of which belongs to a si ngle TodoList. The specification makes the TodoLists shareable by referencing th is document and defining the common properties.</t> | |||
<t>First it would define a set of domain-specific rights. For example, a TodoLis tRights object may have the following properties:</t> | <t>First, it would define a set of domain-specific rights. For example, a TodoLi stRights object may have the following properties:</t> | |||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>mayRead</strong>: <tt>Boolean</tt></t> | <dt><strong>mayRead</strong>: <tt>Boolean</tt></dt> | |||
<t>The user may fetch this TodoList, and any Todos that belong to this TodoList. | <dd>The user may fetch this TodoList and any Todos that belong to this TodoList. | |||
</t></li> | </dd> | |||
<li><t><strong>mayWrite</strong>: <tt>Boolean</tt></t> | <dt><strong>mayWrite</strong>: <tt>Boolean</tt></dt> | |||
<t>The user may create, update, or destroy Todos that belong to this TodoList, a | <dd>The user may create, update, or destroy Todos that belong to this TodoList a | |||
nd may change the "name" property of this TodoList.</t></li> | nd may change the "name" property of this TodoList.</dd> | |||
<li><t><strong>mayAdmin</strong>: <tt>Boolean</tt></t> | <dt><strong>mayAdmin</strong>: <tt>Boolean</tt></dt> | |||
<t>The user may see and modify the "myRights" property of this TodoList, and may | <dd>The user may see and modify the "myRights" property of this TodoList and may | |||
destroy this TodoList.</t></li> | destroy this TodoList.</dd> | |||
</ul> | </dl> | |||
<t>Then in the TodoList data type, we would include the three common properties, | <t>Then in the TodoList data type, we would include the three common | |||
in addition to any type-specific properties (like "name" in this case):</t> | properties described in <xref target="framework-for-shared-data" />, in addit | |||
ion to any type-specific | ||||
properties (like "name" in this case):</t> | ||||
<ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
<li><t><strong>id</strong>: <tt>Id</tt> (immutable; server-set)</t> | <dt><strong>id</strong>: <tt>Id</tt> (immutable; server-set)</dt> | |||
<t>The id of the object.</t></li> | <dd>The id of the object.</dd> | |||
<li><t><strong>name</strong>: <tt>String</tt></t> | <dt><strong>name</strong>: <tt>String</tt></dt> | |||
<t>A name for this list of todos.</t></li> | <dd>A name for this list of Todos.</dd> | |||
<li><t><strong>isSubscribed</strong>: <tt>Boolean</tt></t> | <dt><strong>isSubscribed</strong>: <tt>Boolean</tt></dt> | |||
<t>True if the user has indicated they wish to see this list. If false, clients | <dd>True if the user has indicated they wish to see this list. If <tt>false</tt> | |||
should not display this todo list with the user's other lists, but should provid | , clients should not display this TodoList with the user's other TodoLists but s | |||
e a means for users to see and subscribe to all lists that have been shared with | hould provide a means for users to see and subscribe to all TodoLists that have | |||
them.</t></li> | been shared with them.</dd> | |||
<li><t><strong>myRights</strong>: <tt>TodoListRights</tt></t> | <dt><strong>myRights</strong>: <tt>TodoListRights</tt></dt> | |||
<t>The set of permissions the user currently has for this todo list.</t></li> | <dd>The set of permissions the user currently has for this TodoList.</dd> | |||
<li><t><strong>shareWith</strong>: <tt>Id[TodoListRights]|null</tt></t> | <dt><strong>shareWith</strong>: <tt>Id[TodoListRights]|null</tt></dt> | |||
<t>A map of Principal id to rights to give that Principal, or <tt>null</tt> if n | <dd>If not shared with anyone, the value is <tt>null</tt>. Otherwise, it's a map | |||
ot shared with anyone or the user does not have the "mayAdmin" right for this li | where the keys are Principal ids and the values are the rights given to those P | |||
st. Users with the "mayAdmin" right may set this property to modify who the data | rincipals. Users with the "mayAdmin" right may set this property to modify who t | |||
is shared with. The Principal that owns the account this data is in <bcp14>MUST | he data is shared with. The Principal that owns the Account that this data is in | |||
NOT</bcp14> be in the set of sharees; their rights are implicit.</t></li> | <bcp14>MUST NOT</bcp14> be in the map; their rights are implicit.</dd> | |||
</ul> | </dl> | |||
<t>We would define a new Principal capability with two properties:</t> | <t>We would also define a new Principal capability with two properties:</t> | |||
<ul spacing="compact"> | ||||
<li><t><strong>accountId</strong>: <tt>Id|null</tt></t> | ||||
<t>The accountId containing the todo data for this Principal, if it has been sha | ||||
red with the requesting user.</t></li> | ||||
<li><t><strong>mayShareWith</strong>: <tt>Boolean</tt></t> | ||||
<t>May the user add this Principal as a sharee of a todo list?</t></li> | ||||
</ul> | ||||
<t>A client wishing to let the user configure sharing would look at the account | <dl spacing="normal" newline="true"> | |||
capabilities for the Account containing the user's Todo data, and find the "urn: | <dt><strong>accountId</strong>: <tt>Id|null</tt></dt> | |||
ietf:params:jmap:principals:owner" property, as per <xref target="urn-ietf-param | <dd>The accountId containing the Todo data for this Principal, if it has been sh | |||
s-jmap-principals-owner"></xref>. For example, the JMAP Session object might con | ared with the requesting user.</dd> | |||
tain:</t> | <dt><strong>mayShareWith</strong>: <tt>Boolean</tt></dt> | |||
<dd>The user may give this Principal permission to access a TodoList.</dd> | ||||
</dl> | ||||
<figure><artwork> | <t>A client wishing to let the user configure sharing would look at the "capabil | |||
ities" for the Account containing the user's Todo data and find the "urn:ietf:pa | ||||
rams:jmap:principals:owner" property, as per <xref target="urn-ietf-params-jmap- | ||||
principals-owner"></xref>. For example, the JMAP Session object might contain:</ | ||||
t> | ||||
<figure> | ||||
<name>Part of a JMAP Session Object</name> | ||||
<sourcecode type="json"> | ||||
{ | { | |||
"accounts": { | "accounts": { | |||
"u12345678": { | "u12345678": { | |||
"name": "jane.doe@example.com", | "name": "jane.doe@example.com", | |||
"isPersonal": true, | "isPersonal": true, | |||
"isReadOnly": false, | "isReadOnly": false, | |||
"accountCapabilities": { | "accountCapabilities": { | |||
"urn:com.example:jmap:todo": {}, | "urn:com.example:jmap:todo": {}, | |||
"urn:ietf:params:jmap:principals:owner": { | "urn:ietf:params:jmap:principals:owner": { | |||
"accountIdForPrincipal": "u33084183", | "accountIdForPrincipal": "u33084183", | |||
"principalId": "P105aga511jaa" | "principalId": "P105aga511jaa" | |||
} | } | |||
} | } | |||
}, | }, | |||
... | ... | |||
}, | }, | |||
... | ... | |||
} | }</sourcecode> | |||
</artwork></figure> | </figure> | |||
<t>From this it now knows which account has the Principal data, and can fetch th | <t>From this, the client now knows which Account has the Principal data, | |||
e list of Principals to offer the user to share the list with, making an API req | and it can fetch the list of Principals and offer to share it with | |||
uest like this:</t> | the user by making an API request like this:</t> | |||
<figure><artwork> | <figure> | |||
<name>"methodCalls" Property of a JMAP Request</name> | ||||
<sourcecode type="json"> | ||||
[[ "Principal/get", { | [[ "Principal/get", { | |||
"accountId": "u33084183", | "accountId": "u33084183", | |||
"ids": null | "ids": null | |||
}, "0" ]] | }, "0" ]]</sourcecode> | |||
</artwork></figure> | </figure> | |||
<t>Here's an example response (where Joe Bloggs is another user that this user c ould share their todo list with, but who has not shared any data in their own ac count with this user): | <t>Here's an example response (where "Joe Bloggs" is another user that this user could share their TodoList with; Joe has not shared any of their own data with this user, so the "accounts" property is <tt>null</tt>): | |||
</t> | </t> | |||
<figure><artwork> | <figure> | |||
<name>"methodResponses" Property of a JMAP Response</name> | ||||
<sourcecode type="json"> | ||||
[[ "Principal/get", { | [[ "Principal/get", { | |||
"accountId": "u33084183", | "accountId": "u33084183", | |||
"state": "7b8eff5zz", | "state": "7b8eff5zz", | |||
"list": [{ | "list": [{ | |||
"id": "P2342fnddd20", | "id": "P2342fnddd20", | |||
"type": "individual", | "type": "individual", | |||
"name": "Joe Bloggs", | "name": "Joe Bloggs", | |||
"description": null, | "description": null, | |||
"email": "joe.bloggs@example.com", | "email": "joe.bloggs@example.com", | |||
"timeZone": "Australia/Melbourne", | "timeZone": "Australia/Melbourne", | |||
skipping to change at line 367 ¶ | skipping to change at line 397 ¶ | |||
} | } | |||
}, | }, | |||
"accounts": null | "accounts": null | |||
}, { | }, { | |||
"id": "P674pp24095qo49pr", | "id": "P674pp24095qo49pr", | |||
"name": "Board room", | "name": "Board room", | |||
"type": "location", | "type": "location", | |||
... | ... | |||
}, ... ], | }, ... ], | |||
"notFound": [] | "notFound": [] | |||
}, "0" ]] | }, "0" ]]</sourcecode> | |||
</artwork></figure> | </figure> | |||
<t>A todo list can be shared with Joe Bloggs by updating its shareWith property, as in this example request:</t> | <t>A TodoList can be shared with "Joe Bloggs" by updating its shareWith property , as in this example request:</t> | |||
<figure><artwork> | <figure> | |||
<name>"methodCalls" Property of a JMAP Request</name> | ||||
<sourcecode type="json"> | ||||
[[ "TodoList/set", { | [[ "TodoList/set", { | |||
"accountId": "u12345678", | "accountId": "u12345678", | |||
"update": { | "update": { | |||
"tl01n231": { | "tl01n231": { | |||
"shareWith": { | "shareWith": { | |||
"P2342fnddd20": { | "P2342fnddd20": { | |||
"mayRead": true, | "mayRead": true, | |||
"mayWrite": true, | "mayWrite": true, | |||
"mayAdmin": false | "mayAdmin": false | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
}, "0" ]] | }, "0" ]]</sourcecode> | |||
</artwork></figure> | </figure> | |||
</section> | </section> | |||
</section> | </section> | |||
<section><name>Internationalisation Considerations</name> | <section><name>Internationalization Considerations</name> | |||
<t>Experience has shown that unrestricted use of Unicode can lead to problems su | <t>Experience has shown that unrestricted use of Unicode can lead to problems su | |||
ch as inconsistent rendering, users reading text and interpreting it differently | ch as inconsistent rendering, users reading text and interpreting it differently | |||
than intended, and unexpected results when copying text from one location to an | than intended, and unexpected results when copying text from one location to an | |||
other. Servers MAY choose to mitigate this by restricting the set of characters | other. Servers <bcp14>MAY</bcp14> choose to mitigate this by restricting the set | |||
allowed in otherwise unconstrained <tt>String</tt> fields. The FreeformClass, as | of characters allowed in otherwise unconstrained <tt>String</tt> fields. The Fr | |||
documented in <xref target="RFC8264" section="4.3" sectionFormat="comma" /> mig | eeformClass, as documented in <xref target="RFC8264" section="4.3" sectionFormat | |||
ht be a good starting point for this.</t> | ="comma" />, might be a good starting point for this.</t> | |||
<t>Attempts to set a value containing code points outside of the permissible set | <t>Attempts to set a value containing code points outside of the permissible set | |||
can be handled in a few ways by the server. The first option is to simply strip | can be handled in a few ways by the server. The first option is to simply strip | |||
the forbidden characters and store the resulting string. This is likely to be a | the forbidden characters and store the resulting string. This is likely to be a | |||
ppropriate for control characters for example, where they can end up in data acc | ppropriate for control characters, for example, where they can end up in data ac | |||
identally due to copy-and-paste issues, and are probably invisible to the end us | cidentally due to copy-and-paste issues and are probably invisible to the end us | |||
er. JMAP allows the server to transform data on create/update, as long as any ch | er. JMAP allows the server to transform data on create/update, as long as any ch | |||
anged properties are returned to the client in the <tt>/set</tt> response, so it | anged properties are returned to the client in the "/set" response so it knows w | |||
knows what has changed, as per <xref target="RFC8620" section="5.3" sectionForm | hat has changed, as per <xref target="RFC8620" section="5.3" sectionFormat="comm | |||
at="comma" />. Alternatively, the server MAY just reject the create/update with | a" />. Alternatively, the server <bcp14>MAY</bcp14> just reject the create/updat | |||
an <tt>invalidProperties</tt> SetError.</t> | e with an "invalidProperties" SetError.</t> | |||
</section> | </section> | |||
<section anchor="security-considerations"><name>Security Considerations</name> | <section anchor="security-considerations"><name>Security Considerations</name> | |||
<t>All security considerations of JMAP <xref target="RFC8620"></xref> apply to t his specification. Additional considerations are detailed below.</t> | <t>All security considerations of JMAP <xref target="RFC8620"></xref> apply to t his specification. Additional considerations are detailed below.</t> | |||
<section anchor="spoofing"><name>Spoofing</name> | <section anchor="spoofing"><name>Spoofing</name> | |||
<t>Allowing users to edit their own Principal's name (and, to a lesser extent, e mail, description, or type) could allow a user to change their Principal to look like another user in the system, potentially tricking others into sharing priva te data with them. Servers may choose to forbid this, and <bcp14>SHOULD</bcp14> keep logs of such changes to provide an audit trail.</t> | <t>Allowing users to edit their own Principal's name (and, to a lesser extent, e mail, description, or type) could allow a user to change their Principal to look like another user in the system, potentially tricking others into sharing priva te data with them. Servers may choose to forbid this and <bcp14>SHOULD</bcp14> k eep logs of such changes to provide an audit trail.</t> | |||
<t>Note that simply forbidding the use of a name already in the system is insuff icient protection, as a malicious user could still change their name to somethin g easily confused with the existing name by using trivial misspellings or visual ly similar Unicode characters.</t> | <t>Note that simply forbidding the use of a name already in the system is insuff icient protection, as a malicious user could still change their name to somethin g easily confused with the existing name by using trivial misspellings or visual ly similar Unicode characters.</t> | |||
</section> | </section> | |||
<section anchor="unnoticed-sharing"><name>Unnoticed Sharing</name> | <section anchor="unnoticed-sharing"><name>Unnoticed Sharing</name> | |||
<t>Sharing data with another user allows someone to turn a transitory account co mpromise (e.g., brief access to an unlocked or logged-in client) into a persiste nt compromise (by setting up sharing with a user that is controlled by the attac ker). This can be mitigated by requiring further authorisation for configuring s haring, or sending notifications to the sharer via another channel whenever a ne w sharee is added.</t> | <t>Sharing data with another user allows someone to turn a transitory account co mpromise (e.g., brief access to an unlocked or logged-in client) into a persiste nt compromise (by setting up sharing with a user that is controlled by the attac ker). This can be mitigated by requiring further authorization for configuring s haring or sending notifications to the sharer via another channel whenever a new permission is added.</t> | |||
</section> | </section> | |||
<section anchor="dos"><name>Denial of Service</name> | <section anchor="dos"><name>Denial of Service</name> | |||
<t>By creating many changes to the sharing status of objects, a user can cause m any ShareNotifications to be generated, which could lead to resource exhaustion. Servers can mitigate this by coalescing multiple changes to the same object int o a single notification, limiting the maximum number of notifications it stores per user, and/or rate limiting the changes to sharing permissions in the first p lace. Automatically deleting older notifications after reaching a limit can mean the user is not made aware of a sharing change, which can itself be a security issue. For this reason, it is better to coalesce changes and use other mitigatio n strategies.</t> | <t>By creating many changes to the sharing status of objects, a user can cause m any ShareNotifications to be generated, which could lead to resource exhaustion. Servers can mitigate this by coalescing multiple changes to the same object int o a single notification, limiting the maximum number of notifications it stores per user and/or rate-limiting the changes to sharing permissions in the first pl ace. Automatically deleting older notifications after reaching a limit can mean the user is not made aware of a sharing change, which can itself be a security i ssue. For this reason, it is better to coalesce changes and use other mitigation strategies.</t> | |||
</section> | </section> | |||
<section anchor="unauthorised-principals"><name>Unauthorised Principals</name> | <section anchor="unauthorised-principals"><name>Unauthorized Principals</name> | |||
<t>The set of Principals within a shared environment <bcp14>MUST</bcp14> be stri ctly controlled. If adding a new Principal is open to the public, risks include: </t> | <t>The set of Principals within a shared environment <bcp14>MUST</bcp14> be stri ctly controlled. If adding a new Principal is open to the public, risks include: </t> | |||
<ul spacing="compact"> | <ul spacing="compact"> | |||
<li>An increased risk of a user accidentally sharing data with an unintended per son.</li> | <li>An increased risk of a user accidentally sharing data with an unintended per son.</li> | |||
<li>An attacker may share unwanted or offensive information with the user.</li> | <li>An attacker sharing unwanted or offensive information with the user.</li> | |||
<li>An attacker may share items with spam content in the names in order to gener | <li>An attacker sharing items with spam content in the names in order to generat | |||
ate ShareNotification objects, which are likely to be prominently displayed to t | e ShareNotification objects, which are likely to be prominently displayed to the | |||
he sharee.</li> | user receiving them.</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="iana-considerations"><name>IANA Considerations</name> | <section anchor="iana-considerations"><name>IANA Considerations</name> | |||
<section anchor="jmap-capability-registration-for-principals"><name>JMAP Capabil ity Registration for "principals"</name> | <section anchor="jmap-capability-registration-for-principals"><name>JMAP Capabil ity Registration for "principals"</name> | |||
<t>IANA will register the "principals" JMAP Capability as follows:</t> | <t>IANA has registered "principals" in the "JMAP Capabilities" registry as follo | |||
<t>Capability Name: <tt>urn:ietf:params:jmap:principals</tt></t> | ws:</t> | |||
<t>Specification document: this document</t> | <dl newline="false" spacing="compact"> | |||
<t>Intended use: common</t> | <dt>Capability Name:</dt> <dd><tt>urn:ietf:params:jmap:principals</tt></dd> | |||
<t>Change Controller: IETF</t> | <dt>Intended Use:</dt> <dd>common</dd> | |||
<t>Security and privacy considerations: this document, <xref target="security-co | <dt>Change Controller:</dt> <dd>IETF</dd> | |||
nsiderations" /></t> | <dt>Security and Privacy Considerations:</dt> <dd>RFC 9670, <xref target="secu | |||
rity-considerations" /></dd> | ||||
<dt>Reference:</dt> <dd>RFC 9670</dd> | ||||
</dl> | ||||
</section> | </section> | |||
<section anchor="jmap-capability-registration-for-principals-owner"><name>JMAP C apability Registration for "principals:owner"</name> | <section anchor="jmap-capability-registration-for-principals-owner"><name>JMAP C apability Registration for "principals:owner"</name> | |||
<t>IANA will register the "principals:owner" JMAP Capability as follows:</t> | <t>IANA has registered "principals:owner" in the "JMAP Capabilities" registry as | |||
<t>Capability Name: <tt>urn:ietf:params:jmap:principals:owner</tt></t> | follows:</t> | |||
<t>Specification document: this document</t> | <dl newline="false" spacing="compact"> | |||
<t>Intended use: common</t> | <dt>Capability Name:</dt> <dd><tt>urn:ietf:params:jmap:principals:owner</tt></ | |||
<t>Change Controller: IETF</t> | dd> | |||
<t>Security and privacy considerations: this document, <xref target="security-co | <dt>Intended Use:</dt> <dd>common</dd> | |||
nsiderations" /></t> | <dt>Change Controller:</dt> <dd>IETF</dd> | |||
<dt>Security and Privacy Considerations:</dt> <dd>RFC 9670, <xref target="secu | ||||
rity-considerations" /></dd> | ||||
<dt>Reference:</dt> <dd>RFC 9670</dd> | ||||
</dl> | ||||
</section> | </section> | |||
<section anchor="jmap-data-type-registration-for-principal"><name>JMAP Data Type Registration for "Principal"</name> | <section anchor="jmap-data-type-registration-for-principal"><name>JMAP Data Type Registration for "Principal"</name> | |||
<t>IANA will register the "Principal" JMAP Data Type as follows:</t> | <t>IANA has registered "Principal" in the "JMAP Data Types" registry as follows: | |||
<t>Type Name: <tt>Principal</tt></t> | </t> | |||
<t>Can reference blobs: no</t> | <dl newline="false" spacing="compact"> | |||
<t>Can Use for State Change: yes</t> | <dt>Type Name:</dt> <dd>Principal</dd> | |||
<t>Capability: <tt>urn:ietf:params:jmap:principals</tt></t> | <dt>Can Reference Blobs:</dt> <dd>No</dd> | |||
<t>Specification document: this document</t> | <dt>Can Use for State Change:</dt> <dd>Yes</dd> | |||
<dt>Capability:</dt> <dd><tt>urn:ietf:params:jmap:principals</tt></dd> | ||||
<dt>Reference:</dt> <dd>RFC 9670</dd> | ||||
</dl> | ||||
</section> | </section> | |||
<section anchor="jmap-data-type-registration-for-sharenotification"><name>JMAP D ata Type Registration for "ShareNotification"</name> | <section anchor="jmap-data-type-registration-for-sharenotification"><name>JMAP D ata Type Registration for "ShareNotification"</name> | |||
<t>IANA will register the "ShareNotification" JMAP Data Type as follows:</t> | <t>IANA has registered "ShareNotification" in the "JMAP Data Types" registry as | |||
<t>Type Name: <tt>ShareNotification</tt></t> | follows:</t> | |||
<t>Can reference blobs: no</t> | <dl newline="false" spacing="compact"> | |||
<t>Can Use for State Change: yes</t> | <dt>Type Name:</dt> <dd>ShareNotification</dd> | |||
<t>Capability: <tt>urn:ietf:params:jmap:principals</tt></t> | <dt>Can Reference Blobs:</dt> <dd>No</dd> | |||
<t>Specification document: this document</t> | <dt>Can Use for State Change:</dt> <dd>Yes</dd> | |||
<dt>Capability:</dt> <dd><tt>urn:ietf:params:jmap:principals</tt></dd> | ||||
<dt>Reference:</dt> <dd>RFC 9670</dd> | ||||
</dl> | ||||
</section> | </section> | |||
</section> | </section> | |||
</middle> | </middle> | |||
<back> | <back> | |||
<references> | ||||
<name>References</name> | ||||
<references><name>Normative References</name> | <references><name>Normative References</name> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" | |||
xml"/> | /> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5322. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5322.xml" | |||
xml"/> | /> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" | |||
xml"/> | /> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8620. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8620.xml" | |||
xml"/> | /> | |||
</references> | </references> | |||
<references><name>Informative References</name> | <references><name>Informative References</name> | |||
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8264. | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8264.xml" | |||
xml"/> | /> | |||
<reference anchor="IANA-TZDB" | ||||
target="https://www.iana.org/time-zones"> | ||||
<front> | ||||
<title>Time Zone Database</title> | ||||
<author> | ||||
<organization>IANA</organization> | ||||
</author> | ||||
<date/> | ||||
</front> | ||||
</reference> | ||||
<reference anchor="IANA-JMAP" | ||||
target="https://www.iana.org/assignments/jmap"> | ||||
<front> | ||||
<title>JMAP Data Types</title> | ||||
<author> | ||||
<organization>IANA</organization> | ||||
</author> | ||||
<date/> | ||||
</front> | ||||
</reference> | ||||
</references> | ||||
</references> | </references> | |||
</back> | </back> | |||
</rfc> | </rfc> | |||
End of changes. 64 change blocks. | ||||
395 lines changed or deleted | 461 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |