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 2023/01/11 03:24:00 UTC

[james-project] branch master updated (5b439520f3 -> 50dfd578f9)

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

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


    from 5b439520f3 JAMES-3756 Delegate/set create
     new ad0024f6d7 JAMES-3756 JMAP API endpoint should support delegation
     new b347bd0fcb JAMES-3756 James memory should use DelegationStoreAuthorizator
     new 4db7aa6a54 JAMES-3756 JMAP delegation setting should only be set by account owner
     new 50dfd578f9 JAMES-3756 DelegationProbe should be able to set delegation

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/james/mailbox/MailboxSession.java   |   6 ++
 .../james/modules/mailbox/MemoryMailboxModule.java |   6 +-
 .../distributed/DistributedEmailGetMethodTest.java |   3 +-
 .../distributed/DistributedEmailSetMethodTest.java |   3 +-
 .../rfc8621/contract/DelegateSetContract.scala     |  84 +++++++++++++++-
 .../rfc8621/contract/EmailGetMethodContract.scala  |  93 +++++++++++++++++-
 .../rfc8621/contract/EmailSetMethodContract.scala  | 109 +++++++++++++++++++++
 .../rfc8621/contract/probe/DelegationProbe.scala   |   6 +-
 .../rfc8621/memory/MemoryEmailGetMethodTest.java   |   3 +-
 .../rfc8621/memory/MemoryEmailSetMethodTest.java   |   3 +-
 .../apache/james/jmap/core/SessionTranslator.scala |  51 ++++++++++
 .../apache/james/jmap/delegation/DelegateSet.scala |   1 +
 .../jmap/method/DelegateSetCreatePerformer.scala   |  20 ++--
 .../james/jmap/method/DelegateSetMethod.scala      |   5 +-
 .../james/jmap/method/EmailChangesMethod.scala     |   7 +-
 .../apache/james/jmap/method/EmailGetMethod.scala  |   5 +-
 .../james/jmap/method/EmailImportMethod.scala      |   6 +-
 .../james/jmap/method/EmailQueryMethod.scala       |   6 +-
 .../apache/james/jmap/method/EmailSetMethod.scala  |   4 +-
 .../jmap/method/EmailSubmissionSetMethod.scala     |   5 +-
 .../james/jmap/method/IdentityGetMethod.scala      |   3 +-
 .../james/jmap/method/IdentitySetMethod.scala      |   6 +-
 .../apache/james/jmap/method/MDNParseMethod.scala  |   8 +-
 .../apache/james/jmap/method/MDNSendMethod.scala   |   7 +-
 .../james/jmap/method/MailboxChangesMethod.scala   |   5 +-
 .../james/jmap/method/MailboxGetMethod.scala       |   7 +-
 .../james/jmap/method/MailboxQueryMethod.scala     |   6 +-
 .../james/jmap/method/MailboxSetMethod.scala       |   6 +-
 .../org/apache/james/jmap/method/Method.scala      |  19 ++--
 .../jmap/method/PushSubscriptionGetMethod.scala    |   7 +-
 .../jmap/method/PushSubscriptionSetMethod.scala    |   6 +-
 .../james/jmap/method/QuotaChangesMethod.scala     |   4 +-
 .../apache/james/jmap/method/QuotaGetMethod.scala  |   4 +-
 .../james/jmap/method/QuotaQueryMethod.scala       |   4 +-
 .../james/jmap/method/ThreadChangesMethod.scala    |   6 +-
 .../apache/james/jmap/method/ThreadGetMethod.scala |   5 +-
 .../jmap/method/VacationResponseGetMethod.scala    |   6 +-
 .../jmap/method/VacationResponseSetMethod.scala    |   6 +-
 38 files changed, 453 insertions(+), 88 deletions(-)
 create mode 100644 server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/SessionTranslator.scala


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


[james-project] 02/04: JAMES-3756 James memory should use DelegationStoreAuthorizator

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b347bd0fcbd3601d917e1ed0c937fe26007cc33d
Author: Quan Tran <hq...@linagora.com>
AuthorDate: Mon Jan 9 14:27:58 2023 +0700

    JAMES-3756 James memory should use DelegationStoreAuthorizator
---
 .../java/org/apache/james/modules/mailbox/MemoryMailboxModule.java  | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java b/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
index f51c5d8375..dd9993ca6e 100644
--- a/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
+++ b/server/container/guice/memory/src/main/java/org/apache/james/modules/mailbox/MemoryMailboxModule.java
@@ -23,8 +23,8 @@ import static org.apache.james.modules.Names.MAILBOXMANAGER_NAME;
 
 import javax.inject.Singleton;
 
+import org.apache.james.adapter.mailbox.DelegationStoreAuthorizator;
 import org.apache.james.adapter.mailbox.UserRepositoryAuthenticator;
-import org.apache.james.adapter.mailbox.UserRepositoryAuthorizator;
 import org.apache.james.events.EventListener;
 import org.apache.james.jmap.api.change.EmailChangeRepository;
 import org.apache.james.jmap.api.change.Limit;
@@ -107,7 +107,7 @@ public class MemoryMailboxModule extends AbstractModule {
         bind(MailboxSessionMapperFactory.class).to(InMemoryMailboxSessionMapperFactory.class);
         bind(MailboxPathLocker.class).to(JVMMailboxPathLocker.class);
         bind(Authenticator.class).to(UserRepositoryAuthenticator.class);
-        bind(Authorizator.class).to(UserRepositoryAuthorizator.class);
+        bind(Authorizator.class).to(DelegationStoreAuthorizator.class);
         bind(MailboxManager.class).to(InMemoryMailboxManager.class);
         bind(StoreMailboxManager.class).to(InMemoryMailboxManager.class);
         bind(MailboxChangeRepository.class).to(MemoryMailboxChangeRepository.class);
@@ -129,7 +129,7 @@ public class MemoryMailboxModule extends AbstractModule {
         bind(StoreSubscriptionManager.class).in(Scopes.SINGLETON);
         bind(JVMMailboxPathLocker.class).in(Scopes.SINGLETON);
         bind(UserRepositoryAuthenticator.class).in(Scopes.SINGLETON);
-        bind(UserRepositoryAuthorizator.class).in(Scopes.SINGLETON);
+        bind(DelegationStoreAuthorizator.class).in(Scopes.SINGLETON);
         bind(InMemoryMailboxManager.class).in(Scopes.SINGLETON);
         bind(MemoryMailboxChangeRepository.class).in(Scopes.SINGLETON);
         bind(MemoryEmailChangeRepository.class).in(Scopes.SINGLETON);


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


[james-project] 04/04: JAMES-3756 DelegationProbe should be able to set delegation

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 50dfd578f90a8b590f549197d184b5b2054d8adc
Author: Quan Tran <hq...@linagora.com>
AuthorDate: Wed Jan 11 10:19:19 2023 +0700

    JAMES-3756 DelegationProbe should be able to set delegation
---
 .../apache/james/jmap/rfc8621/contract/probe/DelegationProbe.scala  | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

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/probe/DelegationProbe.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/probe/DelegationProbe.scala
index b966141db6..361034bc70 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/probe/DelegationProbe.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/probe/DelegationProbe.scala
@@ -25,7 +25,7 @@ import javax.inject.Inject
 import org.apache.james.core.Username
 import org.apache.james.user.api.DelegationStore
 import org.apache.james.utils.GuiceProbe
-import reactor.core.scala.publisher.SFlux
+import reactor.core.scala.publisher.{SFlux, SMono}
 
 class DelegationProbeModule extends AbstractModule {
   override def configure(): Unit =
@@ -39,4 +39,8 @@ class DelegationProbe @Inject()(delegationStore: DelegationStore) extends GuiceP
     SFlux.fromPublisher(delegationStore.authorizedUsers(baseUser))
       .collectSeq()
       .block()
+
+  def addAuthorizedUser(baseUser: Username, delegatedUser: Username) =
+    SMono.fromPublisher(delegationStore.addAuthorizedUser(delegatedUser).forUser(baseUser))
+      .block()
 }


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


[james-project] 03/04: JAMES-3756 JMAP delegation setting should only be set by account owner

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4db7aa6a543b80e891698a286f9ce6c6da39d51c
Author: Quan Tran <hq...@linagora.com>
AuthorDate: Mon Jan 9 16:46:54 2023 +0700

    JAMES-3756 JMAP delegation setting should only be set by account owner
---
 .../org/apache/james/mailbox/MailboxSession.java   |  6 ++
 .../rfc8621/contract/DelegateSetContract.scala     | 82 ++++++++++++++++++++++
 .../apache/james/jmap/delegation/DelegateSet.scala |  1 +
 .../jmap/method/DelegateSetCreatePerformer.scala   | 20 ++++--
 4 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxSession.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxSession.java
index 3ea1460b1e..e0315c4415 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxSession.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxSession.java
@@ -82,6 +82,12 @@ public class MailboxSession {
      */
     public static long SYSTEM_SESSION_ID = 0L;
 
+    public static boolean isPrimaryAccount(MailboxSession mailboxSession) {
+        return mailboxSession.loggedInUser
+            .map(loggedInUser -> loggedInUser.equals(mailboxSession.getUser()))
+            .orElse(false);
+    }
+
     public enum SessionType {
         /**
          * Session was created via the System
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/DelegateSetContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
index 4bf9357816..8c37347389 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
@@ -492,4 +492,86 @@ trait DelegateSetContract {
       assertThat(server.getProbe(classOf[DelegationProbe]).getAuthorizedUsers(BOB).asJavaCollection)
         .containsExactly(ANDRE))
   }
+
+  @Test
+  def shouldReturnNotFoundWhenNotDelegated(): Unit = {
+    val request =
+      s"""{
+         |	"using": ["urn:ietf:params:jmap:core", "urn:apache:james:params:jmap:delegation"],
+         |	"methodCalls": [
+         |		[
+         |			"Delegate/set", {
+         |				"accountId": "$ANDRE_ACCOUNT_ID",
+         |				"create": {
+         |					"4f29": {
+         |						"username": "cedric@domain.tld"
+         |					}
+         |				}
+         |			}, "0"
+         |		]
+         |	]
+         |}""".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)
+      .inPath("methodResponses[0][1]")
+      .isEqualTo(
+        s"""{
+           |	"type": "accountNotFound"
+           |}""".stripMargin)
+  }
+
+  @Test
+  def bobCanOnlyManageHisPrimaryAccountSetting(server: GuiceJamesServer): Unit = {
+    server.getProbe(classOf[DelegationProbe]).addAuthorizedUser(ANDRE, BOB)
+    val request =
+      s"""{
+         |	"using": ["urn:ietf:params:jmap:core", "urn:apache:james:params:jmap:delegation"],
+         |	"methodCalls": [
+         |		[
+         |			"Delegate/set", {
+         |				"accountId": "$ANDRE_ACCOUNT_ID",
+         |				"create": {
+         |					"4f29": {
+         |						"username": "cedric@domain.tld"
+         |					}
+         |				}
+         |			}, "0"
+         |		]
+         |	]
+         |}""".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)
+      .inPath("methodResponses[0][1].notCreated")
+      .isEqualTo(
+        s"""{
+           |	"4f29": {
+           |		"type": "forbidden",
+           |		"description": "${BOB.asString()} can not manage ${ANDRE.asString()}'s account settings"
+           |	}
+           |}""".stripMargin)
+  }
 }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala
index 203a0ca498..c2db36f606 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala
@@ -44,6 +44,7 @@ case class DelegateSetResponse(accountId: AccountId,
                                notCreated: Option[Map[DelegateCreationId, SetError]])
 
 case class DelegateSetParseException(setError: SetError) extends IllegalArgumentException
+case class ForbiddenAccountManagement(accessUser: Username, targetUser: Username) extends RuntimeException(s"${accessUser.asString()} can not manage ${targetUser.asString()}'s account settings")
 
 object DelegateSetParseException {
   def from(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): DelegateSetParseException = {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetCreatePerformer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetCreatePerformer.scala
index 789ad15a13..c5e16b745a 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetCreatePerformer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetCreatePerformer.scala
@@ -23,10 +23,11 @@ import javax.inject.Inject
 import org.apache.james.jmap.core.SetError
 import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.delegation.DelegationCreation.{knownProperties, serverSetProperty}
-import org.apache.james.jmap.delegation.{DelegateCreationId, DelegateCreationRequest, DelegateCreationResponse, DelegateSetParseException, DelegateSetRequest, DelegationCreation, DelegationId}
+import org.apache.james.jmap.delegation.{DelegateCreationId, DelegateCreationRequest, DelegateCreationResponse, DelegateSetParseException, DelegateSetRequest, DelegationCreation, DelegationId, ForbiddenAccountManagement}
 import org.apache.james.jmap.json.DelegationSerializer
 import org.apache.james.jmap.method.DelegateSetCreatePerformer.{CreationFailure, CreationResult, CreationResults, CreationSuccess}
 import org.apache.james.mailbox.MailboxSession
+import org.apache.james.mailbox.MailboxSession.isPrimaryAccount
 import org.apache.james.mailbox.exception.UserDoesNotExistException
 import org.apache.james.user.api.{DelegationStore, UsersRepository}
 import play.api.libs.json.JsObject
@@ -58,6 +59,7 @@ object DelegateSetCreatePerformer {
       case e: DelegateSetParseException => e.setError
       case e: UserDoesNotExistException => SetError.invalidArguments(SetErrorDescription(e.getMessage))
       case e: IllegalArgumentException => SetError.invalidArguments(SetErrorDescription(e.getMessage))
+      case e: ForbiddenAccountManagement => SetError.forbidden(SetErrorDescription(e.getMessage))
       case _ => SetError.serverFail(SetErrorDescription(e.getMessage))
     }
   }
@@ -83,12 +85,16 @@ class DelegateSetCreatePerformer @Inject()(delegationStore: DelegationStore,
   }
 
   private def create(delegateCreationId: DelegateCreationId, request: DelegateCreationRequest, mailboxSession: MailboxSession): SMono[CreationResult] =
-    SMono.fromPublisher(usersRepository.containsReactive(request.username))
-      .filter(bool => bool)
-      .flatMap(_ => SMono.fromPublisher(delegationStore.addAuthorizedUser(mailboxSession.getUser, request.username))
-        .`then`(SMono.just[CreationResult](CreationSuccess(delegateCreationId, evaluateCreationResponse(request, mailboxSession))))
-        .onErrorResume(e => SMono.just[CreationResult](CreationFailure(delegateCreationId, e))))
-      .switchIfEmpty(SMono.just[CreationResult](CreationFailure(delegateCreationId, new UserDoesNotExistException(request.username))))
+    if (isPrimaryAccount(mailboxSession)) {
+      SMono.fromPublisher(usersRepository.containsReactive(request.username))
+        .filter(bool => bool)
+        .flatMap(_ => SMono.fromPublisher(delegationStore.addAuthorizedUser(mailboxSession.getUser, request.username))
+          .`then`(SMono.just[CreationResult](CreationSuccess(delegateCreationId, evaluateCreationResponse(request, mailboxSession))))
+          .onErrorResume(e => SMono.just[CreationResult](CreationFailure(delegateCreationId, e))))
+        .switchIfEmpty(SMono.just[CreationResult](CreationFailure(delegateCreationId, new UserDoesNotExistException(request.username))))
+    } else {
+      SMono.just(CreationFailure(delegateCreationId, ForbiddenAccountManagement(mailboxSession.getLoggedInUser.get(), mailboxSession.getUser)))
+    }
 
   private def evaluateCreationResponse(request: DelegateCreationRequest, mailboxSession: MailboxSession): DelegateCreationResponse =
     DelegateCreationResponse(id = DelegationId.from(mailboxSession.getUser, request.username))


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


[james-project] 01/04: JAMES-3756 JMAP API endpoint should support delegation

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ad0024f6d75f260e0aac31f8ab9b3733e50dafdb
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Jan 5 15:30:06 2023 +0700

    JAMES-3756 JMAP API endpoint should support delegation
    
    Co-authored-by: Quan Tran <hq...@linagora.com>
---
 .../distributed/DistributedEmailGetMethodTest.java |   3 +-
 .../distributed/DistributedEmailSetMethodTest.java |   3 +-
 .../rfc8621/contract/DelegateSetContract.scala     |   2 +-
 .../rfc8621/contract/EmailGetMethodContract.scala  |  93 +++++++++++++++++-
 .../rfc8621/contract/EmailSetMethodContract.scala  | 109 +++++++++++++++++++++
 .../rfc8621/memory/MemoryEmailGetMethodTest.java   |   3 +-
 .../rfc8621/memory/MemoryEmailSetMethodTest.java   |   3 +-
 .../apache/james/jmap/core/SessionTranslator.scala |  51 ++++++++++
 .../james/jmap/method/DelegateSetMethod.scala      |   5 +-
 .../james/jmap/method/EmailChangesMethod.scala     |   7 +-
 .../apache/james/jmap/method/EmailGetMethod.scala  |   5 +-
 .../james/jmap/method/EmailImportMethod.scala      |   6 +-
 .../james/jmap/method/EmailQueryMethod.scala       |   6 +-
 .../apache/james/jmap/method/EmailSetMethod.scala  |   4 +-
 .../jmap/method/EmailSubmissionSetMethod.scala     |   5 +-
 .../james/jmap/method/IdentityGetMethod.scala      |   3 +-
 .../james/jmap/method/IdentitySetMethod.scala      |   6 +-
 .../apache/james/jmap/method/MDNParseMethod.scala  |   8 +-
 .../apache/james/jmap/method/MDNSendMethod.scala   |   7 +-
 .../james/jmap/method/MailboxChangesMethod.scala   |   5 +-
 .../james/jmap/method/MailboxGetMethod.scala       |   7 +-
 .../james/jmap/method/MailboxQueryMethod.scala     |   6 +-
 .../james/jmap/method/MailboxSetMethod.scala       |   6 +-
 .../org/apache/james/jmap/method/Method.scala      |  19 ++--
 .../jmap/method/PushSubscriptionGetMethod.scala    |   7 +-
 .../jmap/method/PushSubscriptionSetMethod.scala    |   6 +-
 .../james/jmap/method/QuotaChangesMethod.scala     |   4 +-
 .../apache/james/jmap/method/QuotaGetMethod.scala  |   4 +-
 .../james/jmap/method/QuotaQueryMethod.scala       |   4 +-
 .../james/jmap/method/ThreadChangesMethod.scala    |   6 +-
 .../apache/james/jmap/method/ThreadGetMethod.scala |   5 +-
 .../jmap/method/VacationResponseGetMethod.scala    |   6 +-
 .../jmap/method/VacationResponseSetMethod.scala    |   6 +-
 33 files changed, 343 insertions(+), 77 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java
index 7f8ee6492d..9da6c601b9 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailGetMethodTest.java
@@ -26,6 +26,7 @@ import org.apache.james.DockerOpenSearchExtension;
 import org.apache.james.JamesServerBuilder;
 import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.EmailGetMethodContract;
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.modules.AwsS3BlobStoreExtension;
@@ -55,7 +56,7 @@ public class DistributedEmailGetMethodTest implements EmailGetMethodContract {
         .extension(new RabbitMQExtension())
         .extension(new AwsS3BlobStoreExtension())
         .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
+            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
         .build();
 
     @Override
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java
index 546e3da9b7..5c37b4bd45 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedEmailSetMethodTest.java
@@ -27,6 +27,7 @@ import org.apache.james.GuiceJamesServer;
 import org.apache.james.JamesServerBuilder;
 import org.apache.james.JamesServerExtension;
 import org.apache.james.jmap.rfc8621.contract.EmailSetMethodContract;
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.cassandra.ids.CassandraMessageId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.modules.AwsS3BlobStoreExtension;
@@ -59,7 +60,7 @@ public class DistributedEmailSetMethodTest implements EmailSetMethodContract {
         .extension(new RabbitMQExtension())
         .extension(new AwsS3BlobStoreExtension())
         .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
+            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
         .build();
 
     @Override
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/DelegateSetContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
index 0d9c8d6073..4bf9357816 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
@@ -29,7 +29,7 @@ import org.apache.http.HttpStatus.SC_OK
 import org.apache.james.GuiceJamesServer
 import org.apache.james.jmap.delegation.DelegationId
 import org.apache.james.jmap.http.UserCredential
-import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE, ANDRE_PASSWORD, BOB, BOB_PASSWORD, CEDRIC, DOMAIN, authScheme, baseRequestSpecBuilder}
+import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE, ANDRE_ACCOUNT_ID, ANDRE_PASSWORD, BOB, BOB_PASSWORD, CEDRIC, DOMAIN, authScheme, baseRequestSpecBuilder}
 import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbe
 import org.apache.james.utils.DataProbeImpl
 import org.assertj.core.api.Assertions.assertThat
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 54191b1891..64dca51669 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
@@ -42,7 +42,8 @@ import org.apache.james.jmap.core.UuidState.INSTANCE
 import org.apache.james.jmap.draft.JmapGuiceProbe
 import org.apache.james.jmap.http.UserCredential
 import org.apache.james.jmap.rfc8621.contract.EmailGetMethodContract.createTestMessage
-import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ALICE, ANDRE, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder}
+import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ALICE, ANDRE, ANDRE_ACCOUNT_ID, ANDRE_PASSWORD, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder}
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbe
 import org.apache.james.mailbox.MessageManager.AppendCommand
 import org.apache.james.mailbox.model.MailboxACL.Right
 import org.apache.james.mailbox.model.{MailboxACL, MailboxId, MailboxPath, MessageId}
@@ -82,6 +83,7 @@ trait EmailGetMethodContract {
       .fluent
       .addDomain(DOMAIN.asString)
       .addUser(BOB.asString, BOB_PASSWORD)
+      .addUser(ANDRE.asString(), ANDRE_PASSWORD)
 
     requestSpecification = baseRequestSpecBuilder(server)
       .setAuth(authScheme(UserCredential(BOB, BOB_PASSWORD)))
@@ -7676,6 +7678,95 @@ trait EmailGetMethodContract {
            |}""".stripMargin)
   }
 
+  @Test
+  def bobShouldBeAbleToAccessAndreMailboxWhenDelegated(server: GuiceJamesServer): Unit = {
+    val path = MailboxPath.inbox(ANDRE)
+    server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
+    val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl])
+      .appendMessage(ANDRE.asString, path, AppendCommand.from(
+        ClassLoaderUtils.getSystemResourceAsSharedStream("eml/multipart_simple.eml")))
+      .getMessageId
+
+    server.getProbe(classOf[DelegationProbe]).addAuthorizedUser(ANDRE, BOB)
+
+    val request =
+      s"""{
+         |  "using": [
+         |    "urn:ietf:params:jmap:core",
+         |    "urn:ietf:params:jmap:mail"],
+         |  "methodCalls": [[
+         |    "Email/get",
+         |    {
+         |      "accountId": "$ANDRE_ACCOUNT_ID",
+         |      "ids": ["${messageId.serialize}"],
+         |      "properties": ["messageId"]
+         |    },
+         |    "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)
+      .inPath("methodResponses[0][1].list[0]")
+      .isEqualTo(
+      s"""{
+         |    "id": "${messageId.serialize}",
+         |    "messageId": ["13d4375e-a4a9-f613-06a1-7e8cb1e0ea93@linagora.com"]
+         |}""".stripMargin)
+  }
+
+  @Test
+  def bobShouldNotBeAbleToAccessAndreMailboxWhenNotDelegated(server: GuiceJamesServer): Unit = {
+    val path = MailboxPath.inbox(ANDRE)
+    server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
+    val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl])
+      .appendMessage(ANDRE.asString, path, AppendCommand.from(
+        ClassLoaderUtils.getSystemResourceAsSharedStream("eml/multipart_simple.eml")))
+      .getMessageId
+
+    val request =
+      s"""{
+         |  "using": [
+         |    "urn:ietf:params:jmap:core",
+         |    "urn:ietf:params:jmap:mail"],
+         |  "methodCalls": [[
+         |    "Email/get",
+         |    {
+         |      "accountId": "$ANDRE_ACCOUNT_ID",
+         |      "ids": ["${messageId.serialize}"],
+         |      "properties": ["messageId"]
+         |    },
+         |    "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)
+      .inPath("methodResponses[0][1]")
+      .isEqualTo(
+      s"""{
+         |	"type": "accountNotFound"
+         |}""".stripMargin)
+  }
+
   private def waitForNextState(server: GuiceJamesServer, accountId: AccountId, initialState: State): State = {
     val jmapGuiceProbe: JmapGuiceProbe = server.getProbe(classOf[JmapGuiceProbe])
     awaitAtMostTenSeconds.untilAsserted {
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/EmailSetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailSetMethodContract.scala
index 3456cd798f..c57211742f 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailSetMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailSetMethodContract.scala
@@ -44,6 +44,7 @@ import org.apache.james.jmap.draft.{JmapGuiceProbe, MessageIdProbe}
 import org.apache.james.jmap.http.UserCredential
 import org.apache.james.jmap.rfc8621.contract.DownloadContract.accountId
 import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ACCOUNT_ID, ANDRE, ANDRE_ACCOUNT_ID, ANDRE_PASSWORD, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder}
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbe
 import org.apache.james.mailbox.FlagsBuilder
 import org.apache.james.mailbox.MessageManager.AppendCommand
 import org.apache.james.mailbox.model.MailboxACL.Right
@@ -7145,6 +7146,114 @@ trait EmailSetMethodContract {
            |}""".stripMargin)
   }
 
+  @Test
+  def bobShouldBeAbleToUpdateEmailInAndreMailboxWhenDelegated(server: GuiceJamesServer): Unit = {
+    val message: Message = Fixture.createTestMessage
+    val flags: Flags = new Flags(Flags.Flag.ANSWERED)
+    val path = MailboxPath.inbox(ANDRE)
+    server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
+    val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl]).appendMessage(ANDRE.asString(), path, AppendCommand.builder()
+      .withFlags(flags)
+      .build(message))
+      .getMessageId
+
+    server.getProbe(classOf[DelegationProbe]).addAuthorizedUser(ANDRE, BOB)
+
+    val request =
+      s"""{
+         |  "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+         |  "methodCalls": [
+         |    ["Email/set", {
+         |      "accountId": "$ANDRE_ACCOUNT_ID",
+         |      "update": {
+         |        "${messageId.serialize}":{
+         |          "keywords": {
+         |             "music": true
+         |          }
+         |        }
+         |      }
+         |    }, "c1"],
+         |    ["Email/get",
+         |     {
+         |       "accountId": "$ANDRE_ACCOUNT_ID",
+         |       "ids": ["${messageId.serialize}"],
+         |       "properties": ["keywords"]
+         |     },
+         |     "c2"]]
+         |}""".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)
+      .inPath("methodResponses[1][1].list[0]")
+      .isEqualTo(String.format(
+        """{
+          |   "id":"%s",
+          |   "keywords": {
+          |     "music": true
+          |   }
+          |}
+      """.stripMargin, messageId.serialize))
+  }
+
+  @Test
+  def bobShouldNotBeAbleToUpdateEmailInAndreMailboxWhenNotDelegated(server: GuiceJamesServer): Unit = {
+    val message: Message = Fixture.createTestMessage
+    val flags: Flags = new Flags(Flags.Flag.ANSWERED)
+    val path = MailboxPath.inbox(ANDRE)
+    server.getProbe(classOf[MailboxProbeImpl]).createMailbox(path)
+    val messageId: MessageId = server.getProbe(classOf[MailboxProbeImpl]).appendMessage(ANDRE.asString(), path, AppendCommand.builder()
+      .withFlags(flags)
+      .build(message))
+      .getMessageId
+
+    val request =
+      s"""{
+         |	"using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+         |	"methodCalls": [
+         |		["Email/set", {
+         |			"accountId": "$ANDRE_ACCOUNT_ID",
+         |			"update": {
+         |				"${messageId.serialize}": {
+         |					"keywords": {
+         |						"music": 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)
+      .inPath("methodResponses[0][1]")
+      .isEqualTo(
+        """{
+          |	"type": "accountNotFound"
+          |}""".stripMargin)
+  }
+
   private def buildTestMessage = {
     Message.Builder
       .of
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java
index 95d6719344..2e07e0d2f1 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailGetMethodTest.java
@@ -28,6 +28,7 @@ import org.apache.james.JamesServerExtension;
 import org.apache.james.MemoryJamesConfiguration;
 import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailGetMethodContract;
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.modules.TestJMAPServerModule;
@@ -42,7 +43,7 @@ public class MemoryEmailGetMethodTest implements EmailGetMethodContract {
             .usersRepository(DEFAULT)
             .build())
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
+            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
         .build();
 
     @Override
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java
index 4ff6015f7e..65ecf0e03a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryEmailSetMethodTest.java
@@ -28,6 +28,7 @@ import org.apache.james.JamesServerExtension;
 import org.apache.james.MemoryJamesConfiguration;
 import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.jmap.rfc8621.contract.EmailSetMethodContract;
+import org.apache.james.jmap.rfc8621.contract.probe.DelegationProbeModule;
 import org.apache.james.mailbox.inmemory.InMemoryMessageId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.modules.TestJMAPServerModule;
@@ -43,7 +44,7 @@ public class MemoryEmailSetMethodTest implements EmailSetMethodContract {
             .usersRepository(DEFAULT)
             .build())
         .server(configuration -> MemoryJamesServerMain.createServer(configuration)
-            .overrideWith(new TestJMAPServerModule()))
+            .overrideWith(new TestJMAPServerModule(), new DelegationProbeModule()))
         .build();
 
     @Override
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/SessionTranslator.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/SessionTranslator.scala
new file mode 100644
index 0000000000..8d7a30ad06
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/SessionTranslator.scala
@@ -0,0 +1,51 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ * http://www.apache.org/licenses/LICENSE-2.0                   *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jmap.core
+
+import javax.inject.Inject
+import org.apache.james.core.Username
+import org.apache.james.jmap.method.AccountNotFoundException
+import org.apache.james.mailbox.{MailboxSession, SessionProvider}
+import org.apache.james.user.api.DelegationStore
+import org.apache.james.util.ReactorUtils
+import reactor.core.scala.publisher.{SFlux, SMono}
+
+class SessionTranslator  @Inject()(delegationStore: DelegationStore, sessionProvider: SessionProvider) {
+  def delegateIfNeeded(session: MailboxSession, targetAccountId: AccountId): SMono[MailboxSession] =
+    if (needDelegation(session, targetAccountId)) {
+      delegate(session, targetAccountId)
+    } else {
+      SMono.just(session)
+    }
+
+  private def needDelegation(session: MailboxSession, targetAccountId: AccountId): Boolean =
+   !hasAccountId(targetAccountId)(session.getUser)
+
+  private def hasAccountId(targetAccountId: AccountId)(username: Username): Boolean =
+    AccountId.from(username).toOption.contains(targetAccountId)
+
+  private def delegate(session: MailboxSession, targetAccountId: AccountId): SMono[MailboxSession] =
+    SFlux(delegationStore.delegatedUsers(session.getUser))
+      .filter(hasAccountId(targetAccountId))
+      .flatMap(targetUser => SMono.fromCallable(() => sessionProvider.authenticate(session.getUser).as(targetUser))
+        .subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER))
+      .next()
+      .switchIfEmpty(SMono.error(AccountNotFoundException()))
+}
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala
index ae62250cf7..6b1712e26a 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala
@@ -23,7 +23,7 @@ import eu.timepit.refined.auto._
 import javax.inject.Inject
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_DELEGATION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, UuidState}
+import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, UuidState}
 import org.apache.james.jmap.delegation.{DelegateSetRequest, DelegateSetResponse}
 import org.apache.james.jmap.json.{DelegationSerializer, ResponseSerializer}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -34,7 +34,8 @@ import reactor.core.scala.publisher.SMono
 
 class DelegateSetMethod @Inject()(createPerformer: DelegateSetCreatePerformer,
                                   val metricFactory: MetricFactory,
-                                  val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[DelegateSetRequest] {
+                                  val sessionSupplier: SessionSupplier,
+                                  val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[DelegateSetRequest] {
   override val methodName: Invocation.MethodName = MethodName("Delegate/set")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JAMES_DELEGATION)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala
index 44ee6eef3f..e5a0e91060 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala
@@ -24,21 +24,22 @@ import org.apache.james.jmap.api.change.{CanNotCalculateChangesException, EmailC
 import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{ErrorCode, Invocation, UuidState}
+import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{EmailGetSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{EmailChangesRequest, EmailChangesResponse, HasMoreChanges}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
+
 import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 
 class EmailChangesMethod @Inject()(val metricFactory: MetricFactory,
                                    val emailChangeRepository: EmailChangeRepository,
-                                   val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[EmailChangesRequest] {
+                                   val sessionSupplier: SessionSupplier,
+                                   val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[EmailChangesRequest] {
   override val methodName: MethodName = MethodName("Email/changes")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_MAIL)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala
index 1899e0edf9..a9cc31b665 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala
@@ -28,7 +28,7 @@ import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.UuidState.INSTANCE
-import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, Properties, UuidState}
+import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, Properties, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{EmailGetSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{Email, EmailBodyPart, EmailGetRequest, EmailGetResponse, EmailIds, EmailNotFound, EmailView, EmailViewReaderFactory, SpecificHeaderRequest, UnparsedEmailId}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -80,7 +80,8 @@ class EmailGetMethod @Inject() (readerFactory: EmailViewReaderFactory,
                                 messageIdFactory: MessageId.Factory,
                                 val metricFactory: MetricFactory,
                                 val emailchangeRepository: EmailChangeRepository,
-                                val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[EmailGetRequest] {
+                                val sessionSupplier: SessionSupplier,
+                                val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[EmailGetRequest] {
   override val methodName: MethodName = MethodName("Email/get")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala
index 41bfa69be1..799cf92838 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala
@@ -26,7 +26,7 @@ import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.SetError.SetErrorDescription
-import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SetError, UuidState}
+import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, SetError, UuidState}
 import org.apache.james.jmap.json.{EmailSetSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{BlobId, EmailCreationId, EmailCreationResponse, EmailImport, EmailImportRequest, EmailImportResponse, ThreadId, ValidatedEmailImport}
 import org.apache.james.jmap.method.EmailImportMethod.{ImportFailure, ImportResult, ImportResults, ImportSuccess, ImportWithBlob}
@@ -42,9 +42,10 @@ import org.apache.james.mime4j.stream.MimeConfig
 import org.apache.james.util.ReactorUtils
 import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import java.util.Date
+
 import javax.inject.Inject
+
 import scala.util.{Try, Using}
 
 object EmailImportMethod {
@@ -81,6 +82,7 @@ object EmailImportMethod {
 
 class EmailImportMethod @Inject() (val metricFactory: MetricFactory,
                                    val sessionSupplier: SessionSupplier,
+                                   val sessionTranslator: SessionTranslator,
                                    val blobResolvers: BlobResolvers,
                                    val serializer: EmailSetSerializer,
                                    val mailboxManager: MailboxManager,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
index 454e1893df..7bd1e09ad7 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
@@ -26,7 +26,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JM
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.Limit.Limit
 import org.apache.james.jmap.core.Position.Position
-import org.apache.james.jmap.core.{CanCalculateChanges, Invocation, Limit, Position, QueryState}
+import org.apache.james.jmap.core.{CanCalculateChanges, Invocation, Limit, Position, QueryState, SessionTranslator}
 import org.apache.james.jmap.json.{EmailQuerySerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{Comparator, EmailQueryRequest, EmailQueryResponse, FilterCondition, UnsupportedRequestParameterException}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -38,16 +38,18 @@ import org.apache.james.mailbox.{MailboxManager, MailboxSession}
 import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.util.streams.{Limit => JavaLimit}
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import java.time.ZonedDateTime
+
 import javax.inject.Inject
 import javax.mail.Flags.Flag.DELETED
+
 import scala.jdk.CollectionConverters._
 
 class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer,
                                   mailboxManager: MailboxManager,
                                   val metricFactory: MetricFactory,
                                   val sessionSupplier: SessionSupplier,
+                                  val sessionTranslator: SessionTranslator,
                                   val configuration: JMAPConfiguration,
                                   val emailQueryView: EmailQueryView) extends MethodRequiringAccountId[EmailQueryRequest] {
   override val methodName: MethodName = MethodName("Email/query")
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
index b428729301..376fda8800 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
@@ -23,7 +23,7 @@ import org.apache.james.jmap.api.change.EmailChangeRepository
 import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, UuidState}
+import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{EmailSetSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{EmailSetRequest, EmailSetResponse}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -31,7 +31,6 @@ import org.apache.james.mailbox.MailboxSession
 import org.apache.james.mailbox.model.MessageId
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 case class MessageNotFoundException(messageId: MessageId) extends Exception
@@ -39,6 +38,7 @@ case class MessageNotFoundException(messageId: MessageId) extends Exception
 class EmailSetMethod @Inject()(serializer: EmailSetSerializer,
                                val metricFactory: MetricFactory,
                                val sessionSupplier: SessionSupplier,
+                               val sessionTranslator: SessionTranslator,
                                createPerformer: EmailSetCreatePerformer,
                                deletePerformer: EmailSetDeletePerformer,
                                updatePerformer: EmailSetUpdatePerformer,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
index db97b23baf..cf4647e476 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
@@ -34,7 +34,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EM
 import org.apache.james.jmap.core.Id.{Id, IdConstraint}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.SetError.{SetErrorDescription, SetErrorType}
-import org.apache.james.jmap.core.{ClientId, Invocation, Properties, ServerId, SetError, UuidState}
+import org.apache.james.jmap.core.{ClientId, Invocation, Properties, ServerId, SessionTranslator, SetError, UuidState}
 import org.apache.james.jmap.json.{EmailSubmissionSetSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{EmailSubmissionAddress, EmailSubmissionCreationId, EmailSubmissionCreationRequest, EmailSubmissionCreationResponse, EmailSubmissionId, EmailSubmissionSetRequest, EmailSubmissionSetResponse, Envelope}
 import org.apache.james.jmap.method.EmailSubmissionSetMethod.{CreationFailure, CreationResult, CreationResults, CreationSuccess, LOGGER, MAIL_METADATA_USERNAME_ATTRIBUTE}
@@ -150,7 +150,8 @@ class EmailSubmissionSetMethod @Inject()(serializer: EmailSubmissionSetSerialize
                                          canSendFrom: CanSendFrom,
                                          emailSetMethod: EmailSetMethod,
                                          val metricFactory: MetricFactory,
-                                         val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[EmailSubmissionSetRequest] with Startable {
+                                         val sessionSupplier: SessionSupplier,
+                                         val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[EmailSubmissionSetRequest] with Startable {
   override val methodName: MethodName = MethodName("EmailSubmission/set")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, EMAIL_SUBMISSION)
   var queue: MailQueue = _
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala
index e73e4fa914..acebe60236 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala
@@ -38,7 +38,8 @@ import javax.inject.Inject
 
 class IdentityGetMethod @Inject() (identityRepository: IdentityRepository,
                                    val metricFactory: MetricFactory,
-                                   val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[IdentityGetRequest] {
+                                   val sessionSupplier: SessionSupplier,
+                                   val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[IdentityGetRequest] {
   override val methodName: MethodName = MethodName("Identity/get")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, EMAIL_SUBMISSION)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala
index 2ac9f6ea80..30e3ce530b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala
@@ -22,21 +22,21 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EMAIL_SUBMISSION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, UuidState}
+import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{IdentitySerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{IdentitySetRequest, IdentitySetResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 class IdentitySetMethod @Inject()(createPerformer: IdentitySetCreatePerformer,
                                   updatePerformer: IdentitySetUpdatePerformer,
                                   deletePerformer: IdentitySetDeletePerformer,
                                   val metricFactory: MetricFactory,
-                                  val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[IdentitySetRequest] {
+                                  val sessionSupplier: SessionSupplier,
+                                  val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[IdentitySetRequest] {
   override val methodName: Invocation.MethodName = MethodName("Identity/set")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, EMAIL_SUBMISSION)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala
index 827450390d..74f80dd13d 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala
@@ -21,7 +21,7 @@ package org.apache.james.jmap.method
 
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL, JMAP_MDN}
-import org.apache.james.jmap.core.Invocation
+import org.apache.james.jmap.core.{Invocation, SessionTranslator}
 import org.apache.james.jmap.core.Invocation._
 import org.apache.james.jmap.json.{MDNSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{BlobId, BlobUnParsableException, MDNParseRequest, MDNParseResponse, MDNParseResults, MDNParsed}
@@ -35,9 +35,10 @@ import org.apache.james.mime4j.dom.Message
 import org.apache.james.mime4j.message.DefaultMessageBuilder
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import java.io.InputStream
+
 import javax.inject.Inject
+
 import scala.jdk.OptionConverters._
 import scala.util.{Try, Using}
 
@@ -45,7 +46,8 @@ class MDNParseMethod @Inject()(serializer: MDNSerializer,
                                val blobResolvers: BlobResolvers,
                                val metricFactory: MetricFactory,
                                val mdnEmailIdResolver: MDNEmailIdResolver,
-                               val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[MDNParseRequest] {
+                               val sessionSupplier: SessionSupplier,
+                               val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[MDNParseRequest] {
   override val methodName: MethodName = MethodName("MDN/parse")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_MDN, JMAP_MAIL, JMAP_CORE)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
index 87b330091c..8f26bdd35e 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
@@ -22,7 +22,7 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.api.model.Identity
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL, JMAP_MDN}
-import org.apache.james.jmap.core.Invocation
+import org.apache.james.jmap.core.{Invocation, SessionTranslator}
 import org.apache.james.jmap.core.Invocation._
 import org.apache.james.jmap.json.{MDNSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.MDN._
@@ -47,10 +47,10 @@ import org.apache.james.server.core.MailImpl
 import org.apache.james.util.ReactorUtils
 import play.api.libs.json.{JsError, JsObject, JsSuccess}
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.annotation.PreDestroy
 import javax.inject.Inject
 import javax.mail.internet.MimeMessage
+
 import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 import scala.util.Try
@@ -61,7 +61,8 @@ class MDNSendMethod @Inject()(serializer: MDNSerializer,
                               emailSetMethod: EmailSetMethod,
                               val identityResolver: IdentityResolver,
                               val metricFactory: MetricFactory,
-                              val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[MDNSendRequest] with Startable {
+                              val sessionSupplier: SessionSupplier,
+                              val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[MDNSendRequest] with Startable {
   override val methodName: MethodName = MethodName("MDN/send")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_MDN, JMAP_MAIL, JMAP_CORE)
   var queue: MailQueue = _
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala
index 0a04bde30c..0802cd2b5b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.jmap.api.change.{CanNotCalculateChangesException, Mailbo
 import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{CapabilityIdentifier, ErrorCode, Invocation, Properties, UuidState}
+import org.apache.james.jmap.core.{CapabilityIdentifier, ErrorCode, Invocation, Properties, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{HasMoreChanges, MailboxChangesRequest, MailboxChangesResponse}
 import org.apache.james.jmap.method.MailboxChangesMethod.updatedProperties
@@ -32,8 +32,8 @@ import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
+
 import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 
@@ -44,6 +44,7 @@ object MailboxChangesMethod {
 class MailboxChangesMethod @Inject()(mailboxSerializer: MailboxSerializer,
                                      val metricFactory: MetricFactory,
                                      val sessionSupplier: SessionSupplier,
+                                     val sessionTranslator: SessionTranslator,
                                      val mailboxChangeRepository: MailboxChangeRepository) extends MethodRequiringAccountId[MailboxChangesRequest] {
   override val methodName: MethodName = MethodName("Mailbox/changes")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_MAIL)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
index 416b5d87a9..14678341d5 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.jmap.api.change.MailboxChangeRepository
 import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{AccountId, CapabilityIdentifier, ErrorCode, Invocation, Properties, UuidState}
+import org.apache.james.jmap.core.{AccountId, CapabilityIdentifier, ErrorCode, Invocation, Properties, SessionTranslator, UuidState}
 import org.apache.james.jmap.http.MailboxesProvisioner
 import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{Ids, Mailbox, MailboxFactory, MailboxGet, MailboxGetRequest, MailboxGetResponse, NotFound, PersonalNamespace, Subscriptions, UnparsedMailboxId}
@@ -37,8 +37,8 @@ import org.apache.james.mailbox.{MailboxManager, MailboxSession, SubscriptionMan
 import org.apache.james.metrics.api.MetricFactory
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.Inject
+
 import scala.util.Try
 
 object MailboxGetResults {
@@ -68,7 +68,8 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer,
                                   provisioner: MailboxesProvisioner,
                                   mailboxChangeRepository: MailboxChangeRepository,
                                   val metricFactory: MetricFactory,
-                                  val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[MailboxGetRequest] {
+                                  val sessionSupplier: SessionSupplier,
+                                  val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[MailboxGetRequest] {
   override val methodName: MethodName = MethodName("Mailbox/get")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala
index b12feb469e..b4ec36f72d 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala
@@ -21,19 +21,19 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{CanCalculateChanges, ErrorCode, Invocation, Limit, Position, QueryState}
+import org.apache.james.jmap.core.{CanCalculateChanges, ErrorCode, Invocation, Limit, Position, QueryState, SessionTranslator}
 import org.apache.james.jmap.json.{MailboxQuerySerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{MailboxQueryRequest, MailboxQueryResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.{MailboxSession, SystemMailboxesProvider}
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.Inject
 
 class MailboxQueryMethod @Inject()(systemMailboxesProvider: SystemMailboxesProvider,
                                    val metricFactory: MetricFactory,
-                                   val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[MailboxQueryRequest] {
+                                   val sessionSupplier: SessionSupplier,
+                                   val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[MailboxQueryRequest] {
   override val methodName: MethodName = MethodName("Mailbox/query")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
index 933dcf7383..2dce9e51f5 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.jmap.api.change.MailboxChangeRepository
 import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{Invocation, SetError, UuidState}
+import org.apache.james.jmap.core.{Invocation, SessionTranslator, SetError, UuidState}
 import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{MailboxSetRequest, MailboxSetResponse}
 import org.apache.james.jmap.method.MailboxSetCreatePerformer.MailboxCreationResults
@@ -36,7 +36,6 @@ import org.apache.james.mailbox.model.MailboxId
 import org.apache.james.metrics.api.MetricFactory
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 case class MailboxHasMailException(mailboxId: MailboxId) extends Exception
@@ -51,7 +50,8 @@ class MailboxSetMethod @Inject()(serializer: MailboxSerializer,
                                  updatePerformer: MailboxSetUpdatePerformer,
                                  mailboxChangeRepository: MailboxChangeRepository,
                                  val metricFactory: MetricFactory,
-                                 val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[MailboxSetRequest] {
+                                 val sessionSupplier: SessionSupplier,
+                                 val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[MailboxSetRequest] {
   override val methodName: MethodName = MethodName("Mailbox/set")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala
index 71f0ae3ef8..3358895e7f 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/Method.scala
@@ -21,7 +21,7 @@ package org.apache.james.jmap.method
 import org.apache.james.jmap.api.exception.ChangeNotFoundException
 import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
 import org.apache.james.jmap.core.Invocation.MethodName
-import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation}
+import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, SessionTranslator}
 import org.apache.james.jmap.mail.{IdentityIdNotFoundException, RequestTooLargeException, UnsupportedFilterException, UnsupportedNestingException, UnsupportedRequestParameterException, UnsupportedSortException}
 import org.apache.james.jmap.routes.{ProcessingContext, SessionSupplier}
 import org.apache.james.mailbox.MailboxSession
@@ -30,7 +30,7 @@ import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.SFlux
 
-case class AccountNotFoundException(invocation: Invocation) extends IllegalArgumentException
+case class AccountNotFoundException() extends IllegalArgumentException
 
 case class InvocationWithContext(invocation: Invocation, processingContext: ProcessingContext) {
   def recordInvocation: InvocationWithContext = InvocationWithContext(invocation, processingContext.recordInvocation(invocation))
@@ -52,18 +52,20 @@ trait WithAccountId {
 trait MethodRequiringAccountId[REQUEST <: WithAccountId] extends Method {
   def metricFactory: MetricFactory
   def sessionSupplier: SessionSupplier
+  def sessionTranslator: SessionTranslator
 
   override def process(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession): Publisher[InvocationWithContext] = {
     val either: Either[Exception, Publisher[InvocationWithContext]] = for {
       request <- getRequest(mailboxSession, invocation.invocation)
-      _ <- validateAccountId(request.accountId, mailboxSession, sessionSupplier, invocation.invocation)
+      translatedMailboxSession = sessionTranslator.delegateIfNeeded(mailboxSession, request.accountId)
     } yield {
-      doProcess(capabilities, invocation, mailboxSession, request)
+      translatedMailboxSession.flatMapMany(translatedSession =>
+        SFlux(doProcess(capabilities, invocation, translatedSession, request)))
     }
 
     val result: SFlux[InvocationWithContext] = SFlux.fromPublisher(either.fold(e => SFlux.error[InvocationWithContext](e), r => r))
       .onErrorResume[InvocationWithContext] {
-        case e: AccountNotFoundException => SFlux.just[InvocationWithContext] (InvocationWithContext(e.invocation, invocation.processingContext))
+        case e: AccountNotFoundException => SFlux.just[InvocationWithContext] (InvocationWithContext(Invocation.error(ErrorCode.AccountNotFound, invocation.invocation.methodCallId), invocation.processingContext))
         case e: UnsupportedRequestParameterException => SFlux.just[InvocationWithContext] (InvocationWithContext(Invocation.error(
           ErrorCode.InvalidArguments,
           s"The following parameter ${e.unsupportedParam} is syntactically valid, but is not supported by the server.",
@@ -91,13 +93,6 @@ trait MethodRequiringAccountId[REQUEST <: WithAccountId] extends Method {
     metricFactory.decoratePublisherWithTimerMetric(JMAP_RFC8621_PREFIX + methodName.value, result)
   }
 
-  private def validateAccountId(accountId: AccountId, mailboxSession: MailboxSession, sessionSupplier: SessionSupplier, invocation: Invocation): Either[IllegalArgumentException, MailboxSession] =
-    if (sessionSupplier.validate(mailboxSession.getUser, accountId)) {
-      Right(mailboxSession)
-    } else {
-      Left(AccountNotFoundException(Invocation.error(ErrorCode.AccountNotFound, invocation.methodCallId)))
-    }
-
   def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: REQUEST): Publisher[InvocationWithContext]
 
   def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, REQUEST]
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala
index 0f5b8e6465..9187531bf3 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.jmap.api.model.PushSubscriptionId
 import org.apache.james.jmap.api.pushsubscription.PushSubscriptionRepository
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{Ids, Invocation, PushSubscriptionDTO, PushSubscriptionGetRequest, PushSubscriptionGetResponse, UnparsedPushSubscriptionId}
+import org.apache.james.jmap.core.{Ids, Invocation, PushSubscriptionDTO, PushSubscriptionGetRequest, PushSubscriptionGetResponse, SessionTranslator, UnparsedPushSubscriptionId}
 import org.apache.james.jmap.json.{PushSubscriptionSerializer, ResponseSerializer}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.lifecycle.api.Startable
@@ -32,8 +32,8 @@ import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.Inject
+
 import scala.jdk.CollectionConverters._
 
 case class PushSubscriptionGetResults(results: Seq[PushSubscriptionDTO], notFound: Set[UnparsedPushSubscriptionId]) {
@@ -48,7 +48,8 @@ case class PushSubscriptionGetResults(results: Seq[PushSubscriptionDTO], notFoun
 class PushSubscriptionGetMethod @Inject()(pushSubscriptionSerializer: PushSubscriptionSerializer,
                                           pushSubscriptionRepository: PushSubscriptionRepository,
                                           val metricFactory: MetricFactory,
-                                          val sessionSupplier: SessionSupplier) extends MethodWithoutAccountId[PushSubscriptionGetRequest] with Startable {
+                                          val sessionSupplier: SessionSupplier,
+                                          val sessionTranslator: SessionTranslator) extends MethodWithoutAccountId[PushSubscriptionGetRequest] with Startable {
   override val methodName: Invocation.MethodName = MethodName("PushSubscription/get")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala
index b62243e4f2..e3ca62ebe9 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala
@@ -22,14 +22,13 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{Invocation, PushSubscriptionSetRequest, PushSubscriptionSetResponse}
+import org.apache.james.jmap.core.{Invocation, PushSubscriptionSetRequest, PushSubscriptionSetResponse, SessionTranslator}
 import org.apache.james.jmap.json.{PushSubscriptionSerializer, ResponseSerializer}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.lifecycle.api.Startable
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 class PushSubscriptionSetMethod @Inject()(createPerformer: PushSubscriptionSetCreatePerformer,
@@ -37,7 +36,8 @@ class PushSubscriptionSetMethod @Inject()(createPerformer: PushSubscriptionSetCr
                                           deletePerformer: PushSubscriptionSetDeletePerformer,
                                           pushSubscriptionSerializer: PushSubscriptionSerializer,
                                           val metricFactory: MetricFactory,
-                                          val sessionSupplier: SessionSupplier) extends MethodWithoutAccountId[PushSubscriptionSetRequest] with Startable {
+                                          val sessionSupplier: SessionSupplier,
+                                          val sessionTranslator: SessionTranslator) extends MethodWithoutAccountId[PushSubscriptionSetRequest] with Startable {
   override val methodName: Invocation.MethodName = MethodName("PushSubscription/set")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala
index f451495402..87543161eb 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala
@@ -26,7 +26,7 @@ import org.apache.james.jmap.api.change.CanNotCalculateChangesException
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_QUOTA}
 import org.apache.james.jmap.core.Id.Id
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{ErrorCode, Invocation, UuidState}
+import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{QuotaSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{JmapQuota, QuotaChangesRequest, QuotaChangesResponse}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -35,11 +35,11 @@ import org.apache.james.mailbox.quota.{QuotaManager, UserQuotaRootResolver}
 import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 class QuotaChangesMethod @Inject()(val metricFactory: MetricFactory,
                                    val sessionSupplier: SessionSupplier,
+                                   val sessionTranslator: SessionTranslator,
                                    val quotaManager: QuotaManager,
                                    val quotaRootResolver: UserQuotaRootResolver) extends MethodRequiringAccountId[QuotaChangesRequest] {
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala
index fb339699a8..93f371bc3e 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.core.Username
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_QUOTA}
 import org.apache.james.jmap.core.Id.Id
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodCallId, MethodName}
-import org.apache.james.jmap.core.{ErrorCode, Invocation, MissingCapabilityException, Properties}
+import org.apache.james.jmap.core.{ErrorCode, Invocation, MissingCapabilityException, Properties, SessionTranslator}
 import org.apache.james.jmap.json.{QuotaSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{CountResourceType, JmapQuota, OctetsResourceType, QuotaGetRequest, QuotaIdFactory, QuotaNotFound, QuotaResponseGetResult, UnparsedQuotaId}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -37,11 +37,11 @@ import org.apache.james.util.ReactorUtils
 import org.reactivestreams.Publisher
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.Inject
 
 class QuotaGetMethod @Inject()(val metricFactory: MetricFactory,
                                val sessionSupplier: SessionSupplier,
+                               val sessionTranslator: SessionTranslator,
                                val quotaManager: QuotaManager,
                                val quotaRootResolver: UserQuotaRootResolver) extends MethodRequiringAccountId[QuotaGetRequest] with Startable {
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala
index 2f537b56d5..da484f27fe 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala
@@ -22,7 +22,7 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_QUOTA}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{CanCalculateChanges, ErrorCode, Invocation, Limit, Position, QueryState}
+import org.apache.james.jmap.core.{CanCalculateChanges, ErrorCode, Invocation, Limit, Position, QueryState, SessionTranslator}
 import org.apache.james.jmap.json.{QuotaSerializer, ResponseSerializer}
 import org.apache.james.jmap.mail.{JmapQuota, QuotaQueryFilter, QuotaQueryRequest, QuotaQueryResponse}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -32,11 +32,11 @@ import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
 import play.api.libs.json.JsError
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 class QuotaQueryMethod @Inject()(val metricFactory: MetricFactory,
                                  val sessionSupplier: SessionSupplier,
+                                 val sessionTranslator: SessionTranslator,
                                  val quotaManager: QuotaManager,
                                  val quotaRootResolver: UserQuotaRootResolver) extends MethodRequiringAccountId[QuotaQueryRequest] {
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala
index 5f55e65fdc..998175f699 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala
@@ -22,18 +22,18 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{ErrorCode, Invocation, UuidState}
+import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{ResponseSerializer, ThreadSerializer}
 import org.apache.james.jmap.mail.{HasMoreChanges, ThreadChangesRequest, ThreadChangesResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-
 import javax.inject.Inject
 
 class ThreadChangesMethod @Inject()(val metricFactory: MetricFactory,
-                                    val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[ThreadChangesRequest] {
+                                    val sessionSupplier: SessionSupplier,
+                                    val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[ThreadChangesRequest] {
   override val methodName: MethodName = MethodName("Thread/changes")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_MAIL)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala
index 85b8362384..b0069c940c 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala
@@ -22,7 +22,7 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
-import org.apache.james.jmap.core.{AccountId, Invocation, UuidState}
+import org.apache.james.jmap.core.{AccountId, Invocation, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{ResponseSerializer, ThreadSerializer}
 import org.apache.james.jmap.mail.{Thread, ThreadGetRequest, ThreadGetResponse, ThreadNotFound, UnparsedThreadId}
 import org.apache.james.jmap.routes.SessionSupplier
@@ -31,8 +31,8 @@ import org.apache.james.mailbox.model.{ThreadId => JavaThreadId}
 import org.apache.james.mailbox.{MailboxManager, MailboxSession}
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.Inject
+
 import scala.util.Try
 
 object ThreadGetResult {
@@ -61,6 +61,7 @@ case class ThreadGetResult(threads: Set[Thread], notFound: ThreadNotFound) {
 
 class ThreadGetMethod @Inject()(val metricFactory: MetricFactory,
                                 val sessionSupplier: SessionSupplier,
+                                val sessionTranslator: SessionTranslator,
                                 val threadIdFactory: JavaThreadId.Factory,
                                 val mailboxManager: MailboxManager) extends MethodRequiringAccountId[ThreadGetRequest] {
   override val methodName: MethodName = MethodName("Thread/get")
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala
index 0cee057042..c8da4e4d49 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala
@@ -23,7 +23,7 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_VACATION_RESPONSE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodCallId, MethodName}
 import org.apache.james.jmap.core.UuidState.INSTANCE
-import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, MissingCapabilityException, Properties}
+import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, MissingCapabilityException, Properties, SessionTranslator}
 import org.apache.james.jmap.json.{ResponseSerializer, VacationSerializer}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.jmap.vacation.VacationResponse.UNPARSED_SINGLETON
@@ -33,7 +33,6 @@ import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.vacation.api.{VacationService, AccountId => JavaAccountId}
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.Inject
 
 object VacationResponseGetResult {
@@ -58,7 +57,8 @@ case class VacationResponseGetResult(vacationResponses: Set[VacationResponse], n
 
 class VacationResponseGetMethod @Inject()(vacationService: VacationService,
                                           val metricFactory: MetricFactory,
-                                          val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[VacationResponseGetRequest] {
+                                          val sessionSupplier: SessionSupplier,
+                                          val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[VacationResponseGetRequest] {
   override val methodName: MethodName = MethodName("VacationResponse/get")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_VACATION_RESPONSE)
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala
index 0eb3e03e1a..0acfe169df 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala
@@ -28,7 +28,7 @@ import org.apache.james.jmap.change.{AccountIdRegistrationKey, StateChangeEvent,
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_VACATION_RESPONSE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.SetError.SetErrorDescription
-import org.apache.james.jmap.core.{Invocation, UuidState}
+import org.apache.james.jmap.core.{Invocation, SessionTranslator, UuidState}
 import org.apache.james.jmap.json.{ResponseSerializer, VacationSerializer}
 import org.apache.james.jmap.method.VacationResponseSetMethod.VACATION_RESPONSE_PATCH_OBJECT_KEY
 import org.apache.james.jmap.routes.SessionSupplier
@@ -38,7 +38,6 @@ import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.vacation.api.{VacationPatch, VacationService, AccountId => VacationAccountId}
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-
 import javax.inject.{Inject, Named}
 
 object VacationResponseUpdateResults {
@@ -78,7 +77,8 @@ object VacationResponseSetMethod {
 class VacationResponseSetMethod @Inject()(@Named(InjectionKeys.JMAP) eventBus: EventBus,
                                           vacationService: VacationService,
                                           val metricFactory: MetricFactory,
-                                          val sessionSupplier: SessionSupplier) extends MethodRequiringAccountId[VacationResponseSetRequest] {
+                                          val sessionSupplier: SessionSupplier,
+                                          val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[VacationResponseSetRequest] {
   override val methodName: MethodName = MethodName("VacationResponse/set")
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_VACATION_RESPONSE)
 


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