diff --git a/docs/modules/servers/partials/configure/jvm.adoc b/docs/modules/servers/partials/configure/jvm.adoc index d8200a7d80d..9d7ee219faf 100644 --- a/docs/modules/servers/partials/configure/jvm.adoc +++ b/docs/modules/servers/partials/configure/jvm.adoc @@ -224,3 +224,17 @@ Ex in `jvm.properties` ---- james.rights.crossdomain.allow=false ---- + +== Drop IMAP Recent handling + +This allows for dropping the legacy IMAP flag support, considering all emails as recent. This has no impact on modern +IMAP application as this flag is concidered innacurate. + +Note that this flag is removed in IMAP4Rev2. + +Ex in `jvm.properties` +---- +james.mailbox.handleRecent=false +---- + +Defaults to true (no breaking changes) \ No newline at end of file diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java index bb296318742..80de0e5d9b5 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxRecentsDAO.java @@ -34,6 +34,7 @@ import org.apache.james.mailbox.MessageUid; import org.apache.james.mailbox.cassandra.ids.CassandraId; import org.apache.james.mailbox.cassandra.table.CassandraMailboxRecentsTable; +import org.apache.james.mailbox.store.StoreMessageManager; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.ProtocolVersion; @@ -101,6 +102,9 @@ private PreparedStatement createAddStatement(CqlSession session) { } public Flux getRecentMessageUidsInMailbox(CassandraId mailboxId) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Flux.empty(); + } return cassandraAsyncExecutor.executeRows(bindWithMailbox(mailboxId, readStatement)) .map(row -> TypeCodecs.BIGINT.decodePrimitive(row.getBytesUnsafe(0), protocolVersion)) .map(MessageUid::of); @@ -112,12 +116,18 @@ private BoundStatement bindWithMailbox(CassandraId mailboxId, PreparedStatement } public Mono removeFromRecent(CassandraId mailboxId, MessageUid messageUid) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Mono.empty(); + } return cassandraAsyncExecutor.executeVoid(deleteStatement.bind() .setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid()) .setLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, messageUid.asLong())); } public Mono removeFromRecent(CassandraId mailboxId, List uids) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Mono.empty(); + } if (uids.size() == 1) { return cassandraAsyncExecutor.executeVoid(deleteStatement.bind() .setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid()) @@ -139,17 +149,26 @@ public Mono removeFromRecent(CassandraId mailboxId, List uids) } public Mono delete(CassandraId mailboxId) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Mono.empty(); + } return cassandraAsyncExecutor.executeVoid(deleteAllStatement.bind() .setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())); } public Mono addToRecent(CassandraId mailboxId, MessageUid messageUid) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Mono.empty(); + } return cassandraAsyncExecutor.executeVoid(addStatement.bind() .setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid()) .setLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, messageUid.asLong())); } public Mono addToRecent(CassandraId mailboxId, List uids) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Mono.empty(); + } if (uids.size() == 1) { return cassandraAsyncExecutor.executeVoid(addStatement.bind() .setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid()) diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/FlagsExtractor.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/FlagsExtractor.java index 9141c9fc3ca..b812ada7abf 100644 --- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/FlagsExtractor.java +++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/FlagsExtractor.java @@ -26,6 +26,7 @@ import jakarta.mail.Flags; import org.apache.james.mailbox.cassandra.table.Flag; +import org.apache.james.mailbox.store.StoreMessageManager; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.ProtocolVersion; @@ -44,6 +45,9 @@ public static Flags getFlags(Row row) { private static Flags getFlags(Row row, ProtocolVersion protocolVersion) { Flags flags = new Flags(); for (CqlIdentifier cqlId : Flag.ALL_LOWERCASE) { + if (!StoreMessageManager.HANDLE_RECENT && cqlId.equals(Flag.RECENT)) { + continue; + } if (TypeCodecs.BOOLEAN.decodePrimitive(row.getBytesUnsafe(cqlId), protocolVersion)) { flags.add(Flag.JAVAX_MAIL_FLAG.get(cqlId)); } diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java index f17477fd78c..fdc5c1ec628 100644 --- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAO.java @@ -72,6 +72,7 @@ import org.apache.james.mailbox.postgres.PostgresMailboxId; import org.apache.james.mailbox.postgres.PostgresMessageId; import org.apache.james.mailbox.postgres.mail.PostgresMessageDataDefinition.MessageTable; +import org.apache.james.mailbox.store.StoreMessageManager; import org.apache.james.mailbox.store.mail.MessageMapper; import org.apache.james.mailbox.store.mail.MessageMapper.FetchType; import org.apache.james.mailbox.store.mail.model.MailboxMessage; @@ -170,6 +171,9 @@ public Flux listUnseen(PostgresMailboxId mailboxId, MessageRange ran } public Flux findAllRecentMessageUid(PostgresMailboxId mailboxId) { + if (!StoreMessageManager.HANDLE_RECENT) { + return Flux.empty(); + } return postgresExecutor.executeRows(dslContext -> Flux.from(dslContext.select(MESSAGE_UID) .from(TABLE_NAME) .where(MAILBOX_ID.eq((mailboxId.asUuid()))) diff --git a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java index ba759875e62..858670ffc7a 100644 --- a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java +++ b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxMessageDAOUtils.java @@ -65,6 +65,7 @@ import org.apache.james.mailbox.postgres.PostgresMailboxId; import org.apache.james.mailbox.postgres.PostgresMessageId; import org.apache.james.mailbox.postgres.mail.PostgresMessageDataDefinition; +import org.apache.james.mailbox.store.StoreMessageManager; import org.apache.james.mailbox.store.mail.MessageMapper; import org.apache.james.mailbox.store.mail.model.impl.Properties; import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; @@ -83,6 +84,9 @@ interface PostgresMailboxMessageDAOUtils { Function RECORD_TO_FLAGS_FUNCTION = record -> { Flags flags = new Flags(); BOOLEAN_FLAGS_MAPPING.forEach((flagColumn, flagMapped) -> { + if (!StoreMessageManager.HANDLE_RECENT && flagColumn.equals(IS_RECENT)) { + return; + } if (record.get(flagColumn)) { flags.add(flagMapped); } diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java index 4146c1d0423..283cce71675 100644 --- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java @@ -134,6 +134,9 @@ * {@link MailboxSession}'s. */ public class StoreMessageManager implements MessageManager { + public static final boolean HANDLE_RECENT = Optional.ofNullable(System.getProperty("james.mailbox.handleRecent")) + .map(Boolean::parseBoolean) + .orElse(true); /** * The minimal Permanent flags the {@link MessageManager} must support.
* @@ -494,7 +497,7 @@ private Flags getFlags(MailboxSession mailboxSession, boolean isRecent, Flags fl trimFlags(flags, mailboxSession); } - if (isRecent) { + if (isRecent && HANDLE_RECENT) { flags.add(Flag.RECENT); } return flags;