Expand description
§Neo Email
neo-email
is a library for build email services in a modern and safe way.
§Example
use std::net::SocketAddr;
use std::sync::Arc;
use neo_email::connection::SMTPConnection;
use neo_email::controllers::on_auth::OnAuthController;
use neo_email::controllers::on_email::OnEmailController;
use neo_email::headers::EmailHeaders;
use neo_email::mail::Mail;
use neo_email::message::Message;
use neo_email::server::SMTPServer;
use neo_email::status_code::StatusCodes;
use tokio::sync::Mutex;
#[derive(Debug, Clone, Default)]
pub struct ConnectionState {
pub authenticated: bool,
}
#[tokio::main]
async fn main() {
let addr = SocketAddr::from(([127, 0, 0, 1], 2526));
// Create the server
SMTPServer::<ConnectionState>::new()
// Set the number of workers to 1
.workers(1)
// Set an controller to dispatch when an authentication is received
.on_auth(OnAuthController::new(on_auth))
// Set an controller to dispatch when an email is received
.on_email(OnEmailController::new(on_email))
// Bind the server to the address
.bind(addr)
.await
.unwrap()
// Run the server
.run()
.await;
}
// This function is called when an authentication is received
// Ok(Message) for successful authentication
// Err(Message) for failed authentication and the connection will be closed peacefully
pub async fn on_auth(conn: Arc<Mutex<SMTPConnection<ConnectionState>>>, _data: String) -> Result<Message, Message> {
let conn = conn.lock().await;
let mut state = conn.state.lock().await;
// What is data?
// Data is the raw data after command AUTH, example
// Original Raw Command: AUTH PLAIN AHlvdXJfdXNlcm5hbWUAeW91cl9wYXNzd29yZA==
// Data: PLAIN AHlvdXJfdXNlcm5hbWUAeW91cl9wYXNzd29yZA==
// Using our custom state
state.authenticated = true;
// We can also decide to not authenticate the user
Ok(Message::builder()
.status(neo_email::status_code::StatusCodes::AuthenticationSuccessful)
.message("Authenticated".to_string())
.build())
}
// This function is called when an email is received
// The mail is a struct that contains the email data, in this case the raw email data in a Vec<u8>
// Headers are parsed in a hashmap and the body is a Vec<u8>
pub async fn on_email(conn: Arc<Mutex<SMTPConnection<ConnectionState>>>, mail: Mail<Vec<u8>>) -> Message {
let conn = conn.lock().await;
let state = conn.state.lock().await;
// Extract headers
let headers = mail.headers.clone(); // get the hashmap
let _subject = headers.get(&EmailHeaders::Subject).unwrap(); // get the Option<Subject> header
// Check if the user is authenticated from state set in on_auth
if !state.authenticated {
return Message::builder()
.status(StatusCodes::AuthenticationCredetialsInvalid)
.message("Authentication required".to_string())
.build();
}
log::info!("Received email: {:?}", mail);
Message::builder()
.status(neo_email::status_code::StatusCodes::OK)
.message("Email received".to_string())
.build()
}
§Features
- Modern and safe
- Easy to use
- Customizable
- Async
- Multi-threaded
- Custom controllers
- Custom states
§Features Flags
smtp-experimental-headers
- Enable experimental mail headers featuresmtp-experimental
- Enable SMTP experimental features (includessmtp-experimental-headers
)spf-experimental
- Enable Sender Policy Framework experimental featuresdkim-experimental
- Enable DomainKeys Identified Mail experimental features (includessha1
,sha2
,base64
)` (NOT AVAILABLE)utilities-experimental
- Enable utilities experimental features (includesspf-experimental
anddkim-experimental
)experimental
- Enable all experimental features (includesutilities-experimental
)
§License
Licensed under the MIT license. See LICENSE for more information.
Modules§
- client_
message - Client Message
- command
- Command
- connection
- Connection
- controllers
- Controllers
- errors
- Errors
- handle_
connection - Handle Connection
- headers
- Headers
- message
- Message
- server
- Server
- status_
code - Status Code
- utilities
- Utilities