You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2026/10/19 13:43:20 UTC

(james-project) 05/08: fixup! [ENHANCEMENT] JMAP Web Push: a TTL of four weeks

This is an automated email from the ASF dual-hosted git repository.

chibenwa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit dbd127371b94f4fbc704d05ff96ef243841074fc
Author: Clement Guyon <cg...@linagora.com>
AuthorDate: Mon Oct 12 23:49:30 2026 +0200

    fixup! [ENHANCEMENT] JMAP Web Push: a TTL of four weeks
    
    One week: a push that could not be delivered for a week is not worth
    delivering any more.
---
 CHANGELOG.md                                                          | 2 +-
 .../apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala | 2 +-
 .../scala/org/apache/james/jmap/pushsubscription/PushListener.scala   | 2 +-
 .../scala/org/apache/james/jmap/pushsubscription/PushRequest.scala    | 4 ++--
 .../org/apache/james/jmap/pushsubscription/PushListenerTest.scala     | 4 ++--
 .../pushsubscription/PushSubscriptionSetCreateProcessorTest.scala     | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40b94b7e1b..5049fa1332 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -56,7 +56,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
  - [ENHANCEMENT] Implement negative ACL for JMAP
  - JAMES-4157 Implement JMAP `Blob/copy` (#2896)
  - [ENHANCEMENT] JMAP Web Push: authenticate requests with VAPID and advertise the `urn:ietf:params:jmap:webpush-vapid` capability (RFC-9749), see `webpush.vapid.*` in `jmap.properties`
- - [ENHANCEMENT] JMAP Web Push: ask push services to retain pushes four weeks (`TTL`) instead of 68 years
+ - [ENHANCEMENT] JMAP Web Push: ask push services to retain pushes one week (`TTL`) instead of 68 years
  - JAMES-3728 Implement `MessageIdManager::updateEmail`, allowing `Email/set` update to combine move and setFlags
  - JAMES-4203 Add Identity events, plugged into `CustomIdentityDAO`
  - JAMES-3893 Allow deleting identities via WebAdmin
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala
index 361d307f17..50673d6dcb 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala
@@ -111,7 +111,7 @@ class PushSubscriptionSetCreateProcessor @Inject()(webPushClient: WebPushClient)
     SMono.fromCallable(() => Json.stringify(PushSerializer.serializePushVerification(pushVerification)).getBytes(StandardCharsets.UTF_8))
       .map(clearPayload => keys.map(keysValue => keysValue.encrypt(clearPayload)).getOrElse(clearPayload))
       .flatMap(payload => SMono.fromPublisher(webPushClient.push(pushSubscriptionServerURL, PushRequest(
-        ttl = PushTTL.FOUR_WEEKS,
+        ttl = PushTTL.ONE_WEEK,
         // Without it the client cannot tell that the payload is encrypted, nor read it
         contentCoding = keys.map(_ => Aes128gcm),
         payload = payload))))
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushListener.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushListener.scala
index 4777ea451b..0b52d4db3e 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushListener.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushListener.scala
@@ -90,7 +90,7 @@ class PushListener @Inject()(pushRepository: PushSubscriptionRepository,
       .fold(SMono.empty[Unit])(stateChange => SMono(webPushClient.push(pushSubscription.url, asPushRequest(stateChange, pushSubscription))))
 
   private def asPushRequest(stateChange: StateChange, pushSubscription: PushSubscription): PushRequest =
-    PushRequest(ttl = PushTTL.FOUR_WEEKS,
+    PushRequest(ttl = PushTTL.ONE_WEEK,
       urgency = Some(urgency(stateChange)),
       topic = Some(extractTopic(stateChange)),
       contentCoding = pushSubscription.keys.map(_ => Aes128gcm),
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala
index 85b4b4244a..e143a831d0 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/pushsubscription/PushRequest.scala
@@ -88,8 +88,8 @@ object PushTTL {
       .map(new IllegalArgumentException(_))
 
   val MAX: PushTTL = validate(MAX_INT).toOption.get
-  // The longest push services commonly retain a message: they cap a longer TTL
-  val FOUR_WEEKS: PushTTL = validate(Duration.ofDays(28).getSeconds).toOption.get
+  // A push that could not be delivered for a week is not worth delivering any more
+  val ONE_WEEK: PushTTL = validate(Duration.ofDays(7).getSeconds).toOption.get
 }
 
 case class PushTopicConstraint()
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushListenerTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushListenerTest.scala
index 8c8fae737d..eb5e156b96 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushListenerTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushListenerTest.scala
@@ -126,7 +126,7 @@ class PushListenerTest {
     verify(webPushClient).push(ArgumentMatchers.eq(url), argumentCaptor.capture())
 
     SoftAssertions.assertSoftly(softly => {
-      softly.assertThat(argumentCaptor.getValue.ttl).isEqualTo(PushTTL.FOUR_WEEKS)
+      softly.assertThat(argumentCaptor.getValue.ttl).isEqualTo(PushTTL.ONE_WEEK)
       softly.assertThat(new String(argumentCaptor.getValue.payload, StandardCharsets.UTF_8))
         .isEqualTo(s"""{"@type":"StateChange","changed":{"$bobAccountId":{"Email":"${state1.value.toString}"}}}""")
     })
@@ -217,7 +217,7 @@ class PushListenerTest {
     verify(webPushClient).push(ArgumentMatchers.eq(url), argumentCaptor.capture())
 
     SoftAssertions.assertSoftly(softly => {
-      softly.assertThat(argumentCaptor.getValue.ttl).isEqualTo(PushTTL.FOUR_WEEKS)
+      softly.assertThat(argumentCaptor.getValue.ttl).isEqualTo(PushTTL.ONE_WEEK)
       softly.assertThat(new String(argumentCaptor.getValue.payload, StandardCharsets.UTF_8))
         .isEqualTo(s"""{"@type":"StateChange","changed":{"$bobAccountId":{"Email":"${state1.value.toString}","Mailbox":"${state2.value.toString}"}}}""")
     })
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushSubscriptionSetCreateProcessorTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushSubscriptionSetCreateProcessorTest.scala
index 333b670b39..593275b14d 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushSubscriptionSetCreateProcessorTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/pushsubscription/PushSubscriptionSetCreateProcessorTest.scala
@@ -77,7 +77,7 @@ class PushSubscriptionSetCreateProcessorTest {
 
     assertThat(requests.size).isEqualTo(1)
     assertThat(requests.head.containsHeader("Content-Encoding")).isFalse
-    assertThat(requests.head.getFirstHeader("TTL")).isEqualTo("2419200")
+    assertThat(requests.head.getFirstHeader("TTL")).isEqualTo("604800")
     assertThatJson(requests.head.getBodyAsString)
       .isEqualTo(
         """{


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org