diff --git a/CHANGELOG.md b/CHANGELOG.md index eaf97a25d..93956a015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ### Changes - order contact lists by "last seen"; this affects `dc_get_chat_contacts()`, `dc_get_contacts()` and `dc_get_blocked_contacts()` #3562 +- add `internet_access` flag to `dc_msg_get_webxdc_info()` #3516 ### Fixes - do not emit notifications for blocked chats #3557 diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index b1a3967c4..68b3f5d10 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -3763,6 +3763,11 @@ char* dc_msg_get_webxdc_blob (const dc_msg_t* msg, const char* * URL where the source code of the Webxdc and other information can be found; * defaults to an empty string. * Implementations may offer an menu or a button to open this URL. + * - internet_access: + * true if the Webxdc should get full internet access, including Webrtc. + * currently, this is only true for encrypted Webxdc's in the self chat + * that have requested internet access in the manifest. + * this is useful for development and maybe for internal integrations at some point. * * @memberof dc_msg_t * @param msg The webxdc instance. diff --git a/deltachat-jsonrpc/src/api/types/webxdc.rs b/deltachat-jsonrpc/src/api/types/webxdc.rs index fe652bb43..f89310667 100644 --- a/deltachat-jsonrpc/src/api/types/webxdc.rs +++ b/deltachat-jsonrpc/src/api/types/webxdc.rs @@ -33,6 +33,8 @@ pub struct WebxdcMessageInfo { /// defaults to an empty string. /// Implementations may offer an menu or a button to open this URL. source_code_url: Option, + /// True if full internet access should be granted to the app. + internet_access: bool, } impl WebxdcMessageInfo { @@ -47,6 +49,7 @@ impl WebxdcMessageInfo { document, summary, source_code_url, + internet_access, } = message.get_webxdc_info(context).await?; Ok(Self { @@ -55,6 +58,7 @@ impl WebxdcMessageInfo { document: maybe_empty_string_to_option(document), summary: maybe_empty_string_to_option(summary), source_code_url: maybe_empty_string_to_option(source_code_url), + internet_access, }) } } diff --git a/deltachat-jsonrpc/typescript/generated/types.ts b/deltachat-jsonrpc/typescript/generated/types.ts index 4748902eb..d36e5519e 100644 --- a/deltachat-jsonrpc/typescript/generated/types.ts +++ b/deltachat-jsonrpc/typescript/generated/types.ts @@ -94,5 +94,9 @@ export type WebxdcMessageInfo={ * defaults to an empty string. * Implementations may offer an menu or a button to open this URL. */ -"sourceCodeUrl":(string|null);}; +"sourceCodeUrl":(string|null); +/** + * True if full internet access should be granted to the app. + */ +"internetAccess":boolean;}; export type __AllTyps=[string,boolean,Record,U32,U32,null,(U32)[],U32,null,(U32|null),(Account)[],U32,Account,U32,string,(ProviderInfo|null),U32,boolean,U32,Record,U32,string,(string|null),null,U32,Record,null,U32,string,null,U32,string,Qr,U32,string,(string|null),U32,(string)[],Record,U32,null,U32,null,U32,(U32)[],U32,U32,Usize,U32,string,U32,U32,string,null,U32,(U32|null),(string|null),(U32|null),(ChatListEntry)[],U32,(ChatListEntry)[],Record,U32,U32,FullChat,U32,U32,null,U32,U32,null,U32,string,string,U32,U32,U32,U32,(U32)[],U32,U32,Message,U32,(U32)[],Record,U32,U32,Contact,U32,string,(string|null),U32,U32,U32,U32,U32,U32,null,U32,U32,null,U32,(Contact)[],U32,U32,(string|null),(U32)[],U32,U32,(string|null),(Contact)[],U32,(U32)[],Record,U32,(U32|null),Viewtype,(Viewtype|null),(Viewtype|null),(U32)[],U32,U32,string,string,null,U32,U32,U32,string,U32,U32,WebxdcMessageInfo,U32,string,U32,U32]; diff --git a/src/webxdc.rs b/src/webxdc.rs index 6a071bf15..2f2cbc73c 100644 --- a/src/webxdc.rs +++ b/src/webxdc.rs @@ -56,6 +56,7 @@ struct WebxdcManifest { name: Option, min_api: Option, source_code_url: Option, + request_internet_access: Option, } /// Parsed information from WebxdcManifest and fallbacks. @@ -66,6 +67,7 @@ pub struct WebxdcInfo { pub document: String, pub summary: String, pub source_code_url: String, + pub internet_access: bool, } /// Status Update ID. @@ -676,6 +678,7 @@ impl Message { name: None, min_api: None, source_code_url: None, + request_internet_access: None, } } } else { @@ -683,6 +686,7 @@ impl Message { name: None, min_api: None, source_code_url: None, + request_internet_access: None, } }; @@ -694,6 +698,10 @@ impl Message { } } + let internet_access = manifest.request_internet_access.unwrap_or_default() + && self.chat_id.is_self_talk(context).await.unwrap_or_default() + && self.get_showpadlock(); + Ok(WebxdcInfo { name: if let Some(name) = manifest.name { name @@ -712,16 +720,20 @@ impl Message { .get(Param::WebxdcDocument) .unwrap_or_default() .to_string(), - summary: self - .param - .get(Param::WebxdcSummary) - .unwrap_or_default() - .to_string(), + summary: if internet_access { + "Dev Mode: Do not enter sensitive data!".to_string() + } else { + self.param + .get(Param::WebxdcSummary) + .unwrap_or_default() + .to_string() + }, source_code_url: if let Some(url) = manifest.source_code_url { url } else { "".to_string() }, + internet_access, }) } } @@ -729,8 +741,8 @@ impl Message { #[cfg(test)] mod tests { use crate::chat::{ - add_contact_to_chat, create_group_chat, forward_msgs, resend_msgs, send_msg, send_text_msg, - ChatId, ProtectionStatus, + add_contact_to_chat, create_broadcast_list, create_group_chat, forward_msgs, resend_msgs, + send_msg, send_text_msg, ChatId, ProtectionStatus, }; use crate::chatlist::Chatlist; use crate::config::Config; @@ -1781,6 +1793,19 @@ sth_for_the = "future""# Ok(()) } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_parse_webxdc_manifest_request_internet_access() -> Result<()> { + let result = parse_webxdc_manifest(r#"request_internet_access = 3"#.as_bytes()); + assert!(result.is_err()); + let manifest = parse_webxdc_manifest(r#" source_code_url="https://foo.org""#.as_bytes())?; + assert_eq!(manifest.request_internet_access, None); + let manifest = parse_webxdc_manifest(r#" request_internet_access=false"#.as_bytes())?; + assert_eq!(manifest.request_internet_access, Some(false)); + let manifest = parse_webxdc_manifest(r#"request_internet_access = true"#.as_bytes())?; + assert_eq!(manifest.request_internet_access, Some(true)); + Ok(()) + } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_webxdc_min_api_too_large() -> Result<()> { let t = TestContext::new_alice().await; @@ -2191,6 +2216,51 @@ sth_for_the = "future""# Ok(()) } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_webxdc_internet_access() -> Result<()> { + let t = TestContext::new_alice().await; + let self_id = t.get_self_chat().await.id; + let single_id = t.create_chat_with_contact("bob", "bob@e.com").await.id; + let group_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?; + let broadcast_id = create_broadcast_list(&t).await?; + + let mut first_test = true; // only the first test has all conditions for internet access + + for e2ee in ["1", "0"] { + t.set_config(Config::E2eeEnabled, Some(e2ee)).await?; + for chat_id in [self_id, single_id, group_id, broadcast_id] { + for internet_xdc in [true, false] { + let mut instance = create_webxdc_instance( + &t, + "foo.xdc", + if internet_xdc { + include_bytes!("../test-data/webxdc/request-internet-access.xdc") + } else { + include_bytes!("../test-data/webxdc/minimal.xdc") + }, + ) + .await?; + let instance_id = send_msg(&t, chat_id, &mut instance).await?; + t.send_webxdc_status_update( + instance_id, + r#"{"summary":"real summary", "payload": 42}"#, + "descr", + ) + .await?; + let instance = Message::load_from_db(&t, instance_id).await?; + let info = instance.get_webxdc_info(&t).await?; + assert_eq!(info.internet_access, first_test); + assert_eq!(info.summary.contains("Do not enter sensitive"), first_test); + assert_eq!(info.summary.contains("real summary"), !first_test); + + first_test = false; + } + } + } + + Ok(()) + } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_webxdc_chatlist_summary() -> Result<()> { let t = TestContext::new_alice().await; diff --git a/test-data/webxdc/request-internet-access.xdc b/test-data/webxdc/request-internet-access.xdc new file mode 100644 index 000000000..ce1a2b8c0 Binary files /dev/null and b/test-data/webxdc/request-internet-access.xdc differ