From 04f863e2f393704ef7468f1149bbec6833a07208 Mon Sep 17 00:00:00 2001 From: Bailey Townsend Date: Mon, 2 Mar 2026 20:33:50 -0600 Subject: [PATCH] split up some code --- Cargo.lock | 52 +++++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 2 +- src/mailer.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 46 ++++----------------------------------------- 4 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 src/mailer.rs diff --git a/Cargo.lock b/Cargo.lock index 9c63f7c..a499082 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,6 +84,29 @@ dependencies = [ "object", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-compression" version = "0.4.36" @@ -139,16 +162,16 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.1.2", + "rustix", "slab", "windows-sys 0.61.2", ] [[package]] name = "async-lock" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ "event-listener 5.4.1", "event-listener-strategy", @@ -170,7 +193,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.1", "futures-lite", - "rustix 1.1.2", + "rustix", ] [[package]] @@ -185,7 +208,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.2", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -2315,6 +2338,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + [[package]] name = "litemap" version = "0.8.1" @@ -2335,6 +2364,9 @@ name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +dependencies = [ + "value-bag", +] [[package]] name = "loom" @@ -2920,7 +2952,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.2", + "rustix", "windows-sys 0.61.2", ] @@ -3417,15 +3449,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.59.0", + "linux-raw-sys", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f791277..dfa48ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ scrypt = "0.11" #Leaveing these two cause I think it is needed by the email crate for ssl aws-lc-rs = "1.15.2" rustls = { version = "0.23", default-features = false, features = ["tls12", "std", "logging", "aws_lc_rs"] } -lettre = { version = "0.11", default-features = false, features = ["builder", "webpki-roots", "rustls", "aws-lc-rs", "smtp-transport", "tokio1", "tokio1-rustls"] } +lettre = { version = "0.11", default-features = false, features = ["builder", "webpki-roots", "rustls", "aws-lc-rs", "smtp-transport", "sendmail-transport", "tokio1", "tokio1-rustls"] } handlebars = { version = "6.4.0", features = ["rust-embed"] } rust-embed = "8.9.0" axum-template = { version = "3.0.0", features = ["handlebars"] } diff --git a/src/mailer.rs b/src/mailer.rs new file mode 100644 index 0000000..11b9bc9 --- /dev/null +++ b/src/mailer.rs @@ -0,0 +1,46 @@ +use anyhow::Context; +use lettre::{AsyncSendmailTransport, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor}; +use std::env; +use url::Url; + +pub enum Mailer { + Smtp(AsyncSmtpTransport), + Sendmail(AsyncSendmailTransport), +} + +impl Mailer { + pub async fn send(&self, msg: Message) -> anyhow::Result<()> { + match self { + Mailer::Smtp(m) => { + m.send(msg).await.context("SMTP send failed")?; + Ok(()) + } + Mailer::Sendmail(m) => { + m.send(msg).await.context("sendmail send failed")?; + Ok(()) + } + } + } +} + +pub fn build_mailer_from_env() -> anyhow::Result { + let raw = env::var("PDS_EMAIL_SMTP_URL") + .context("PDS_EMAIL_SMTP_URL is not set in your pds.env file")?; + + let url = Url::parse(&raw).context("PDS_EMAIL_SMTP_URL is not a valid URL")?; + + let use_sendmail = url.scheme() == "sendmail" + || url + .query_pairs() + .any(|(k, v)| k == "sendmail" && v == "true"); + + if use_sendmail { + Ok(Mailer::Sendmail( + AsyncSendmailTransport::::new(), + )) + } else { + Ok(Mailer::Smtp( + AsyncSmtpTransport::::from_url(raw.as_str())?.build(), + )) + } +} diff --git a/src/main.rs b/src/main.rs index 72eac77..c91cf22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ #![warn(clippy::unwrap_used)] use crate::gate::{get_gate, post_gate}; +use crate::mailer::{Mailer, build_mailer_from_env}; use crate::oauth_provider::sign_in; use crate::xrpc::com_atproto_server::{ create_account, create_session, describe_server, get_session, update_email, }; -use anyhow::{Result, Context}; +use anyhow::Result; use axum::{ Router, body::Body, @@ -19,7 +20,6 @@ use handlebars::Handlebars; use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor}; use jacquard_common::types::did::Did; use jacquard_identity::{PublicResolver, resolver::PlcSource}; -use lettre::{AsyncTransport, AsyncSmtpTransport, AsyncSendmailTransport, Message, Tokio1Executor}; use rand::Rng; use rust_embed::RustEmbed; use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode}; @@ -37,11 +37,11 @@ use tower_http::{ }; use tracing::log; use tracing_subscriber::{EnvFilter, fmt, prelude::*}; -use url::Url; mod auth; mod gate; pub mod helpers; +pub mod mailer; mod middleware; mod oauth_provider; mod xrpc; @@ -160,45 +160,6 @@ pub struct AppState { app_config: AppConfig, } -pub enum Mailer { - Smtp(AsyncSmtpTransport), - Sendmail(AsyncSendmailTransport), -} - -impl Mailer { - pub async fn send(&self, msg: Message) -> Result<()> { - match self { - Mailer::Smtp(m) => { - m.send(msg).await.context("SMTP send failed")?; - Ok(()) - } - Mailer::Sendmail(m) => { - m.send(msg).await.context("sendmail send failed")?; - Ok(()) - } - } - } -} - -fn build_mailer_from_env() -> Result { - let raw = env::var("PDS_EMAIL_SMTP_URL") - .context("PDS_EMAIL_SMTP_URL is not set in your pds.env file")?; - - let url = Url::parse(&raw).context("PDS_EMAIL_SMTP_URL is not a valid URL")?; - - let use_sendmail = url.scheme() == "sendmail" - || url.query_pairs().any(|(k, v)| k == "sendmail" && v == "true"); - - if use_sendmail { - Ok(Mailer::Sendmail(AsyncSendmailTransport::::new())) - } else { - Ok(Mailer::Smtp( - AsyncSmtpTransport::::from_url(raw.as_str())? - .build(), - )) - } -} - async fn root_handler() -> impl axum::response::IntoResponse { let body = r" @@ -254,6 +215,7 @@ async fn main() -> Result<(), Box> { let account_db_url = format!("{pds_root}/account.sqlite"); let account_options = SqliteConnectOptions::new() + .journal_mode(SqliteJournalMode::Wal) .filename(account_db_url) .busy_timeout(Duration::from_secs(5)); -- 2.51.2