Skip to content

Commit

Permalink
backend/docker: Add sender email and name to also brand emails.
Browse files Browse the repository at this point in the history
This commit also contains changes to use utils::send_email everywhere emails get sent.
  • Loading branch information
ffreddow committed Jan 28, 2025
1 parent 486a40e commit e195a1b
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 83 deletions.
10 changes: 6 additions & 4 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
DATABASE_URL=
JWT_SECRET=
MAIL_USER=
MAIL_PASS=
MAIL_RELAY=
MAIL_RELAY_PORT=
EMAIL_USER=
EMAIL_PASS=
EMAIL_RELAY=
EMAIL_RELAY_PORT=
FRONTEND_URL=
SENDER_EMAIL=
SENDER_NAME=
8 changes: 6 additions & 2 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ pub struct AppState {
pub jwt_secret: String,
pub mailer: SmtpTransport,
pub frontend_url: String,
pub sender_email: String,
pub sender_name: String,
}

pub fn clean_recovery_tokens(
Expand Down Expand Up @@ -293,8 +295,8 @@ pub(crate) mod tests {
) -> web::Data<AppState> {
let pool = pool.unwrap_or_else(|| db_connector::test_connection_pool());

let mail = std::env::var("MAIL_USER").expect("MAIL must be set");
let pass = std::env::var("MAIL_PASS").expect("MAIL_PASS must be set");
let mail = std::env::var("EMAIL_USER").expect("EMAIL must be set");
let pass = std::env::var("EMAIL_PASS").expect("EMAIL_PASS must be set");
let mailer = SmtpTransport::relay("mail.tinkerforge.com")
.unwrap()
.port(465)
Expand All @@ -306,6 +308,8 @@ pub(crate) mod tests {
jwt_secret: std::env::var("JWT_SECRET").expect("JWT_SECRET must be set!"),
mailer,
frontend_url: std::env::var("FRONTEND_URL").expect("FRONTEND_URL must be set!"),
sender_email: String::new(),
sender_name: String::new(),
};

web::Data::new(state)
Expand Down
17 changes: 11 additions & 6 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,24 +128,29 @@ async fn main() -> std::io::Result<()> {

reset_wg_keys(&pool);

let mail = std::env::var("MAIL_USER").expect("MAIL_USER must be set");
let pass = std::env::var("MAIL_PASS").expect("MAIL_PASS must be set");
let relay = std::env::var("MAIL_RELAY").expect("MAIL_RELAY must be set");
let port: u16 = std::env::var("MAIL_RELAY_PORT")
.expect("MAIL_RELAY_PORT must be set")
let email = std::env::var("EMAIL_USER").expect("EMAIL_USER must be set");
let pass = std::env::var("EMAIL_PASS").expect("EMAIL_PASS must be set");
let relay = std::env::var("EMAIL_RELAY").expect("EMAIL_RELAY must be set");
let port: u16 = std::env::var("EMAIL_RELAY_PORT")
.expect("EMAIL_RELAY_PORT must be set")
.parse()
.unwrap();
let mailer = SmtpTransport::starttls_relay(&relay)
.unwrap()
.port(port)
.credentials(Credentials::new(mail, pass))
.credentials(Credentials::new(email, pass))
.build();

let sender_email = std::env::var("SENDER_EMAIL").expect("SENDER_EMAIL must be set");
let sender_name = std::env::var("SENDER_NAME").expect("SENDER_NAME must be set");

let state = web::Data::new(AppState {
pool: pool.clone(),
jwt_secret: std::env::var("JWT_SECRET").expect("JWT_SECRET must be set!"),
mailer,
frontend_url: std::env::var("FRONTEND_URL").expect("FRONTEND_URL must be set!"),
sender_email,
sender_name,
});

monitoring::start_monitoring(state.clone());
Expand Down
12 changes: 3 additions & 9 deletions backend/src/monitoring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use std::time::Duration;
use actix_web::web;
use anyhow::Error;
use askama::Template;
use backend::utils;
use backend::{utils::get_connection, AppState};
use diesel::prelude::*;
use diesel::{
r2d2::{ConnectionManager, PooledConnection},
PgConnection, QueryDsl,
};
use lettre::{message::header::ContentType, Message, Transport};

#[derive(Template)]
#[template(path = "monitoring.html")]
Expand Down Expand Up @@ -38,14 +38,8 @@ fn send_mail(state: &web::Data<AppState>, num_users: i64, num_chargers: i64) ->
server_name: &std::env::var("SERVER_NAME")?,
};
let body = body.render()?;
let mail = Message::builder()
.from("Warp <warp@tinkerforge.com>".parse()?)
.to(std::env::var("MONITORING_MAIL")?.parse()?)
.subject("Monitoring mail")
.header(ContentType::TEXT_HTML)
.body(body)?;

state.mailer.send(&mail)?;
utils::send_email(&std::env::var("MONITORING_EMAIL")?, "Monitoring mail", body, state);

Ok(())
}
Expand All @@ -55,7 +49,7 @@ pub fn start_monitoring(state: web::Data<AppState>) {
log::info!("Monitoring Mailer disabled");
return;
}
if let Err(_) = std::env::var("MONITORING_MAIL") {
if let Err(_) = std::env::var("MONITORING_EMAIL") {
log::info!("Monitoring Mailer disabled");
return;
}
Expand Down
30 changes: 8 additions & 22 deletions backend/src/routes/auth/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ use askama::Template;
use chrono::Days;
use db_connector::models::{users::User, verification::Verification};
use diesel::{prelude::*, result::Error::NotFound};
use lettre::{message::header::ContentType, Message, SmtpTransport, Transport};
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use validator::Validate;

use crate::{
error::Error,
routes::auth::VERIFICATION_EXPIRATION_DAYS,
utils::{get_connection, web_block_unpacked},
utils::{self, get_connection, web_block_unpacked},
AppState,
};

Expand Down Expand Up @@ -87,20 +86,19 @@ fn send_verification_mail(
name: String,
id: Verification,
email: String,
mailer: SmtpTransport,
frontend_url: String,
state: web::Data<AppState>,
lang: String,
) -> Result<(), actix_web::Error> {
let link = format!("{}/api/auth/verify?id={}", frontend_url, id.id.to_string());
let link = format!("{}/api/auth/verify?id={}", state.frontend_url, id.id.to_string());

let body = match lang.as_str() {
let (body, subject) = match lang.as_str() {
"de" | "de-DE" => {
let template = VerifyEmailDETemplate {
name: &name,
link: &link,
};
match template.render() {
Ok(body) => body,
Ok(body) => (body, "Email verifizieren"),
Err(_err) => return Err(Error::InternalError.into()),
}
}
Expand All @@ -110,24 +108,13 @@ fn send_verification_mail(
link: &link,
};
match template.render() {
Ok(body) => body,
Ok(body) => (body, "Verify email"),
Err(_err) => return Err(Error::InternalError.into()),
}
}
};

let email = Message::builder()
.from("Warp <warp@tinkerforge.com>".parse().unwrap())
.to(email.parse().unwrap())
.subject("Verify email")
.header(ContentType::TEXT_HTML)
.body(body)
.unwrap();

match mailer.send(&email) {
Ok(_) => println!("Email sent successfully!"),
Err(e) => panic!("Could not send email: {e:?}"),
}
utils::send_email(&email, subject, body, &state);

Ok(())
}
Expand Down Expand Up @@ -230,8 +217,7 @@ pub async fn register(
user_insert.name,
verify,
data.email.clone(),
state.mailer.clone(),
state.frontend_url.clone(),
state.clone(),
lang.into(),
)
.ok();
Expand Down
32 changes: 8 additions & 24 deletions backend/src/routes/auth/start_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use actix_web::{get, web, HttpResponse, Responder};
use askama::Template;
use db_connector::models::recovery_tokens::RecoveryToken;
use diesel::prelude::*;
use lettre::{message::header::ContentType, Message, SmtpTransport, Transport};
use serde::Deserialize;
use utoipa::IntoParams;
use uuid::Uuid;

use crate::{
error::Error,
routes::user::{get_user, get_user_id},
utils::{get_connection, web_block_unpacked},
utils::{self, get_connection, web_block_unpacked},
AppState,
};

Expand Down Expand Up @@ -38,23 +37,22 @@ fn send_email(
name: String,
token_id: Uuid,
email: String,
mailer: SmtpTransport,
frontend_url: String,
state: web::Data<AppState>,
lang: String,
) -> actix_web::Result<()> {
let link = format!(
"{}/recovery?token={}&email={}",
frontend_url, token_id, email
state.frontend_url, token_id, email
);

let body = match lang.as_str() {
let (body, subject) = match lang.as_str() {
"de" | "de-DE" => {
let template = StartRecoveryDETemplate {
name: &name,
link: &link,
};
match template.render() {
Ok(b) => b,
Ok(b) => (b, "Passwort Wiederherstellung"),
Err(_err) => return Err(Error::InternalError.into()),
}
}
Expand All @@ -64,26 +62,13 @@ fn send_email(
link: &link,
};
match template.render() {
Ok(b) => b,
Ok(b) => (b, "Password Recovery"),
Err(_err) => return Err(Error::InternalError.into()),
}
}
};

let mail = Message::builder()
.from("Warp <warp@tinkerforge.com>".parse().unwrap())
.to(email.parse().unwrap())
.subject("Password Recovery")
.header(ContentType::TEXT_HTML)
.body(body)
.unwrap();
match mailer.send(&mail) {
Ok(_) => log::debug!("Send password recovery mail was successful."),
Err(err) => {
log::error!("Failed to send: {}", err);
return Err(Error::InternalError.into());
}
}
utils::send_email(&email, subject, body, &state);

Ok(())
}
Expand Down Expand Up @@ -147,8 +132,7 @@ pub async fn start_recovery(
user.name,
token_id,
email,
state.mailer.clone(),
state.frontend_url.clone(),
state.clone(),
lang.into(),
)
.ok();
Expand Down
8 changes: 6 additions & 2 deletions backend/src/routes/user/update_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ use validator::Validate;
#[template(path = "email_change_notification_en.html")]
struct EmailChangeNotificationEn {
name: String,
sender_email: String,
}

#[allow(unused)]
#[derive(Template)]
#[template(path = "email_change_notification_de.html")]
struct EmailChangeNotificationDe {
name: String,
sender_email: String,
}

#[allow(unused)]
Expand All @@ -54,17 +56,19 @@ fn send_email_change_notification(
"de" => {
let template = EmailChangeNotificationDe {
name: name.to_string(),
sender_email: state.sender_email.clone(),
};
(template.render().unwrap(), "E-Mail-Adresse geändert")
}
_ => {
let template = EmailChangeNotificationEn {
name: name.to_string(),
sender_email: state.sender_email.clone(),
};
(template.render().unwrap(), "Email address changed")
}
};
send_email(&old_email, subject, body, &state.mailer);
send_email(&old_email, subject, body, &state);
});
}

Expand Down Expand Up @@ -100,7 +104,7 @@ fn send_verification_mail(
}
};

send_email(&email, subject, body, &state.mailer);
send_email(&email, subject, body, &state);
});
}

Expand Down
6 changes: 3 additions & 3 deletions backend/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,16 @@ pub async fn validate_auth_token(
Ok(())
}

pub fn send_email(email: &str, subject: &str, body: String, mailer: &lettre::SmtpTransport) {
pub fn send_email(email: &str, subject: &str, body: String, state: &web::Data<AppState>, ) {
let email = Message::builder()
.from("Warp <warp@tinkerforge.com>".parse().unwrap())
.from(format!("{} <{}>", state.sender_name, state.sender_email).parse().unwrap())
.to(email.parse().unwrap())
.subject(subject)
.header(ContentType::TEXT_HTML)
.body(body)
.unwrap();

match mailer.send(&email) {
match state.mailer.send(&email) {
Ok(_) => println!("Email sent successfully!"),
Err(e) => panic!("Could not send email: {e:?}"),
}
Expand Down
2 changes: 1 addition & 1 deletion backend/templates/email_change_notification_de.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
</head>
<body>
<h3>Hallo {{name}}</h3>
<p>Du hast deine E-Mail-Adresse geändert. Falls Du diese Änderung nicht veranlasst hast, schreibe bitte eine E-Mail an <a href="mailto:warp@tinkerforge.com">warp@tinkerforge.com</a></p>
<p>Du hast deine E-Mail-Adresse geändert. Falls Du diese Änderung nicht veranlasst hast, schreibe bitte eine E-Mail an <a href="mailto:{{sender_email}}">{{sender_email}}</a></p>
</body>
</html>
2 changes: 1 addition & 1 deletion backend/templates/email_change_notification_en.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</head>
<body>
<h3>Hello {{name}}</h3>
<p>You changed your email-address. In case you did not initiate this please write a e-mail to <a href="mailto:warp@tinkerforge.com">warp@tinkerforge.com</a></p>
<p>You changed your email-address. In case you did not initiate this please write a e-mail to <a href="mailto:{{sender_email}}">{{sender_email}}</a></p>
</body>
</html>
12 changes: 8 additions & 4 deletions docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ POSTGRES_USER=

DATABASE_URL=
JWT_SECRET=
MAIL_USER=
MAIL_PASS=
MAIL_RELAY=
MAIL_RELAY_PORT=
EMAIL_USER=
EMAIL_PASS=
EMAIL_RELAY=
EMAIL_RELAY_PORT=
FRONTEND_URL=
SENDER_EMAIL=
SENDER_NAME=
MONITORING_MAIL=
SERVER_NAME=

SERVICEDOMAIN=
EMAIL=
Expand Down
Loading

0 comments on commit e195a1b

Please sign in to comment.