| rfc9610.original.xml | rfc9610.xml | |||
|---|---|---|---|---|
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="UTF-8"?> | |||
| <rfc version="3" ipr="trust200902" docName="draft-ietf-jmap-contacts-10" submiss | ||||
| ionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XIn | ||||
| clude" indexInclude="true" consensus="true"> | ||||
| <front> | <!DOCTYPE rfc [ | |||
| <title abbrev="JMAP Contacts">JMAP for Contacts</title><seriesInfo value="draft- | <!ENTITY nbsp " "> | |||
| ietf-jmap-contacts-10" stream="IETF" status="standard" name="Internet-Draft"></s | <!ENTITY zwsp "​"> | |||
| eriesInfo> | <!ENTITY nbhy "‑"> | |||
| <author role="editor" initials="N.M." surname="Jenkins" fullname="Neil Jenkins"> | <!ENTITY wj "⁠"> | |||
| <organization>Fastmail</organization> | ]> | |||
| <address> | ||||
| <rfc version="3" ipr="trust200902" docName="draft-ietf-jmap-contacts-10" number= | ||||
| "9610" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w | ||||
| 3.org/2001/XInclude" sortRefs="true" symRefs="true" tocInclude="true" consensus= | ||||
| "true" updates="" obsoletes=""> | ||||
| <front> | ||||
| <title abbrev="JMAP Contacts">JSON Meta Application Protocol (JMAP) for Cont | ||||
| acts</title> | ||||
| <seriesInfo name="RFC" value="9610"/> | ||||
| <author role="editor" initials="N." surname="Jenkins" fullname="Neil Jenkins | ||||
| "> | ||||
| <organization>Fastmail</organization> | ||||
| <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> | <code>VIC 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="June" day="07"></date> | <date year="2024" month="December"/> | |||
| <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>contacts</keyword> | <keyword>contacts</keyword> | |||
| <abstract> | <abstract> | |||
| <t>This document specifies a data model for synchronising contacts data with a s erver using JMAP.</t> | <t>This document specifies a data model for synchronising contact data with a se rver using the JSON Meta Application Protocol (JMAP).</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 eric protocol for synchronising data, such as mail, calendars or contacts, betwe en a client and a server. It is optimised for mobile and web environments, and a ims to provide a consistent interface to different data types.</t> | <t>The JSON Meta Application Protocol (JMAP) <xref target="RFC8620"></xref> is a generic protocol for synchronising data, such as mail, calendars, or contacts, between a client and a server. It is optimised for mobile and web environments a nd aims to provide a consistent interface to different data types.</t> | |||
| <t>This specification defines a data model for synchronising contacts between a client and a server using JMAP.</t> | <t>This specification defines a data model for synchronising contacts between a client and a server using JMAP.</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", | <t> | |||
| "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this d | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU | |||
| ocument are to be interpreted as described in BCP 14 <xref target="RFC2119"></xr | IRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | |||
| ef> <xref target="RFC8174"></xref> when, and only when, they appear in all capit | NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14> | |||
| als, as shown here.</t> | RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | |||
| <t>Type signatures, examples and property descriptions in this document follow t | "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to | |||
| he conventions established in <xref target="RFC8620" section="1.1" sectionFormat | be interpreted as | |||
| ="of" />. The Id, UnsignedInt, and UTCDate data types defined in Sections <xref | described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | |||
| target="RFC8620" section="1.2" sectionFormat="bare" />, <xref target="RFC8620" | when, and only when, they appear in all capitals, as shown here. | |||
| section="1.3" sectionFormat="bare" />, and <xref target="RFC8620" section="1.4" | </t> | |||
| sectionFormat="bare" /> of <xref target="RFC8620" /> are also used in this docum | ||||
| ent.</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" />. The Id, UnsignedInt, and UTCDate data types defined in Sections <xre | ||||
| f target="RFC8620" section="1.2" sectionFormat="bare" />, <xref target="RFC8620" | ||||
| section="1.3" sectionFormat="bare" />, and <xref target="RFC8620" section="1.4" | ||||
| sectionFormat="bare" /> of <xref target="RFC8620" /> are also used in this docu | ||||
| ment.</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 on, see <xref target="RFC8620" section="1.6" sectionFormat="comma"></xref>.</t> | <t>The same terminology used in the core JMAP specification (see <xref target="R FC8620" section="1.6" sectionFormat="of"></xref>) is also used in this document. </t> | |||
| <t>The terms AddressBook and ContactCard (with these specific capitalizations) a re used to refer to the data types defined in this document and instances of tho se data types.</t> | <t>The terms AddressBook and ContactCard (with these specific capitalizations) a re used to refer to the data types defined in this document and instances of tho se 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>An Account (see <xref target="RFC8620" section="1.6.2" sectionFormat="comma"> | <t>An Account (see <xref target="RFC8620" section="1.6.2" sectionFormat="of"></x | |||
| </xref>) with support for the contacts data model contains zero or more AddressB | ref>) with support for the contact data model contains zero or more AddressBook | |||
| ook objects, which is a named collection of zero or more ContactCards. A Contact | objects, which is a named collection of zero or more ContactCards. A ContactCard | |||
| Card is a representation of a person, company, or other entity, or a group of su | is a representation of a person, company, entity, or a group of such entities i | |||
| ch entities, in JSContact Card format, as defined in <xref target="RFC9553" sect | n JSContact Card format, as defined in <xref target="RFC9553" section="2" />. Ea | |||
| ion="2" />. Each ContactCard belongs to one or more AddressBooks.</t> | ch ContactCard belongs to one or more AddressBooks.</t> | |||
| <t>In servers with support for JMAP Sharing <xref target="I-D.ietf-jmap-sharing" | <t>In servers with support for JMAP Sharing <xref target="RFC9670" />, users may | |||
| />, users may see and configure sharing of contact data with others. Sharing pe | see and configure sharing of contact data with others. Sharing permissions are | |||
| rmissions are managed per AddressBook.</t> | managed per AddressBook.</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 one additional capability URI.</t> | <t>The capabilities object is returned as part of the JMAP Session object; see < xref target="RFC8620" section="2" sectionFormat="of"></xref>. This document defi nes one additional capability URI.</t> | |||
| <section anchor="urn-ietf-params-jmap-contacts"><name>urn:ietf:params:jmap:conta cts</name> | <section anchor="urn-ietf-params-jmap-contacts"><name>urn:ietf:params:jmap:conta cts</name> | |||
| <t>This represents support for the AddressBook and ContactCard data types and as | <t>This represents support for the AddressBook and ContactCard data types and as | |||
| sociated API methods. The value of this property in the JMAP Session capabilitie | sociated API methods. The value of this property in the JMAP Session "capabiliti | |||
| s property is an empty object.</t> | es" property is an 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 MUST contain the following information on server capabilities and p | an object that <bcp14>MUST</bcp14> contain the following information on server c | |||
| ermissions for that account:</t> | apabilities and permissions for that account:</t> | |||
| <ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
| <li><t><strong>maxAddressBooksPerCard</strong>: <tt>UnsignedInt|null</tt></t> | <dt><strong>maxAddressBooksPerCard</strong>: <tt>UnsignedInt|null</tt></dt> | |||
| <t>The maximum number of AddressBooks (see <xref target="addressbooks" />) that | <dd>The maximum number of AddressBooks (see <xref target="addressbooks" />) that | |||
| can be assigned to a single ContactCard object (see <xref target="contactcards" | can be assigned to a single ContactCard object (see <xref target="contactcards" | |||
| />). This MUST be an integer >= 1, or null for no limit (or rather, the limit | />). This <bcp14>MUST</bcp14> be an integer >= 1, or null for no limit (or r | |||
| is always the number of AddressBooks in the account).</t></li> | ather, the limit is always the number of AddressBooks in the account).</dd> | |||
| <li><t><strong>mayCreateAddressBook</strong>: <tt>Boolean</tt></t> | <dt><strong>mayCreateAddressBook</strong>: <tt>Boolean</tt></dt> | |||
| <t>The user may create an AddressBook in this account if, and only if, this is t | <dd>The user may create an AddressBook in this account if, and only if, this is | |||
| rue.</t></li> | true.</dd> | |||
| </ul> | </dl> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="addressbooks"><name>AddressBooks</name> | <section anchor="addressbooks"><name>AddressBooks</name> | |||
| <t>An AddressBook is a named collection of ContactCards. All ContactCards are as | <t>An AddressBook is a named collection of ContactCards. All ContactCards are as | |||
| sociated with one or more AddressBook.</t> | sociated with one or more AddressBooks.</t> | |||
| <t>A <strong>AddressBook</strong> object has the following properties:</t> | <t>An <strong>AddressBook</strong> object has the following properties:</t> | |||
| <ul> | <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 AddressBook.</t></li> | <dd>The id of the AddressBook.</dd> | |||
| <li><t><strong>name</strong>: <tt>String</tt></t> | <dt><strong>name</strong>: <tt>String</tt></dt> | |||
| <t>The user-visible name of the AddressBook. This MUST NOT be the empty string a | <dd>The user-visible name of the AddressBook. This <bcp14>MUST NOT</bcp14> be th | |||
| nd MUST NOT be greater than 255 octets in size when encoded as UTF-8.</t></li> | e empty string and <bcp14>MUST NOT</bcp14> be greater than 255 octets in size wh | |||
| <li><t><strong>description</strong>: <tt>String|null</tt> (default: null)</t> | en encoded as UTF-8.</dd> | |||
| <t>An optional longer-form description of the AddressBook, to provide context in | <dt><strong>description</strong>: <tt>String|null</tt> (default: null)</dt> | |||
| shared environments where users need more than just the name.</t></li> | <dd>An optional long-form description of the AddressBook that provides context i | |||
| <li><t><strong>sortOrder</strong>: <tt>UnsignedInt</tt> (default: 0)</t> | n shared environments where users need more than just the name.</dd> | |||
| <t>Defines the sort order of AddressBooks when presented in the client's UI, so | <dt><strong>sortOrder</strong>: <tt>UnsignedInt</tt> (default: 0)</dt> | |||
| it is consistent between devices. The number MUST be an integer in the range | <dd><t>Defines the sort order of AddressBooks when presented in the client's UI | |||
| 0 <= sortOrder < 2<sup>31.</sup></t> | so it is consistent between devices. The number <bcp14>MUST</bcp14> be an intege | |||
| <t>An AddressBook with a lower order is to be displayed before a AddressBook | r in the range 0 <= sortOrder < 2<sup>31</sup>.</t> | |||
| with a higher order in any list of AddressBooks in the client's UI. AddressBooks | <t>An AddressBook with a lower order is to be displayed before a AddressBook wit | |||
| with equal order should be sorted in alphabetical order by name. The sorting s | h a higher order in any list of AddressBooks in the client's UI. AddressBooks wi | |||
| hould take into account locale-specific character order convention.</t> | th equal order should be sorted in alphabetical order by name. The sorting shou | |||
| </li> | ld take into account locale-specific character order convention.</t></dd> | |||
| <li><t><strong>isDefault</strong>: <tt>Boolean</tt> (server-set)</t> | <dt><strong>isDefault</strong>: <tt>Boolean</tt> (server-set)</dt> | |||
| <t>This SHOULD be true for exactly one AddressBook in any account, and MUST NOT | <dd>This <bcp14>SHOULD</bcp14> be true for exactly one AddressBook in any accoun | |||
| t and <bcp14>MUST NOT</bcp14> | ||||
| be true for more than one AddressBook within an account. The default | be true for more than one AddressBook within an account. The default | |||
| AddressBook should be used by clients whenever they need to choose an | AddressBook should be used by clients whenever they need to choose an | |||
| AddressBook for the user within this account, and they do not have any other | AddressBook for the user within this account and they do not have any other | |||
| information on which to make a choice. For example, if the user creates a new | information on which to make a choice. For example, if the user creates a new | |||
| contact card, the client may automatically set the card as belonging to the | contact card, the client may automatically set the card as belonging to the | |||
| default AddressBook from the user's primary account.</t> | default AddressBook from the user's primary account.</dd> | |||
| </li> | <dt><strong>isSubscribed</strong>: <tt>Boolean</tt></dt> | |||
| <li><t><strong>isSubscribed</strong>: <tt>Boolean</tt></t> | <dd><t>True if the user has indicated they wish to see this AddressBook in their | |||
| <t>True if the user has indicated they wish to see this AddressBook in their cli | client. This <bcp14>SHOULD</bcp14> default to false for AddressBooks in shared | |||
| ent. This SHOULD default to false for AddressBooks in shared accounts the user h | accounts that the user has access to and true for any new AddressBooks created b | |||
| as access to and true for any new AddressBooks created by the user themself.</t> | y the user themself.</t> | |||
| <t>If false, the AddressBook and its contents SHOULD only be displayed when | <t>If false, the AddressBook and its contents <bcp14>SHOULD</bcp14> only be | |||
| the user explicitly requests it or to offer it for the user to subscribe to.</t> | displayed when the user explicitly requests it. The UI may offer to the user the | |||
| </li> | option of subscribing to it.</t> | |||
| <li><t><strong>shareWith</strong>: <tt>Id[AddressBookRights]|null</tt> (default: | </dd> | |||
| null)</t> | <dt><strong>shareWith</strong>: <tt>Id[AddressBookRights]|null</tt> (default: nu | |||
| <t>A map of Principal (<xref target="I-D.ietf-jmap-sharing" section="2" />) id t | ll)</dt> | |||
| o rights for principals this AddressBook is shared with. The principal to which | <dd>A map of the Principal id (<xref target="RFC9670" section="2" />) to rights | |||
| this AddressBook belongs MUST NOT be in this set. This is null if the AddressBoo | for Principals this AddressBook is shared with. The Principal to which this Addr | |||
| k is not shared with anyone, or the server does not support <xref target="I-D.ie | essBook belongs <bcp14>MUST NOT</bcp14> be in this set. This is null if the Addr | |||
| tf-jmap-sharing" />. The value may be modified only if the user has the mayShare | essBook is not shared with anyone or if the server does not support <xref target | |||
| right. The account id for the principals may be found in the <tt>urn:ietf:param | ="RFC9670" />. The value may be modified only if the user has the "mayShare" rig | |||
| s:jmap:principals:owner</tt> capability of the Account to which the AddressBook | ht. The account id for the Principals may be found in the <tt>urn:ietf:params:jm | |||
| belongs.</t> | ap:principals:owner</tt> capability of the Account to which the AddressBook belo | |||
| </li> | ngs.</dd> | |||
| <li><t><strong>myRights</strong>: <tt>AddressBookRights</tt> (server-set)</t> | <dt><strong>myRights</strong>: <tt>AddressBookRights</tt> (server-set)</dt> | |||
| <t>The set of access rights the user has in relation to this AddressBook.</t> | <dd>The set of access rights the user has in relation to this AddressBook.</dd> | |||
| </li> | </dl> | |||
| </ul> | ||||
| <t>An <strong>AddressBookRights</strong> object has the following properties:</t > | <t>An <strong>AddressBookRights</strong> object has 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 the ContactCards in this AddressBook.</t></li> | <dd>The user may fetch the ContactCards in this AddressBook.</dd> | |||
| <li><t><strong>mayWrite</strong>: <tt>Boolean</tt></t> | <dt><strong>mayWrite</strong>: <tt>Boolean</tt></dt> | |||
| <t>The user may create, modify or destroy all ContactCards in this AddressBook, | <dd>The user may create, modify, or destroy all ContactCards in this AddressBook | |||
| or move them to or from this AddressBook.</t></li> | , or move them to or from this AddressBook.</dd> | |||
| <li><t><strong>mayShare</strong>: <tt>Boolean</tt></t> | <dt><strong>mayShare</strong>: <tt>Boolean</tt></dt> | |||
| <t>The user may modify the "shareWith" property for this AddressBook.</t></li> | <dd>The user may modify the "shareWith" property for this AddressBook.</dd> | |||
| <li><t><strong>mayDelete</strong>: <tt>Boolean</tt></t> | <dt><strong>mayDelete</strong>: <tt>Boolean</tt></dt> | |||
| <t>The user may delete the AddressBook itself.</t></li> | <dd>The user may delete the AddressBook itself.</dd> | |||
| </ul> | </dl> | |||
| <section anchor="addressbook-get"><name>AddressBook/get</name> | <section anchor="addressbook-get"><name>AddressBook/get</name> | |||
| <t>This is a standard "/get" method as described in <xref target="RFC8620" secti on="5.1" sectionFormat="comma"></xref>. The <em>ids</em> argument may be <tt>nul l</tt> to fetch all at once.</t> | <t>This is a standard "/get" method as described in <xref target="RFC8620" secti on="5.1" sectionFormat="of"></xref>. The "ids" argument may be null to fetch all at once.</t> | |||
| </section> | </section> | |||
| <section anchor="addressbook-changes"><name>AddressBook/changes</name> | <section anchor="addressbook-changes"><name>AddressBook/changes</name> | |||
| <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="of"></xref>.</t> | |||
| </section> | </section> | |||
| <section anchor="addressbook-set"><name>AddressBook/set</name> | <section anchor="addressbook-set"><name>AddressBook/set</name> | |||
| <t>This is a standard "/set" method as described in <xref target="RFC8620" secti on="5.3" sectionFormat="comma"></xref> but with the following additional request argument:</t> | <t>This is a standard "/set" method as described in <xref target="RFC8620" secti on="5.3" sectionFormat="of"></xref>, but with the following additional request a rguments:</t> | |||
| <ul> | <dl spacing="normal" newline="true"> | |||
| <li><t><strong>onDestroyRemoveContents</strong>: <tt>Boolean</tt> (default: fals | <dt><strong>onDestroyRemoveContents</strong>: <tt>Boolean</tt> (default: false)< | |||
| e)</t> | /dt> | |||
| <t>If false, any attempt to destroy an AddressBook that still has a ContactCard | <dd>If false, any attempt to destroy an AddressBook that still has a ContactCard | |||
| in it will be rejected with an <tt>addressBookHasContents</tt> SetError. If | in it will be rejected with an "addressBookHasContents" SetError. If | |||
| true, any ContactCard that is in the AddressBook will be removed from it, and if | true, any ContactCard that is in the AddressBook will be removed from it, and if | |||
| such a ContactCard does not belong to any other AddressBook it will be destroye | such a ContactCard does not belong to any other AddressBook, it will be destroy | |||
| d.</t> | ed.</dd> | |||
| </li> | <dt><strong>onSuccessSetIsDefault</strong>: <tt>Id|null</tt></dt> | |||
| <li><t><strong>onSuccessSetIsDefault</strong>: <tt>Id|null</tt></t> | <dd>If an id is given, and all creates, updates, and destroys (if any) succeed | |||
| <t>If an id is given, and all creates, updates and destroys (if any) succeed | ||||
| without error, the server will try to set this AddressBook as the default. | without error, the server will try to set this AddressBook as the default. | |||
| (For references to AddressBook creations, this is equivalent to a | (For references to AddressBook creations, this is equivalent to a | |||
| creation-reference, so the id will be the creation id prefixed with a "#".)</t> | creation-reference, so the id will be the creation id prefixed with a "#".)</dd> | |||
| </li> | </dl> | |||
| </ul> | ||||
| <t>If the id is not found, or the change is not permitted by the server for | ||||
| policy reasons, it MUST be ignored and the currently default AddressBook (if | ||||
| any) will remain as such. No error is returned to the client in this case.</t> | ||||
| <t>As per <xref target="RFC8620" section="5.3" sectionFormat="comma"></xref>, if | ||||
| the default is successfully changed, any | ||||
| changed objects MUST be reported in either the "created" or "updated" | ||||
| argument in the response as appropriate, with the server-set value included.< | ||||
| /t> | ||||
| <t>The "shareWith" property may only be set by users that have the mayShare righ | ||||
| t. When modifying the shareWith property, the user cannot give a right to a prin | ||||
| cipal if the principal did not already have that right and the user making the c | ||||
| hange also does not have that right. Any attempt to do so MUST be rejected with | ||||
| a <tt>forbidden</tt> SetError.</t> | ||||
| <t>Users can subscribe or unsubscribe to an AddressBook by setting the "isSubscr | ||||
| ibed" property. The server MAY forbid users from subscribing to certain AddressB | ||||
| ooks even though they have permission to see them, rejecting the update with a < | ||||
| tt>forbidden</tt> SetError.</t> | ||||
| <t>The following extra SetError type is defined:</t> | ||||
| <t>For "destroy":</t> | ||||
| <ul spacing="compact"> | <t>If the id is not found or if the change is not permitted by the server for | |||
| <li><strong>addressBookHasContents</strong>: The AddressBook has at least one Co | policy reasons, it <bcp14>MUST</bcp14> be ignored and the current default | |||
| ntactCard assigned to it, and the "onDestroyRemoveContents" argument was false.< | AddressBook (if any) will remain as such. No error is returned to the client | |||
| /li> | in this case.</t> | |||
| </ul> | <t>As per <xref target="RFC8620" section="5.3" sectionFormat="of"></xref>, if th | |||
| e default AddressBook is successfully changed, any changed objects <bcp14>MUST</ | ||||
| bcp14> be reported in either the "created" or "updated" argument in the response | ||||
| as appropriate, with the server-set value included.</t> | ||||
| <t>The "shareWith" property may only be set by users that have the "mayShare" ri | ||||
| ght. 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 t | ||||
| he change also does not have that right. Any attempt to do so <bcp14>MUST</bcp14 | ||||
| > be rejected with a "forbidden" SetError.</t> | ||||
| <t>Users can subscribe or unsubscribe to an AddressBook by setting the "isSubscr | ||||
| ibed" property. The server <bcp14>MAY</bcp14> forbid users from subscribing to c | ||||
| ertain AddressBooks even though they have permission to see them, rejecting the | ||||
| update with a "forbidden" SetError.</t> | ||||
| <t>The following extra SetError type is defined for "destroy":</t> | ||||
| <dl spacing="normal"> | ||||
| <dt><strong>addressBookHasContents</strong>:</dt> <dd>The AddressBook has at lea | ||||
| st one ContactCard assigned to it and the "onDestroyRemoveContents" argument was | ||||
| false.</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="contactcards"><name>ContactCards</name> | <section anchor="contactcards"><name>ContactCards</name> | |||
| <t>A <strong>ContactCard</strong> object contains information about a person, co mpany, or other entity, or represents a group of such entities. It is a JSContac t Card object, as defined in <xref target="RFC9553" section="2" />, with the fol lowing additional properties:</t> | <t>A <strong>ContactCard</strong> object contains information about a person, co mpany, or other entity, or represents a group of such entities. It is a JSContac t Card object as defined in <xref target="RFC9553" section="2" /> with the follo wing additional properties:</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 ContactCard. The id property MAY be different to the ContactCar | <dd>The id of the ContactCard. The "id" property <bcp14>MAY</bcp14> be different | |||
| d's "uid" property (as defined in <xref target="RFC9553" section="2.1.9" />). Ho | to the ContactCard's "uid" property (as defined in <xref target="RFC9553" secti | |||
| wever there MUST NOT be more than one ContactCard with the same "uid" in an Acco | on="2.1.9" />). However, there <bcp14>MUST NOT</bcp14> be more than one ContactC | |||
| unt.</t></li> | ard with the same uid in an Account.</dd> | |||
| <li><t><strong>addressBookIds</strong>: <tt>Id[Boolean]</tt></t> | <dt><strong>addressBookIds</strong>: <tt>Id[Boolean]</tt></dt> | |||
| <t>The set of AddressBook ids this ContactCard belongs to. A card MUST belong to | <dd>The set of AddressBook ids that this ContactCard belongs to. A card <bcp14>M | |||
| at least one AddressBook at all times (until it is destroyed). The set is repre | UST</bcp14> belong to at least one AddressBook at all times (until it is destroy | |||
| sented as an object, with each key being an AddressBook id. The value for each k | ed). The set is represented as an object, with each key being an AddressBook id. | |||
| ey in the object MUST be true.</t></li> | The value for each key in the object <bcp14>MUST</bcp14> be true.</dd> | |||
| </ul> | </dl> | |||
| <t>For any Media object in the card (see <xref target="RFC9553" section="2.6.4" />), a new property is defined:</t> | <t>For any Media object in the card (see <xref target="RFC9553" section="2.6.4" />), a new property is defined:</t> | |||
| <ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
| <li><t><strong>blobId</strong>: <tt>Id</tt></t> | <dt><strong>blobId</strong>: <tt>Id</tt></dt> | |||
| <t>An id for the Blob representing the binary contents of the resource.</t></li> | <dd>An id for the Blob representing the binary contents of the resource.</dd> | |||
| </ul> | </dl> | |||
| <t>When returning ContactCards, any Media with a URI that uses the <tt>data</tt> | <t>When returning ContactCards, any Media with a URI that uses the "data:" URL s | |||
| URL scheme (<xref target="RFC2397" />) SHOULD return a <tt>blobId</tt> property | cheme <xref target="RFC2397" /> <bcp14>SHOULD</bcp14> return a "blobId" property | |||
| and omit the <tt>uri</tt> property, as this lets clients load the (potentially | and omit the "uri" property, as this lets clients load the (potentially large) | |||
| large) image file only when needed, and avoids the overhead of Base64 encoding. | image file only when needed and avoids the overhead of Base64 encoding. The "med | |||
| The "mediaType" property MUST also be set. Similarly, when creating or updating | iaType" property <bcp14>MUST</bcp14> also be set. Similarly, when creating or up | |||
| a ContactCard, clients MAY send a <tt>blobId</tt> instead of the <tt>uri</tt> pr | dating a ContactCard, clients <bcp14>MAY</bcp14> send a "blobId" instead of the | |||
| operty for a Media object.</t> | "uri" property for a Media object.</t> | |||
| <t>A contact card with a "kind" property equal to "group" represents a group of | <t>A contact card with a "kind" property equal to "group" represents a group of | |||
| contacts. Clients often present these separately from other contact cards. The " | contacts. Clients often present these separately from other contact cards. The " | |||
| members" property, as defined in <xref target="RFC9553" section="2.1.6" />, cont | members" property, as defined in <xref target="RFC9553" section="2.1.6" />, cont | |||
| ains a set of UIDs (as defined in <xref target="RFC9553" section="2.1.9" />) for | ains a set of uids (as defined in <xref target="RFC9553" section="2.1.9" />) for | |||
| other contacts that are the members of this group. Clients should consider the | other contacts that are the members of this group. | |||
| group to contain any ContactCard with a matching UID, from any account they have | Clients should consider the group to contain any ContactCard with a matching uid | |||
| access to with support for the <tt>urn:ietf:params:jmap:contacts</tt> capabilit | from any account they have access to that has support for the <tt>urn:ietf:para | |||
| y. UIDs that cannot be found SHOULD be ignored but preserved. For example, suppo | ms:jmap:contacts</tt> capability. Any uid that cannot be found <bcp14>SHOULD</bc | |||
| se a user adds contacts from a shared address book to their private group, then | p14> be ignored but preserved. For example, suppose a user adds contacts from a | |||
| temporarily loses access to this address book. The UIDs cannot be resolved so th | shared address book to their private group, then temporarily loses access to thi | |||
| e contacts will disappear from the group. However, if they are given permission | s address book. The uids cannot be resolved, so the contacts will disappear from | |||
| to access the data again the UIDs will be found and the contacts will reappear.< | the group. However, if they are given permission to access the data again, the | |||
| /t> | uids will be found and the contacts will reappear.</t> | |||
| <section anchor="contactcard-get"><name>ContactCard/get</name> | <section anchor="contactcard-get"><name>ContactCard/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="of"></xref>.</t> | |||
| </section> | </section> | |||
| <section anchor="contactcard-changes"><name>ContactCard/changes</name> | <section anchor="contactcard-changes"><name>ContactCard/changes</name> | |||
| <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="of"></xref>.</t> | |||
| </section> | </section> | |||
| <section anchor="contactcard-query"><name>ContactCard/query</name> | <section anchor="contactcard-query"><name>ContactCard/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="of"></xref>.</t> | |||
| <section anchor="filtering"><name>Filtering</name> | <section anchor="filtering"><name>Filtering</name> | |||
| <t>A <strong>FilterCondition</strong> object has the following properties, any o f which may be omitted:</t> | <t>A <strong>FilterCondition</strong> object has the following properties, any o f which may be omitted:</t> | |||
| <ul spacing="compact"> | <dl spacing="normal" newline="true"> | |||
| <li><t><strong>inAddressBook</strong>: <tt>Id</tt></t> | <dt><strong>inAddressBook</strong>: <tt>Id</tt></dt> | |||
| <t>An AddressBook id. A card must be in this address book to match the condition | <dd>An AddressBook id. A card must be in this address book to match the conditio | |||
| .</t></li> | n.</dd> | |||
| <li><t><strong>uid</strong>: <tt>String</tt></t> | <dt><strong>uid</strong>: <tt>String</tt></dt> | |||
| <t>A card must have this string exactly as its uid (as defined in <xref target=" | <dd>A card must have this string exactly as its uid (as defined in <xref target= | |||
| RFC9553" section="2.1.9" />) to match.</t></li> | "RFC9553" section="2.1.9" />) to match.</dd> | |||
| <li><t><strong>hasMember</strong>: <tt>String</tt></t> | <dt><strong>hasMember</strong>: <tt>String</tt></dt> | |||
| <t>A card must have a "members" property (as defined in <xref target="RFC9553" s | <dd>A card must have a "members" property (as defined in <xref target="RFC9553" | |||
| ection="2.1.6" />) that contains this string as one of the uids in the set to ma | section="2.1.6" />) that contains this string as one of the uids in the set to m | |||
| tch.</t></li> | atch.</dd> | |||
| <li><t><strong>kind</strong>: <tt>String</tt></t> | <dt><strong>kind</strong>: <tt>String</tt></dt> | |||
| <t>A card must have a kind property (as defined in <xref target="RFC9553" sectio | <dd>A card must have a "kind" property (as defined in <xref target="RFC9553" sec | |||
| n="2.1.4" />) that equals this string exactly to match.</t></li> | tion="2.1.4" />) that equals this string exactly to match.</dd> | |||
| <li><t><strong>createdBefore</strong>: <tt>UTCDate</tt></t> | <dt><strong>createdBefore</strong>: <tt>UTCDate</tt></dt> | |||
| <t>The "created" date-time of the ContactCard (as defined in <xref target="RFC95 | <dd>The "created" date-time of the ContactCard (as defined in <xref target="RFC9 | |||
| 53" section="2.1.3" />) must be before this date-time to match the condition.</t | 553" section="2.1.3" />) must be before this date-time to match the condition.</ | |||
| ></li> | dd> | |||
| <li><t><strong>createdAfter</strong>: <tt>UTCDate</tt></t> | <dt><strong>createdAfter</strong>: <tt>UTCDate</tt></dt> | |||
| <t>The "created" date-time of the ContactCard (as defined in <xref target="RFC95 | <dd>The "created" date-time of the ContactCard (as defined in <xref target="RFC9 | |||
| 53" section="2.1.3" />) must be the same or after this date-time to match the co | 553" section="2.1.3" />) must be the same or after this date-time to match the c | |||
| ndition.</t></li> | ondition.</dd> | |||
| <li><t><strong>updatedBefore</strong>: <tt>UTCDate</tt></t> | <dt><strong>updatedBefore</strong>: <tt>UTCDate</tt></dt> | |||
| <t>The "updated" date-time of the ContactCard (as defined in <xref target="RFC95 | <dd>The "updated" date-time of the ContactCard (as defined in <xref target="RFC9 | |||
| 53" section="2.1.10" />) must be before this date-time to match the condition.</ | 553" section="2.1.10" />) must be before this date-time to match the condition.< | |||
| t></li> | /dd> | |||
| <li><t><strong>updatedAfter</strong>: <tt>UTCDate</tt></t> | <dt><strong>updatedAfter</strong>: <tt>UTCDate</tt></dt> | |||
| <t>The "updated" date-time of the ContactCard (as defined in <xref target="RFC95 | <dd>The "updated" date-time of the ContactCard (as defined in <xref target="RFC9 | |||
| 53" section="2.1.10" />) must be the same or after this date-time to match the c | 553" section="2.1.10" />) must be the same or after this date-time to match the | |||
| ondition.</t></li> | condition.</dd> | |||
| <li><t><strong>text</strong>: <tt>String</tt></t> | <dt><strong>text</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the text matches with text in the card.</t>< | <dd>A card matches this condition if the text matches with text in the card.</dd | |||
| /li> | > | |||
| <li><t><strong>name</strong>: <tt>String</tt></t> | <dt><strong>name</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the value of any NameComponent in the "name" | <dd>A card matches this condition if the value of any NameComponent in the "name | |||
| property, or the "full" property in the "name" property of the card, (as define | " property or the "full" property in the "name" property of the card (as defined | |||
| d in <xref target="RFC9553" section="2.2.1.2" />) matches the value.</t></li> | in <xref target="RFC9553" section="2.2.1.2" />) matches the value.</dd> | |||
| <li><t><strong>name/given</strong>: <tt>String</tt></t> | <dt><strong>name/given</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the value of a NameComponent with kind "give | <dd>A card matches this condition if the value of a NameComponent with kind "giv | |||
| n" inside the "name" property of the card (as defined in <xref target="RFC9553" | en" inside the "name" property of the card (as defined in <xref target="RFC9553" | |||
| section="2.2.1.2" />) matches the value.</t></li> | section="2.2.1.2" />) matches the value.</dd> | |||
| <li><t><strong>name/surname</strong>: <tt>String</tt></t> | <dt><strong>name/surname</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the value of a NameComponent with kind "surn | <dd>A card matches this condition if the value of a NameComponent with kind "sur | |||
| ame" inside the "name" property of the card (as defined in <xref target="RFC9553 | name" inside the "name" property of the card (as defined in <xref target="RFC955 | |||
| " section="2.2.1.2" />) matches the value.</t></li> | 3" section="2.2.1.2" />) matches the value.</dd> | |||
| <li><t><strong>name/surname2</strong>: <tt>String</tt></t> | <dt><strong>name/surname2</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the value of a NameComponent with kind "surn | <dd>A card matches this condition if the value of a NameComponent with kind "sur | |||
| ame2" inside the "name" property of the card (as defined in <xref target="RFC955 | name2" inside the "name" property of the card (as defined in <xref target="RFC95 | |||
| 3" section="2.2.1.2" />) matches the value.</t></li> | 53" section="2.2.1.2" />) matches the value.</dd> | |||
| <li><t><strong>nickname</strong>: <tt>String</tt></t> | <dt><strong>nickname</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the "name" of any Nickname in the "nicknames | <dd>A card matches this condition if the "name" of any Nickname in the "nickname | |||
| " property of the card (as defined in <xref target="RFC9553" section="2.2.2" />) | s" property of the card (as defined in <xref target="RFC9553" section="2.2.2" /> | |||
| matches the value.</t></li> | ) matches the value.</dd> | |||
| <li><t><strong>organization</strong>: <tt>String</tt></t> | <dt><strong>organization</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the "name" of any Organization in the "organ | <dd>A card matches this condition if the "name" of any Organization in the "orga | |||
| izations" property of the card (as defined in <xref target="RFC9553" section="2. | nizations" property of the card (as defined in <xref target="RFC9553" section="2 | |||
| 2.3" />) matches the value.</t></li> | .2.3" />) matches the value.</dd> | |||
| <li><t><strong>email</strong>: <tt>String</tt></t> | <dt><strong>email</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the "address" or "label" of any EmailAddress | <dd>A card matches this condition if the "address" or "label" of any EmailAddres | |||
| in the "emails" property of the card (as defined in <xref target="RFC9553" sect | s in the "emails" property of the card (as defined in <xref target="RFC9553" sec | |||
| ion="2.3.1" />) matches the value.</t></li> | tion="2.3.1" />) matches the value.</dd> | |||
| <li><t><strong>phone</strong>: <tt>String</tt></t> | <dt><strong>phone</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the "number" or "label" of any Phone in the | <dd>A card matches this condition if the "number" or "label" of any Phone in the | |||
| "phones" property of the card (as defined in <xref target="RFC9553" section="2.3 | "phones" property of the card (as defined in <xref target="RFC9553" section="2. | |||
| .3" />) matches the value.</t></li> | 3.3" />) matches the value.</dd> | |||
| <li><t><strong>onlineService</strong>: <tt>String</tt></t> | <dt><strong>onlineService</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the "service", "uri", "user", or "label" of | <dd>A card matches this condition if the "service", "uri", "user", or "label" of | |||
| any OnlineService in the "onlineServices" property of the card (as defined in <x | any OnlineService in the "onlineServices" property of the card (as defined in < | |||
| ref target="RFC9553" section="2.3.2" />) matches the value.</t></li> | xref target="RFC9553" section="2.3.2" />) matches the value.</dd> | |||
| <li><t><strong>address</strong>: <tt>String</tt></t> | <dt><strong>address</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the value of any AddressComponent in the "ad | <dd>A card matches this condition if the value of any AddressComponent in the "a | |||
| dresses" property, or the "full" property in the "addresses" property of the car | ddresses" property or the "full" property in the "addresses" property of the car | |||
| d, (as defined in <xref target="RFC9553" section="2.5.1" />) matches the value.< | d (as defined in <xref target="RFC9553" section="2.5.1" />) matches the value.</ | |||
| /t></li> | dd> | |||
| <li><t><strong>note</strong>: <tt>String</tt></t> | <dt><strong>note</strong>: <tt>String</tt></dt> | |||
| <t>A card matches this condition if the "note" of any Note in the "notes" proper | <dd>A card matches this condition if the "note" of any Note in the "notes" prope | |||
| ty of the card (as defined in <xref target="RFC9553" section="2.8.3" />) matches | rty of the card (as defined in <xref target="RFC9553" section="2.8.3" />) matche | |||
| the value.</t></li> | s the value.</dd> | |||
| </ul> | </dl> | |||
| <t>If zero properties are specified on the FilterCondition, the condition MUST a | <t>If zero properties are specified on the FilterCondition, the condition <bcp14 | |||
| lways evaluate to <tt>true</tt>. If multiple properties are specified, ALL must | >MUST</bcp14> always evaluate to true. If multiple properties are specified, ALL | |||
| apply for the condition to be <tt>true</tt> (it is equivalent to splitting the o | must apply for the condition to be true (it is equivalent to splitting the obje | |||
| bject into one-property conditions and making them all the child of an AND filte | ct into one-property conditions and making them all the child of an AND filter o | |||
| r operator).</t> | perator).</t> | |||
| <t>The exact semantics for matching <tt>String</tt> fields is <strong>deliberate | <t>The exact semantics for matching <tt>String</tt> fields is deliberately not d | |||
| ly not defined</strong> to allow for flexibility in indexing implementation, sub | efined to allow for flexibility in indexing implementation, subject to the follo | |||
| ject to the following:</t> | wing:</t> | |||
| <ul spacing="compact"> | <ul spacing="normal"> | |||
| <li>Text SHOULD be matched in a case-insensitive manner.</li> | <li>Text <bcp14>SHOULD</bcp14> be matched in a case-insensitive manner.</li> | |||
| <li>Text contained in either (but matched) single or double quotes SHOULD be tre | <li>Text contained in either (but matched) single or double quotes <bcp14>SHOULD | |||
| ated as a <strong>phrase search</strong>, that is a match is required for that e | </bcp14> be treated as a phrase search. That is, a match is required for that ex | |||
| xact sequence of words, excluding the surrounding quotation marks. Use <tt>\"</t | act sequence of words, excluding the surrounding quotation marks. Use <tt>\"</tt | |||
| t>, <tt>\'</tt> and <tt>\\</tt> to match a literal <tt>"</tt>, <tt>'</tt> and <t | >, <tt>\'</tt>, and <tt>\\</tt> to match a literal <tt>"</tt>, <tt>'</tt>, and < | |||
| t>\</tt> respectively in a phrase.</li> | tt>\</tt> respectively in a phrase.</li> | |||
| <li>Outside of a phrase, white-space SHOULD be treated as dividing separate toke | <li>Outside of a phrase, whitespace <bcp14>SHOULD</bcp14> be treated as dividing | |||
| ns that may be searched for separately in the contact, but MUST all be present f | separate tokens that may be searched for separately in the contact, but <bcp14> | |||
| or the contact to match the filter.</li> | MUST</bcp14> all be present for the contact to match the filter.</li> | |||
| <li>Tokens MAY be matched on a whole-word basis using stemming (so for example a | <li>Tokens <bcp14>MAY</bcp14> be matched on a whole-word basis using stemming (e | |||
| text search for <tt>bus</tt> would match "buses" but not "business").</li> | .g., a text search for <tt>bus</tt> would match "buses", but not "business").</l | |||
| i> | ||||
| </ul> | </ul> | |||
| </section> | </section> | |||
| <section anchor="sorting"><name>Sorting</name> | <section anchor="sorting"><name>Sorting</name> | |||
| <t>The following value for the "property" field on the Comparator object | <t>The following values for the "property" field on the Comparator object | |||
| MUST be supported for sorting:</t> | <bcp14>MUST</bcp14> be supported for sorting:</t> | |||
| <ul spacing="compact"> | <ul spacing="normal"> | |||
| <li>"created" - The "created" date on the ContactCard.</li> | <li>"created" - The "created" date on the ContactCard.</li> | |||
| <li>"updated" - The "updated" date on the ContactCard.</li> | <li>"updated" - The "updated" date on the ContactCard.</li> | |||
| </ul> | </ul> | |||
| <t>The following values for the "property" field on the Comparator object SHOULD be supported for sorting:</t> | <t>The following values for the "property" field on the Comparator object <bcp14 >SHOULD</bcp14> be supported for sorting:</t> | |||
| <ul spacing="compact"> | <ul spacing="normal"> | |||
| <li>"name/given" - The value of the first NameComponent in the "name" property | <li>"name/given" - The value of the first NameComponent in the "name" property | |||
| whose "kind" is "given".</li> | whose "kind" is "given".</li> | |||
| <li>"name/surname" - The value of the first NameComponent in the "name" property | <li>"name/surname" - The value of the first NameComponent in the "name" property | |||
| whose "kind" is "surname".</li> | whose "kind" is "surname".</li> | |||
| <li>"name/surname2" - The value of the first NameComponent in the "name" | <li>"name/surname2" - The value of the first NameComponent in the "name" | |||
| property whose "kind" is "surname2".</li> | property whose "kind" is "surname2".</li> | |||
| </ul> | </ul> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="contactcard-querychanges"><name>ContactCard/queryChanges</name> | <section anchor="contactcard-querychanges"><name>ContactCard/queryChanges</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="of"></xref>.</t> | |||
| </section> | </section> | |||
| <section anchor="contactcard-set"><name>ContactCard/set</name> | <section anchor="contactcard-set"><name>ContactCard/set</name> | |||
| <t>This is a standard "/set" method as described in <xref target="RFC8620" secti | <t>This is a standard "/set" method as described in <xref target="RFC8620" secti | |||
| on="5.3" sectionFormat="comma"></xref>.</t> | on="5.3" sectionFormat="of"></xref>.</t> | |||
| <t>To set a new photo, the file must first be uploaded using the upload mechanis | <t>To set a new photo, the file must first be uploaded using the upload mechanis | |||
| m as described in <xref target="RFC8620" section="6.1" sectionFormat="comma"></x | m as described in <xref target="RFC8620" section="6.1" sectionFormat="of"></xref | |||
| ref>. This will give the client a valid blobId/size/type to use. The server MUST | >. This will give the client a valid blobId, size, and type to use. The server < | |||
| reject attempts to set a file that is not a recognised image type as the photo | bcp14>MUST</bcp14> reject attempts to set a file that is not a recognised image | |||
| for a card.</t> | type as the photo for a card.</t> | |||
| </section> | </section> | |||
| <section anchor="contactcard-copy"><name>ContactCard/copy</name> | <section anchor="contactcard-copy"><name>ContactCard/copy</name> | |||
| <t>This is a standard "/copy" method as described in <xref target="RFC8620" sect ion="5.4" sectionFormat="comma"></xref>.</t> | <t>This is a standard "/copy" method as described in <xref target="RFC8620" sect ion="5.4" sectionFormat="of"></xref>.</t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="examples"><name>Examples</name> | <section anchor="examples"><name>Examples</name> | |||
| <t>For brevity, in the following examples only the "methodCalls" property of the Request object, and the "methodResponses" property of the Response object is sh own.</t> | <t>For brevity, only the "methodCalls" property of the Request object and the "m ethodResponses" property of the Response object is shown in the following exampl es.</t> | |||
| <section anchor="fetching-initial-data"><name>Fetching initial data</name> | <section anchor="fetching-initial-data"><name>Fetching Initial Data</name> | |||
| <t>A user has authenticated and the client has fetched the JMAP Session object. | <t>A user has authenticated and the client has fetched the JMAP Session object. | |||
| It finds a single Account with the "urn:ietf:params:jmap:contacts" capability, w | It finds a single Account with the "urn:ietf:params:jmap:contacts" capability wi | |||
| ith id "a0x9", and wants to fetch all the address books and contacts. It might m | th id "a0x9" and wants to fetch all the address books and contacts. It might mak | |||
| ake the following request:</t> | e the following request:</t> | |||
| <artwork>[ | <figure> | |||
| <name>"methodCalls" Property of a JMAP Request</name> | ||||
| <sourcecode type="json">[ | ||||
| ["AddressBook/get", { | ["AddressBook/get", { | |||
| "accountId": "a0x9" | "accountId": "a0x9" | |||
| }, "0"], | }, "0"], | |||
| ["ContactCard/get", { | ["ContactCard/get", { | |||
| "accountId": "a0x9" | "accountId": "a0x9" | |||
| }, "1"] | }, "1"] | |||
| ] | ]</sourcecode> | |||
| </artwork> | </figure> | |||
| <t>The server might respond with something like:</t> | <t>The server might respond with something like:</t> | |||
| <artwork>[ | <figure> | |||
| <name>"methodResponses" Property of a JMAP Response</name> | ||||
| <sourcecode type="json">[ | ||||
| ["AddressBook/get", { | ["AddressBook/get", { | |||
| "accountId": "a0x9", | "accountId": "a0x9", | |||
| "list": [{ | "list": [{ | |||
| "id": "062adcfa-105d-455c-bc60-6db68b69c3f3", | "id": "062adcfa-105d-455c-bc60-6db68b69c3f3", | |||
| "name": "Personal", | "name": "Personal", | |||
| "description": null, | "description": null, | |||
| "sortOrder": 0, | "sortOrder": 0, | |||
| "isDefault": true, | "isDefault": true, | |||
| "isSubscribed": true, | "isSubscribed": true, | |||
| "shareWith": { | "shareWith": { | |||
| "3f1502e0-63fe-4335-9ff3-e739c188f5dd": { | "3f1502e0-63fe-4335-9ff3-e739c188f5dd": { | |||
| "mayRead": true, | ||||
| "mayWrite": false, | ||||
| "mayShare": false, | ||||
| "mayDelete": false | ||||
| } | ||||
| }, | ||||
| "myRights": { | ||||
| "mayRead": true, | ||||
| "mayWrite": true, | ||||
| "mayShare": true, | ||||
| "mayDelete": false | ||||
| } | ||||
| }, { | ||||
| "id": "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe", | ||||
| "name": "Autosaved", | ||||
| "description": null, | ||||
| "sortOrder": 1, | ||||
| "isDefault": false, | ||||
| "isSubscribed": true, | ||||
| "shareWith": null, | ||||
| "myRights": { | ||||
| "mayRead": true, | "mayRead": true, | |||
| "mayWrite": true, | "mayWrite": false, | |||
| "mayShare": true, | "mayShare": false, | |||
| "mayDelete": false | "mayDelete": false | |||
| } | } | |||
| }], | }, | |||
| "notFound": [], | "myRights": { | |||
| "state": "~4144" | "mayRead": true, | |||
| "mayWrite": true, | ||||
| "mayShare": true, | ||||
| "mayDelete": false | ||||
| } | ||||
| }, { | ||||
| "id": "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe", | ||||
| "name": "Autosaved", | ||||
| "description": null, | ||||
| "sortOrder": 1, | ||||
| "isDefault": false, | ||||
| "isSubscribed": true, | ||||
| "shareWith": null, | ||||
| "myRights": { | ||||
| "mayRead": true, | ||||
| "mayWrite": true, | ||||
| "mayShare": true, | ||||
| "mayDelete": false | ||||
| } | ||||
| }], | ||||
| "notFound": [], | ||||
| "state": "~4144" | ||||
| }, "0"], | }, "0"], | |||
| ["Contact/get", { | ["ContactCard/get", { | |||
| "accountId": "a0x9", | "accountId": "a0x9", | |||
| "list": [{ | "list": [{ | |||
| "id": "3", | "id": "3", | |||
| "addressBookIds": { | "addressBookIds": { | |||
| "062adcfa-105d-455c-bc60-6db68b69c3f3": true | "062adcfa-105d-455c-bc60-6db68b69c3f3": true | |||
| }, | }, | |||
| "name": { | "name": { | |||
| "components": [ | "components": [ | |||
| { "kind": "given", "value": "Joe" }, | { "kind": "given", "value": "Joe" }, | |||
| { "kind": "surname", "value": "Bloggs" } | { "kind": "surname", "value": "Bloggs" } | |||
| ], | ], | |||
| "isOrdered": true | "isOrdered": true | |||
| }, | }, | |||
| "emails": { | "emails": { | |||
| "0": { | "0": { | |||
| "contexts": { | "contexts": { | |||
| "private": true | "private": true | |||
| }, | }, | |||
| "address": "joe.bloggs@example.com" | "address": "joe.bloggs@example.com" | |||
| } | ||||
| } | } | |||
| }], | } | |||
| "notFound": [], | }], | |||
| "state": "ewarbckaqJ::112" | "notFound": [], | |||
| "state": "ewarbckaqJ::112" | ||||
| }, "1"] | }, "1"] | |||
| ] | ]</sourcecode> | |||
| </artwork> | </figure> | |||
| </section> | </section> | |||
| <section anchor="changing-the-default-address-book"><name>Changing the default a ddress book</name> | <section anchor="changing-the-default-address-book"><name>Changing the Default A ddress Book</name> | |||
| <t>The client tries to change the default address book from "Personal" to "Autos aved" (and makes no other change):</t> | <t>The client tries to change the default address book from "Personal" to "Autos aved" (and makes no other change):</t> | |||
| <artwork>[ | <figure> | |||
| <name>"methodCalls" Property of a JMAP Request</name> | ||||
| <sourcecode type="json">[ | ||||
| ["AddressBook/set", { | ["AddressBook/set", { | |||
| "accountId": "a0x9", | "accountId": "a0x9", | |||
| "onSuccessSetIsDefault": "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe" | "onSuccessSetIsDefault": "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe" | |||
| }, "0"] | }, "0"] | |||
| ] | ]</sourcecode> | |||
| </artwork> | </figure> | |||
| <t>The server allows the change, returning the following response:</t> | <t>The server allows the change, returning the following response:</t> | |||
| <artwork>[ | <figure> | |||
| <name>"methodResponses" Property of a JMAP Response</name> | ||||
| <sourcecode type="json">[ | ||||
| ["AddressBook/set", { | ["AddressBook/set", { | |||
| "accountId": "a0x9", | "accountId": "a0x9", | |||
| "updated": { | "updated": { | |||
| "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe": { | "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe": { | |||
| "isDefault": true | "isDefault": true | |||
| }, | }, | |||
| "062adcfa-105d-455c-bc60-6db68b69c3f3": { | "062adcfa-105d-455c-bc60-6db68b69c3f3": { | |||
| "isDefault": false | "isDefault": false | |||
| } | }, | |||
| "oldState": "~4144", | ||||
| "newState": "~4148" | ||||
| } | } | |||
| }, "0"] | }, "0"] | |||
| ] | ]</sourcecode> | |||
| </artwork> | </figure> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section><name>Internationalisation Considerations</name> | <section><name>Internationalisation 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> | ="of"/>, might be a good starting point for | |||
| <t>Attempts to set a value containing code points outside of the permissible set | this.</t> | |||
| can be handled in a few ways by the server. The server could choose to strip th | ||||
| e forbidden characters, or replace them with U+FFFD (the Unicode replacement cha | <t>Attempts to set a value containing code points outside of the permissible set | |||
| racter), and store the resulting string. This is likely to be appropriate for no | can be handled in a few ways by the server. The server could choose to strip th | |||
| n-printable characters — such as the "Control Codes" defined in <xref target="UN | e forbidden characters or replace them with U+FFFD (the Unicode replacement char | |||
| ICODE"/> Section 23.1, excluding newline (U+000A), carriage return (U+000D), and | acter) and store the resulting string. This is likely to be appropriate for non- | |||
| tab (U+0009) — which can end up in data accidentally due to copy-and-paste issu | printable characters -- such as the "Control Codes" defined in <eref target="htt | |||
| es, but are invisible to the end user. JMAP allows the server to transform data | ps://www.unicode.org/versions/latest/core-spec/chapter-23/#G20365">Section 23.1< | |||
| on create/update, as long as any changed properties are returned to the client i | /eref> of <xref target="UNICODE"/>, excluding newline (U+000A), carriage return | |||
| n the <tt>/set</tt> response, so it knows what has changed, as per <xref target= | (U+000D), and tab (U+0009) -- that can end up in data accidentally due to copy-a | |||
| "RFC8620" section="5.3" sectionFormat="comma" />. Alternatively, the server MAY | nd-paste issues but are invisible to the end user. JMAP allows the server to tra | |||
| just reject the create/update with an <tt>invalidProperties</tt> SetError.</t> | nsform data on create/update as long as any changed properties are returned to t | |||
| he client in the "/set" response so it knows what has changed, as per <xref targ | ||||
| et="RFC8620" section="5.3" sectionFormat="of" />. Alternatively, the server <bcp | ||||
| 14>MAY</bcp14> just reject the create/update with an "invalidProperties" SetErro | ||||
| r.</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>All security considerations of JMAP <xref target="RFC8620"></xref> apply to t | |||
| this specification. Additional considerations specific to the data types and fu | his specification. Additional considerations specific to the data types and func | |||
| nctionality introduced by this document are described in the following subsectio | tionality introduced by this document are described in the following subsection. | |||
| n.</t> | </t> | |||
| <t>Contacts consist almost entirely of private, personally identifiable informat | <t>Contacts consist almost entirely of private, personally identifiable informat | |||
| ion, and represent the social connections of users. Privacy leaks can have real | ion, and represent the social connections of users. Privacy leaks can have real | |||
| world consequences, and contacts servers and clients MUST be mindful of the need | world consequences, and contact servers and clients <bcp14>MUST</bcp14> be mindf | |||
| to keep all data secure.</t> | ul of the need to keep all data secure.</t> | |||
| <t>Servers MUST enforce the ACLs set on address books to ensure only authorised | <t>Servers <bcp14>MUST</bcp14> enforce the Access Control Lists (ACLs) set on ad | |||
| data is shared.</t> | dress books to ensure only authorised data is shared.</t> | |||
| </section> | </section> | |||
| <section anchor="iana-considerations"><name>IANA Considerations</name> | <section anchor="iana-considerations"><name>IANA Considerations</name> | |||
| <section anchor="jmap-capability-registration-for-contacts"><name>JMAP capabilit | <section anchor="jmap-capability-registration-for-contacts"><name>JMAP Capabilit | |||
| y registration for "contacts"</name> | y Registration for "contacts"</name> | |||
| <t>IANA will register "contacts" in the "JMAP Capabilities" registry as follows: | <t>IANA has registered "contacts" in the "JMAP Capabilities" registry as follows | |||
| </t> | :</t> | |||
| <t>Capability Name: <tt>urn:ietf:params:jmap:contacts</tt></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:contacts</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>this document, <xref target=" | |||
| security-considerations" /></dd> | ||||
| <dt>Reference:</dt><dd>this document</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| <section anchor="jmap-data-type-registration-for-addressbook"><name>JMAP Data Ty pe Registration for "AddressBook"</name> | <section anchor="jmap-data-type-registration-for-addressbook"><name>JMAP Data Ty pe Registration for "AddressBook"</name> | |||
| <t>IANA will register "AddressBook" in the "JMAP Data Types" registry as follows | <t>IANA has registered "AddressBook" in the "JMAP Data Types" registry as follow | |||
| :</t> | s:</t> | |||
| <t>Type Name: <tt>AddressBook</tt></t> | <dl newline="false" spacing="compact"> | |||
| <t>Can reference blobs: no</t> | <dt>Type Name:</dt><dd><tt>AddressBook</tt></dd> | |||
| <t>Can Use for State Change: yes</t> | <dt>Can Reference Blobs:</dt><dd>No</dd> | |||
| <t>Capability: <tt>urn:ietf:params:jmap:contacts</tt></t> | <dt>Can Use for State Change:</dt><dd>Yes</dd> | |||
| <t>Specification document: this document</t> | <dt>Capability:</dt><dd><tt>urn:ietf:params:jmap:contacts</tt></dd> | |||
| <dt>Reference:</dt><dd>this document</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| <section anchor="jmap-data-type-registration-for-contactcard"><name>JMAP Data Ty pe Registration for "ContactCard"</name> | <section anchor="jmap-data-type-registration-for-contactcard"><name>JMAP Data Ty pe Registration for "ContactCard"</name> | |||
| <t>IANA will register "ContactCard" in the "JMAP Data Types" registry as follows | <t>IANA has registered "ContactCard" in the "JMAP Data Types" registry as follow | |||
| :</t> | s:</t> | |||
| <t>Type Name: <tt>ContactCard</tt></t> | ||||
| <t>Can reference blobs: yes</t> | <dl newline="false" spacing="compact"> | |||
| <t>Can Use for State Change: yes</t> | <dt>Type Name:</dt><dd><tt>ContactCard</tt></dd> | |||
| <t>Capability: <tt>urn:ietf:params:jmap:contacts</tt></t> | <dt>Can Reference Blobs:</dt><dd>Yes</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:contacts</tt></dd> | ||||
| <dt>Reference:</dt><dd>this document</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| <section anchor="jmap-error-codes-registry" title="JMAP Error Codes Registry"> | <section anchor="jmap-error-codes-registry" title="JMAP Error Codes Registry"> | |||
| <t>The following subsection registers a new error code in the "JMAP | <t>The following subsection has registered a new error code in the "JMAP | |||
| Error Codes" registry, as defined in <xref target="RFC8620" section="9"/>. | Error Codes" registry, as defined in <xref target="RFC8620" section="9"/>. | |||
| </t> | </t> | |||
| <section anchor="addressbookhascontents" title="addressBookHasContents"> | <section anchor="addressbookhascontents" title="addressBookHasContents"> | |||
| <t>JMAP Error Code: addressBookHasContents</t> | <dl newline="false" spacing="compact"> | |||
| <t>Intended use: common</t> | <dt>JMAP Error Code:</dt><dd>addressBookHasContents</dd> | |||
| <t>Change controller: IETF</t> | <dt>Intended Use:</dt><dd>common</dd> | |||
| <t>Reference: This document, <xref target="addressbook-set"/></t> | <dt>Change Controller:</dt><dd>IETF</dd> | |||
| <t>Description: The AddressBook has at least one ContactCard assigned to it, and | <dt>Description:</dt><dd>The AddressBook has at least one ContactCard assigned t | |||
| the "onDestroyRemoveContents" argument was false.</t> | o it, and the "onDestroyRemoveContents" argument was false.</dd> | |||
| <dt>Reference:</dt><dd>This document, <xref target="addressbook-set"/></dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="jscontact-property-registrations"> | <section anchor="jscontact-property-registrations"> | |||
| <name>JSContact Property Registrations</name> | <name>JSContact Property Registrations</name> | |||
| <t>IANA will register the following additional properties in the JSContact Prope rties Registry, as defined in <xref target="RFC9553" section="3"/>.</t> | <t>IANA has registered the following additional properties in the "JSContact Pro perties" registry, as defined in <xref target="RFC9553" section="3"/>.</t> | |||
| <section anchor="id"><name>id</name> | <section anchor="id"><name>id</name> | |||
| <t>Property Name: id</t> | <dl newline="false" spacing="compact"> | |||
| <t>Property Type: Not applicable</t> | <dt>Property Name:</dt><dd>id</dd> | |||
| <t>Property Context: Card</t> | <dt>Property Type:</dt><dd>not applicable</dd> | |||
| <t>Intended Use: Reserved</t> | <dt>Property Context:</dt><dd>Card</dd> | |||
| <t>Since Version: 1.0</t> | <dt>Intended Usage:</dt><dd>reserved</dd> | |||
| <t>Change Controller: IETF</t> | <dt>Since Version:</dt><dd>1.0</dd> | |||
| <dt>Change Controller:</dt><dd>IETF</dd> | ||||
| <dt>Reference:</dt><dd>this document</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| <section anchor="addressBookIds"><name>addressBookIds</name> | <section anchor="addressBookIds"><name>addressBookIds</name> | |||
| <t>Property Name: addressBookIds</t> | <dl newline="false" spacing="compact"> | |||
| <t>Property Type: Not applicable</t> | <dt>Property Name:</dt><dd>addressBookIds</dd> | |||
| <t>Property Context: Card</t> | <dt>Property Type:</dt><dd>not applicable</dd> | |||
| <t>Intended Use: Reserved</t> | <dt>Property Context:</dt><dd>Card</dd> | |||
| <t>Since Version: 1.0</t> | <dt>Intended Usage:</dt><dd>reserved</dd> | |||
| <t>Change Controller: IETF</t> | <dt>Since Version:</dt><dd>1.0</dd> | |||
| <dt>Change Controller:</dt><dd>IETF</dd> | ||||
| <dt>Reference:</dt><dd>this document</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| <section anchor="blobId"><name>blobId</name> | <section anchor="blobId"><name>blobId</name> | |||
| <t>Property Name: blobId</t> | <dl newline="false" spacing="compact"> | |||
| <t>Property Type: Not applicable</t> | <dt>Property Name:</dt><dd>blobId</dd> | |||
| <t>Property Context: Media</t> | <dt>Property Type:</dt><dd>not applicable</dd> | |||
| <t>Intended Use: Reserved</t> | <dt>Property Context:</dt><dd>Media</dd> | |||
| <t>Since Version: 1.0</t> | <dt>Intended Usage:</dt><dd>reserved</dd> | |||
| <t>Change Controller: IETF</t> | <dt>Since Version:</dt><dd>1.0</dd> | |||
| <dt>Change Controller:</dt><dd>IETF</dd> | ||||
| <dt>Reference:</dt><dd>this document</dd> | ||||
| </dl> | ||||
| </section> | </section> | |||
| </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://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" /> | |||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2397.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2397.xml" /> | |||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" /> | |||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8620.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8620.xml" /> | |||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9553.xml" /> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9553.xml" /> | |||
| <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-jma p-sharing.xml"/> | <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9670.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="UNICODE" target="http://www.unicode.org/versions/latest/"> | <reference anchor="UNICODE" target="https://www.unicode.org/versions/latest/"> | |||
| <front> | <front> | |||
| <title abbrev="Unicode">The Unicode Standard</title> | <title abbrev="Unicode">The Unicode Standard</title> | |||
| <author><organization>The Unicode Consortium</organization><address /></author> | <author><organization>The Unicode Consortium</organization><address /></author> | |||
| </front> | </front> | |||
| <annotation>Note that this reference is to the latest version of | ||||
| Unicode, rather than to a specific release. It is not expected that | ||||
| future changes in the Unicode Standard will affect the referenced | ||||
| definitions.</annotation> | ||||
| </reference> | </reference> | |||
| </references> | ||||
| </references> | ||||
| </references> | ||||
| </back> | </back> | |||
| </rfc> | </rfc> | |||
| End of changes. 75 change blocks. | ||||
| 479 lines changed or deleted | 527 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. | ||||