Skip to content

Commit

Permalink
feat: Add skipped domains (#1293)
Browse files Browse the repository at this point in the history
* feat: Add skipped domains

* clippy
  • Loading branch information
amaury1093 authored Mar 29, 2023
1 parent ba5c7ec commit 29119fa
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/src/smtp/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub enum SmtpError {
HotmailError(HotmailError),
/// Error when verifying a Microsoft 365 email via HTTP request.
Microsoft365Error(Microsoft365Error),
/// Email is in the `skipped_domains` parameter.
SkippedDomain(String),
}

impl From<SocksError> for SmtpError {
Expand Down
26 changes: 26 additions & 0 deletions core/src/smtp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ pub async fn check_smtp(
input: &CheckEmailInput,
) -> Result<SmtpDetails, SmtpError> {
let host_lowercase = host.to_lowercase().to_string();

if input
.skipped_domains
.iter()
.any(|d| host_lowercase.contains(d))
{
return Err(SmtpError::SkippedDomain(format!(
"Reacher currently cannot verify emails from @{domain}"
)));
}

// FIXME Is this `contains` too lenient?
if input.yahoo_use_api && host_lowercase.contains("yahoo") {
return yahoo::check_yahoo(to_email, input)
Expand Down Expand Up @@ -129,4 +140,19 @@ mod tests {
_ => panic!("check_smtp did not time out"),
}
}

#[test]
fn should_skip_domains() {
let runtime = Runtime::new().unwrap();

let to_email = EmailAddress::from_str("foo@icloud.com").unwrap();
let host = Name::from_str("mx01.mail.icloud.com.").unwrap();
let input = CheckEmailInput::default();

let res = runtime.block_on(check_smtp(&to_email, &host, 25, "icloud.com", &input));
match res {
Err(SmtpError::SkippedDomain(_)) => (),
r => panic!("{:?}", r),
}
}
}
44 changes: 44 additions & 0 deletions core/src/util/input_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,25 @@ pub struct CheckEmailInput {
///
/// Defaults to Opportunistic.
pub smtp_security: SmtpSecurity,
/// **IMPORTANT:** This is a beta feature, and might be completely removed,
/// or moved somewhere else, before the next release.
///
/// List of domains to skip when doing an SMTP connection, because we know
/// they return "unknown". For each string in this list, we check if the MX
/// record **contains** the string; if yes, we return an error saying the
/// SMTP verification is skipped.
///
/// Related issue: https://github.com/reacherhq/check-if-email-exists/issues/937
///
/// ## Example
///
/// If you want to skip Zoho emails, it's good enough to ".zoho.com." to
/// the list. This way it will skip all Zoho emails as their MX records
/// show "mx{N}.zoho.com.". Simply putting "zoho" might give false
/// positives if you have an email provider like "mycustomzoho.com".
///
/// Defaults to: [""]
pub skipped_domains: Vec<String>,
}

impl Default for CheckEmailInput {
Expand All @@ -157,6 +176,21 @@ impl Default for CheckEmailInput {
check_gravatar: false,
haveibeenpwned_api_key: None,
retries: 2,
skipped_domains: vec![
// on @bluewin.ch
// - mx-v02.bluewin.ch.
".bluewin.ch.".into(),
// on @bluewin.ch
// - mxbw-bluewin-ch.hdb-cs04.ellb.ch.
"bluewin-ch.".into(),
// on @gmx.de, @gmx.ch, @gmx.net
".gmx.net.".into(),
// on @icloud.com
".mail.icloud.com.".into(),
// on @web.de
".web.de.".into(),
".zoho.com.".into(),
],
}
}
}
Expand Down Expand Up @@ -305,6 +339,16 @@ impl CheckEmailInput {
self.hotmail_use_headless = use_headless;
self
}

/// **IMPORTANT:** This is a beta feature, and might be completely removed,
/// or moved somewhere else, before the next release.
///
/// List of domains to skip when doing an SMTP connection, because we know
/// they return "unknown".
pub fn set_skipped_domains(&mut self, domains: Vec<String>) -> &mut CheckEmailInput {
self.skipped_domains = domains;
self
}
}

/// An enum to describe how confident we are that the recipient address is
Expand Down

0 comments on commit 29119fa

Please sign in to comment.