Skip to content

Commit

Permalink
fix(core): Headless check for Microsoft365 too (reacherhq#1346)
Browse files Browse the repository at this point in the history
* fix(core): Headless check for Microsoft365 too

* Remove SMTP_TIMEOUT env var
  • Loading branch information
amaury1093 authored and juhniorsantos committed Apr 11, 2024
1 parent 4a43236 commit b2d84be
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 23 deletions.
1 change: 0 additions & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ These are the environment variables used to configure the HTTP server. To pass t
| `RCH_HTTP_HOST` | No | The host name to bind the HTTP server to. | `127.0.0.1` |
| `PORT` | No | The port to bind the HTTP server to, often populated by the cloud provider. | `8080` |
| `RCH_HOTMAIL_USE_HEADLESS` | No | Set to a running WebDriver process endpoint (e.g. `http://localhost:4444`) to use a headless navigator to Hotmail's password recovery page to check Hotmail/Outlook addresses. We recommend `chromedriver` as it allows parallel requests. | not defined |
| `RCH_SMTP_TIMEOUT` | No | The default timeout of each SMTP connection, in seconds. Can be overwritten in each request using the `smtp_timeout` field. | 10s |
| `RCH_SENTRY_DSN` | No | If set, bug reports will be sent to this [Sentry](https://sentry.io) DSN. | not defined |
| `RCH_HEADER_SECRET` | No | If set, then all HTTP requests must have the `x-reacher-secret` header set to this value. This is used to protect the backend against public unwanted HTTP requests. | undefined |
| `RCH_DATABASE_MAX_CONNECTIONS` | No | (Bulk) Connections created for the database pool | 5 |
Expand Down
25 changes: 25 additions & 0 deletions backend/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,31 @@ use super::sentry_util;
/// Same as `check-if-email-exists`'s check email, but adds some additional
/// inputs and error handling.
pub async fn check_email(input: CheckEmailInput) -> CheckEmailOutput {
let hotmail_use_headless = env::var("RCH_HOTMAIL_USE_HEADLESS").ok();
let 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(),
];

let input = CheckEmailInput {
// If we want to override core check-if-email-exists's default values
// for CheckEmailInput for the backend, we do it here.
hotmail_use_headless,
skipped_domains,
..input
};

let res = ciee_check_email(&input).await;

sentry_util::log_unknown_errors(&res);
Expand Down
12 changes: 5 additions & 7 deletions core/src/smtp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub use error::*;

use self::{
gmail::is_gmail,
outlook::{is_hotmail, is_outlook},
outlook::{is_microsoft365, is_outlook},
yahoo::is_yahoo,
};

Expand Down Expand Up @@ -84,7 +84,7 @@ pub async fn check_smtp(
.await
.map_err(|err| err.into());
}
if input.microsoft365_use_api && is_outlook(&host_lowercase) {
if input.microsoft365_use_api && is_microsoft365(&host_lowercase) {
match outlook::microsoft365::check_microsoft365_api(to_email, input).await {
Ok(Some(smtp_details)) => return Ok(smtp_details),
// Continue in the event of an error/ambiguous result.
Expand All @@ -101,10 +101,7 @@ pub async fn check_smtp(
}
#[cfg(feature = "headless")]
if let Some(webdriver) = &input.hotmail_use_headless {
// The password recovery page do not always work with Microsoft 365
// addresses. So we only test with @hotmail and @outlook addresses.
// ref: https://github.com/reacherhq/check-if-email-exists/issues/1185
if is_hotmail(&host_lowercase) {
if is_outlook(&host_lowercase) {
return outlook::hotmail::check_password_recovery(to_email, webdriver)
.await
.map_err(|err| err.into());
Expand Down Expand Up @@ -144,7 +141,8 @@ mod tests {

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 mut input = CheckEmailInput::default();
input.set_skipped_domains(vec![".mail.icloud.com.".into()]);

let res = runtime.block_on(check_smtp(&to_email, &host, 25, "icloud.com", &input));
match res {
Expand Down
5 changes: 5 additions & 0 deletions core/src/smtp/outlook/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ pub fn is_hotmail(host: &str) -> bool {
host.to_lowercase()
.ends_with(".olc.protection.outlook.com.")
}

/// Check if an address is a Microsoft365 email address.
pub fn is_microsoft365(host: &str) -> bool {
is_outlook(host) && !is_hotmail(host)
}
16 changes: 1 addition & 15 deletions core/src/util/input_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,21 +176,7 @@ 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(),
],
skipped_domains: vec![],
}
}
}
Expand Down

0 comments on commit b2d84be

Please sign in to comment.