mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
This way, the statistics / self-reporting bot will be made into an opt-in regular sending of statistics, where you enable the setting once and then they will be sent automatically. The statistics will be sent to a bot, so that the user can see exactly which data is being sent, and how often. The chat will be archived and muted by default, so that it doesn't disturb the user. The collected statistics will focus on the public-key-verification that is performed while scanning a QR code. Later on, we can add more statistics to collect. **Context:** _This is just to give a rough idea; I would need to write a lot more than a few paragraphs in order to fully explain all the context here_. End-to-end encrypted messengers are generally susceptible to MitM attacks. In order to mitigate against this, messengers offer some way of verifying the chat partner's public key. However, numerous studies found that most popular messengers implement this public-key-verification in a way that is not understood by users, and therefore ineffective - [a 2021 "State of Knowledge" paper concludes:](https://dl.acm.org/doi/pdf/10.1145/3558482.3581773) > Based on our evaluation, we have determined that all current E2EE apps, particularly when operating in opportunistic E2EE mode, are incapable of repelling active man-in-the-middle (MitM) attacks. In addition, we find that none of the current E2EE apps provide better and more usable [public key verification] ceremonies, resulting in insecure E2EE communications against active MitM attacks. This is why Delta Chat tries to go a different route: When the user scans a QR code (regardless of whether the QR code creates a 1:1 chat, invites to a group, or subscribes to a broadcast channel), a public-key-verification is performed in the background, without the user even having to know about this. The statistics collected here are supposed to tell us whether Delta Chat succeeds to nudge the users into using QR codes in a way that is secure against MitM attacks. **Plan for statistics-sending:** - [x] Get this PR reviewed and merged (but don't make it available in the UI yet; if Android wants to make a release in the meantime, I will create a PR that removes the option there) - [x] Set the interval to 1 week again (right now, it's 1 minute for testing) - [ ] Write something for people who are interested in what exactly we count, and link to it (see `TODO[blog post]` in the code) - [ ] Prepare a short survey for participants - [ ] Fine-tune the texts at https://github.com/deltachat/deltachat-android/pull/3794, and get it reviewed and merged - [ ] After the next release, ask people to enable the statistics-sending
297 lines
10 KiB
Rust
297 lines
10 KiB
Rust
//! # Constants.
|
|
|
|
#![allow(missing_docs)]
|
|
|
|
use std::sync::LazyLock;
|
|
|
|
use deltachat_derive::{FromSql, ToSql};
|
|
use percent_encoding::{AsciiSet, NON_ALPHANUMERIC};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::chat::ChatId;
|
|
|
|
pub static DC_VERSION_STR: LazyLock<String> =
|
|
LazyLock::new(|| env!("CARGO_PKG_VERSION").to_string());
|
|
|
|
/// Set of characters to percent-encode in email addresses and names.
|
|
pub(crate) const NON_ALPHANUMERIC_WITHOUT_DOT: &AsciiSet = &NON_ALPHANUMERIC.remove(b'.');
|
|
|
|
#[derive(
|
|
Debug,
|
|
Default,
|
|
Display,
|
|
Clone,
|
|
Copy,
|
|
PartialEq,
|
|
Eq,
|
|
FromPrimitive,
|
|
ToPrimitive,
|
|
FromSql,
|
|
ToSql,
|
|
Serialize,
|
|
Deserialize,
|
|
)]
|
|
#[repr(i8)]
|
|
pub enum Blocked {
|
|
#[default]
|
|
Not = 0,
|
|
Yes = 1,
|
|
Request = 2,
|
|
}
|
|
|
|
#[derive(
|
|
Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql,
|
|
)]
|
|
#[repr(u8)]
|
|
pub enum ShowEmails {
|
|
Off = 0,
|
|
AcceptedContacts = 1,
|
|
#[default] // also change Config.ShowEmails props(default) on changes
|
|
All = 2,
|
|
}
|
|
|
|
#[derive(
|
|
Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql,
|
|
)]
|
|
#[repr(u8)]
|
|
pub enum MediaQuality {
|
|
#[default] // also change Config.MediaQuality props(default) on changes
|
|
Balanced = 0,
|
|
Worse = 1,
|
|
}
|
|
|
|
pub const DC_HANDSHAKE_CONTINUE_NORMAL_PROCESSING: i32 = 0x01;
|
|
pub const DC_HANDSHAKE_STOP_NORMAL_PROCESSING: i32 = 0x02;
|
|
pub const DC_HANDSHAKE_ADD_DELETE_JOB: i32 = 0x04;
|
|
|
|
pub(crate) const DC_FROM_HANDSHAKE: i32 = 0x01;
|
|
|
|
pub const DC_GCL_ARCHIVED_ONLY: usize = 0x01;
|
|
pub const DC_GCL_NO_SPECIALS: usize = 0x02;
|
|
pub const DC_GCL_ADD_ALLDONE_HINT: usize = 0x04;
|
|
pub const DC_GCL_FOR_FORWARDING: usize = 0x08;
|
|
|
|
pub const DC_GCL_ADD_SELF: u32 = 0x02;
|
|
pub const DC_GCL_ADDRESS: u32 = 0x04;
|
|
|
|
// unchanged user avatars are resent to the recipients every some days
|
|
pub(crate) const DC_RESEND_USER_AVATAR_DAYS: i64 = 14;
|
|
|
|
// warn about an outdated app after a given number of days.
|
|
// reference is the release date.
|
|
// as not all system get speedy updates,
|
|
// do not use too small value that will annoy users checking for nonexistent updates.
|
|
// "90 days" has proven to be too short at some point (user were informed but there was no update)
|
|
pub(crate) const DC_OUTDATED_WARNING_DAYS: i64 = 183;
|
|
|
|
/// messages that should be deleted get this chat_id; the messages are deleted from the working thread later then. This is also needed as rfc724_mid should be preset as long as the message is not deleted on the server (otherwise it is downloaded again)
|
|
pub const DC_CHAT_ID_TRASH: ChatId = ChatId::new(3);
|
|
/// only an indicator in a chatlist
|
|
pub const DC_CHAT_ID_ARCHIVED_LINK: ChatId = ChatId::new(6);
|
|
/// only an indicator in a chatlist
|
|
pub const DC_CHAT_ID_ALLDONE_HINT: ChatId = ChatId::new(7);
|
|
/// larger chat IDs are "real" chats, their messages are "real" messages.
|
|
pub const DC_CHAT_ID_LAST_SPECIAL: ChatId = ChatId::new(9);
|
|
|
|
/// Chat type.
|
|
#[derive(
|
|
Debug,
|
|
Display,
|
|
Clone,
|
|
Copy,
|
|
PartialEq,
|
|
Eq,
|
|
PartialOrd,
|
|
Ord,
|
|
FromPrimitive,
|
|
ToPrimitive,
|
|
FromSql,
|
|
ToSql,
|
|
IntoStaticStr,
|
|
Serialize,
|
|
Deserialize,
|
|
)]
|
|
#[repr(u32)]
|
|
pub enum Chattype {
|
|
/// A 1:1 chat, i.e. a normal chat with a single contact.
|
|
///
|
|
/// Created by [`ChatId::create_for_contact`].
|
|
Single = 100,
|
|
|
|
/// Group chat.
|
|
///
|
|
/// Created by [`crate::chat::create_group`].
|
|
Group = 120,
|
|
|
|
/// An (unencrypted) mailing list,
|
|
/// created by an incoming mailing list email.
|
|
Mailinglist = 140,
|
|
|
|
/// Outgoing broadcast channel, called "Channel" in the UI.
|
|
///
|
|
/// The user can send into this chat,
|
|
/// and all recipients will receive messages
|
|
/// in an `InBroadcast`.
|
|
///
|
|
/// Called `broadcast` here rather than `channel`,
|
|
/// because the word "channel" already appears a lot in the code,
|
|
/// which would make it hard to grep for it.
|
|
///
|
|
/// Created by [`crate::chat::create_broadcast`].
|
|
OutBroadcast = 160,
|
|
|
|
/// Incoming broadcast channel, called "Channel" in the UI.
|
|
///
|
|
/// This chat is read-only,
|
|
/// and we do not know who the other recipients are.
|
|
///
|
|
/// This is similar to a `MailingList`,
|
|
/// with the main difference being that
|
|
/// `InBroadcast`s are encrypted.
|
|
///
|
|
/// Called `broadcast` here rather than `channel`,
|
|
/// because the word "channel" already appears a lot in the code,
|
|
/// which would make it hard to grep for it.
|
|
InBroadcast = 165,
|
|
}
|
|
|
|
pub const DC_MSG_ID_DAYMARKER: u32 = 9;
|
|
pub const DC_MSG_ID_LAST_SPECIAL: u32 = 9;
|
|
|
|
/// String that indicates that something is left out or truncated.
|
|
pub(crate) const DC_ELLIPSIS: &str = "[...]";
|
|
// how many lines desktop can display when fullscreen (fullscreen at zoomlevel 1x)
|
|
// (taken from "subjective" testing what looks ok)
|
|
pub const DC_DESIRED_TEXT_LINES: usize = 38;
|
|
// how many chars desktop can display per line (from "subjective" testing)
|
|
pub const DC_DESIRED_TEXT_LINE_LEN: usize = 100;
|
|
|
|
/// Message length limit.
|
|
///
|
|
/// To keep bubbles and chat flow usable and to avoid problems with controls using very long texts,
|
|
/// we limit the text length to `DC_DESIRED_TEXT_LEN`. If the text is longer, the full text can be
|
|
/// retrieved using has_html()/get_html().
|
|
///
|
|
/// Note that for simplicity maximum length is defined as the number of Unicode Scalar Values (Rust
|
|
/// `char`s), not Unicode Grapheme Clusters.
|
|
pub const DC_DESIRED_TEXT_LEN: usize = DC_DESIRED_TEXT_LINE_LEN * DC_DESIRED_TEXT_LINES;
|
|
|
|
// Flags for configuring IMAP and SMTP servers.
|
|
// These flags are optional
|
|
// and may be set together with the username, password etc.
|
|
// via dc_set_config() using the key "server_flags".
|
|
|
|
/// Force OAuth2 authorization.
|
|
///
|
|
/// This flag does not skip automatic configuration.
|
|
/// Before calling configure() with DC_LP_AUTH_OAUTH2 set,
|
|
/// the user has to confirm access at the URL returned by dc_get_oauth2_url().
|
|
pub const DC_LP_AUTH_OAUTH2: i32 = 0x2;
|
|
|
|
/// Force NORMAL authorization, this is the default.
|
|
/// If this flag is set, automatic configuration is skipped.
|
|
pub const DC_LP_AUTH_NORMAL: i32 = 0x4;
|
|
|
|
/// if none of these flags are set, the default is chosen
|
|
pub const DC_LP_AUTH_FLAGS: i32 = DC_LP_AUTH_OAUTH2 | DC_LP_AUTH_NORMAL;
|
|
|
|
// max. weight of images to send w/o recoding
|
|
pub const BALANCED_IMAGE_BYTES: usize = 500_000;
|
|
pub const WORSE_IMAGE_BYTES: usize = 130_000;
|
|
|
|
// max. width/height and bytes of an avatar
|
|
pub(crate) const BALANCED_AVATAR_SIZE: u32 = 512;
|
|
pub(crate) const BALANCED_AVATAR_BYTES: usize = 60_000;
|
|
pub(crate) const WORSE_AVATAR_SIZE: u32 = 128;
|
|
pub(crate) const WORSE_AVATAR_BYTES: usize = 20_000; // this also fits to Outlook servers don't allowing headers larger than 32k.
|
|
|
|
// max. width/height of images scaled down because of being too huge
|
|
pub const BALANCED_IMAGE_SIZE: u32 = 1280;
|
|
pub const WORSE_IMAGE_SIZE: u32 = 640;
|
|
|
|
/// Limit for received images size. Bigger images become `Viewtype::File` to avoid excessive memory
|
|
/// usage by UIs.
|
|
pub const MAX_RCVD_IMAGE_PIXELS: u32 = 50_000_000;
|
|
|
|
// Key for the folder configuration version (see below).
|
|
pub(crate) const DC_FOLDERS_CONFIGURED_KEY: &str = "folders_configured";
|
|
// this value can be increased if the folder configuration is changed and must be redone on next program start
|
|
pub(crate) const DC_FOLDERS_CONFIGURED_VERSION: i32 = 5;
|
|
|
|
// If more recipients are needed in SMTP's `RCPT TO:` header, the recipient list is split into
|
|
// chunks. This does not affect MIME's `To:` header. Can be overwritten by setting
|
|
// `max_smtp_rcpt_to` in the provider db.
|
|
pub(crate) const DEFAULT_MAX_SMTP_RCPT_TO: usize = 50;
|
|
|
|
/// How far the last quota check needs to be in the past to be checked by the background function (in seconds).
|
|
pub(crate) const DC_BACKGROUND_FETCH_QUOTA_CHECK_RATELIMIT: u64 = 12 * 60 * 60; // 12 hours
|
|
|
|
/// How far in the future the sender timestamp of a message is allowed to be, in seconds. Also used
|
|
/// in the group membership consistency algo to reject outdated membership changes.
|
|
pub(crate) const TIMESTAMP_SENT_TOLERANCE: i64 = 60;
|
|
|
|
// To make text edits clearer for Non-Delta-MUA or old Delta Chats, edited text will be prefixed by EDITED_PREFIX.
|
|
// Newer Delta Chats will remove the prefix as needed.
|
|
pub(crate) const EDITED_PREFIX: &str = "✏️";
|
|
|
|
// Strings needed to render the Autocrypt Setup Message.
|
|
// Left untranslated as not being supported/recommended workflow and as translations would require deep knowledge.
|
|
pub(crate) const ASM_SUBJECT: &str = "Autocrypt Setup Message";
|
|
pub(crate) const ASM_BODY: &str = "This is the Autocrypt Setup Message \
|
|
used to transfer your end-to-end setup between clients.
|
|
|
|
To decrypt and use your setup, \
|
|
open the message in an Autocrypt-compliant client \
|
|
and enter the setup code presented on the generating device.
|
|
|
|
If you see this message in a chatmail client (Delta Chat, Arcane Chat, Delta Touch ...), \
|
|
use \"Settings / Add Second Device\" instead.";
|
|
|
|
/// Period between `sql::housekeeping()` runs.
|
|
pub(crate) const HOUSEKEEPING_PERIOD: i64 = 24 * 60 * 60;
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use num_traits::FromPrimitive;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_chattype_values() {
|
|
// values may be written to disk and must not change
|
|
assert_eq!(Chattype::Single, Chattype::from_i32(100).unwrap());
|
|
assert_eq!(Chattype::Group, Chattype::from_i32(120).unwrap());
|
|
assert_eq!(Chattype::Mailinglist, Chattype::from_i32(140).unwrap());
|
|
assert_eq!(Chattype::OutBroadcast, Chattype::from_i32(160).unwrap());
|
|
}
|
|
|
|
#[test]
|
|
fn test_showemails_values() {
|
|
// values may be written to disk and must not change
|
|
assert_eq!(ShowEmails::All, ShowEmails::default());
|
|
assert_eq!(ShowEmails::Off, ShowEmails::from_i32(0).unwrap());
|
|
assert_eq!(
|
|
ShowEmails::AcceptedContacts,
|
|
ShowEmails::from_i32(1).unwrap()
|
|
);
|
|
assert_eq!(ShowEmails::All, ShowEmails::from_i32(2).unwrap());
|
|
}
|
|
|
|
#[test]
|
|
fn test_blocked_values() {
|
|
// values may be written to disk and must not change
|
|
assert_eq!(Blocked::Not, Blocked::default());
|
|
assert_eq!(Blocked::Not, Blocked::from_i32(0).unwrap());
|
|
assert_eq!(Blocked::Yes, Blocked::from_i32(1).unwrap());
|
|
assert_eq!(Blocked::Request, Blocked::from_i32(2).unwrap());
|
|
}
|
|
|
|
#[test]
|
|
fn test_mediaquality_values() {
|
|
// values may be written to disk and must not change
|
|
assert_eq!(MediaQuality::Balanced, MediaQuality::default());
|
|
assert_eq!(MediaQuality::Balanced, MediaQuality::from_i32(0).unwrap());
|
|
assert_eq!(MediaQuality::Worse, MediaQuality::from_i32(1).unwrap());
|
|
}
|
|
}
|