From b17da02d3ee613c18eae586dff352bada2e1de8f Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:58:31 +0200 Subject: [PATCH] Fix JMAP: Return RFC-3339-conformant UTCDate literals in capabilities: min `0001-01-01T00:00:00Z`, max `9999-12-31T23:59:59Z` --- CHANGELOG.md | 1 + .../src/config/mailstore/capabilities.rs | 25 ++++++++++++++++--- tests/src/jmap/principal/get.rs | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97610f6b..58195c74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If ## Fixed - OAuth resource indicators: Accept `imap`, `smtp`, `pop3` and `sieve` as valid resource indicators for OAuth access tokens. - PostgreSQL: Incomplete channel binding implementation. +- JMAP: Return RFC-3339-conformant UTCDate literals in capabilities: min `0001-01-01T00:00:00Z`, max `9999-12-31T23:59:59Z`. - Reject invalid duration values (e.g. `1h30m`). ## [0.16.12] - 2026-07-06 diff --git a/crates/common/src/config/mailstore/capabilities.rs b/crates/common/src/config/mailstore/capabilities.rs index 131ca9e9..500014a9 100644 --- a/crates/common/src/config/mailstore/capabilities.rs +++ b/crates/common/src/config/mailstore/capabilities.rs @@ -7,7 +7,6 @@ use crate::config::mailstore::jmap::JmapConfig; use ahash::AHashSet; use calcard::icalendar::ICalendarDuration; -use chrono::{DateTime, Utc}; use jmap_proto::{ object::{email::EmailComparator, file_node::FileNodeComparator}, request::capability::{ @@ -84,8 +83,28 @@ impl JmapConfig { Capability::Calendars, Capabilities::Calendar(CalendarCapabilities { max_calendars_per_event: None, - min_date_time: UTCDate::from_timestamp(DateTime::::MIN_UTC.timestamp()), - max_date_time: UTCDate::from_timestamp(DateTime::::MAX_UTC.timestamp()), + min_date_time: UTCDate { + year: 1, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + tz_before_gmt: false, + tz_hour: 0, + tz_minute: 0, + }, + max_date_time: UTCDate { + year: 9999, + month: 12, + day: 31, + hour: 23, + minute: 59, + second: 59, + tz_before_gmt: false, + tz_hour: 0, + tz_minute: 0, + }, max_expanded_query_duration: ICalendarDuration::from_seconds(86400 * 365) .to_string(), max_participants_per_event: bp diff --git a/tests/src/jmap/principal/get.rs b/tests/src/jmap/principal/get.rs index 29d1b2a4..218f3dca 100644 --- a/tests/src/jmap/principal/get.rs +++ b/tests/src/jmap/principal/get.rs @@ -105,7 +105,7 @@ pub async fn test(test: &TestServer) { "urn:ietf:params:jmap:calendars": { "maxCalendarsPerEvent": null, "minDateTime": "0001-01-01T00:00:00Z", - "maxDateTime": "65534-12-31T23:59:59Z", + "maxDateTime": "9999-12-31T23:59:59Z", "maxExpandedQueryDuration": "P52W1D", "maxParticipantsPerEvent": 20, "mayCreateCalendar": true