Skip to main content

JMAP for Contacts
draft-ietf-jmap-contacts-02

The information below is for an old version of the document.
Document Type
This is an older version of an Internet-Draft that was ultimately published as RFC 9610.
Author Neil Jenkins
Last updated 2024-01-03 (Latest revision 2023-11-06)
RFC stream Internet Engineering Task Force (IETF)
Formats
Reviews
Additional resources Mailing list discussion
Stream WG state In WG Last Call
Associated WG milestone
Dec 2023
Submit Contacts document to the IESG
Document shepherd Jim Fenton
IESG IESG state Became RFC 9610 (Proposed Standard)
Consensus boilerplate Yes
Telechat date (None)
Responsible AD (None)
Send notices to fenton@bluepopcorn.net
draft-ietf-jmap-contacts-02
JMAP                                                   N.M. Jenkins, Ed.
Internet-Draft                                                  Fastmail
Intended status: Standards Track                         7 November 2023
Expires: 10 May 2024

                           JMAP for Contacts
                      draft-ietf-jmap-contacts-02

Abstract

   This document specifies a data model for synchronising contacts data
   with a server using JMAP.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 10 May 2024.

Copyright Notice

   Copyright (c) 2023 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.  Code Components
   extracted from this document must include Revised BSD License text as
   described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Revised BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2

Jenkins                    Expires 10 May 2024                  [Page 1]
Internet-Draft                JMAP Contacts                November 2023

     1.1.  Notational conventions  . . . . . . . . . . . . . . . . .   2
     1.2.  Terminology . . . . . . . . . . . . . . . . . . . . . . .   3
     1.3.  Data Model Overview . . . . . . . . . . . . . . . . . . .   3
     1.4.  Addition to the Capabilities Object . . . . . . . . . . .   3
       1.4.1.  urn:ietf:params:jmap:contacts . . . . . . . . . . . .   3
   2.  AddressBooks  . . . . . . . . . . . . . . . . . . . . . . . .   4
     2.1.  AddressBook/get . . . . . . . . . . . . . . . . . . . . .   5
     2.2.  AddressBook/changes . . . . . . . . . . . . . . . . . . .   5
     2.3.  AddressBook/set . . . . . . . . . . . . . . . . . . . . .   5
   3.  ContactCards  . . . . . . . . . . . . . . . . . . . . . . . .   5
     3.1.  ContactCard/get . . . . . . . . . . . . . . . . . . . . .   6
     3.2.  ContactCard/changes . . . . . . . . . . . . . . . . . . .   6
     3.3.  ContactCard/query . . . . . . . . . . . . . . . . . . . .   7
       3.3.1.  Filtering . . . . . . . . . . . . . . . . . . . . . .   7
       3.3.2.  Sorting . . . . . . . . . . . . . . . . . . . . . . .   8
     3.4.  ContactCard/queryChanges  . . . . . . . . . . . . . . . .   9
     3.5.  ContactCard/set . . . . . . . . . . . . . . . . . . . . .   9
     3.6.  ContactCard/copy  . . . . . . . . . . . . . . . . . . . .   9
   4.  Security considerations . . . . . . . . . . . . . . . . . . .   9
     4.1.  Privacy . . . . . . . . . . . . . . . . . . . . . . . . .   9
   5.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  10
     5.1.  JMAP capability registration for "contacts" . . . . . . .  10
   6.  Normative References  . . . . . . . . . . . . . . . . . . . .  10
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  10

1.  Introduction

   JMAP ([RFC8620] JSON Meta Application Protocol) 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, and aims to provide a consistent interface to different
   data types.

   This specification defines a data model for synchronising contacts
   between a client and a server using JMAP.

1.1.  Notational conventions

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in BCP
   14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

   Type signatures, examples and property descriptions in this document
   follow the conventions established in Section 1.1 of [RFC8620].  Data
   types defined in the core specification are also used in this
   document.

Jenkins                    Expires 10 May 2024                  [Page 2]
Internet-Draft                JMAP Contacts                November 2023

1.2.  Terminology

   The same terminology is used in this document as in the core JMAP
   specification, see [RFC8620], Section 1.6.

   The terms AddressBook and ContactCard (with these specific
   capitalizations) are used to refer to the data types defined in this
   document and instances of those data types.

1.3.  Data Model Overview

   An Account (see [RFC8620], Section 1.6.2) with support for the
   contacts data model contains zero or more AddressBook objects, which
   is a named collection of ContactCards.  A ContactCard is a
   representation of a person, company, or other entity, or a group of
   such entities, in RFCXXXX JSContact Card format.  Each ContactCard
   belongs to one or more AddressBooks.

   In servers with support for JMAP Sharing [RFC XXX], data may be
   shared with other users.  Sharing permissions are managed per
   AddressBook.

1.4.  Addition to the Capabilities Object

   The capabilities object is returned as part of the JMAP Session
   object; see [RFC8620], Section 2.  This document defines two
   additional capability URIs.

1.4.1.  urn:ietf:params:jmap:contacts

   This represents support for the AddressBook and ContactCard data
   types and associated API methods.  The value of this property in the
   JMAP Session capabilities property is an empty object.

   The value of this property in an account’ (U+2019)s
   accountCapabilities property is an object that MUST contain the
   following information on server capabilities and permissions for that
   account:

   *  *maxAddressBooksPerCard*: UnsignedInt|null The maximum number of
      AddressBooks (see Section XXX) that can be can assigned to a
      single ContactCard object (see Section XXX).  This MUST be an
      integer >= 1, or null for no limit (or rather, the limit is always
      the number of AddressBooks in the account).
   *  *mayCreateAddressBook*: Boolean If true, the user may create an
      AddressBook in this account.

Jenkins                    Expires 10 May 2024                  [Page 3]
Internet-Draft                JMAP Contacts                November 2023

2.  AddressBooks

   An AddressBook is a named collection of ContactCards.  All
   ContactCards are associated with one or more AddressBook.

   A *AddressBook* object has the following properties:

   *  *id*: Id (immutable; server-set) The id of the AddressBook.

   *  *name*: String The user-visible name of the AddressBook.  This may
      be any UTF-8 string of at least 1 character in length and maximum
      255 octets in size.

   *  *isSubscribed*: Boolean Has the user indicated they wish to see
      this AddressBook in their client?  This SHOULD default to false
      for AddressBooks in shared accounts the user has access to and
      true for any new AddressBooks created by the user themself.

      If false, the AddressBook and its contents should only be
      displayed when the user explicitly requests it or to offer it for
      the user to subscribe to.

   *  *shareWith*: Id[AddressBookRights]|null (default: null) A map of
      Principal id to rights for principals this AddressBook is shared
      with.  The principal to which this AddressBook belongs MUST NOT be
      in this set.  This is null if the AddressBook is not shared with
      anyone.  May be modified only if the user has the mayAdmin right.
      The account id for the principals may be found in the
      urn:ietf:params:jmap:principals:owner capability of the Account to
      which the AddressBook belongs.

   *  *myRights*: AddressBookRights (server-set) The set of access
      rights the user has in relation to this AddressBook.

   An *AddressBookRights* object has the following properties:

   *  *mayRead*: Boolean The user may fetch the ContactCards in this
      AddressBook.
   *  *mayWrite*: Boolean The user may create, modify or destroy all
      ContactCards in this AddressBook, or move them to or from this
      AddressBook.
   *  *mayAdmin*: Boolean The user may modify sharing for this
      AddressBook.
   *  *mayDelete*: Boolean The user may delete the AddressBook itself.

Jenkins                    Expires 10 May 2024                  [Page 4]
Internet-Draft                JMAP Contacts                November 2023

2.1.  AddressBook/get

   This is a standard "/get" method as described in [RFC8620],
   Section 5.1.  The _ids_ argument may be null to fetch all at once.

2.2.  AddressBook/changes

   This is a standard "/changes" method as described in [RFC8620],
   Section 5.2.

2.3.  AddressBook/set

   This is a standard "/set" method as described in [RFC8620],
   Section 5.3 but with the following additional request argument:

   *  *onDestroyRemoveContents*: Boolean (default: false) If false, any
      attempt to destroy an AddressBook that still has a ContactCard in
      it will be rejected with a addressBookHasContents SetError.  If
      true, any ContactCards that were in the AddressBook will be
      destroyed.

   The "shareWith" property may only be set by users that have the
   mayAdmin right.  When modifying the shareWith property, the user
   cannot give a right to a principal if the principal did not already
   have that right and the user making the change also does not have
   that right.  Any attempt to do so must be rejected with a forbidden
   SetError.

   Users can subscribe or unsubscribe to an AddressBook by setting the
   "isSubscribed" property.  The server MAY forbid users from
   subscribing to certain AddressBooks even though they have permission
   to see them, rejecting the update with a forbidden SetError.

   The following extra SetError types are defined:

   For "destroy":

   *  *addressBookHasContents*: The AddressBook has at least one
      ContactCard assigned to it, and the "onDestroyRemoveContents"
      argument was false.

3.  ContactCards

   A *ContactCard* object contains information about a person, company,
   or other entity, or represents a group of such entities.  It is a
   JSCard object, as defined in RFCXXXX, with the following additional
   properties:

Jenkins                    Expires 10 May 2024                  [Page 5]
Internet-Draft                JMAP Contacts                November 2023

   *  *id*: Id (immutable; server-set) The id of the ContactCard.  The
      id uniquely identifies a ContactCard with a particular "uid"
      within a particular account.
   *  *addressBookId*: Id[Boolean] The set of AddressBook ids this
      ContactCard belongs to.  A card MUST belong to at least one
      AddressBook at all times (until it is destroyed).  The set is
      represented as an object, with each key being an AddressBook id.
      The value for each key in the object MUST be true.

   For any Media object in the card (see RFCXXX, Section XXX), a new
   property is defined:

   *  *blobId*: Id An id for the Blob representing the binary contents
      of the resource.

   When returning ContactCards, any Media with a data: URI SHOULD return
   a blobId property and omit the uri property.  The "mediaType"
   property MUST also be set.  Similarly, when creating or updating a
   ContactCard, clients MAY send a blobId instead of the uri property
   for a Media object.

   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 "members" property, as defined in RFC XXX,
   Section XXX, contains a set of UIDs for other contacts that are the
   members of this group.  Clients should consider the group to contain
   any ContactCard with a matching UID, from any account they have
   access to with support for the urn:ietf:params:jmap:contacts
   capability.  UIDs that cannot be found SHOULD be ignored but
   preserved.  For example, suppose a user adds contacts from a shared
   address book to their private group, then temporarily loses access to
   this address book.  The UIDs cannot be resolved so the contacts will
   disappear from the group.  However, if they are given permission to
   access the data again the UIDs will be found and the contacts will
   reappear.

3.1.  ContactCard/get

   This is a standard "/get" method as described in [RFC8620],
   Section 5.1.

3.2.  ContactCard/changes

   This is a standard "/changes" method as described in [RFC8620],
   Section 5.2.

Jenkins                    Expires 10 May 2024                  [Page 6]
Internet-Draft                JMAP Contacts                November 2023

3.3.  ContactCard/query

   This is a standard "/query" method as described in [RFC8620],
   Section 5.5.

3.3.1.  Filtering

   A *FilterCondition* object has the following properties, any of which
   may be omitted:

   *  *inAddressBook*: Id An AddressBook id.  A card must be in this
      address book to match the condition.
   *  *uid*: String A card must have this string exactly as its uid to
      match.
   *  *hasMember*: String A card must have a "members" property that
      contains this string as one of the uids in the set to match.
   *  *kind*: String A card must have a type property that equals this
      string exactly to match.
   *  *createdBefore*: UTCDate The "created" date-time of the
      ContactCard must be before this date-time to match the condition.
   *  *createdAfter*: UTCDate The "created" date-time of the ContactCard
      must be the same or after this date-time to match the condition.
   *  *updatedBefore*: UTCDate The "updated" date-time of the
      ContactCard must be before this date-time to match the condition.
   *  *updatedAfter*: UTCDate The "updated" date-time of the ContactCard
      must be the same or after this date-time to match the condition.
   *  *text*: String A card matches this condition if the text matches
      with text in the card.
   *  *name*: String 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 matches the value.
   *  *name/given*: String A card matches this condition if the value of
      a NameComponent with kind "given" inside the "name" property of
      the card matches the value.
   *  *name/surname*: String A card matches this condition if the value
      of a NameComponent with kind "surname" inside the "name" property
      of the card matches the value.
   *  *name/surname2*: String A card matches this condition if the value
      of a NameComponent with kind "surname2" inside the "name" property
      of the card matches the value.
   *  *nickName*: String A card matches this condition if the "name" of
      any NickName in the "nickNames" property of the card matches the
      value.
   *  *organization*: String A card matches this condition if the "name"
      of any Organization in the "organizations" property of the card
      matches the value.

Jenkins                    Expires 10 May 2024                  [Page 7]
Internet-Draft                JMAP Contacts                November 2023

   *  *email*: String A card matches this condition if the "address" or
      "label" of any EmailAddress in the "emails" property of the card
      matches the value.
   *  *phone*: String A card matches this condition if the "number" or
      "label" of any Phone in the "phones" property of the card matches
      the value.
   *  *onlineService*: String A card matches this condition if the
      "service", "uri", "user", or "label" of any OnlineService in the
      "onlineServices" property of the card matches the value.
   *  *address*: String A card matches this condition if the value of
      any StreetComponent in the "street" property, or the "locality",
      "region", "country", or "postcode" property in any Address in the
      "addresses" property of the card matches the value.
   *  *note*: String A card matches this condition if the "note" of any
      Note in the "notes" property of the card matches the value.

   If zero properties are specified on the FilterCondition, the
   condition MUST always evaluate to true.  If multiple properties are
   specified, ALL must apply for the condition to be true (it is
   equivalent to splitting the object into one-property conditions and
   making them all the child of an AND filter operator).

   The exact semantics for matching String fields is *deliberately not
   defined* to allow for flexibility in indexing implementation, subject
   to the following:

   *  Text SHOULD be matched in a case-insensitive manner.
   *  Text contained in either (but matched) single or double quotes
      SHOULD be treated as a *phrase search*, that is a match is
      required for that exact sequence of words, excluding the
      surrounding quotation marks.  Use \", \' and \\ to match a literal
      ", ' and \ respectively in a phrase.
   *  Outside of a phrase, white-space SHOULD be treated as dividing
      separate tokens that may be searched for separately in the
      contact, but MUST all be present for the contact to match the
      filter.
   *  Tokens MAY be matched on a whole-word basis using stemming (so for
      example a text search for bus would match "buses" but not
      "business").

3.3.2.  Sorting

   The following value for the "property" field on the Comparator object
   MUST be supported for sorting:

   *  "created" - The "created" date on the ContactCard.
   *  "updated" - The "updated" date on the ContactCard.

Jenkins                    Expires 10 May 2024                  [Page 8]
Internet-Draft                JMAP Contacts                November 2023

   The following values for the "property" field on the Comparator
   object SHOULD be supported for sorting:

   *  "name/given" - The value of the first NameComponent in the "name"
      property whose "kind" is "given".
   *  "name/surname" - The value of the first NameComponent in the
      "name" property whose "kind" is "surname".
   *  "name/surname2" - The value of the first NameComponent in the
      "name" property whose "kind" is "surname2".

3.4.  ContactCard/queryChanges

   This is a standard "/queryChanges" method as described in [RFC8620],
   Section 5.6.

3.5.  ContactCard/set

   This is a standard "/set" method as described in [RFC8620],
   Section 5.3.

   To set a new photo, the file must first be uploaded using the upload
   mechanism as described in [RFC8620], Section 6.1.  This will give the
   client a valid blobId/size/type to use.  The server SHOULD reject
   attempts to set a file that is not a recognised image type as the
   photo for a card.

3.6.  ContactCard/copy

   This is a standard "/copy" method as described in [RFC8620],
   Section 5.4.

4.  Security considerations

   All security considerations of JMAP ([RFC8620]) apply to this
   specification.  Additional considerations specific to the data types
   and functionality introduced by this document are described in the
   following subsections.

4.1.  Privacy

   Contacts consist almost entirely of private, personally identifiable
   information, 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 to keep all data secure.

   Servers MUST enforce the ACLs set on address books to ensure only
   authorised data is shared.

Jenkins                    Expires 10 May 2024                  [Page 9]
Internet-Draft                JMAP Contacts                November 2023

5.  IANA Considerations

5.1.  JMAP capability registration for "contacts"

   IANA will register the "contacts" JMAP Capability as follows:

   Capability Name: urn:ietf:params:jmap:contacts

   Specification document: this document

   Intended use: common

   Change Controller: IETF

   Security and privacy considerations: this document, section XXX

6.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

   [RFC8620]  Jenkins, N. and C. Newman, "The JSON Meta Application
              Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, July
              2019, <https://www.rfc-editor.org/info/rfc8620>.

Author's Address

   Neil Jenkins (editor)
   Fastmail
   PO Box 234, Collins St West
   Melbourne  VIC 8007
   Australia
   Email: neilj@fastmailteam.com
   URI:   https://www.fastmail.com

Jenkins                    Expires 10 May 2024                 [Page 10]