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

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


The following commit(s) were added to refs/heads/master by this push:
     new 791833b8f5 [FIX] Email/get full view: hasAttachment should filter out 
inlined at… (#2709)
791833b8f5 is described below

commit 791833b8f5a79191a1b41a361def5f2943ab058e
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Mon May 12 03:52:14 2025 +0200

    [FIX] Email/get full view: hasAttachment should filter out inlined at… 
(#2709)
---
 .../resources/eml/simple-inlined-attachment.eml    | 121 +++++++++++++++++++++
 .../rfc8621/contract/EmailGetMethodContract.scala  | 114 +++++++++++++++++++
 .../scala/org/apache/james/jmap/mail/Email.scala   |   4 +-
 3 files changed, 238 insertions(+), 1 deletion(-)

diff --git 
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/resources/eml/simple-inlined-attachment.eml
 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/resources/eml/simple-inlined-attachment.eml
new file mode 100644
index 0000000000..d1568982ee
--- /dev/null
+++ 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/resources/eml/simple-inlined-attachment.eml
@@ -0,0 +1,121 @@
+Date: Wed, 26 Jan 2022 12:21:37 +0100
+From: Bob <b...@domain.tld>
+To: Alice <al...@domain.tld>
+MIME-Version: 1.0
+Subject: inlined attachment
+Message-ID: <mime4j.16b.d30609c122843f4e.196a380f...@domain.tld>
+Content-Type: multipart/related;
+ boundary="-=Part.16d.b16547c587c987fd.196a380f8d4.b92d6af2f0294389=-"
+
+---=Part.16d.b16547c587c987fd.196a380f8d4.b92d6af2f0294389=-
+Content-Type: multipart/alternative;
+ boundary="-=Part.16c.d54cec4b999aebb5.196a380f8d2.7189347f48aceda7=-"
+
+---=Part.16c.d54cec4b999aebb5.196a380f8d2.7189347f48aceda7=-
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+Accept-Language: fr-FR, en-US, vi-VN, ru-RU, ar-TN, it-IT, de-DE
+Content-Language: vi-VN
+
+
+start[Screenshot 2025-05-06 at 09]end
+
+
+---=Part.16c.d54cec4b999aebb5.196a380f8d2.7189347f48aceda7=-
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+Accept-Language: fr-FR, en-US, vi-VN, ru-RU, ar-TN, it-IT, de-DE
+Content-Language: vi-VN
+
+<div><br></div><div>start</div><div><img src=3D"cid:e612b3e0-2a24-11f0-aacf=
+-77a69744ec20" alt=3D"Screenshot 2025-05-06 at 09" style=3D"max-width:770px=
+;" data-mimetype=3D"image/png"></div><div>end</div><div><br></div><div><br>=
+</div>
+---=Part.16c.d54cec4b999aebb5.196a380f8d2.7189347f48aceda7=---
+
+---=Part.16d.b16547c587c987fd.196a380f8d4.b92d6af2f0294389=-
+Content-Type: image/png;
+ name="=?US-ASCII?Q?Screenshot_2025-05-06_at_09.50.27.png?="; charset=base64
+Content-Disposition: inline
+Content-Transfer-Encoding: base64
+Content-ID: e612b3e0-2a24-11f0-aacf-77a69744ec20
+
+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
+2cPcU7IX7FXs/WNf6r6b+8P2Nx9gH6g9aHlw/SHGoeI6pG56XXd9Zn17Q1JD2+HQw82NXo2Hjjge
+2dFk2lRxVPfosmPUYwuO9R4vON5zQnqi62TGycfNk5rvnhp36vrp6NOtZ8LOnD8bdPbUOc654+e9
+zzdd8Lxw+CL7Yv0lt0t1La4th351/fVQq1tr3WX3yw1XPK40to1pO3bV9+rJawHXzl7nXb90I+JG
+2834m7dvpdxqvy28/fxOzp1Xv+X/9vnu3HuEe8X3Ne+XPjB8UPm77e972t3ajz4MeNjyKPbR3ceC
+xy+eyJ986VjwlPa09JnJs+rnzs+bOoM6r/wx/o+OF9IXn7uK/tT6c/1Lm5cH//L7q6V7XHfHK9mr
+3tdL3ui/2fHW5W1zT1TPg3e57z6/L/6g/6HqI/vjuU+Jn559nvqF9KXsq+3Xxm9h3+715vb2Svky
+ft+nAAaUR5t0AF7vAICWBAADnhup41Xnw76CqM60fQj8J6w6Q/YVNwBq4Td9dBf8urkFwN5tAFhB
+fXoKAFE0AOI8ADp69GAdOMv1nTuVhQjPBpt5X9Ny08C/Kaoz6Q9+D22BUtUFDG3/BXkhgywpQj4b
+AAAAimVYSWZNTQAqAAAACAAEARoABQAAAAEAAAA+ARsABQAAAAEAAABGASgAAwAAAAEAAgAAh2kA
+BAAAAAEAAABOAAAAAAAAAJAAAAABAAAAkAAAAAEAA5KGAAcAAAASAAAAeKACAAQAAAABAAAAsqAD
+AAQAAAABAAAATAAAAABBU0NJSQAAAFNjcmVlbnNob3ReQ+6gAAAACXBIWXMAABYlAAAWJQFJUiTw
+AAAB1WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpu
+czptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9
+Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRm
+OkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8v
+bnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj43
+NjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4x
+Nzg8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpVc2VyQ29tbWVudD5TY3Jl
+ZW5zaG90PC9leGlmOlVzZXJDb21tZW50PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9y
+ZGY6UkRGPgo8L3g6eG1wbWV0YT4KYNB7JQAAABxpRE9UAAAAAgAAAAAAAAAmAAAAKAAAACYAAAAm
+AAABBBOG5jIAAADQSURBVHgB7NIBEQAgDAMx5l80cLjgL1Owtpl9bzkNfN7AgPz5gt5/DYAMQqIB
+kBMzCgEyA4kGQE7MKATIDCQaADkxoxAgM5BoAOTEjEKAzECiAZATMwoBMgOJBkBOzCgEyAwkGgA5
+MaMQIDOQaADkxIxCgMxAogGQEzMKATIDiQZATswoBMgMJBoAOTGjECAzkGgA5MSMQoDMQKIBkBMz
+CgEyA4kGQE7MKATIDCQaADkxoxAgM5BoAOTEjEKAzECiAZATMwoBMgOJBkBOzCjEAQAA///X4LVo
+AAAAzklEQVTt0gERACAMAzHmXzRwuOAvU7C2mX1vOQ183sCA/PmC3n8NgAxCogGQEzMKATIDiQZA
+TswoBMgMJBoAOTGjECAzkGgA5MSMQoDMQKIBkBMzCgEyA4kGQE7MKATIDCQaADkxoxAgM5BoAOTE
+jEKAzECiAZATMwoBMgOJBkBOzCgEyAwkGgA5MaMQIDOQaADkxIxCgMxAogGQEzMKATIDiQZATswo
+BMgMJBoAOTGjECAzkGgA5MSMQoDMQKIBkBMzCgEyA4kGQE7MKMQBRz8vLLnQPmEAAAAASUVORK5C
+YII=
+
+---=Part.16d.b16547c587c987fd.196a380f8d4.b92d6af2f0294389=---
diff --git 
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
index e2625c020c..2d98222a51 100644
--- 
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
+++ 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailGetMethodContract.scala
@@ -4828,6 +4828,120 @@ trait EmailGetMethodContract {
          |}""".stripMargin)
   }
 
+  @Test
+  def 
inlinedAttachmentMailShouldNotBeCountedAsHasAttachmentWhenEmailFullView(server: 
GuiceJamesServer): Unit = {
+    val path = MailboxPath.inbox(BOB)
+    val mailboxId = 
server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
+    val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl])
+      .appendMessage(BOB.asString, path, AppendCommand.from(
+        
ClassLoaderUtils.getSystemResourceAsSharedStream("eml/simple-inlined-attachment.eml")))
+      .getMessageId
+
+    val request =
+      s"""{
+         |     "using": [
+         |             "urn:ietf:params:jmap:core",
+         |             "urn:ietf:params:jmap:mail"
+         |     ],
+         |     "methodCalls": [
+         |             [
+         |                     "Email/get",
+         |                     {
+         |                             "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+         |                             "ids": ["${messageId.serialize}"],
+         |                             "properties": [
+         |                                     "id",
+         |                                     "subject",
+         |                                     "from",
+         |                                     "to",
+         |                                     "cc",
+         |                                     "bcc",
+         |                                     "keywords",
+         |                                     "size",
+         |                                     "receivedAt",
+         |                                     "sentAt",
+         |                                     "preview",
+         |                                     "hasAttachment",
+         |                                     "attachments",
+         |                                     "replyTo",
+         |                                     "mailboxIds"
+         |                             ],
+         |                             "fetchTextBodyValues": true
+         |                     },
+         |                     "c1"
+         |             ]
+         |     ]
+         |}""".stripMargin
+    val response = `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(request)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract
+      .body
+      .asString
+
+    assertThatJson(response)
+      .whenIgnoringPaths("methodResponses[0][1].state")
+      .isEqualTo(
+      s"""{
+         |    "sessionState": "${SESSION_STATE.value}",
+         |    "methodResponses": [
+         |        [
+         |            "Email/get",
+         |            {
+         |                "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+         |                "state": "33ac468f-7903-4f68-ac3e-8120505b5c3d",
+         |                "list": [
+         |                    {
+         |                        "id": "${messageId.serialize}",
+         |                        "keywords": {},
+         |                        "mailboxIds": {
+         |                            "${mailboxId.serialize}": true
+         |                        },
+         |                        "size": 7609,
+         |                        "receivedAt": "$${json-unit.ignore}",
+         |                        "to": [
+         |                            {
+         |                                "name": "Alice",
+         |                                "email": "al...@domain.tld"
+         |                            }
+         |                        ],
+         |                        "from": [
+         |                            {
+         |                                "name": "Bob",
+         |                                "email": "b...@domain.tld"
+         |                            }
+         |                        ],
+         |                        "subject": "inlined attachment",
+         |                        "sentAt": "$${json-unit.ignore}",
+         |                        "attachments": [
+         |                            {
+         |                                "partId": "5",
+         |                                "blobId": "${messageId.serialize}_5",
+         |                                "size": 4334,
+         |                                "name": "Screenshot 2025-05-06 at 
09.50.27.png",
+         |                                "type": "image/png",
+         |                                "charset": "base64",
+         |                                "disposition": "inline",
+         |                                "cid": 
"e612b3e0-2a24-11f0-aacf-77a69744ec20"
+         |                            }
+         |                        ],
+         |                        "hasAttachment": false,
+         |                        "preview": "start[Screenshot 2025-05-06 at 
09]end"
+         |                    }
+         |                ],
+         |                "notFound": []
+         |            },
+         |            "c1"
+         |        ]
+         |    ]
+         |}""".stripMargin)
+  }
+
   @Test
   def 
shouldUseFastViewWithAttachmentMetadataWhenSupportedBodyProperties(server: 
GuiceJamesServer): Unit = {
     val path = MailboxPath.inbox(BOB)
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
index b60b4ae0eb..a0de324aea 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
@@ -38,6 +38,7 @@ import 
org.apache.james.jmap.api.projections.{MessageFastViewPrecomputedProperti
 import org.apache.james.jmap.core.Id.{Id, IdConstraint}
 import org.apache.james.jmap.core.{Properties, UTCDate}
 import org.apache.james.jmap.mail.BracketHeader.sanitize
+import org.apache.james.jmap.mail.Disposition.ATTACHMENT
 import org.apache.james.jmap.mail.EmailFullViewFactory.extractBodyValues
 import org.apache.james.jmap.mail.EmailGetRequest.MaxBodyValueBytes
 import org.apache.james.jmap.mail.EmailHeaderName.{ADDRESSES_NAMES, DATE, 
MESSAGE_ID_NAMES}
@@ -625,7 +626,8 @@ private class EmailFullViewFactory 
@Inject()(zoneIdProvider: ZoneIdProvider, pre
           size = sanitizeSize(firstMessage.getSize)),
         header = EmailHeaders.from(zoneIdProvider.get())(mime4JMessage),
         bodyMetadata = EmailBodyMetadata(
-          hasAttachment = 
HasAttachment(!firstMessage.getLoadedAttachments.isEmpty),
+          hasAttachment = 
HasAttachment(bodyStructure.attachments.exists(attachment =>
+            attachment.disposition.contains(ATTACHMENT) && 
attachment.cid.isEmpty)),
           preview = preview),
         body = EmailBody(
           bodyStructure = bodyStructure,


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

Reply via email to