Skip to content

Commit d52d6f5

Browse files
committed
Make self reporting into a setting
1 parent e0607b3 commit d52d6f5

File tree

5 files changed

+72
-14
lines changed

5 files changed

+72
-14
lines changed

deltachat-jsonrpc/src/api.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,10 @@ impl CommandApi {
375375
Ok(BlobObject::create_and_deduplicate(&ctx, file, file)?.to_abs_path())
376376
}
377377

378+
/// Deprecated 2025-04. Use the "self_reporting" config instead.
378379
async fn draft_self_report(&self, account_id: u32) -> Result<u32> {
379380
let ctx = self.get_context(account_id).await?;
380-
Ok(ctx.draft_self_report().await?.to_u32())
381+
Ok(ctx.send_self_report().await?.to_u32())
381382
}
382383

383384
/// Sets the given configuration key.

src/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,13 @@ pub enum Config {
428428
/// used for signatures, encryption to self and included in `Autocrypt` header.
429429
KeyId,
430430

431+
/// Send statistics to Delta Chat's developers.
432+
/// Can be exposed to the user as a setting.
433+
SelfReporting,
434+
435+
/// Last time statistics were sent to Delta Chat's developers
436+
LastSelfReportSent,
437+
431438
/// This key is sent to the self_reporting bot so that the bot can recognize the user
432439
/// without storing the email address
433440
SelfReportingId,

src/context.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ use crate::debug_logging::DebugLogging;
2525
use crate::download::DownloadState;
2626
use crate::events::{Event, EventEmitter, EventType, Events};
2727
use crate::imap::{FolderMeaning, Imap, ServerMetadata};
28-
use crate::key::{load_self_secret_key, self_fingerprint};
28+
use crate::key::{load_self_public_key, load_self_secret_key, DcKey as _};
29+
use crate::log::LogExt;
2930
use crate::login_param::{ConfiguredLoginParam, EnteredLoginParam};
30-
use crate::message::{self, Message, MessageState, MsgId};
31+
use crate::message::{self, Message, MessageState, MsgId, Viewtype};
3132
use crate::param::{Param, Params};
3233
use crate::peer_channels::Iroh;
3334
use crate::push::PushSubscriber;
@@ -1043,6 +1044,18 @@ impl Context {
10431044
.await?
10441045
.to_string(),
10451046
);
1047+
res.insert(
1048+
"self_reporting",
1049+
self.get_config_bool(Config::SelfReporting)
1050+
.await?
1051+
.to_string(),
1052+
);
1053+
res.insert(
1054+
"last_self_report_sent",
1055+
self.get_config_i64(Config::LastSelfReportSent)
1056+
.await?
1057+
.to_string(),
1058+
);
10461059

10471060
let elapsed = time_elapsed(&self.creation_time);
10481061
res.insert("uptime", duration_to_str(elapsed));
@@ -1162,7 +1175,8 @@ impl Context {
11621175
Some(id) => id,
11631176
None => {
11641177
let id = create_id();
1165-
self.set_config(Config::SelfReportingId, Some(&id)).await?;
1178+
self.set_config_internal(Config::SelfReportingId, Some(&id))
1179+
.await?;
11661180
id
11671181
}
11681182
};
@@ -1176,7 +1190,15 @@ impl Context {
11761190
///
11771191
/// On the other end, a bot will receive the message and make it available
11781192
/// to Delta Chat's developers.
1179-
pub async fn draft_self_report(&self) -> Result<ChatId> {
1193+
pub async fn send_self_report(&self) -> Result<ChatId> {
1194+
info!(self, "Sending self report.");
1195+
// Setting `Config::LastHousekeeping` at the beginning avoids endless loops when things do not
1196+
// work out for whatever reason or are interrupted by the OS.
1197+
self.set_config_internal(Config::LastSelfReportSent, Some(&time().to_string()))
1198+
.await
1199+
.log_err(self)
1200+
.ok();
1201+
11801202
const SELF_REPORTING_BOT_VCARD: &str = include_str!("../assets/self-reporting-bot.vcf");
11811203
let contact_id: ContactId = *import_vcard(self, SELF_REPORTING_BOT_VCARD)
11821204
.await?
@@ -1189,9 +1211,26 @@ impl Context {
11891211
.set_protection(self, ProtectionStatus::Protected, time(), Some(contact_id))
11901212
.await?;
11911213

1192-
let mut msg = Message::new_text(self.get_self_report().await?);
1214+
let mut msg = Message::new(Viewtype::File);
1215+
msg.set_text(
1216+
"The attachment contains anonymous usage statistics, \
1217+
because you enabled this in the settings. \
1218+
This helps us improve the security of Delta Chat. \
1219+
See TODO[blog post] for more information."
1220+
.to_string(),
1221+
);
1222+
msg.set_file_from_bytes(
1223+
self,
1224+
"statistics.txt",
1225+
self.get_self_report().await?.as_bytes(),
1226+
Some("text/plain"),
1227+
)?;
11931228

1194-
chat_id.set_draft(self, Some(&mut msg)).await?;
1229+
crate::chat::send_msg(self, chat_id, &mut msg)
1230+
.await
1231+
.context("Failed to send self_reporting message")
1232+
.log_err(self)
1233+
.ok();
11951234

11961235
Ok(chat_id)
11971236
}

src/context/context_tests.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -595,18 +595,15 @@ async fn test_get_next_msgs() -> Result<()> {
595595
async fn test_draft_self_report() -> Result<()> {
596596
let alice = TestContext::new_alice().await;
597597

598-
let chat_id = alice.draft_self_report().await?;
599-
let msg = get_chat_msg(&alice, chat_id, 0, 1).await;
598+
let chat_id = alice.send_self_report().await?;
599+
let msg = get_chat_msg(&alice, chat_id, 0, 2).await;
600600
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionEnabled);
601601

602602
let chat = Chat::load_from_db(&alice, chat_id).await?;
603603
assert!(chat.is_protected());
604604

605-
let mut draft = chat_id.get_draft(&alice).await?.unwrap();
606-
assert!(draft.text.starts_with("core_version"));
607-
608-
// Test that sending into the protected chat works:
609-
let _sent = alice.send_msg(chat_id, &mut draft).await;
605+
let statistics_msg = get_chat_msg(&alice, chat_id, 1, 2).await;
606+
assert_eq!(statistics_msg.get_filename().unwrap(), "statistics.txt");
610607

611608
Ok(())
612609
}

src/scheduler.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,20 @@ async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session)
505505
}
506506
};
507507

508+
//#[cfg(target_os = "android")] TODO
509+
if ctx.get_config_bool(Config::SelfReporting).await? {
510+
match ctx.get_config_i64(Config::LastSelfReportSent).await {
511+
Ok(last_selfreport_time) => {
512+
let next_selfreport_time = last_selfreport_time.saturating_add(30); // TODO increase to 1 day or 1 week
513+
if next_selfreport_time <= time() {
514+
ctx.send_self_report().await?;
515+
}
516+
}
517+
Err(err) => {
518+
warn!(ctx, "Failed to get last self_reporting time: {}", err);
519+
}
520+
}
521+
}
508522
match ctx.get_config_bool(Config::FetchedExistingMsgs).await {
509523
Ok(fetched_existing_msgs) => {
510524
if !fetched_existing_msgs {

0 commit comments

Comments
 (0)