From 7988f3068d13cb8b0b0c0ee387c4a6fb89f93d34 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 9 Dec 2024 13:04:00 +0000 Subject: [PATCH] fix: do not subscribe to heartbeat if already subscribed via metadata --- src/imap.rs | 82 +++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index d6319e67dd..9ede057728 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -1565,47 +1565,49 @@ impl Session { .await? .map_or(true, |config_token| device_token != config_token); - if device_token_changed && self.can_metadata() && self.can_push() { - let folder = context - .get_config(Config::ConfiguredInboxFolder) - .await? - .context("INBOX is not configured")?; - - let encrypted_device_token = - encrypt_device_token(&device_token).context("Failed to encrypt device token")?; - - // We expect that the server supporting `XDELTAPUSH` capability - // has non-synchronizing literals support as well: - // . - let encrypted_device_token_len = encrypted_device_token.len(); - - if encrypted_device_token_len <= 4096 { - self.run_command_and_check_ok(&format_setmetadata( - &folder, - &encrypted_device_token, - )) - .await - .context("SETMETADATA command failed")?; + if self.can_metadata() && self.can_push() { + if device_token_changed { + let folder = context + .get_config(Config::ConfiguredInboxFolder) + .await? + .context("INBOX is not configured")?; - // Store device token saved on the server - // to prevent storing duplicate tokens. - // The server cannot deduplicate on its own - // because encryption gives a different - // result each time. - context - .set_config_internal(Config::DeviceToken, Some(&device_token)) - .await?; - } else { - // If Apple or Google (FCM) gives us a very large token, - // do not even try to give it to IMAP servers. - // - // Limit of 4096 is arbitrarily selected - // to be the same as required by LITERAL- IMAP extension. - // - // Dovecot supports LITERAL+ and non-synchronizing literals - // of any length, but there is no reason for tokens - // to be that large even after OpenPGP encryption. - warn!(context, "Device token is too long for LITERAL-, ignoring."); + let encrypted_device_token = encrypt_device_token(&device_token) + .context("Failed to encrypt device token")?; + + // We expect that the server supporting `XDELTAPUSH` capability + // has non-synchronizing literals support as well: + // . + let encrypted_device_token_len = encrypted_device_token.len(); + + if encrypted_device_token_len <= 4096 { + self.run_command_and_check_ok(&format_setmetadata( + &folder, + &encrypted_device_token, + )) + .await + .context("SETMETADATA command failed")?; + + // Store device token saved on the server + // to prevent storing duplicate tokens. + // The server cannot deduplicate on its own + // because encryption gives a different + // result each time. + context + .set_config_internal(Config::DeviceToken, Some(&device_token)) + .await?; + } else { + // If Apple or Google (FCM) gives us a very large token, + // do not even try to give it to IMAP servers. + // + // Limit of 4096 is arbitrarily selected + // to be the same as required by LITERAL- IMAP extension. + // + // Dovecot supports LITERAL+ and non-synchronizing literals + // of any length, but there is no reason for tokens + // to be that large even after OpenPGP encryption. + warn!(context, "Device token is too long for LITERAL-, ignoring."); + } } context.push_subscribed.store(true, Ordering::Relaxed); } else if !context.push_subscriber.heartbeat_subscribed().await {