mirror of
https://github.com/chatmail/core.git
synced 2026-05-17 13:56:30 +03:00
fix: recognize all transport addresses as own addresses
Fix get_secondary_addrs() which was using `secondary_addrs` config that is not updated anymore. Instead of using `secondary_addrs` config, use the `transports` table which contains all the addresses.
This commit is contained in:
@@ -201,3 +201,19 @@ def test_transport_synchronization(acfactory, log) -> None:
|
|||||||
|
|
||||||
assert ac1.wait_for_incoming_msg().get_snapshot().text == "Hello!"
|
assert ac1.wait_for_incoming_msg().get_snapshot().text == "Hello!"
|
||||||
assert ac1_clone.wait_for_incoming_msg().get_snapshot().text == "Hello!"
|
assert ac1_clone.wait_for_incoming_msg().get_snapshot().text == "Hello!"
|
||||||
|
|
||||||
|
|
||||||
|
def test_recognize_self_address(acfactory) -> None:
|
||||||
|
alice, bob = acfactory.get_online_accounts(2)
|
||||||
|
|
||||||
|
bob_chat = bob.create_chat(alice)
|
||||||
|
|
||||||
|
qr = acfactory.get_account_qr()
|
||||||
|
alice.add_transport_from_qr(qr)
|
||||||
|
|
||||||
|
new_alice_addr = alice.list_transports()[1]["addr"]
|
||||||
|
alice.set_config("configured_addr", new_alice_addr)
|
||||||
|
|
||||||
|
bob_chat.send_text("Hello!")
|
||||||
|
msg = alice.wait_for_incoming_msg().get_snapshot()
|
||||||
|
assert msg.chat == alice.create_chat(bob)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
|
|||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use crate::blob::BlobObject;
|
use crate::blob::BlobObject;
|
||||||
use crate::configure::EnteredLoginParam;
|
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::events::EventType;
|
use crate::events::EventType;
|
||||||
use crate::log::LogExt;
|
use crate::log::LogExt;
|
||||||
@@ -21,7 +20,7 @@ use crate::mimefactory::RECOMMENDED_FILE_SIZE;
|
|||||||
use crate::provider::Provider;
|
use crate::provider::Provider;
|
||||||
use crate::sync::{self, Sync::*, SyncData};
|
use crate::sync::{self, Sync::*, SyncData};
|
||||||
use crate::tools::get_abs_path;
|
use crate::tools::get_abs_path;
|
||||||
use crate::transport::ConfiguredLoginParam;
|
use crate::transport::{ConfiguredLoginParam, add_pseudo_transport};
|
||||||
use crate::{constants, stats};
|
use crate::{constants, stats};
|
||||||
|
|
||||||
/// The available configuration keys.
|
/// The available configuration keys.
|
||||||
@@ -204,7 +203,7 @@ pub enum Config {
|
|||||||
/// `ProviderOptions::delete_to_trash`.
|
/// `ProviderOptions::delete_to_trash`.
|
||||||
DeleteToTrash,
|
DeleteToTrash,
|
||||||
|
|
||||||
/// The primary email address. Also see `SecondaryAddrs`.
|
/// The primary email address.
|
||||||
ConfiguredAddr,
|
ConfiguredAddr,
|
||||||
|
|
||||||
/// List of configured IMAP servers as a JSON array.
|
/// List of configured IMAP servers as a JSON array.
|
||||||
@@ -306,10 +305,6 @@ pub enum Config {
|
|||||||
/// Meant to help profile owner to differ between profiles with similar names.
|
/// Meant to help profile owner to differ between profiles with similar names.
|
||||||
PrivateTag,
|
PrivateTag,
|
||||||
|
|
||||||
/// All secondary self addresses separated by spaces
|
|
||||||
/// (`addr1@example.org addr2@example.org addr3@example.org`)
|
|
||||||
SecondaryAddrs,
|
|
||||||
|
|
||||||
/// Read-only core version string.
|
/// Read-only core version string.
|
||||||
#[strum(serialize = "sys.version")]
|
#[strum(serialize = "sys.version")]
|
||||||
SysVersion,
|
SysVersion,
|
||||||
@@ -819,16 +814,7 @@ impl Context {
|
|||||||
self,
|
self,
|
||||||
"Creating a pseudo configured account which will not be able to send or receive messages. Only meant for tests!"
|
"Creating a pseudo configured account which will not be able to send or receive messages. Only meant for tests!"
|
||||||
);
|
);
|
||||||
self.sql
|
add_pseudo_transport(self, addr).await?;
|
||||||
.execute(
|
|
||||||
"INSERT INTO transports (addr, entered_param, configured_param) VALUES (?, ?, ?)",
|
|
||||||
(
|
|
||||||
addr,
|
|
||||||
serde_json::to_string(&EnteredLoginParam::default())?,
|
|
||||||
format!(r#"{{"addr":"{addr}","imap":[],"imap_user":"","imap_password":"","smtp":[],"smtp_user":"","smtp_password":"","certificate_checks":"Automatic","oauth2":false}}"#)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
self.sql
|
self.sql
|
||||||
.set_raw_config(Config::ConfiguredAddr.as_ref(), Some(addr))
|
.set_raw_config(Config::ConfiguredAddr.as_ref(), Some(addr))
|
||||||
.await?;
|
.await?;
|
||||||
@@ -958,16 +944,6 @@ impl Context {
|
|||||||
pub(crate) async fn set_primary_self_addr(&self, primary_new: &str) -> Result<()> {
|
pub(crate) async fn set_primary_self_addr(&self, primary_new: &str) -> Result<()> {
|
||||||
self.quota.write().await.take();
|
self.quota.write().await.take();
|
||||||
|
|
||||||
// add old primary address (if exists) to secondary addresses
|
|
||||||
let mut secondary_addrs = self.get_all_self_addrs().await?;
|
|
||||||
// never store a primary address also as a secondary
|
|
||||||
secondary_addrs.retain(|a| !addr_cmp(a, primary_new));
|
|
||||||
self.set_config_internal(
|
|
||||||
Config::SecondaryAddrs,
|
|
||||||
Some(secondary_addrs.join(" ").as_str()),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
self.sql
|
self.sql
|
||||||
.set_raw_config(Config::ConfiguredAddr.as_ref(), Some(primary_new))
|
.set_raw_config(Config::ConfiguredAddr.as_ref(), Some(primary_new))
|
||||||
.await?;
|
.await?;
|
||||||
@@ -985,14 +961,10 @@ impl Context {
|
|||||||
|
|
||||||
/// Returns all secondary self addresses.
|
/// Returns all secondary self addresses.
|
||||||
pub(crate) async fn get_secondary_self_addrs(&self) -> Result<Vec<String>> {
|
pub(crate) async fn get_secondary_self_addrs(&self) -> Result<Vec<String>> {
|
||||||
let secondary_addrs = self
|
self.sql.query_map_vec("SELECT addr FROM transports WHERE addr NOT IN (SELECT value FROM config WHERE keyname='configured_addr')", (), |row| {
|
||||||
.get_config(Config::SecondaryAddrs)
|
let addr: String = row.get(0)?;
|
||||||
.await?
|
Ok(addr)
|
||||||
.unwrap_or_default();
|
}).await
|
||||||
Ok(secondary_addrs
|
|
||||||
.split_ascii_whitespace()
|
|
||||||
.map(|s| s.to_string())
|
|
||||||
.collect())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the primary self address.
|
/// Returns the primary self address.
|
||||||
|
|||||||
@@ -94,59 +94,6 @@ async fn test_set_config_bool() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
||||||
async fn test_self_addrs() -> Result<()> {
|
|
||||||
let alice = TestContext::new_alice().await;
|
|
||||||
|
|
||||||
assert!(alice.is_self_addr("alice@example.org").await?);
|
|
||||||
assert_eq!(alice.get_all_self_addrs().await?, vec!["alice@example.org"]);
|
|
||||||
assert!(!alice.is_self_addr("alice@alice.com").await?);
|
|
||||||
|
|
||||||
// Test adding the same primary address
|
|
||||||
alice.set_primary_self_addr("alice@example.org").await?;
|
|
||||||
alice.set_primary_self_addr("Alice@Example.Org").await?;
|
|
||||||
assert_eq!(alice.get_all_self_addrs().await?, vec!["Alice@Example.Org"]);
|
|
||||||
|
|
||||||
// Test adding a new (primary) self address
|
|
||||||
// The address is trimmed during configure by `LoginParam::from_database()`,
|
|
||||||
// so `set_primary_self_addr()` doesn't have to trim it.
|
|
||||||
alice.set_primary_self_addr("Alice@alice.com").await?;
|
|
||||||
assert!(alice.is_self_addr("aliCe@example.org").await?);
|
|
||||||
assert!(alice.is_self_addr("alice@alice.com").await?);
|
|
||||||
assert_eq!(
|
|
||||||
alice.get_all_self_addrs().await?,
|
|
||||||
vec!["Alice@alice.com", "Alice@Example.Org"]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check that the entry is not duplicated
|
|
||||||
alice.set_primary_self_addr("alice@alice.com").await?;
|
|
||||||
alice.set_primary_self_addr("alice@alice.com").await?;
|
|
||||||
assert_eq!(
|
|
||||||
alice.get_all_self_addrs().await?,
|
|
||||||
vec!["alice@alice.com", "Alice@Example.Org"]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test switching back
|
|
||||||
alice.set_primary_self_addr("alice@example.org").await?;
|
|
||||||
assert_eq!(
|
|
||||||
alice.get_all_self_addrs().await?,
|
|
||||||
vec!["alice@example.org", "alice@alice.com"]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test setting a new primary self address, the previous self address
|
|
||||||
// should be kept as a secondary self address
|
|
||||||
alice.set_primary_self_addr("alice@alice.xyz").await?;
|
|
||||||
assert_eq!(
|
|
||||||
alice.get_all_self_addrs().await?,
|
|
||||||
vec!["alice@alice.xyz", "alice@example.org", "alice@alice.com"]
|
|
||||||
);
|
|
||||||
assert!(alice.is_self_addr("alice@example.org").await?);
|
|
||||||
assert!(alice.is_self_addr("alice@alice.com").await?);
|
|
||||||
assert!(alice.is_self_addr("Alice@alice.xyz").await?);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_mdns_default_behaviour() -> Result<()> {
|
async fn test_mdns_default_behaviour() -> Result<()> {
|
||||||
let t = &TestContext::new_alice().await;
|
let t = &TestContext::new_alice().await;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContext;
|
||||||
|
use crate::transport::add_pseudo_transport;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_folder_meaning_by_name() {
|
fn test_get_folder_meaning_by_name() {
|
||||||
@@ -271,12 +272,14 @@ async fn test_get_imap_search_command() -> Result<()> {
|
|||||||
r#"FROM "alice@example.org""#
|
r#"FROM "alice@example.org""#
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_pseudo_transport(&t, "alice@another.com").await?;
|
||||||
t.ctx.set_primary_self_addr("alice@another.com").await?;
|
t.ctx.set_primary_self_addr("alice@another.com").await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_imap_self_sent_search_command(&t.ctx).await?,
|
get_imap_self_sent_search_command(&t.ctx).await?,
|
||||||
r#"OR (FROM "alice@another.com") (FROM "alice@example.org")"#
|
r#"OR (FROM "alice@another.com") (FROM "alice@example.org")"#
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_pseudo_transport(&t, "alice@third.com").await?;
|
||||||
t.ctx.set_primary_self_addr("alice@third.com").await?;
|
t.ctx.set_primary_self_addr("alice@third.com").await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_imap_self_sent_search_command(&t.ctx).await?,
|
get_imap_self_sent_search_command(&t.ctx).await?,
|
||||||
|
|||||||
@@ -756,6 +756,21 @@ pub(crate) async fn sync_transports(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds transport entry to the `transports` table with empty configuration.
|
||||||
|
pub(crate) async fn add_pseudo_transport(context: &Context, addr: &str) -> Result<()> {
|
||||||
|
context.sql
|
||||||
|
.execute(
|
||||||
|
"INSERT INTO transports (addr, entered_param, configured_param) VALUES (?, ?, ?)",
|
||||||
|
(
|
||||||
|
addr,
|
||||||
|
serde_json::to_string(&EnteredLoginParam::default())?,
|
||||||
|
format!(r#"{{"addr":"{addr}","imap":[],"imap_user":"","imap_password":"","smtp":[],"smtp_user":"","smtp_password":"","certificate_checks":"Automatic","oauth2":false}}"#)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user