diff --git a/deltachat-jsonrpc/src/api.rs b/deltachat-jsonrpc/src/api.rs index 5fb0efed4..5d96fce47 100644 --- a/deltachat-jsonrpc/src/api.rs +++ b/deltachat-jsonrpc/src/api.rs @@ -45,7 +45,7 @@ pub mod types; use num_traits::FromPrimitive; use types::account::Account; -use types::chat::FullChat; +use types::chat::{EncryptionInfo, FullChat}; use types::contact::{ContactObject, VcardContact}; use types::events::Event; use types::http::HttpResponse; @@ -708,6 +708,19 @@ impl CommandApi { ChatId::new(chat_id).get_encryption_info(&ctx).await } + /// Get encryption info for a chat. + async fn get_chat_encryption_info_json( + &self, + account_id: u32, + chat_id: u32, + ) -> Result { + let ctx = self.get_context(account_id).await?; + Ok(ChatId::new(chat_id) + .get_encryption_info_json(&ctx) + .await? + .into()) + } + /// Get QR code text that will offer a [SecureJoin](https://securejoin.delta.chat/) invitation. /// /// If `chat_id` is a group chat ID, SecureJoin QR code for the group is returned. diff --git a/deltachat-jsonrpc/src/api/types/chat.rs b/deltachat-jsonrpc/src/api/types/chat.rs index 9c3c4cd98..18b7a1c78 100644 --- a/deltachat-jsonrpc/src/api/types/chat.rs +++ b/deltachat-jsonrpc/src/api/types/chat.rs @@ -9,6 +9,7 @@ use deltachat::context::Context; use num_traits::cast::ToPrimitive; use serde::{Deserialize, Serialize}; use typescript_type_def::TypeDef; +use yerpc::JsonSchema; use super::color_int_to_hex_string; use super::contact::ContactObject; @@ -239,3 +240,23 @@ impl JSONRPCChatVisibility { } } } + +#[derive(Debug, JsonSchema, TypeDef, Serialize, Deserialize)] +pub struct EncryptionInfo { + /// Addresses with End-to-end encryption preferred. + pub mutual: Vec, + /// Addresses with End-to-end encryption available. + pub no_preference: Vec, + /// Addresses with no encryption. + pub reset: Vec, +} + +impl From for EncryptionInfo { + fn from(encryption_info: chat::EncryptionInfo) -> Self { + EncryptionInfo { + mutual: encryption_info.mutual, + no_preference: encryption_info.no_preference, + reset: encryption_info.reset, + } + } +} diff --git a/src/chat.rs b/src/chat.rs index c1d2f3d1d..6802bb64d 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -105,6 +105,17 @@ pub enum ProtectionStatus { ProtectionBroken = 3, // `2` was never used as a value. } +/// Encryption info for a single chat. +#[derive(Debug)] +pub struct EncryptionInfo { + /// Addresses with End-to-end encryption preferred. + pub mutual: Vec, + /// Addresses with End-to-end encryption available. + pub no_preference: Vec, + /// Addresses with no encryption. + pub reset: Vec, +} + /// The reason why messages cannot be sent to the chat. /// /// The reason is mainly for logging and displaying in debug REPL, thus not translated. @@ -1335,6 +1346,38 @@ impl ChatId { Ok(ret.trim().to_string()) } + /// Returns encryption preferences of all chat contacts. + pub async fn get_encryption_info_json(self, context: &Context) -> Result { + let mut mutual = vec![]; + let mut no_preference = vec![]; + let mut reset = vec![]; + + for contact_id in get_chat_contacts(context, self) + .await? + .iter() + .filter(|&contact_id| !contact_id.is_special()) + { + let contact = Contact::get_by_id(context, *contact_id).await?; + let addr = contact.get_addr().to_string(); + let peerstate = Peerstate::from_addr(context, &addr).await?; + + match peerstate + .filter(|peerstate| peerstate.peek_key(false).is_some()) + .map(|peerstate| peerstate.prefer_encrypt) + { + Some(EncryptPreference::Mutual) => mutual.push(addr), + Some(EncryptPreference::NoPreference) => no_preference.push(addr), + Some(EncryptPreference::Reset) | None => reset.push(addr), + }; + } + + Ok(EncryptionInfo { + mutual, + no_preference, + reset, + }) + } + /// Bad evil escape hatch. /// /// Avoid using this, eventually types should be cleaned up enough