mirror of
https://github.com/chatmail/core.git
synced 2026-04-25 01:16:29 +03:00
@@ -139,6 +139,15 @@ impl ContactId {
|
|||||||
pub const fn to_u32(&self) -> u32 {
|
pub const fn to_u32(&self) -> u32 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark contact as bot.
|
||||||
|
pub(crate) async fn mark_bot(&self, context: &Context, is_bot: bool) -> Result<()> {
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.execute("UPDATE contacts SET is_bot=? WHERE id=?;", (is_bot, self.0))
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ContactId {
|
impl fmt::Display for ContactId {
|
||||||
@@ -223,6 +232,9 @@ pub struct Contact {
|
|||||||
|
|
||||||
/// Last seen message signature for this contact, to be displayed in the profile.
|
/// Last seen message signature for this contact, to be displayed in the profile.
|
||||||
status: String,
|
status: String,
|
||||||
|
|
||||||
|
/// If the contact is a bot.
|
||||||
|
is_bot: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Possible origins of a contact.
|
/// Possible origins of a contact.
|
||||||
@@ -366,7 +378,7 @@ impl Contact {
|
|||||||
.sql
|
.sql
|
||||||
.query_row_optional(
|
.query_row_optional(
|
||||||
"SELECT c.name, c.addr, c.origin, c.blocked, c.last_seen,
|
"SELECT c.name, c.addr, c.origin, c.blocked, c.last_seen,
|
||||||
c.authname, c.param, c.status
|
c.authname, c.param, c.status, c.is_bot
|
||||||
FROM contacts c
|
FROM contacts c
|
||||||
WHERE c.id=?;",
|
WHERE c.id=?;",
|
||||||
(contact_id,),
|
(contact_id,),
|
||||||
@@ -379,6 +391,7 @@ impl Contact {
|
|||||||
let authname: String = row.get(5)?;
|
let authname: String = row.get(5)?;
|
||||||
let param: String = row.get(6)?;
|
let param: String = row.get(6)?;
|
||||||
let status: Option<String> = row.get(7)?;
|
let status: Option<String> = row.get(7)?;
|
||||||
|
let is_bot: bool = row.get(8)?;
|
||||||
let contact = Self {
|
let contact = Self {
|
||||||
id: contact_id,
|
id: contact_id,
|
||||||
name,
|
name,
|
||||||
@@ -389,6 +402,7 @@ impl Contact {
|
|||||||
origin,
|
origin,
|
||||||
param: param.parse().unwrap_or_default(),
|
param: param.parse().unwrap_or_default(),
|
||||||
status: status.unwrap_or_default(),
|
status: status.unwrap_or_default(),
|
||||||
|
is_bot,
|
||||||
};
|
};
|
||||||
Ok(contact)
|
Ok(contact)
|
||||||
},
|
},
|
||||||
@@ -498,6 +512,11 @@ impl Contact {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether contact is a bot.
|
||||||
|
pub fn is_bot(&self) -> bool {
|
||||||
|
self.is_bot
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if an e-mail address belongs to a known and unblocked contact.
|
/// Check if an e-mail address belongs to a known and unblocked contact.
|
||||||
///
|
///
|
||||||
/// Known and unblocked contacts will be returned by `get_contacts()`.
|
/// Known and unblocked contacts will be returned by `get_contacts()`.
|
||||||
|
|||||||
@@ -2341,6 +2341,8 @@ mod tests {
|
|||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.get_text(), "hello".to_string());
|
assert_eq!(msg.get_text(), "hello".to_string());
|
||||||
assert!(msg.is_bot());
|
assert!(msg.is_bot());
|
||||||
|
let contact = Contact::get_by_id(&alice, msg.from_id).await?;
|
||||||
|
assert!(contact.is_bot());
|
||||||
|
|
||||||
// Alice receives a message from Bob who is not the bot anymore.
|
// Alice receives a message from Bob who is not the bot anymore.
|
||||||
receive_imf(
|
receive_imf(
|
||||||
@@ -2358,6 +2360,8 @@ mod tests {
|
|||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.get_text(), "hello again".to_string());
|
assert_eq!(msg.get_text(), "hello again".to_string());
|
||||||
assert!(!msg.is_bot());
|
assert!(!msg.is_bot());
|
||||||
|
let contact = Contact::get_by_id(&alice, msg.from_id).await?;
|
||||||
|
assert!(!contact.is_bot());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,11 @@ pub(crate) struct MimeMessage {
|
|||||||
/// for e.g. late-parsing HTML.
|
/// for e.g. late-parsing HTML.
|
||||||
pub decoded_data: Vec<u8>,
|
pub decoded_data: Vec<u8>,
|
||||||
|
|
||||||
|
/// Hop info for debugging.
|
||||||
pub(crate) hop_info: String,
|
pub(crate) hop_info: String,
|
||||||
|
|
||||||
|
/// Whether the contact sending this should be marked as bot.
|
||||||
|
pub(crate) is_bot: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -373,6 +377,9 @@ impl MimeMessage {
|
|||||||
signatures.clear();
|
signatures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-submitted is also set by holiday-notices so we also check `chat-version`
|
||||||
|
let is_bot = headers.contains_key("auto-submitted") && headers.contains_key("chat-version");
|
||||||
|
|
||||||
let mut parser = MimeMessage {
|
let mut parser = MimeMessage {
|
||||||
parts: Vec::new(),
|
parts: Vec::new(),
|
||||||
headers,
|
headers,
|
||||||
@@ -401,6 +408,7 @@ impl MimeMessage {
|
|||||||
is_mime_modified: false,
|
is_mime_modified: false,
|
||||||
decoded_data: Vec::new(),
|
decoded_data: Vec::new(),
|
||||||
hop_info,
|
hop_info,
|
||||||
|
is_bot,
|
||||||
};
|
};
|
||||||
|
|
||||||
match partial {
|
match partial {
|
||||||
|
|||||||
@@ -377,6 +377,8 @@ pub(crate) async fn receive_imf_inner(
|
|||||||
.handle_reports(context, from_id, sent_timestamp, &mime_parser.parts)
|
.handle_reports(context, from_id, sent_timestamp, &mime_parser.parts)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
from_id.mark_bot(context, mime_parser.is_bot).await?;
|
||||||
|
|
||||||
Ok(Some(received_msg))
|
Ok(Some(received_msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -740,6 +740,15 @@ CREATE INDEX smtp_messageid ON imap(rfc724_mid);
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add is_bot column to contacts table with default false.
|
||||||
|
if dbversion < 103 {
|
||||||
|
sql.execute_migration(
|
||||||
|
"ALTER TABLE contacts ADD COLUMN is_bot INTEGER NOT NULL DEFAULT 0",
|
||||||
|
103,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
let new_version = sql
|
let new_version = sql
|
||||||
.get_raw_config_int(VERSION_CFG)
|
.get_raw_config_int(VERSION_CFG)
|
||||||
.await?
|
.await?
|
||||||
|
|||||||
Reference in New Issue
Block a user