forked from jmug/stoatchat
Re-write email backend, use SMTP directly.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use reqwest::blocking::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct CaptchaResponse {
|
||||
success: bool
|
||||
success: bool,
|
||||
}
|
||||
|
||||
pub fn verify(user_token: &Option<String>) -> Result<(), String> {
|
||||
|
||||
96
src/util/email.rs
Normal file
96
src/util/email.rs
Normal file
@@ -0,0 +1,96 @@
|
||||
use lettre::message::{header, MultiPart, SinglePart};
|
||||
use lettre::transport::smtp::authentication::Credentials;
|
||||
use lettre::{Message, SmtpTransport, Transport};
|
||||
|
||||
use super::variables::{PUBLIC_URL, SMTP_FROM, SMTP_HOST, SMTP_PASSWORD, SMTP_USERNAME};
|
||||
|
||||
lazy_static! {
|
||||
static ref MAILER: lettre::transport::smtp::SmtpTransport =
|
||||
SmtpTransport::relay(SMTP_HOST.as_ref())
|
||||
.unwrap()
|
||||
.credentials(Credentials::new(
|
||||
SMTP_USERNAME.to_string(),
|
||||
SMTP_PASSWORD.to_string()
|
||||
))
|
||||
.build();
|
||||
}
|
||||
|
||||
fn send(message: Message) -> Result<(), String> {
|
||||
MAILER
|
||||
.send(&message)
|
||||
.map_err(|err| format!("Failed to send email! {}", err.to_string()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_multipart(text: &str, html: &str) -> MultiPart {
|
||||
MultiPart::mixed().multipart(
|
||||
MultiPart::alternative()
|
||||
.singlepart(
|
||||
SinglePart::quoted_printable()
|
||||
.header(header::ContentType(
|
||||
"text/plain; charset=utf8".parse().unwrap(),
|
||||
))
|
||||
.body(text),
|
||||
)
|
||||
.multipart(
|
||||
MultiPart::related().singlepart(
|
||||
SinglePart::eight_bit()
|
||||
.header(header::ContentType(
|
||||
"text/html; charset=utf8".parse().unwrap(),
|
||||
))
|
||||
.body(html),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn send_verification_email(email: String, code: String) -> Result<(), String> {
|
||||
let url = format!("{}/api/account/verify/{}", PUBLIC_URL.to_string(), code);
|
||||
let email = Message::builder()
|
||||
.from(SMTP_FROM.to_string().parse().unwrap())
|
||||
.to(email.parse().unwrap())
|
||||
.subject("Verify your email!")
|
||||
.multipart(generate_multipart(
|
||||
&format!("Verify your email here: {}", url),
|
||||
&format!("<a href=\"{}\">Click to verify your email!</a>", url),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
send(email)
|
||||
}
|
||||
|
||||
pub fn send_password_reset(email: String, code: String) -> Result<(), String> {
|
||||
let url = format!("{}/api/account/reset/{}", PUBLIC_URL.to_string(), code);
|
||||
let email = Message::builder()
|
||||
.from(SMTP_FROM.to_string().parse().unwrap())
|
||||
.to(email.parse().unwrap())
|
||||
.subject("Reset your password.")
|
||||
.multipart(generate_multipart(
|
||||
&format!("Reset your password here: {}", url),
|
||||
&format!("<a href=\"{}\">Click to reset your password!</a>", url),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
send(email)
|
||||
}
|
||||
|
||||
pub fn send_welcome_email(email: String, username: String) -> Result<(), String> {
|
||||
let email = Message::builder()
|
||||
.from(SMTP_FROM.to_string().parse().unwrap())
|
||||
.to(email.parse().unwrap())
|
||||
.subject("Welcome to REVOLT!")
|
||||
.multipart(
|
||||
generate_multipart(
|
||||
&format!("Welcome, {}! You can now use REVOLT.", username),
|
||||
&format!(
|
||||
"<b>Welcome, {}!</b><br/>You can now use REVOLT.<br/><a href=\"{}\">Go to REVOLT</a>",
|
||||
username,
|
||||
PUBLIC_URL.to_string()
|
||||
)
|
||||
)
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
send(email)
|
||||
}
|
||||
@@ -3,6 +3,8 @@ use rand::{distributions::Alphanumeric, Rng};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
pub mod captcha;
|
||||
pub mod email;
|
||||
pub mod variables;
|
||||
|
||||
pub fn vec_to_set<T: Clone + Eq + std::hash::Hash>(data: &[T]) -> HashSet<T> {
|
||||
HashSet::from_iter(data.iter().cloned())
|
||||
|
||||
27
src/util/variables.rs
Normal file
27
src/util/variables.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use std::env;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref MONGO_URI: String =
|
||||
env::var("REVOLT_MONGO_URI").expect("Missing REVOLT_MONGO_URI environment variable.");
|
||||
pub static ref PUBLIC_URL: String =
|
||||
env::var("REVOLT_PUBLIC_URL").expect("Missing REVOLT_PUBLIC_URL environment variable.");
|
||||
pub static ref USE_EMAIL_VERIFICATION: bool = env::var("REVOLT_USE_EMAIL_VERIFICATION").map_or(
|
||||
env::var("REVOLT_SMTP_HOST").is_ok()
|
||||
&& env::var("REVOLT_SMTP_USERNAME").is_ok()
|
||||
&& env::var("REVOLT_SMTP_PASSWORD").is_ok()
|
||||
&& env::var("REVOLT_SMTP_FROM").is_ok(),
|
||||
|v| v == *"1"
|
||||
);
|
||||
pub static ref USE_HCAPTCHA: bool = env::var("REVOLT_HCAPTCHA_KEY").is_ok();
|
||||
pub static ref SMTP_HOST: String =
|
||||
env::var("REVOLT_SMTP_HOST").unwrap_or_else(|_| "".to_string());
|
||||
pub static ref SMTP_USERNAME: String =
|
||||
env::var("SMTP_USERNAME").unwrap_or_else(|_| "".to_string());
|
||||
pub static ref SMTP_PASSWORD: String =
|
||||
env::var("SMTP_PASSWORD").unwrap_or_else(|_| "".to_string());
|
||||
pub static ref SMTP_FROM: String = env::var("SMTP_FROM").unwrap_or_else(|_| "".to_string());
|
||||
pub static ref HCAPTCHA_KEY: String =
|
||||
env::var("REVOLT_HCAPTCHA_KEY").unwrap_or_else(|_| "".to_string());
|
||||
pub static ref WS_HOST: String =
|
||||
env::var("REVOLT_WS_HOST").unwrap_or_else(|_| "0.0.0.0:9999".to_string());
|
||||
}
|
||||
Reference in New Issue
Block a user