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:18 UTC

(james-project) 03/08: [FIX] JMAP Web Push: tell that a PushVerification is encrypted

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 edb263173f79d65cbdad3ce9b0f5562c6972f52a
Author: Clement Guyon <cg...@linagora.com>
AuthorDate: Mon Oct 12 22:08:33 2026 +0200

    [FIX] JMAP Web Push: tell that a PushVerification is encrypted
    
    A PushVerification sent to a subscription with keys was encrypted but
    carried no Content-Encoding header, unlike StateChange pushes: the push
    service delivers it, the client cannot read it, and the subscription is
    never verified.
    
    Its TTL follows the one of the other pushes.
---
 .../james/jmap/method/PushSubscriptionSetCreatePerformer.scala    | 8 ++++++--
 .../pushsubscription/PushSubscriptionSetCreateProcessorTest.scala | 3 +++
 2 files changed, 9 insertions(+), 2 deletions(-)

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 3335602948..361d307f17 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
@@ -10,7 +10,7 @@ import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.core.{Properties, PushSubscriptionCreation, PushSubscriptionCreationId, PushSubscriptionCreationParseException, PushSubscriptionCreationResponse, PushSubscriptionSetRequest, SetError}
 import org.apache.james.jmap.json.{PushSerializer, PushSubscriptionSerializer}
 import org.apache.james.jmap.method.PushSubscriptionSetCreatePerformer.{CreationFailure, CreationResult, CreationResults, CreationSuccess}
-import org.apache.james.jmap.pushsubscription.{PushRequest, PushTTL, WebPushClient}
+import org.apache.james.jmap.pushsubscription.{Aes128gcm, PushRequest, PushTTL, WebPushClient}
 import org.apache.james.mailbox.MailboxSession
 import org.slf4j.LoggerFactory
 import play.api.libs.json.{JsObject, JsPath, Json, JsonValidationError}
@@ -110,7 +110,11 @@ 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(PushTTL.MAX, payload = payload))))
+      .flatMap(payload => SMono.fromPublisher(webPushClient.push(pushSubscriptionServerURL, PushRequest(
+        ttl = PushTTL.FOUR_WEEKS,
+        // Without it the client cannot tell that the payload is encrypted, nor read it
+        contentCoding = keys.map(_ => Aes128gcm),
+        payload = payload))))
 }
 
 case class PushVerification(pushSubscriptionId: PushSubscriptionId,
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 cda353b6df..333b670b39 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
@@ -76,6 +76,8 @@ class PushSubscriptionSetCreateProcessorTest {
         .withPath("/subscribe")).toSeq
 
     assertThat(requests.size).isEqualTo(1)
+    assertThat(requests.head.containsHeader("Content-Encoding")).isFalse
+    assertThat(requests.head.getFirstHeader("TTL")).isEqualTo("2419200")
     assertThatJson(requests.head.getBodyAsString)
       .isEqualTo(
         """{
@@ -101,6 +103,7 @@ class PushSubscriptionSetCreateProcessorTest {
         .withMethod("POST")
         .withPath("/subscribe")).toSeq
     assertThat(requests.size).isEqualTo(1)
+    assertThat(requests.head.getFirstHeader("Content-Encoding")).isEqualTo("aes128gcm")
 
     assertThatJson(requests.head.getBodyAsString)
       .isNotEqualTo(


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