add template path to environment

This commit is contained in:
Franz Dietrich 2023-02-05 14:06:46 +01:00
parent 5a45099e7b
commit b06baabb8c
Signed by: dietrich
GPG Key ID: F0CE5A20AB5C4B27
3 changed files with 70 additions and 50 deletions

1
.env
View File

@ -4,3 +4,4 @@ SMTP_USER="SMTP_USERNAME"
SMTP_PASSWORD="SMTP_PASSWORD" SMTP_PASSWORD="SMTP_PASSWORD"
PORT="8087" PORT="8087"
PATH_TO_STATICS="terminwahl_front/dist/" PATH_TO_STATICS="terminwahl_front/dist/"
PATH_TO_TEMPLATES="terminwahl_back/templates/"

View File

@ -3,7 +3,9 @@ use std::error::Error;
use actix_web::{error, web, HttpResponse}; use actix_web::{error, web, HttpResponse};
use futures::future; use futures::future;
use handlebars::Handlebars; use handlebars::Handlebars;
use lettre::{message::header::ContentType, Message, SmtpTransport, Transport}; use lettre::{
message::header::ContentType, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor,
};
use log::debug; use log::debug;
use rand::{distributions::Alphanumeric, thread_rng, Rng}; use rand::{distributions::Alphanumeric, thread_rng, Rng};
use serde::Serialize; use serde::Serialize;
@ -35,7 +37,7 @@ impl FullAppointment {
pub async fn save_appointments_json( pub async fn save_appointments_json(
pool: web::Data<Pool>, pool: web::Data<Pool>,
mailer: web::Data<SmtpTransport>, mailer: web::Data<AsyncSmtpTransport<Tokio1Executor>>,
handlebars: web::Data<Handlebars<'_>>, handlebars: web::Data<Handlebars<'_>>,
input: web::Json<(Vec<PlannedAppointment>, Nutzer)>, input: web::Json<(Vec<PlannedAppointment>, Nutzer)>,
) -> Result<HttpResponse, error::Error> { ) -> Result<HttpResponse, error::Error> {
@ -55,6 +57,7 @@ pub async fn save_appointments_json(
.await .await
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
debug!("Loading the appointments");
let full_appointments = future::try_join_all(appointments.into_iter().map( let full_appointments = future::try_join_all(appointments.into_iter().map(
|PlannedAppointment { |PlannedAppointment {
teacher_id, teacher_id,
@ -63,24 +66,25 @@ pub async fn save_appointments_json(
)) ))
.await .await
.expect("Failed to get full list of appointments"); .expect("Failed to get full list of appointments");
debug!("Send the email");
let mail_result = send_confirmation_request( let mail_result = send_confirmation_request(
&full_appointments, &full_appointments,
&nutzer, &nutzer,
&validation_key, &validation_key,
&handlebars, handlebars.as_ref(),
&mailer, &mailer,
); )
.await;
Ok(HttpResponse::Ok().json(mail_result)) Ok(HttpResponse::Ok().json(mail_result))
} }
pub fn send_confirmation_request( pub async fn send_confirmation_request<'a>(
appointments: &Vec<FullAppointment>, appointments: &Vec<FullAppointment>,
nutzer: &Nutzer, nutzer: &Nutzer,
validation_key: &str, validation_key: &str,
handlebars: &Handlebars, handlebars: &Handlebars<'a>,
mailer: &SmtpTransport, mailer: &AsyncSmtpTransport<Tokio1Executor>,
) -> RequestState { ) -> RequestState {
let data = json! { let data = json! {
{ {
@ -89,43 +93,56 @@ pub fn send_confirmation_request(
"validation_key": validation_key "validation_key": validation_key
}}; }};
debug!("{:?}", handlebars.get_templates()); debug!("{:?}", handlebars.get_templates());
if let Ok(email_text) = handlebars.render("email_confirm", &data) { match handlebars.render("email_confirm", &data) {
let email = match Message::builder() Ok(email_text) => {
.from( let email = match Message::builder()
"Franz Dietrich <franz.dietrich@uhlandshoehe.de>" .from(
.parse() "Franz Dietrich <franz.dietrich@uhlandshoehe.de>"
.expect("Should not fail"), .parse()
) .expect("Should not fail"),
.to( )
match format!("{} <{}>", nutzer.name, nutzer.email).parse() { .to(
Ok(v) => v, match format!("{} <{}>", nutzer.name, nutzer.email).parse() {
Err(_) => return RequestState::Error, Ok(v) => v,
}, Err(e) => {
) debug!("Error while sending email {e}");
.subject("Elternsprechtag: Bestätigen Sie Ihre Termine") return RequestState::Error;
.header(ContentType::TEXT_PLAIN) }
.body( },
match lettre::message::Body::new_with_encoding( )
email_text, .subject("Elternsprechtag: Bestätigen Sie Ihre Termine")
lettre::message::header::ContentTransferEncoding::Base64, .header(ContentType::TEXT_PLAIN)
.body(
match lettre::message::Body::new_with_encoding(
email_text,
lettre::message::header::ContentTransferEncoding::Base64,
) {
Ok(body) => body,
Err(e) => {
debug!("Error while sending email {e:?}");
return RequestState::Error;
}
},
) { ) {
Ok(body) => body, Ok(message) => message,
Err(_) => return RequestState::Error, Err(e) => {
}, debug!("Error while sending email {e}");
) { return RequestState::Error;
Ok(message) => message, }
Err(_) => return RequestState::Error, };
};
// Send the email // Send the email
match mailer.send(&email) { match mailer.send(email).await {
Ok(_) => RequestState::Success, Ok(_) => RequestState::Success,
Err(e) => { Err(e) => {
debug!("Failed to send: {e}"); debug!("Failed to send: {e}");
RequestState::Error RequestState::Error
}
} }
} }
} else { Err(e) => {
RequestState::Error debug!("Failed to send email: Template did not render {e}");
RequestState::Error
}
} }
} }

View File

@ -8,7 +8,7 @@ use actix_web::{
}; };
use dotenv::dotenv; use dotenv::dotenv;
use handlebars::Handlebars; use handlebars::Handlebars;
use lettre::{transport::smtp::authentication::Credentials, SmtpTransport}; use lettre::{transport::smtp::authentication::Credentials, AsyncSmtpTransport, Tokio1Executor};
use log::debug; use log::debug;
use std::env; use std::env;
use terminwahl_back::{api, db, handlebars_helper::TimeOfDate, views, CssPath}; use terminwahl_back::{api, db, handlebars_helper::TimeOfDate, views, CssPath};
@ -25,22 +25,24 @@ async fn main() -> std::io::Result<()> {
let smtp_user = env::var("SMTP_USER").expect("Failed to get smtp user"); let smtp_user = env::var("SMTP_USER").expect("Failed to get smtp user");
let smtp_password = env::var("SMTP_PASSWORD").expect("Failed to get smtp password"); let smtp_password = env::var("SMTP_PASSWORD").expect("Failed to get smtp password");
let wasm_statics = env::var("PATH_TO_STATICS").expect("Failed to get statics path"); let wasm_statics = env::var("PATH_TO_STATICS").expect("Failed to get statics path");
let handlebars_templates = env::var("PATH_TO_TEMPLATES").expect("Failed to get templates path");
let port: u16 = env::var("PORT") let port: u16 = env::var("PORT")
.expect("Failed to get port") .expect("Failed to get port")
.parse() .parse()
.expect("Not a Portnumber"); .expect("Not a Portnumber");
let credentials = Credentials::new(smtp_user, smtp_password); let credentials = Credentials::new(smtp_user, smtp_password);
let smtp_pool = SmtpTransport::relay("smtp.1und1.de") let smtp_pool: AsyncSmtpTransport<Tokio1Executor> =
.expect("Failed to connect to smtp") AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.1und1.de")
// Add credentials for authentication .expect("Failed to connect to smtp")
.credentials(credentials) // Add credentials for authentication
// Connection pool settings .credentials(credentials)
.build(); // Connection pool settings
.build();
let mut handlebars = Handlebars::new(); let mut handlebars = Handlebars::new();
handlebars.register_helper("time_of", Box::new(TimeOfDate)); handlebars.register_helper("time_of", Box::new(TimeOfDate));
handlebars handlebars
.register_templates_directory(".hbs", "terminwahl_back/templates") .register_templates_directory(".hbs", handlebars_templates)
.unwrap(); .unwrap();
log::info!("starting HTTP server at http://localhost:8080"); log::info!("starting HTTP server at http://localhost:8080");