[JMAP] Re: JMAP for Calendars comments

Mauro De Gennaro <mauro@stalw.art> Fri, 10 October 2025 09:06 UTC

Return-Path: <mauro@stalw.art>
X-Original-To: jmap@mail2.ietf.org
Delivered-To: jmap@mail2.ietf.org
Received: from localhost (localhost [127.0.0.1]) by mail2.ietf.org (Postfix) with ESMTP id 17792708BF7F for <jmap@mail2.ietf.org>; Fri, 10 Oct 2025 02:06:50 -0700 (PDT)
X-Virus-Scanned: amavisd-new at ietf.org
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Level:
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: mail2.ietf.org (amavisd-new); dkim=pass (2048-bit key) header.d=stalw.art header.b="bdrjPBvA"; dkim=neutral reason="invalid (unsupported algorithm ed25519-sha256)" header.d=stalw.art header.b="6oqVEkZK"
Received: from mail2.ietf.org ([166.84.6.31]) by localhost (mail2.ietf.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yBsv2hczEH_A for <jmap@mail2.ietf.org>; Fri, 10 Oct 2025 02:06:49 -0700 (PDT)
Received: from mail.stalw.art (mail.stalw.art [135.181.195.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mail2.ietf.org (Postfix) with ESMTPS id E0736708BF64 for <jmap@ietf.org>; Fri, 10 Oct 2025 02:06:48 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; s=202404r; d=stalw.art; c=relaxed/relaxed; h=Message-Id:To:Date:Subject:From; t=1760087207; bh=ofsgD6Q65egFJ2yENX5O93M UXITJyarc1p0JKxzGxIc=; b=bdrjPBvAJW53bULxDnOk4v7IS++SOb9NIbdOyg5MX/Uc+uL1fi Duhqigv8qSNpBJsW8L/WvmJATHuGMFhl9CStM9dND05LHV600wwQ9Ec61cDpORXLJvYHY1v2Cbx V4JocP87NJphn+xQAPBhBmGifGSD2qmD/txUDFcdS5bQ+zFhXmel2rY6ZC++EeUyZ2S0scQVlXj OkEEOgwwPX33Jv3anjavO9LEhsKZeaHa69JaKlgsVlC6v8O8vzbaVyZ4BbSPdzyz8RLqCpnrHEe Cb2sVlpAyZBnlf4ydxivZNV41q/Ui0ZvFL9crFAUNV7Og0VRS7yXvX05tg3Qk6HxXww==;
DKIM-Signature: v=1; a=ed25519-sha256; s=202404e; d=stalw.art; c=relaxed/relaxed; h=Message-Id:To:Date:Subject:From; t=1760087207; bh=ofsgD6Q65egFJ2yENX5O93M UXITJyarc1p0JKxzGxIc=; b=6oqVEkZK0uxXocOri4MAAPrDE/CTthgh1zpE/Rj4RYAY8msl+7 9p/Vf2rBIARSp1wrEUIph4NK1V0w9Qt89hBw==;
From: Mauro De Gennaro <mauro@stalw.art>
Content-Type: multipart/alternative; boundary="Apple-Mail=_62D7D24E-FEDC-4739-9D4F-4359196AE843"
Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3731.700.6.1.11\))
Date: Fri, 10 Oct 2025 11:06:37 +0200
References: <101DEC25-A12F-4063-90FB-446C6E5190BF@stalw.art> <4aa2017d-5ef4-486f-a264-2c8e2bec6094@dogfoodapp.fastmail.com> <34E1318A-C0D3-495F-9076-6B914C60D59F@stalw.art> <4561708e-c41a-4ef5-a644-0444eabbc083@dogfoodapp.fastmail.com>
To: IETF JMAP Mailing List <jmap@ietf.org>
In-Reply-To: <4561708e-c41a-4ef5-a644-0444eabbc083@dogfoodapp.fastmail.com>
Message-Id: <7A250971-CC56-4D31-9B23-058B29A38E68@stalw.art>
X-Mailer: Apple Mail (2.3731.700.6.1.11)
Message-ID-Hash: BHYXZWW3OOGBBQHJ5BM55G4AA7BKCDLI
X-Message-ID-Hash: BHYXZWW3OOGBBQHJ5BM55G4AA7BKCDLI
X-MailFrom: mauro@stalw.art
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-jmap.ietf.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
X-Mailman-Version: 3.3.9rc6
Precedence: list
Subject: [JMAP] Re: JMAP for Calendars comments
List-Id: JSON Meta Access Protocol <jmap.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/jmap/TtCIOSXgdW2Yyqhc9MhfXjNBX9k>
List-Archive: <https://mailarchive.ietf.org/arch/browse/jmap>
List-Help: <mailto:jmap-request@ietf.org?subject=help>
List-Owner: <mailto:jmap-owner@ietf.org>
List-Post: <mailto:jmap@ietf.org>
List-Subscribe: <mailto:jmap-join@ietf.org>
List-Unsubscribe: <mailto:jmap-leave@ietf.org>


>> Finding the principal for a calendar address: As mentioned before, it’s currently not possible to obtain the principal ID for a given calendar address. Allowing Principal/query to search by calendarAddress would solve this and avoid the need to add a new property to the Participant object.
>> 
> I'm still not quite clear on the use case you have here. The only one I can see (using your scenario) is that you are Wile E. Coyote and want to check the availability of Road Runner so you can invite them to an event, but you only know their alias runner@acme.net <mailto:runner@acme.net> and not road_runner@acme.net <mailto:road_runner@acme.net>? That … doesn't seem very likely?

For this use case, I’m thinking from the perspective of a calendar client implementer. For example, suppose the client UI lists all participants in an event, and the user can right-click on a participant to view their availability or share something else (a file node, mailbox, etc.) with them before the meeting. As you said, the client only knows the participant’s alias and display name.

Currently, the only way for the user to locate the corresponding principal (so they can view availability or share data) is to close that view and perform a manual search by name or by calendar address (if it’s a mailto: URI and happens to match the principal’s email). Allowing Principal/query to search by calendarAddress would let clients automatically map a known calendar address to its principal, when that mapping exists.

>> Discovering a principal’s calendar addresses:
>> 
> This is already in the spec <https://www.ietf.org/archive/id/draft-ietf-jmap-calendars-25.html#section-2.1>:

Thanks, I hadn’t yet implemented the new capabilities and missed that.


>> Identifying the main account ID of a principal: Suppose Road Runner wants to share his personal calendar (or a mailbox) with Wile. He queries for Wile’s Principal and sees account IDs “A1” and “A3” listed under the accounts property. But how can his client tell which one is Wile’s main account?
>> 
> Also in the same bit of the spec <https://www.ietf.org/archive/id/draft-ietf-jmap-calendars-25.html#section-2.1>:

I missed that as well, though my earlier comment was meant more broadly about JMAP for Sharing in general, not just JMAP for Calendars. I think the question still applies to other shareable data types such as mailboxes, file nodes, and address books.

JMAP for Sharing defines the account property as “A map of Account id to Account object for each JMAP Account containing data for this Principal that the user has access to, or null if none.” Then there’s the urn:ietf:params:jmap:principals:owner capability, which indicates that the Account (and its data) is owned by the referenced Principal.

However, if a Principal owns multiple Accounts (for example, a personal account and a group account), how can a client determine which one is the principal’s primary account ID -- i.e., the one that should be used when sharing mailboxes, address books, or files?

Just to clarify the model in Stalwart: when a Principal is a member of a group, they also own the group’s account data in addition to their own. It’s also possible for a group to share data with an individual Principal, in which case that Principal does not own the shared data.

>> I also have a few additional comments and questions unrelated to the above:
>> 
>> CalendarEvent/set: The line “If 'utcStart' is set, this is translated into a 'start' property using the server's current time zone information” isn’t entirely clear. I assume it means the event is converted to the calendar’s default time zone?
>> 
> If the "timeZone" property of the event is null, then yes. If not-null, it should be translated into local time using whatever time zone was set by that property. By "The server's current time zone information" I just meant the current version of the IANA DB it has at the time. I agree this could be clearer.

Ah, so the client must also provide a timeZone property when using utcStart and utcEnd? If so, the sentence “If set, the server will convert the UTC date to the event’s current time zone and store the local time” could be clearer. Perhaps it should explicitly state that when creating a new event:

- the client should provide a timeZone property,
- if missing, the calendar’s default time zone is used, and
- if the calendar has no default, then Etc/GMT is assumed.

>> Conflicting calendar defaults: When an event is added to multiple calendars with different default alerts, time zones, etc., how should these preferences be applied?
>> 
> The time zone one is trickier, and is not currently defined in the spec I think. So if you have an event without a time zone, and it's in multiple calendars with different default time zone properties … err, I have no idea what you should do. I think all you can do is pick one, and try to make it stable? Any other suggestions?

Yes, it’s a tricky case. In my implementation, I choose the most common time zone among the calendars. If there’s no clear majority, I fall back to the time zone from the first calendarId associated with the event.


>> Principal/getAvailability:
>> 
>> The method requires both a principalId and an accountId. Could the accountId be made optional so the server returns combined availability for all calendars the principal can access?
>> 
> The accountId here is the account id in which to find the Principal object (just like every other JMAP method — when you're supplying record ids, you need to know the account id in which to look for them). It's not the account id in which to look for calendars/events for that principal: you should indeed look at all calendars/accounts the Principal has access to (subject to the includeInAvailability property etc. set on the calendar for that principal).

That makes sense now,I found it confusing initially because I hadn’t noticed that JMAP Sharing says “In most systems, the user will have access to a single Account containing Principal objects. In some situations, for example, when aggregating data from different places, there may be multiple Accounts containing Principal objects.”

In my implementation, the accountId parameter is ignored for all Principal/* calls, since principals reside in a directory rather than within a specific account. Even when the server connects to multiple directories, it routes and filters internally so that users only see the principals they have permission to access.

What are the intended use cases for systems that have multiple accounts containing principals? Could the accountId parameter perhaps be made optional on Principal/* methods to simplify the more common single-directory scenario?


>> It’s unclear what busyStatus should be used when participationStatus is needsAction, tentative (and maybe also that delegated should not be included).
> "tentative" — The event status is "tentative" or the Principal's "participationStatus" is "tentative".
> 
> That's an "or", so if the event status is tentative, the busyStatus here would be tentative, according to the spec. (Or have I misunderstood your question?)

I was referring to the busyStatus of the BusyPeriod object, which can be confirmed, tentative, or unavailable. My question was which value should be used when the participant’s participationStatus is needsAction (I mistakenly included tentative earlier). It might also be worth clarifying (though perhaps it’s obvious) that when participation is delegated, the participant should be considered available during that time.

>> Recurrence range matching: CalDAV treats time ranges differently for VEVENT and VTODO (RFC 4791 §9.9). Should JMAP for Calendars follow the same behavior for consistency?
>> 
> I'm not sure I quite follow here. JMAP Calendars does not return todos, only events, so I'm not sure how VTODO is relevant?

Right, that makes sense. I had assumed JMAP for Calendars also covered Tasks, since ietf-calext-jscalendar-icalendar defines conversion rules for them.  But I now see that the introduction explicitly says that "unlike CalDAV, it does not define access to tasks”, sorry!

Since I wasn’t following the JMAP list closely at the time, I also wrongly assumed that the reason the JMAP for Tasks draft was allowed to expire was because JMAP for Calendars was intended to cover tasks as well.

Out of curiosity, what was the reasoning for leaving Tasks out of the spec? The current methods in JMAP Calendars already seem well suited for Tasks with only minor extensions.


>> CalendarEvent/query: The cannotCalculateOccurrences error seems to cover general recurrence failures. Would it be useful to define a specific error when a recurrence range expansion is too large?
>> 
> You mean if it exceeds the maxExpandedQueryDuration duration (found in the capabilities)? Yeah, that should maybe have a different error type.

Yes, exactly.

>> Shared personal calendars: The specification currently focuses on shared group calendars, which is great, but it might also need to clarify the rules for shared personal calendars (for example, how Principal/getAvailability should behave in that context).
>> 
> I'm not quite sure what you're looking for here; if it's not cleared up by the comments above, could you please clarify what's unclear?

Yes, that’s clear now. My point was simply that the spec’s sharing discussions mostly focus on group calendars. It might be useful to explicitly note any differing rules or expectations for shared personal calendars, though the intended behavior can indeed be inferred from the existing text.



Thanks,
Mauro