-
-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
close #4620 This PR introduces a new core API to parse mailto links into a uniform data format. This could be used to unify the different implementations on the current platforms. To complete this PR we have to decide for which APIs we want to expose this (now) internal API (c, python, json-rpc, etc.), and if we want such an API at all as it doesn't have a corresponding UI-PR and is not _really_ needed.
- Loading branch information
Showing
1 changed file
with
89 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ use mailparse::headers::Headers; | |
use mailparse::MailHeaderMap; | ||
use rand::{thread_rng, Rng}; | ||
use tokio::{fs, io}; | ||
use url::Url; | ||
|
||
use crate::chat::{add_device_msg, add_device_msg_with_importance}; | ||
use crate::constants::{DC_ELLIPSIS, DC_OUTDATED_WARNING_DAYS}; | ||
|
@@ -481,7 +482,43 @@ pub(crate) fn time() -> i64 { | |
.as_secs() as i64 | ||
} | ||
|
||
/// Very simple email address wrapper. | ||
/// Struct containing all mailto information | ||
#[derive(Debug, Default, Eq, PartialEq)] | ||
pub struct MailTo { | ||
pub to: Vec<EmailAddress>, | ||
pub subject: Option<String>, | ||
pub body: Option<String>, | ||
} | ||
|
||
/// Parse mailto urls | ||
pub fn parse_mailto(mailto_url: &str) -> Option<MailTo> { | ||
if let Ok(url) = Url::parse(mailto_url) { | ||
if url.scheme() == "mailto" { | ||
let mut mailto: MailTo = Default::default(); | ||
// Extract the email address | ||
url.path().split(',').for_each(|email| { | ||
if let Ok(email) = EmailAddress::new(email) { | ||
mailto.to.push(email); | ||
} | ||
}); | ||
|
||
// Extract query parameters | ||
for (key, value) in url.query_pairs() { | ||
if key == "subject" { | ||
mailto.subject = Some(value.to_string()); | ||
} else if key == "body" { | ||
mailto.body = Some(value.to_string()); | ||
} | ||
} | ||
Some(mailto) | ||
} else { | ||
None | ||
} | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
/// | ||
/// Represents an email address, right now just the `name@domain` portion. | ||
/// | ||
|
@@ -1283,4 +1320,55 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; | |
assert_eq!(remove_subject_prefix("Fwd: Subject"), "Subject"); | ||
assert_eq!(remove_subject_prefix("Fw: Subject"), "Subject"); | ||
} | ||
|
||
#[test] | ||
fn test_parse_mailto() { | ||
let mailto_url = "mailto:[email protected]"; | ||
let reps = parse_mailto(mailto_url); | ||
assert_eq!( | ||
Some(MailTo { | ||
to: vec![EmailAddress { | ||
local: "someone".to_string(), | ||
domain: "example.com".to_string() | ||
}], | ||
subject: None, | ||
body: None | ||
}), | ||
reps | ||
); | ||
|
||
let mailto_url = "mailto:[email protected]?subject=Hello%20World"; | ||
let reps = parse_mailto(mailto_url); | ||
assert_eq!( | ||
Some(MailTo { | ||
to: vec![EmailAddress { | ||
local: "someone".to_string(), | ||
domain: "example.com".to_string() | ||
}], | ||
subject: Some("Hello World".to_string()), | ||
body: None | ||
}), | ||
reps | ||
); | ||
|
||
let mailto_url = "mailto:[email protected],[email protected]?subject=Hello%20World&body=This%20is%20a%20test"; | ||
let reps = parse_mailto(mailto_url); | ||
assert_eq!( | ||
Some(MailTo { | ||
to: vec![ | ||
EmailAddress { | ||
local: "someone".to_string(), | ||
domain: "example.com".to_string() | ||
}, | ||
EmailAddress { | ||
local: "someoneelse".to_string(), | ||
domain: "example.com".to_string() | ||
} | ||
], | ||
subject: Some("Hello World".to_string()), | ||
body: Some("This is a test".to_string()) | ||
}), | ||
reps | ||
); | ||
} | ||
} |