groupware: add mock endpoints for addressbooks and contacts

This commit is contained in:
Pascal Bleser
2025-09-30 15:50:48 +02:00
parent 3cf1a1702e
commit 9079be072c
15 changed files with 1923 additions and 114 deletions

View File

@@ -3,8 +3,15 @@ package jmap
import (
"io"
"time"
"github.com/opencloud-eu/opencloud/pkg/jscalendar"
)
// TODO
type UTCDate struct {
time.Time
}
const (
JmapCore = "urn:ietf:params:jmap:core"
JmapMail = "urn:ietf:params:jmap:mail"
@@ -52,6 +59,30 @@ var (
}
)
// Should the calendars events be used as part of availability calculation?
//
// This MUST be one of:
// !- `all“: all events are considered.
// !- `attending“: events the user is a confirmed or tentative participant of are considered.
// !- `none“: all events are ignored (but may be considered if also in another calendar).
//
// This should default to “all” for the calendars in the users own account, and “none” for calendars shared with the user.
type IncludeInAvailability string
const (
IncludeInAvailabilityAll = IncludeInAvailability("all")
IncludeInAvailabilityAttending = IncludeInAvailability("attending")
IncludeInAvailabilityNone = IncludeInAvailability("none")
)
var (
IncludeInAvailabilities = []IncludeInAvailability{
IncludeInAvailabilityAll,
IncludeInAvailabilityAttending,
IncludeInAvailabilityNone,
}
)
type SessionMailAccountCapabilities struct {
// The maximum number of Mailboxes that can be can assigned to a single Email object.
//
@@ -2908,6 +2939,244 @@ type AddressBook struct {
MyRights AddressBookRights `json:"myRights"`
}
type CalendarRights struct {
// The user may read the free-busy information for this calendar.
MayReadFreeBusy bool `json:"mayReadFreeBusy"`
// The user may fetch the events in this calendar.
MayReadItems bool `json:"mayReadItems"`
// The user may create, modify or destroy all events in this calendar, or move events
// to or from this calendar.
//
// If this is `true`, the `mayWriteOwn`, `mayUpdatePrivate` and `mayRSVP`
// properties MUST all also be `true`.
MayWriteAll bool `json:"mayWriteAll"`
// The user may create, modify or destroy an event on this calendar if either they are
// the owner of the event or the event has no owner.
//
// This means the user may also transfer ownership by updating an event so they are no longer an owner.
MayWriteOwn bool `json:"mayWriteOwn"`
// The user may modify per-user properties on all events in the calendar, even if they would
// not otherwise have permission to modify that event.
//
// These properties MUST all be stored per-user, and changes do not affect any other user of the calendar.
//
// The user may also modify these properties on a per-occurrence basis for recurring events
// (updating the `recurrenceOverrides` property of the event to do so).
MayUpdatePrivate bool `json:"mayUpdatePrivate"`
// The user may modify the following properties of any `Participant` object that corresponds
// to one of the user's `ParticipantIdentity` objects in the account, even if they would not
// otherwise have permission to modify that event.
//
// !- `participationStatus`
// !- `participationComment`
// !- `expectReply`
// !- `scheduleAgent`
// !- `scheduleSequence`
// !- `scheduleUpdated`
//
// If the event has its `mayInviteSelf` property set to `true`, then the user may also add a
// new `Participant` to the event with `scheduleId`/`sendTo` properties that are the same as
// the `scheduleId`/`sendTo` properties of one of the user's `ParticipantIdentity` objects in
// the account.
//
// The `roles` property of the participant MUST only contain `attendee`.
//
// If the event has its `mayInviteOthers` property set to `true` and there is an existing
// `Participant` in the event corresponding to one of the user's `ParticipantIdentity` objects
// in the account, then the user may also add new participants.
//
// The `roles` property of any new participant MUST only contain `attendee`.
//
// The user may also do all of the above on a per-occurrence basis for recurring events
// (updating the recurrenceOverrides property of the event to do so).
MayRSVP bool `json:"mayRSVP"`
// The user may modify the `shareWith` property for this calendar.
MayAdmin bool `json:"mayAdmin"`
// The user may delete the calendar itself.
MayDelete bool `json:"mayDelete"`
}
// A Calendar is a named collection of events.
//
// All events are associated with at least one calendar.
//
// The user is an owner for an event if the `CalendarEvent` object has a `participants`
// property, and one of the `Participant` objects both:
// 1. Has the `owner` role.
// 2. Corresponds to one of the user's `ParticipantIdentity` objects in the account.
//
// An event has no owner if its `participants` property is null or omitted, or if none
// of the `Participant` objects have the `owner` role.
type Calendar struct {
// The id of the calendar (immutable; server-set).
Id string `json:"id"`
// The user-visible name of the calendar.
//
// This may be any UTF-8 string of at least 1 character in length and maximum 255 octets in size.
Name string `json:"name"`
// An optional longer-form description of the calendar, to provide context in shared environments
// where users need more than just the name.
Description string `json:"description,omitempty"`
// A color to be used when displaying events associated with the calendar.
//
// If not null, the value MUST be a case-insensitive color name taken from the set of names
// defined in Section 4.3 of CSS Color Module Level 3 COLORS, or an RGB value in hexadecimal
// notation, as defined in Section 4.2.1 of CSS Color Module Level 3.
//
// The color SHOULD have sufficient contrast to be used as text on a white background.
Color string `json:"color,omitempty"`
// Defines the sort order of calendars when presented in the clients UI, so it is consistent
// between devices.
//
// The number MUST be an integer in the range 0 <= sortOrder < 2^31.
//
// A calendar with a lower order should be displayed before a calendar with a higher order in any
// list of calendars in the clients UI.
//
// Calendars with equal order SHOULD be sorted in alphabetical order by name.
//
// The sorting should take into account locale-specific character order convention.
SortOrder uint `json:"sortOrder,omitzero"`
// True if the user has indicated they wish to see this Calendar in their client.
//
// This SHOULD default to `false` for Calendars in shared accounts the user has access to and `true`
// for any new Calendars created by the user themself.
//
// If false, the calendar SHOULD only be displayed when the user explicitly requests it or to offer
// it for the user to subscribe to.
//
// For example, a company may have a large number of shared calendars which all employees have
// permission to access, but you would only subscribe to the ones you care about and want to be able
// to have normally accessible.
IsSubscribed bool `json:"isSubscribed"`
// Should the calendars events be displayed to the user at the moment?
//
// Clients MUST ignore this property if `isSubscribed` is false.
//
// If an event is in multiple calendars, it should be displayed if `isVisible` is `true`
// for any of those calendars.
//
// default: true
IsVisible bool `json:"isVisible"`
// This SHOULD be true for exactly one calendar in any account, and MUST NOT be true for more
// than one calendar within an account (server-set).
//
// The default calendar should be used by clients whenever they need to choose a calendar
// 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 event, the client may automatically set the event as
// belonging to the default calendar from the users primary account.
IsDefault bool `json:"isDefault,omitzero"`
// Should the calendars events be used as part of availability calculation?
//
// This MUST be one of:
// !- `all``: all events are considered.
// !- `attending``: events the user is a confirmed or tentative participant of are considered.
// !- `none``: all events are ignored (but may be considered if also in another calendar).
//
// This should default to “all” for the calendars in the users own account, and “none” for calendars shared with the user.
IncludeInAvailability IncludeInAvailability `json:"includeInAvailability,omitempty"`
// A map of alert ids to Alert objects (see [@!RFC8984], Section 4.5.2) to apply for events
// where `showWithoutTime` is `false` and `useDefaultAlerts` is `true`.
//
// Ids MUST be unique across all default alerts in the account, including those in other
// calendars; a UUID is recommended.
// If omitted on creation, the default is server dependent.
//
// For example, servers may choose to always default to null, or may copy the alerts from the default calendar.
DefaultAlertsWithTime map[string]jscalendar.Alert `json:"defaultAlertsWithTime,omitempty"`
// A map of alert ids to Alert objects (see [@!RFC8984], Section 4.5.2) to apply for events where
// `showWithoutTime` is `true` and `useDefaultAlerts` is `true`.
//
// Ids MUST be unique across all default alerts in the account, including those in other
// calendars; a UUID is recommended.
//
// If omitted on creation, the default is server dependent.
//
// For example, servers may choose to always default to null, or may copy the alerts from the default calendar.
DefaultAlertsWithoutTime map[string]jscalendar.Alert `json:"defaultAlertsWithoutTime,omitempty"`
// The time zone to use for events without a time zone when the server needs to resolve them into
// absolute time, e.g., for alerts or availability calculation.
//
// The value MUST be a time zone id from the IANA Time Zone Database TZDB.
//
// If null, the `timeZone` of the accounts associated `Principal` will be used.
//
// Clients SHOULD use this as the default for new events in this calendar if set.
TimeZone string `json:"timeZone,omitempty"`
// A map of `Principal` id to rights for principals this calendar is shared with.
//
// The principal to which this calendar belongs MUST NOT be in this set.
//
// This is null if the calendar is not shared with anyone.
//
// May be modified only if the user has the `mayAdmin` right.
//
// The account id for the principals may be found in the `urn:ietf:params:jmap:principals:owner`
// capability of the `Account` to which the calendar belongs.
ShareWith map[string]CalendarRights `json:"shareWith,omitempty"`
// The set of access rights the user has in relation to this Calendar.
//
// If any event is in multiple calendars, the user has the following rights:
// !- The user may fetch the event if they have the mayReadItems right on any calendar the event is in.
// !- The user may remove an event from a calendar (by modifying the events “calendarIds” property) if the user
// has the appropriate permission for that calendar.
// !- The user may make other changes to the event if they have the right to do so in all calendars to which the
// event belongs.
MyRights *CalendarRights `json:"myRights,omitempty"`
}
// A CalendarEvent object contains information about an event, or recurring series of events,
// that takes place at a particular time.
//
// It is a JSCalendar Event object, as defined in [@!RFC8984], with additional properties.
type CalendarEvent struct {
// The id of the CalendarEvent (immutable; server-set).
//
// The id uniquely identifies a JSCalendar Event with a particular `uid` and
// `recurrenceId` within a particular account.
Id string `json:"id"`
baseEventId string
calendarIds map[string]bool
isDraft bool
isOrigin bool
utcStart UTCDate
utcEnd UTCDate
// TODO https://jmap.io/spec-calendars.html#calendar-events
jscalendar.Event
}
type ErrorResponse struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`

View File

@@ -1001,7 +1001,7 @@ type RecurrenceRule struct {
//
// This is the `INTERVAL` part from iCalendar.
//
// Default: `1`
// Default: 1
Interval uint `json:"interval,omitzero"`
// This is the calendar system in which this recurrence rule operates, in lowercase.
@@ -1011,7 +1011,7 @@ type RecurrenceRule struct {
//
// This is the `RSCALE` part from iCalendar RSCALE [RFC7529], converted to lowercase.
//
// Default: `gregorian`
// Default: gregorian
//
// [CLDR]: https://github.com/unicode-org/cldr/blob/latest/common/bcp47/calendar.xml
// [RFC7529]: https://www.rfc-editor.org/rfc/rfc7529.html
@@ -1028,7 +1028,7 @@ type RecurrenceRule struct {
//
// This is the `SKIP` part from iCalendar `RSCALE` [RFC7529], converted to lowercase.
//
// Default: `omit`
// Default: omit
Skip Skip `json:"skip,omitempty"`
// This is the day on which the week is considered to start, represented as a lowercase, abbreviated,
@@ -1045,7 +1045,7 @@ type RecurrenceRule struct {
//
// This is the `WKST` part from iCalendar.
//
// Default: `mo`
// Default: mo
FirstDayOfWeek DayOfWeek `json:"firstDayOfWeek,omitempty"`
// These are days of the week on which to repeat.
@@ -1262,7 +1262,7 @@ type Participant struct {
// !- `client`: The calendar client will send the scheduling messages.
// !- `none`: No scheduling messages are to be sent to this participant.
//
// Default: `server`
// Default: server
ScheduleAgent ScheduleAgent `json:"scheduleAgent,omitempty"`
// A client may set the property on a participant to true to request that the server send a scheduling
@@ -1369,6 +1369,14 @@ type Participant struct {
//
// The property value MUST be a positive integer between 0 and 100.
PercentComplete uint `json:"percentComplete,omitzero"`
// This is a URI as defined by [@!RFC3986] or any other IANA-registered form for a URI.
//
// It is the same as the `CAL-ADDRESS` value of an `ATTENDEE` or `ORGANIZER` in iCalendar ([@!RFC5545]);
// it globally identifies a particular participant, even across different events.
//
// This is a JMAP addition to JSCalendar.
ScheduleId string `json:"scheduleId,omitempty"`
}
type Trigger interface {
@@ -1464,7 +1472,7 @@ type Alert struct {
// !- `email`: The alert should trigger an email sent out to the user, notifying them of the alert. This action is
// typically only appropriate for server implementations.
//
// Default: `display`
// Default: display
Action AlertAction `json:"action,omitempty"`
}
@@ -1656,7 +1664,7 @@ type CommonObject struct {
// Descriptions of type text/html MAY contain cid URLs [RFC2392] to reference links in the calendar
// object by use of the cid property of the Link object.
//
// Default: `text/plain`
// Default: text/plain
DescriptionContentType string `json:"descriptionContentType,omitempty"`
// This is a map of link ids to `Link` objects, representing external resources associated with the object.
@@ -1789,7 +1797,7 @@ type Object struct {
//
// Such events are also commonly known as "all-day" events.
//
// Default: `false`
// Default: false
ShowWithoutTime bool `json:"showWithoutTime,omitzero"`
// This is a map of location ids to `Location` objects, representing locations associated with the object.
@@ -2011,7 +2019,7 @@ type Object struct {
// If an implementation cannot determine the user's default alerts, or none are set, it MUST process
// he alerts property as if `useDefaultAlerts` is set to false.
//
// Default: `false`
// Default: false
UseDefaultAlerts bool `json:"useDefaultAlerts,omitzero"`
// This is a map of alert ids to Alert objects, representing alerts/reminders to display or send
@@ -2052,6 +2060,44 @@ type Object struct {
//
// If omitted, this MUST be presumed to be `null` (i.e., floating time).
TimeZone string `json:"timeZone,omitempty"`
// If true, any user may add themselves to the event as a participant with the
// `attendee` role.
//
// This property MUST NOT be altered in the `recurrenceOverrides`; it may only be set on the base object.
//
// This indicates the event will accept "party crasher" RSVPs via iTIP, subject to any
// other domain-specific restrictions, and users may add themselves to the event via JMAP as
// long as they have the mayRSVP permission for the calendar.
//
// This is a JMAP addition to JSCalendar.
//
// default: false
MayInviteSelf bool `json:"mayInviteSelf,omitzero"`
// If true, any current participant with the `attendee` role may add new participants with the
// `attendee` role to the event.
//
// This property MUST NOT be altered in the `recurrenceOverrides`; it may only be set on the base object.
//
// The `mayRSVP` permission for the calendar is also required in conjunction with this event property
// for users to be allowed to make this change via JMAP.
//
// This is a JMAP addition to JSCalendar.
//
// default: false
MayInviteOthers bool `json:"mayInviteOthers,omitzero"`
// If true, only the owners of the event may see the full set of participants.
//
// Other sharees of the event may only see the owners and themselves.
//
// This property MUST NOT be altered in the `recurrenceOverrides`; it may only be set on the base object.
//
// This is a JMAP addition to JSCalendar.
//
// default: false
HideAttendees bool `json:"hideAttendees,omitzero"`
}
type Event struct {

View File

@@ -11,35 +11,373 @@ import (
"time"
)
// The kind of the name component.
//
// !- `title`: an honorific title or prefix, e.g., `Mr.`, `Ms.`, or `Dr.`
// !- `given`: a given name, also known as "first name" or "personal name"
// !- `given2`: a name that appears between the given and surname such as a middle name or patronymic name
// !- `surname`: a surname, also known as "last name" or "family name"
// !- `surname2`: a secondary surname (used in some cultures), also known as "maternal surname"
// !- `credential`: a credential, also known as "accreditation qualifier" or "honorific suffix", e.g., `B.A.`, `Esq.`
// !- `generation`: a generation marker or qualifier, e.g., `Jr.` or `III`
// !- `separator`: a formatting separator between two ordered name non-separator components; the value property of the component includes the verbatim separator, for example, a hyphen character or even an empty string. This value has higher precedence than the defaultSeparator property of the Name. Implementations MUST NOT insert two consecutive separator components; instead, they SHOULD insert a single separator component with the combined value; this component kind MUST NOT be set if the `Name` `isOrdered` property value is `false`
type NameComponentKind string
// The kind of the address component.
//
// The enumerated values are:
// ! `room`: the room, suite number, or identifier
// ! `apartment`: the extension designation such as the apartment number, unit, or box number
// ! `floor`: the floor or level the address is located on
// ! `building`: the building, tower, or condominium the address is located in
// ! `number`: the street number, e.g., `"123"`; this value is not restricted to numeric values and can include any value such
// as number ranges (`"112-10"`), grid style (`"39.2 RD"`), alphanumerics (`"N6W23001"`), or fractionals (`"123 1/2"`)
// ! `name`: the street name
// ! `block`: the block name or number
// ! `subdistrict`: the subdistrict, ward, or other subunit of a district
// ! `district`: the district name
// ! `locality`: the municipality, city, town, village, post town, or other locality
// ! `region`: the administrative area such as province, state, prefecture, county, or canton
// ! `postcode`: the postal code, post code, ZIP code, or other short code associated with the address by the relevant country's postal system
// ! `country`: the country name
// ! `direction`: the cardinal direction or quadrant, e.g., "north"
// ! `landmark`: the publicly known prominent feature that can substitute the street name and number, e.g., "White House" or "Taj Mahal"
// ! `postOfficeBox`: the post office box number or identifier
// ! `separator`: a formatting separator between two ordered address non-separator components; the value property of the component includes the
// verbatim separator, for example, a hyphen character or even an empty string; this value has higher precedence than the `defaultSeparator` property
// of the `Address`; implementations MUST NOT insert two consecutive separator components; instead, they SHOULD insert a single separator component
// with the combined value; this component kind MUST NOT be set if the `Address` `isOrdered` property value is `false`.
type AddressComponentKind string
// The relationship of the related Card to the Card, defined as a set of relation types.
//
// The keys in the set define the relation type; the values for each key in the set MUST be "true".
//
// The relationship between the two objects is undefined if the set is empty.
//
// The initial list of enumerated relation types matches the IANA-registered TYPE `IANA-vCard“
// parameter values of the vCard RELATED property ([Section 6.6.6 of RFC6350]):
// !- `acquaintance`
// !- `agent`
// !- `child`
// !- `co-resident`
// !- `co-worker`
// !- `colleague`
// !- `contact`
// !- `crush`
// !- `date`
// !- `emergency`
// !- `friend`
// !- `kin`
// !- `me`
// !- `met`
// !- `muse`
// !- `neighbor`
// !- `parent`
// !- `sibling`
// !- `spouse`
// !- `sweetheart`
//
// [Section 6.6.6 of RFC6350]: https://www.rfc-editor.org/rfc/rfc6350.html#section-6.6.6
type Relationship string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type MediaContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type NicknameContext string
// The contexts in which to use this address.
//
// The boolean value MUST be `true`.
//
// In addition to the common contexts, allowed key values are:
// ! `billing`: an address to be used for billing
// ! `delivery`: an address to be used for delivering physical items
type AddressContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type DirectoryContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type EmailAddressContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type OnlineServiceContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type OrganizationContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type PronounsContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type PhoneContext string
// The set of contact features that the phone number may be used for.
//
// The set is represented as an object, with each key being a method type.
//
// The boolean value MUST be `true`.
//
// The enumerated values are:
// !- `mobile`: this number is for a mobile phone
// !- `voice`: this number supports calling by voice
// !- `text`: this number supports text messages (SMS)
// !- `video`: this number supports video conferencing
// !- `main-number`: this number is a main phone number such as the number of the front desk at a company, as opposed to a direct-dial number of an individual employee
// !- `textphone`: this number is for a device for people with hearing or speech difficulties
// !- `fax`: this number supports sending faxes
// !- `pager`: this number is for a pager or beeper
type PhoneFeature string
// The organizational or situational kind of the title.
//
// Some organizations and individuals distinguish between titles as organizational
// positions and roles as more temporary assignments such as in project management.
//
// The enumerated values are:
// !- `title`
// !- `role`
type TitleKind string
// The grammatical gender to use in salutations and other grammatical constructs.
//
// For example, the German language distinguishes by grammatical gender in salutations such as
// `Sehr geehrte` (feminine) and `Sehr geehrter` (masculine).
//
// The enumerated values are:
// !- `animate`
// !- `common`
// !- `feminine`
// !- `inanimate`
// !- `masculine`
// !- `neuter`
//
// Note that the grammatical gender does not allow inferring the gender identities or assigned
// sex of the contact.
type GrammaticalGenderType string
// The kind of anniversary.
//
// The enumerated values are:
// ! `birth`: a birthday anniversary
// ! `death`: a deathday anniversary
// ! `wedding`: a wedding day anniversary
type AnniversaryKind string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type LanguagePrefContext string
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type SchedulingAddressContext string
// The kind of personal information.
//
// The enumerated values are:
// ! `expertise`: a field of expertise or a credential
// ! `hobby`: a hobby
// ! `interest`: an interest
type PersonalInfoKind string
// The level of expertise or engagement in hobby or interest.
//
// The enumerated values are:
// ! `high`
// ! `medium`
// ! `low`
type PersonalInfoLevel string
// The kind of the entity the Card represents (default: `individual“).
//
// Values are:
// !- `individual`: a single person
// !- `group`: a group of people or entities
// !- `org`: an organization
// !- `location`: a named location
// !- `device`: a device such as an appliance, a computer, or a network element
// !- `application`: a software application
//
// example: individual
type ContactCardKind string
// The kind of the `Directory` resource.
//
// The allowed values are defined in the property definition that makes use of the Resource type.
//
// Some property definitions may change this property from being optional to mandatory.
//
// 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 9553, Section 2.1.6], 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.
//
// [RFC 9553, Section 2.1.8]: https://www.rfc-editor.org/rfc/rfc9553#members
type DirectoryKind string
// The kind of the `Calendar` resource.
//
// The allowed values are defined in the property definition that makes use of the Resource type.
//
// Some property definitions may change this property from being optional to mandatory.
//
// 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 9553, Section 2.1.6], 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.
//
// [RFC 9553, Section 2.1.8]: https://www.rfc-editor.org/rfc/rfc9553#members
type CalendarKind string
type CryptoKeyKind string
// The kind of the `Link` resource.
//
// The allowed values are defined in the property definition that makes use of the Resource type.
//
// Some property definitions may change this property from being optional to mandatory.
//
// 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 9553, Section 2.1.6], 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.
//
// [RFC 9553, Section 2.1.8]: https://www.rfc-editor.org/rfc/rfc9553#members
type LinkKind string
// The kind of the `Media` resource.
//
// The allowed values are defined in the property definition that makes use of the Resource type.
//
// Some property definitions may change this property from being optional to mandatory.
//
// 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 9553, Section 2.1.6], 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.
//
// [RFC 9553, Section 2.1.8]: https://www.rfc-editor.org/rfc/rfc9553#members
type MediaKind string
// The contexts in which to use this resource.
//
// The contexts in which to use the contact information.
//
// For example, someone might have distinct phone numbers for `work` and `private` contexts and may set the
// desired context on the respective phone number in the `phones` property.
//
// This section defines common contexts.
//
// Additional contexts may be defined in the properties or data types that make use of this property.
//
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type CalendarContext string
// The contexts in which to use this resource.
//
// The contexts in which to use the contact information.
//
// For example, someone might have distinct phone numbers for `work` and `private` contexts and may set the
// desired context on the respective phone number in the `phones` property.
//
// This section defines common contexts.
//
// Additional contexts may be defined in the properties or data types that make use of this property.
//
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type CryptoKeyContext string
// The contexts in which to use this resource.
//
// The contexts in which to use the contact information.
//
// For example, someone might have distinct phone numbers for `work` and `private` contexts and may set the
// desired context on the respective phone number in the `phones` property.
//
// This section defines common contexts.
//
// Additional contexts may be defined in the properties or data types that make use of this property.
//
// The enumerated common context values are:
// !- `private`: the contact information that may be used in a private context.
// !- `work`: the contact information that may be used in a professional context.
type LinkContext string
// The JSContact version of this Card.
//
// The value MUST be one of the IANA-registered JSContact Version values for the version property.
//
// example: 1.0
type JSContactVersion string
type TypeOfAddress string
@@ -598,32 +936,6 @@ type CryptoKey struct {
// The value MUST be `CryptoKey`, if set.
Type TypeOfCryptoKey `json:"@type,omitempty"`
// The kind of the resource.
//
// The allowed values are defined in the property definition that makes use of the Resource type.
//
// Some property definitions may change this property from being optional to mandatory.
//
// 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 9553, Section 2.1.6], 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.
//
// [RFC 9553, Section 2.1.8]: https://www.rfc-editor.org/rfc/rfc9553#members
Kind CryptoKeyKind `json:"kind,omitempty"`
// The resource value.
//
// This MUST be a URI as defined in [Section 3 of RFC3986].
@@ -1229,7 +1541,7 @@ type Name struct {
// The indicator if the name components in the components property are ordered.
//
// Default: `false`
// default: false
IsOrdered bool `json:"isOrdered,omitzero"`
// The default separator to insert between name component values when concatenating all name component values to a single String.
@@ -1495,24 +1807,24 @@ type AddressComponent struct {
// The kind of the address component.
//
// The enumerated values are:
// !- `room`: the room, suite number, or identifier
// !- `apartment`: the extension designation such as the apartment number, unit, or box number
// !- `floor`: the floor or level the address is located on
// !- `building`: the building, tower, or condominium the address is located in
// !- `number`: the street number, e.g., `"123"`; this value is not restricted to numeric values and can include any value such
// ! `room`: the room, suite number, or identifier
// ! `apartment`: the extension designation such as the apartment number, unit, or box number
// ! `floor`: the floor or level the address is located on
// ! `building`: the building, tower, or condominium the address is located in
// ! `number`: the street number, e.g., `"123"`; this value is not restricted to numeric values and can include any value such
// as number ranges (`"112-10"`), grid style (`"39.2 RD"`), alphanumerics (`"N6W23001"`), or fractionals (`"123 1/2"`)
// !- `name`: the street name
// !- `block`: the block name or number
// !- `subdistrict`: the subdistrict, ward, or other subunit of a district
// !- `district`: the district name
// !- `locality`: the municipality, city, town, village, post town, or other locality
// !- `region`: the administrative area such as province, state, prefecture, county, or canton
// !- `postcode`: the postal code, post code, ZIP code, or other short code associated with the address by the relevant country's postal system
// !- `country`: the country name
// !- `direction`: the cardinal direction or quadrant, e.g., "north"
// !- `landmark`: the publicly known prominent feature that can substitute the street name and number, e.g., "White House" or "Taj Mahal"
// !- `postOfficeBox`: the post office box number or identifier
// !- `separator`: a formatting separator between two ordered address non-separator components; the value property of the component includes the
// ! `name`: the street name
// ! `block`: the block name or number
// ! `subdistrict`: the subdistrict, ward, or other subunit of a district
// ! `district`: the district name
// ! `locality`: the municipality, city, town, village, post town, or other locality
// ! `region`: the administrative area such as province, state, prefecture, county, or canton
// ! `postcode`: the postal code, post code, ZIP code, or other short code associated with the address by the relevant country's postal system
// ! `country`: the country name
// ! `direction`: the cardinal direction or quadrant, e.g., "north"
// ! `landmark`: the publicly known prominent feature that can substitute the street name and number, e.g., "White House" or "Taj Mahal"
// ! `postOfficeBox`: the post office box number or identifier
// ! `separator`: a formatting separator between two ordered address non-separator components; the value property of the component includes the
// verbatim separator, for example, a hyphen character or even an empty string; this value has higher precedence than the `defaultSeparator` property
// of the `Address`; implementations MUST NOT insert two consecutive separator components; instead, they SHOULD insert a single separator component
// with the combined value; this component kind MUST NOT be set if the `Address` `isOrdered` property value is `false`.
@@ -1548,7 +1860,9 @@ type Address struct {
// and the `defaultSeparator` property MUST NOT be set.
Components []AddressComponent `json:"components,omitempty"`
// The indicator if the address components in the components property are ordered (default: `false`).
// The indicator if the address components in the components property are ordered
//
// default: false
IsOrdered bool `json:"isOrdered,omitzero"`
// The Alpha-2 country code as of [ISO.3166-1].
@@ -1573,8 +1887,8 @@ type Address struct {
// The boolean value MUST be `true`.
//
// In addition to the common contexts, allowed key values are:
// !- `billing`: an address to be used for billing
// !- `delivery`: an address to be used for delivering physical items
// ! `billing`: an address to be used for billing
// ! `delivery`: an address to be used for delivering physical items
Contexts map[AddressContext]bool `json:"contexts,omitempty"`
// The full address, including street, region, or country.
@@ -1704,9 +2018,9 @@ type Anniversary struct {
// The kind of anniversary.
//
// The enumerated values are:
// !- `birth`: a birthday anniversary
// !- `death`: a deathday anniversary
// !- `wedding`: a wedding day anniversary
// ! `birth`: a birthday anniversary
// ! `death`: a deathday anniversary
// ! `wedding`: a wedding day anniversary
Kind AnniversaryKind `json:"kind"`
// The date of the anniversary in the Gregorian calendar.
@@ -1748,9 +2062,9 @@ type PersonalInfo struct {
// The kind of personal information.
//
// The enumerated values are:
// !- `expertise`: a field of expertise or a credential
// !- `hobby`: a hobby
// !- `interest`: an interest
// ! `expertise`: a field of expertise or a credential
// ! `hobby`: a hobby
// ! `interest`: an interest
Kind PersonalInfoKind `json:"kind"`
// The actual information.
@@ -1759,9 +2073,9 @@ type PersonalInfo struct {
// The level of expertise or engagement in hobby or interest.
//
// The enumerated values are:
// !- `high`
// !- `medium`
// !- `low`
// ! `high`
// ! `medium`
// ! `low`
Level PersonalInfoLevel `json:"level,omitempty"`
// The position of the personal information in the list of all `PersonalInfo` objects that
@@ -1880,8 +2194,6 @@ type ContactCard struct {
//
// A group Card without the members property can be considered an abstract grouping or one whose members
// are known empirically (e.g., `IETF Participants`).
//
// example: {"kind": "group", "name": {"full": "The Doe family"}, "uid": "urn:uuid:ab4310aa-fa43-11e9-8f0b-362b9e155667", "members": {"urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af": true, "urn:uuid:b8767877-b4a1-4c70-9acc-505d3819e519": true}
Members map[string]bool `json:"members,omitempty"`
// The identifier for the product that created the Card.
@@ -1908,8 +2220,6 @@ type ContactCard struct {
// }
// }
// ```
//
// example: "relatedTo": {"urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6": {"relation": {"friend": true}}, "8cacdfb7d1ffdb59@example.com": {"relation": {}}}
RelatedTo map[string]Relation `json:"relatedTo,omitempty"`
// An identifier that associates the object as the same across different systems, address books, and views.