urn:ietf:params:jmap:contacts), avec des fiches en objets JSContact (RFC 9553). Les mêmes données sont servies en CardDAV.
Objets et méthodes
Comportements à connaître
- Le serveur possède l’
uid. Unuidfourni par le client à la création est rejeté (invalidProperties) : c’est le serveur qui le frappe, ce qui rend la correspondance CardDAV sans ambiguïté. addressBookIdsest optionnel à la création : une appartenance omise classe la fiche dans le carnet par défaut.- L’historique de versions est de premier rang.
ContactCard/getHistoryliste les versions antérieures d’une fiche,restoreVersionen ramène une. Les modifications de n’importe quel protocole (JMAP ou CardDAV) sont versionnées pareil. - L’aller-retour est sans perte. Les composantes de nom et d’adresse se transposent complètement entre vCard (3.0/4.0) et JSContact dans les deux sens ; les propriétés vCard sans modèle JSContact sont préservées plutôt qu’abandonnées. Un
PUTCardDAV qui dupliquerait un UID existant d’une autre source est refusé, jamais dupliqué en silence. - La dépréciation est annoncée honnêtement. L’objet de capacité du compte annonce la posture du modèle AddressBook pour que les clients s’adaptent, au lieu de découvrir le comportement par essais.
Les annuaires de tenant
Une organisation peut publier des jeux de contacts partagés (« Clients », « Personnel ») tenus sur le plan d’administration. Le choix de conception qui structure toute la surface : un annuaire n’est pas un conteneur dans lequel les membres classent des fiches. Les membres ne voient aucun conteneur. Ce qu’un membre voit, c’est son propre carnet d’adresses, où les entrées arrivent en fiches lisibles seulement, avecsource: "organization" et directorySource: "tenant:<directoryId>" : le plan même qu’alimente un connecteur LDAP ou SCIM externe. Un client qui affiche déjà les contacts d’origine organisationnelle n’a aucun écran à ajouter.
Qui écrit quoi. Les objets annuaire sont réservés au rôle d’administrateur de tenant. Les entrées sont réservées aux editorIds de leur annuaire, qui sont des identifiants de principal : y nommer un groupe est valide et courant, et l’appartenance est résolue par l’expansion des bénéficiaires au moment du contrôle d’accès, jamais stockée déjà expansée. Ajouter quelqu’un à un groupe lui donne donc le droit d’éditer sans toucher à l’annuaire.
Deux comportements à connaître avant de bâtir dessus :
mayEditest calculé pour vous, et vous ne pouvez pas le calculer vous-même. Il suit le rôle de tenant de l’appelant et l’expansion de groupes côté serveur : deux comptes lisent donc légitimement des valeurs différentes pour le même annuaire, et le dériver depuiseditorIdsest impossible, cette liste étant aveugle à l’appartenance aux groupes par conception. C’est exactement pour cela qu’il est déclaré dans le canon publié au lieu d’être laissé à la déduction depuis le type TypeScript.- La comptabilité du serveur ne vous appartient pas. La propriété
cardporte la fiche JSContact et rien d’autre : les clés de projection commesourceoudirectoryIdposées à l’intérieur sont refusées, pas écrasées en silence.
notFound, invalidProperties plutôt qu’une coercition, accountNotFound, stateMismatch.