feat: customize webmaster email

This commit is contained in:
Max Hohlfeld 2025-05-24 21:27:33 +02:00
parent 513e8983b9
commit a608204103
9 changed files with 59 additions and 16 deletions

2
.env
View File

@ -6,9 +6,11 @@ SQLX_OFFLINE=true
# 64 byte long openssl rand -base64 64
SECRET_KEY="changeInProdOrHandAb11111111111111111111111111111111111111111111"
HOSTNAME="localhost"
WEBMASTER_EMAIL="admin@example.com"
SERVER_ADDRESS="127.0.0.1"
SERVER_PORT="8080"
APP_ENVIRONMENT="development"
SMTP_SERVER="localhost"
SMTP_PORT="1025"
# SMTP_LOGIN=""

View File

@ -17,6 +17,7 @@ pub struct Config {
pub smtp_login: Option<String>,
pub smtp_password: Option<String>,
pub smtp_tlstype: SmtpTlsType,
pub webmaster_email: String
}
#[derive(Clone)]
@ -67,6 +68,7 @@ pub fn load_config(env: &Environment) -> Result<Config, anyhow::Error> {
smtp_login: env::var("SMTP_LOGIN").map(Some).unwrap_or(None),
smtp_password: env::var("SMTP_PASSWORD").map(Some).unwrap_or(None),
smtp_tlstype: SmtpTlsType::from(env::var("SMTP_TLSTYPE")?),
webmaster_email: env::var("WEBMASTER_EMAIL")?,
};
Ok(config)

View File

@ -6,14 +6,16 @@ use sqlx::PgPool;
use crate::{
models::PasswordReset,
utils::{ApplicationError, TemplateResponse},
utils::{ApplicationError, Customization, TemplateResponse},
};
use super::ResetPasswordTemplate;
#[derive(Template)]
#[template(path = "user/forgot_password.html")]
struct ForgotPasswordTemplate {}
struct ForgotPasswordTemplate<'a> {
webmaster_email: &'a str,
}
#[derive(Deserialize)]
struct TokenQuery {
@ -25,6 +27,7 @@ pub async fn get(
user: Option<Identity>,
pool: web::Data<PgPool>,
query: web::Query<TokenQuery>,
customization: web::Data<Customization>,
) -> Result<impl Responder, ApplicationError> {
if user.is_some() {
return Ok(HttpResponse::Found()
@ -45,6 +48,8 @@ pub async fn get(
}
}
let template = ForgotPasswordTemplate {};
let template = ForgotPasswordTemplate {
webmaster_email: &customization.webmaster_email,
};
Ok(template.to_response()?)
}

View File

@ -19,6 +19,7 @@ use tracing_panic::panic_hook;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, EnvFilter};
use utils::Customization;
use crate::postgres_session_store::SqlxPostgresqlSessionStore;
use crate::utils::manage_commands::{handle_command, parse_args};
@ -49,6 +50,9 @@ async fn main() -> anyhow::Result<()> {
let pool = PgPool::connect(&config.database_url).await?;
let mailer = Mailer::new(&config)?;
let customization = Customization {
webmaster_email: config.webmaster_email.clone(),
};
handle_command(args.command, &pool, &mailer).await?;
@ -56,7 +60,14 @@ async fn main() -> anyhow::Result<()> {
let port = config.server_port;
info!("Starting server on http://{address}:{port}.");
HttpServer::new(move || create_app(config.clone(), pool.clone(), mailer.clone()))
HttpServer::new(move || {
create_app(
config.clone(),
pool.clone(),
mailer.clone(),
customization.clone(),
)
})
.bind((address, port))?
.run()
.await?;
@ -68,6 +79,7 @@ pub fn create_app(
config: Config,
pool: Pool<Postgres>,
mailer: Mailer,
customization: Customization,
) -> App<
impl ServiceFactory<
ServiceRequest,
@ -84,6 +96,7 @@ pub fn create_app(
App::new()
.app_data(web::Data::new(pool))
.app_data(web::Data::new(mailer))
.app_data(web::Data::new(customization))
.configure(endpoints::init)
.wrap(middleware::ErrorAppender)
.wrap(TracingLogger::default())

View File

@ -0,0 +1,4 @@
#[derive(Clone)]
pub struct Customization {
pub webmaster_email: String,
}

View File

@ -5,6 +5,7 @@ pub mod event_planning_template;
pub mod manage_commands;
pub mod password_change;
mod template_response_trait;
mod app_customization;
pub mod token_generation;
#[cfg(test)]
@ -13,6 +14,7 @@ pub mod test_helper;
pub use application_error::ApplicationError;
pub use date_time_format::DateTimeFormat;
pub use template_response_trait::TemplateResponse;
pub use app_customization::Customization;
use chrono::{NaiveDate, Utc};

View File

@ -8,6 +8,7 @@ use actix_web::{
};
use rand::{distr::Alphanumeric, rng, Rng};
use crate::utils::Customization;
use crate::{create_app, mail::Mailer};
use brass_config::{load_config, Config, Environment};
use regex::{Captures, Regex};
@ -29,10 +30,15 @@ impl DbTestContext {
Response = ServiceResponse<impl MessageBody>,
Error = actix_web::error::Error,
> {
let customization = Customization {
webmaster_email: self.config.webmaster_email.clone(),
};
init_service(create_app(
self.config.clone(),
self.db_pool.clone(),
Mailer::new_stub(),
customization,
))
.await
}

View File

@ -6,7 +6,7 @@
<h1 class="title">Brass - Passwort zurücksetzen</h1>
<article class="message is-info">
<div class="message-body">
Gib deine E-Mail Adresse ein und erhalte einen Link zum Zurücksetzen deines Passworts, sofern ein Account mit dieser Adresse existiert. Bei Problemen wende dich an <a href="mailto:mail@example.com">mail@example.com</a>.
Gib deine E-Mail Adresse ein und erhalte einen Link zum Zurücksetzen deines Passworts, sofern ein Account mit dieser Adresse existiert. Bei Problemen wende dich an <a href="mailto:{{ webmaster_email }}">{{ webmaster_email }}</a>.
</div>
</article>
<form class="box" hx-post="/reset-password">

View File

@ -28,13 +28,22 @@
<div id="error-message" class="mb-3 help is-danger"></div>
<div class="level">
<button class="button is-primary level-left">
<div class="level-left">
<button class="button is-primary level-item">
<svg class="icon">
<use href="/static/feather-sprite.svg#log-in" />
</svg>
<span>Anmelden</span>
</button>
<a class="button is-info is-light level-right" hx-boost="true" href="/reset-password">Passwort vergessen</a>
</div>
<div class="level-right level-item">
<a class="button is-info is-light" href="/reset-password">
<svg class="icon">
<use href="/static/feather-sprite.svg#help-circle" />
</svg>
<span>Passwort vergessen</span>
</a>
</div>
</div>
</form>
</div>