This commit is contained in:
mdecimus 2024-05-23 16:32:47 +02:00
parent 7251908aad
commit 46076c6f20
17 changed files with 81 additions and 38 deletions

24
Cargo.lock generated
View file

@ -1005,7 +1005,7 @@ dependencies = [
[[package]]
name = "common"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"arc-swap",
@ -1580,7 +1580,7 @@ dependencies = [
[[package]]
name = "directory"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"argon2",
@ -2785,7 +2785,7 @@ checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
[[package]]
name = "imap"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"common",
@ -2987,7 +2987,7 @@ dependencies = [
[[package]]
name = "jmap"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"aes",
"aes-gcm",
@ -3423,7 +3423,7 @@ dependencies = [
[[package]]
name = "mail-server"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"common",
"directory",
@ -3442,7 +3442,7 @@ dependencies = [
[[package]]
name = "managesieve"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"bincode",
@ -3719,7 +3719,7 @@ dependencies = [
[[package]]
name = "nlp"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"bincode",
@ -4304,7 +4304,7 @@ dependencies = [
[[package]]
name = "pop3"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"common",
"imap",
@ -5789,7 +5789,7 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "smtp"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"bincode",
@ -5905,7 +5905,7 @@ dependencies = [
[[package]]
name = "stalwart-cli"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"clap",
"console",
@ -5936,7 +5936,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "store"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"arc-swap",
@ -6786,7 +6786,7 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "utils"
version = "0.8.0"
version = "0.8.1"
dependencies = [
"ahash 0.8.11",
"base64 0.22.1",

View file

@ -5,7 +5,7 @@ authors = ["Stalwart Labs Ltd. <hello@stalw.art>"]
license = "AGPL-3.0-only"
repository = "https://github.com/stalwartlabs/cli"
homepage = "https://github.com/stalwartlabs/cli"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
readme = "README.md"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "common"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"
@ -16,7 +16,7 @@ mail-auth = { version = "0.4" }
mail-send = { version = "0.4", default-features = false, features = ["cram-md5"] }
smtp-proto = { version = "0.1", features = ["serde_support"] }
dns-update = { version = "0.1" }
ahash = { version = "0.8.0", features = ["serde"] }
ahash = { version = "0.8.1", features = ["serde"] }
parking_lot = "0.12.1"
regex = "1.7.0"
tracing = "0.1"

View file

@ -1,6 +1,6 @@
[package]
name = "directory"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "imap"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -10,7 +10,7 @@ utils = { path = "../utils" }
mail-parser = { version = "0.9", features = ["full_encoding", "serde_support", "ludicrous_mode"] }
fast-float = "0.2.0"
serde = { version = "1.0", features = ["derive"]}
ahash = { version = "0.8.0", features = ["serde"] }
ahash = { version = "0.8.1", features = ["serde"] }
serde_json = { version = "1.0", features = ["raw_value"] }
tracing = "0.1"

View file

@ -1,6 +1,6 @@
[package]
name = "jmap"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -58,7 +58,7 @@ impl JMAP {
account_id: u32,
mut changes: ChangeLogBuilder,
) -> Result<u64, MethodError> {
if changes.change_id == u64::MAX {
if changes.change_id == u64::MAX || changes.change_id == 0 {
changes.change_id = self.assign_change_id(account_id).await?;
}
let state = changes.change_id;

View file

@ -7,7 +7,7 @@ homepage = "https://stalw.art"
keywords = ["imap", "jmap", "smtp", "email", "mail", "server"]
categories = ["email"]
license = "AGPL-3.0-only"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "managesieve"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "nlp"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "pop3"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -7,7 +7,7 @@ homepage = "https://stalw.art/smtp"
keywords = ["smtp", "email", "mail", "server"]
categories = ["email"]
license = "AGPL-3.0-only"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "store"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"
@ -18,7 +18,7 @@ rand = "0.8.5"
roaring = "0.10.1"
rayon = { version = "1.5.1", optional = true }
serde = { version = "1.0", features = ["derive"]}
ahash = { version = "0.8.0", features = ["serde"] }
ahash = { version = "0.8.1", features = ["serde"] }
lazy_static = "1.4"
xxhash-rust = { version = "0.8.5", features = ["xxh3"] }
farmhash = "1.1.5"

View file

@ -28,13 +28,13 @@ use crate::Serialize;
use super::{IntoOperations, MaybeDynamicValue, Operation, SerializeWithId};
#[derive(Default)]
#[derive(Default, Debug)]
pub struct ChangeLogBuilder {
pub change_id: u64,
pub changes: VecMap<u8, Changes>,
}
#[derive(Default)]
#[derive(Default, Debug)]
pub struct Changes {
pub inserts: AHashSet<u64>,
pub updates: AHashSet<u64>,

View file

@ -1,6 +1,6 @@
[package]
name = "utils"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
resolver = "2"

View file

@ -22,6 +22,8 @@
*/
use ahash::AHashSet;
use directory::backend::internal::manage::ManageDirectory;
use imap_proto::ResponseType;
use jmap::{
mailbox::{INBOX_ID, JUNK_ID, TRASH_ID},
JMAP,
@ -32,6 +34,8 @@ use store::{
IterateParams, LogKey, U32_LEN, U64_LEN,
};
use crate::imap::{AssertResult, ImapConnection, Type};
use super::JMAPTest;
pub async fn test(params: &mut JMAPTest) {
@ -42,8 +46,30 @@ pub async fn test(params: &mut JMAPTest) {
let trash_id = Id::from(TRASH_ID).to_string();
let junk_id = Id::from(JUNK_ID).to_string();
// Connect to IMAP
params
.directory
.create_test_user_with_email("jdoe@example.com", "secret", "John Doe")
.await;
let account_id = server
.core
.storage
.data
.get_or_create_account_id("jdoe@example.com")
.await
.unwrap();
let mut imap = ImapConnection::connect(b"_x ").await;
imap.assert_read(Type::Untagged, ResponseType::Ok).await;
imap.send("AUTHENTICATE PLAIN {32+}\r\nAGpkb2VAZXhhbXBsZS5jb20Ac2VjcmV0")
.await;
imap.assert_read(Type::Tagged, ResponseType::Ok).await;
imap.send("STATUS INBOX (UIDNEXT MESSAGES UNSEEN)").await;
imap.assert_read(Type::Tagged, ResponseType::Ok)
.await
.assert_contains("MESSAGES 0");
// Create test messages
client.set_default_account_id(Id::from(1u64));
client.set_default_account_id(Id::from(account_id));
let mut message_ids = Vec::new();
let mut pass = 0;
let mut changes = AHashSet::new();
@ -84,10 +110,19 @@ pub async fn test(params: &mut JMAPTest) {
}
}
// Check IMAP status
imap.send("LIST \"\" \"*\" RETURN (STATUS (MESSAGES))")
.await;
imap.assert_read(Type::Tagged, ResponseType::Ok)
.await
.assert_contains("\"INBOX\" (MESSAGES 2)")
.assert_contains("\"Deleted Items\" (MESSAGES 2)")
.assert_contains("\"Junk Mail\" (MESSAGES 2)");
// Make sure both messages and changes are present
assert_eq!(
server
.get_document_ids(1, Collection::Email)
.get_document_ids(account_id, Collection::Email)
.await
.unwrap()
.unwrap()
@ -96,12 +131,12 @@ pub async fn test(params: &mut JMAPTest) {
);
// Purge junk/trash messages and old changes
server.purge_account(1).await;
server.purge_account(account_id).await;
// Only 4 messages should remain
assert_eq!(
server
.get_document_ids(1, Collection::Email)
.get_document_ids(account_id, Collection::Email)
.await
.unwrap()
.unwrap()
@ -111,7 +146,7 @@ pub async fn test(params: &mut JMAPTest) {
assert_eq!(
server
.get_tag(
1,
account_id,
Collection::Email,
Property::MailboxIds,
TagValue::Id(INBOX_ID)
@ -125,7 +160,7 @@ pub async fn test(params: &mut JMAPTest) {
assert_eq!(
server
.get_tag(
1,
account_id,
Collection::Email,
Property::MailboxIds,
TagValue::Id(TRASH_ID)
@ -139,7 +174,7 @@ pub async fn test(params: &mut JMAPTest) {
assert_eq!(
server
.get_tag(
1,
account_id,
Collection::Email,
Property::MailboxIds,
TagValue::Id(JUNK_ID)
@ -151,6 +186,15 @@ pub async fn test(params: &mut JMAPTest) {
1
);
// Check IMAP status
imap.send("LIST \"\" \"*\" RETURN (STATUS (MESSAGES))")
.await;
imap.assert_read(Type::Tagged, ResponseType::Ok)
.await
.assert_contains("\"INBOX\" (MESSAGES 2)")
.assert_contains("\"Deleted Items\" (MESSAGES 1)")
.assert_contains("\"Junk Mail\" (MESSAGES 1)");
// Compare changes
let new_changes = get_changes(&server).await;
assert!(!changes.is_empty());
@ -186,7 +230,6 @@ async fn get_changes(server: &JMAP) -> AHashSet<(u64, u8)> {
.ascending()
.no_values(),
|key, _| {
assert_eq!(key.deserialize_be_u32(0).unwrap(), 1);
changes.insert((
key.deserialize_be_u64(key.len() - U64_LEN).unwrap(),
key[U32_LEN],