diff --git a/.env b/.env index 8b21e48..34ba4c4 100644 --- a/.env +++ b/.env @@ -4,3 +4,8 @@ RUST_LOG=debug KEY_SECRET="NEPJs#8jjn8SK8GC7QEC^*P844UgsyEbQB8mRWXkT%3mPrwewZoc25MMby9H#R*w2KzaQgMkk#Pif$kxrLy*N5L!Ch%jxbWoa%gb" JWT_SECRET="42^iFq&ZnQbUf!hwGWXd&CpyY6QQyJmkPU%esFCvne5&Ejcb3nJ4&GyHZp!MArZLf^9*5c6!!VgM$iZ8T%d#&bWTi&xbZk2S@4RN" PGDATESTYLE= +SENDMAIL_SECRET=1a9dd7ba41edc5fd030e2281c52b7b49-02fa25a3-02e6d387 +SENDMAIL_KEY_ID=02fa25a3-02e6d387 +SMTP_HOST=smtp.mailgun.org +SMTP_USER=bazzar@sandbox69e5633f64264d8c973b3c82408dfb17.mailgun.org +SMTP_PASSWORD=49940d86d0742959f677c74cc542abb0-02fa25a3-f65fc7b4 diff --git a/Cargo.lock b/Cargo.lock index f5eea45..ff5e836 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -609,6 +609,7 @@ dependencies = [ "hmac", "jemallocator", "jwt", + "lettre", "log", "oauth2", "parking_lot 0.12.0", @@ -1046,6 +1047,15 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "email-encoding" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6690291166824e467790ac08ba42f241791567e8337bbf00c5a6e87889629f98" +dependencies = [ + "base64", +] + [[package]] name = "encoding_rs" version = "0.8.31" @@ -1080,6 +1090,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + [[package]] name = "firestorm" version = "0.5.0" @@ -1398,6 +1417,17 @@ dependencies = [ "digest 0.10.3", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "http" version = "0.2.6" @@ -1631,6 +1661,34 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lettre" +version = "0.10.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5144148f337be14dabfc0f0d85b691a68ac6c77ef22a5c47c5504b70a7c9fcf3" +dependencies = [ + "async-trait", + "base64", + "email-encoding", + "fastrand", + "futures-io", + "futures-util", + "hostname", + "httpdate", + "idna", + "mime", + "nom", + "once_cell", + "quoted_printable", + "regex", + "rustls 0.20.4", + "rustls-pemfile", + "tokio", + "tokio-rustls 0.23.3", + "tracing", + "webpki-roots 0.22.3", +] + [[package]] name = "libc" version = "0.2.123" @@ -1714,6 +1772,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matches" version = "0.1.9" @@ -2205,6 +2269,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quoted_printable" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f" + [[package]] name = "rand" version = "0.8.5" diff --git a/api/Cargo.toml b/api/Cargo.toml index 3b4dd8b..16d386b 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -62,3 +62,5 @@ oauth2 = { version = "4.1.0", features = [] } async-trait = { version = "0.1.53", features = [] } jemallocator = { version = "0.3.2", features = [] } + +lettre = { version = "0.10.0-rc.5", default-features = false, features = ["tracing", "smtp-transport", "hostname", "builder", "tokio1-rustls-tls"] } diff --git a/api/src/actors/email_manager.rs b/api/src/actors/email_manager.rs new file mode 100644 index 0000000..7b800bf --- /dev/null +++ b/api/src/actors/email_manager.rs @@ -0,0 +1,32 @@ +use lettre::transport::smtp::authentication::Credentials; +use lettre::{AsyncSmtpTransport, Tokio1Executor}; + +#[derive(Debug, thiserror::Error)] +pub enum Error {} + +pub type Result = std::result::Result; + +pub struct EmailManager { + mailer: AsyncSmtpTransport, +} + +impl actix::Actor for EmailManager { + type Context = actix::Context; +} + +impl EmailManager { + pub fn build() -> Result { + let smtp_credentials = Credentials::new( + std::env::var("SMTP_USER").expect("Missing SMTP_USER variable"), + std::env::var("SMTP_PASSWORD").expect("Missing SMTP_PASSWORD variable"), + ); + + let mailer = AsyncSmtpTransport::::relay( + &std::env::var("SMTP_USER").expect("Missing SMTP_USER env variable"), + ) + .expect("Can't construct async smtp mailer") + .credentials(smtp_credentials) + .build(); + Ok(Self { mailer }) + } +} diff --git a/api/src/actors/mod.rs b/api/src/actors/mod.rs index b921207..0e24353 100644 --- a/api/src/actors/mod.rs +++ b/api/src/actors/mod.rs @@ -1,4 +1,5 @@ pub mod cart_manager; pub mod database; +pub mod email_manager; pub mod order_manager; pub mod token_manager;