diff --git a/backend/openapi.json b/backend/openapi.json index 0b27f6253..3b3e17562 100644 --- a/backend/openapi.json +++ b/backend/openapi.json @@ -59,7 +59,7 @@ "is_deliverable": false, "is_disabled": false, "method": { - "type": "SmtpConnection", + "type": "Smtp", "host": "alt3.gmail-smtp-in.l.google.com." } }, @@ -279,7 +279,7 @@ "description": "Has this email address been disabled by the email provider?" }, "method": { - "$ref": "#/components/schemas/SmtpMethod" + "$ref": "#/components/schemas/VerifMethod" } }, "required": [ @@ -326,7 +326,7 @@ "HotmailVerifyMethod": { "type": "string", "x-stoplight": { - "id": "o6xocxf6tktur" + "id": "tiy37w0jp5x13" }, "title": "HotmailVerifyMethod", "enum": ["Api", "Headless", "Smtp"], @@ -335,7 +335,7 @@ "GmailVerifyMethod": { "type": "string", "x-stoplight": { - "id": "jbq83vpkfcmth" + "id": "2p7yqzxi6n3bj" }, "title": "GmailVerifyMethod", "enum": ["Api", "Smtp"], @@ -435,7 +435,7 @@ "Duration": { "title": "Duration", "x-stoplight": { - "id": "0s9q75wxim1iw" + "id": "kwbhwi9fkpg6q" }, "type": "object", "description": "An object representing a duration (seconds + nanoseconds).", @@ -454,20 +454,20 @@ "DebugDetails": { "title": "DebugDetails", "x-stoplight": { - "id": "ndv3lpqeuypvn" + "id": "jhror15zeepgx" }, "type": "object", "properties": { "start_time": { "type": "string", "x-stoplight": { - "id": "hxi446woaebm1" + "id": "ms8ftx9vwth1a" } }, "end_time": { "type": "string", "x-stoplight": { - "id": "m4p986hhzuzbl" + "id": "g2kydtwtmr7po" } }, "duration": { @@ -476,36 +476,38 @@ "server_ip": { "type": "string", "x-stoplight": { - "id": "ld3cp67qd2nx8" + "id": "ktn104e8oyu6d" } } } }, - "SmtpMethod": { - "title": "SmtpMethod", + "VerifMethod": { + "title": "VerifMethod", "x-stoplight": { - "id": "hbfxytnpskv3z" + "id": "yfa2hjmyy321x" }, "type": "object", "properties": { "type": { "x-stoplight": { - "id": "leobepj9orvp2" + "id": "dzmw4acub9xp6" }, - "enum": [ - "SmtpConnection", - "Headless", - "Api", - "Skipped" - ], + "enum": ["Smtp", "Headless", "Api", "Skipped"], "description": "The method used to perform the email verification" }, "host": { "type": "string", "x-stoplight": { - "id": "25lammyt3h5qc" + "id": "nvnjrm1137x96" }, "description": "If `type` is `SmtpConnection`, the hostname that Reacher connected to." + }, + "port": { + "type": "number", + "x-stoplight": { + "id": "xpxzvllzxxyyn" + }, + "description": "If `type` is `SmtpConnection`, the port that Reacher connected to." } }, "required": ["type"] diff --git a/backend/tests/check_email.rs b/backend/tests/check_email.rs index 7f99ffc6b..e2c46c793 100644 --- a/backend/tests/check_email.rs +++ b/backend/tests/check_email.rs @@ -23,8 +23,8 @@ use reacher_backend::routes::create_routes; use warp::http::StatusCode; use warp::test::request; -const FOO_BAR_RESPONSE: &str = r#"{"input":"foo@bar","is_reachable":"invalid","misc":{"is_disposable":false,"is_role_account":false,"gravatar_url":null,"haveibeenpwned":null},"mx":{"accepts_mail":false,"records":[]},"smtp":{"can_connect_smtp":false,"has_full_inbox":false,"is_catch_all":false,"is_deliverable":false,"is_disabled":false,"method":{"type":"Skipped"}},"syntax":{"address":null,"domain":"","is_valid_syntax":false,"username":"","normalized_email":null,"suggestion":null}"#; -const FOO_BAR_BAZ_RESPONSE: &str = r#"{"input":"foo@bar.baz","is_reachable":"invalid","misc":{"is_disposable":false,"is_role_account":false,"gravatar_url":null,"haveibeenpwned":null},"mx":{"accepts_mail":false,"records":[]},"smtp":{"can_connect_smtp":false,"has_full_inbox":false,"is_catch_all":false,"is_deliverable":false,"is_disabled":false,"method":{"type":"Skipped"}},"syntax":{"address":"foo@bar.baz","domain":"bar.baz","is_valid_syntax":true,"username":"foo","normalized_email":"foo@bar.baz","suggestion":null}"#; +const FOO_BAR_RESPONSE: &str = r#"{"input":"foo@bar","is_reachable":"invalid","misc":{"is_disposable":false,"is_role_account":false,"gravatar_url":null,"haveibeenpwned":null},"mx":{"accepts_mail":false,"records":[]},"smtp":{"can_connect_smtp":false,"has_full_inbox":false,"is_catch_all":false,"is_deliverable":false,"is_disabled":false,"verif_method":{"type":"Skipped"}},"syntax":{"address":null,"domain":"","is_valid_syntax":false,"username":"","normalized_email":null,"suggestion":null}"#; +const FOO_BAR_BAZ_RESPONSE: &str = r#"{"input":"foo@bar.baz","is_reachable":"invalid","misc":{"is_disposable":false,"is_role_account":false,"gravatar_url":null,"haveibeenpwned":null},"mx":{"accepts_mail":false,"records":[]},"smtp":{"can_connect_smtp":false,"has_full_inbox":false,"is_catch_all":false,"is_deliverable":false,"is_disabled":false,"verif_method":{"type":"Skipped"}},"syntax":{"address":"foo@bar.baz","domain":"bar.baz","is_valid_syntax":true,"username":"foo","normalized_email":"foo@bar.baz","suggestion":null}"#; #[tokio::test] async fn test_input_foo_bar() { diff --git a/core/src/smtp/connect.rs b/core/src/smtp/connect.rs index 5c6ffb3e0..0bae03857 100644 --- a/core/src/smtp/connect.rs +++ b/core/src/smtp/connect.rs @@ -26,7 +26,7 @@ use std::iter; use std::str::FromStr; use std::time::Duration; -use super::{parser, SmtpConnection, SmtpMethod}; +use super::{parser, SmtpConnection, VerifMethod}; use super::{SmtpDetails, SmtpError}; use crate::{ rules::{has_rule, Rule}, @@ -334,8 +334,9 @@ async fn check_smtp_without_retry( is_catch_all, is_deliverable: deliverability.is_deliverable, is_disabled: deliverability.is_disabled, - method: SmtpMethod::SmtpConnection(SmtpConnection { + verif_method: VerifMethod::Smtp(SmtpConnection { host: host.to_string(), + port, }), }) } diff --git a/core/src/smtp/mod.rs b/core/src/smtp/mod.rs index bfc0434fe..731bad6d4 100644 --- a/core/src/smtp/mod.rs +++ b/core/src/smtp/mod.rs @@ -45,15 +45,22 @@ use self::{ #[derive(Debug, Default, Deserialize, Serialize)] pub struct SmtpConnection { + /// The host we connected to via SMTP. pub host: String, + /// The port we connected to via SMTP. + pub port: u16, } #[derive(Debug, Default, Deserialize, Serialize)] #[serde(tag = "type")] -pub enum SmtpMethod { - SmtpConnection(SmtpConnection), +pub enum VerifMethod { + /// Email verification was done via SMTP. + Smtp(SmtpConnection), + /// Email verification was done via an HTTP API. Api, + /// Email verification was done via a headless browser. Headless, + /// Email verification was skipped. #[default] Skipped, } @@ -71,7 +78,7 @@ pub struct SmtpDetails { pub is_deliverable: bool, /// Is the email blocked or disabled by the provider? pub is_disabled: bool, - pub method: SmtpMethod, + pub verif_method: VerifMethod, } /// Get all email details we can from one single `EmailAddress`, without diff --git a/core/src/smtp/outlook/headless.rs b/core/src/smtp/outlook/headless.rs index 64690ecc4..92bed7092 100644 --- a/core/src/smtp/outlook/headless.rs +++ b/core/src/smtp/outlook/headless.rs @@ -23,7 +23,7 @@ use futures::TryFutureExt; use crate::{ smtp::{ headless::{create_headless_client, HeadlessError}, - SmtpDetails, SmtpMethod, + SmtpDetails, VerifMethod, }, LOG_TARGET, }; @@ -102,7 +102,7 @@ pub async fn check_password_recovery( is_catch_all: false, is_deliverable, is_disabled: false, - method: SmtpMethod::Headless, + verif_method: VerifMethod::Headless, }) } diff --git a/core/src/smtp/outlook/microsoft365.rs b/core/src/smtp/outlook/microsoft365.rs index dc5fe265c..4117dd2ad 100644 --- a/core/src/smtp/outlook/microsoft365.rs +++ b/core/src/smtp/outlook/microsoft365.rs @@ -19,7 +19,7 @@ use reqwest::Error as ReqwestError; use serde::Serialize; use crate::{ - smtp::{http_api::create_client, SmtpDetails, SmtpMethod}, + smtp::{http_api::create_client, SmtpDetails, VerifMethod}, util::ser_with_display::ser_with_display, CheckEmailInput, LOG_TARGET, }; @@ -85,7 +85,7 @@ pub async fn check_microsoft365_api( Ok(Some(SmtpDetails { can_connect_smtp: true, is_deliverable: true, - method: SmtpMethod::Api, + verif_method: VerifMethod::Api, ..Default::default() })) } else { diff --git a/core/src/smtp/yahoo/api.rs b/core/src/smtp/yahoo/api.rs index c71b96d2c..6f8c85fea 100644 --- a/core/src/smtp/yahoo/api.rs +++ b/core/src/smtp/yahoo/api.rs @@ -16,7 +16,7 @@ use super::YahooError; use crate::{ - smtp::{http_api::create_client, SmtpDetails, SmtpMethod}, + smtp::{http_api::create_client, SmtpDetails, VerifMethod}, util::{constants::LOG_TARGET, input_output::CheckEmailInput}, }; use regex::Regex; @@ -168,7 +168,7 @@ pub async fn check_api(to_email: &str, input: &CheckEmailInput) -> Result Result