diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index 706ee8d..41eec67 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -9,7 +9,7 @@ serde = { version = "1.0.219", features = ["derive"] } tera = "1.20.0" tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } -tower-http = { version = "0.6.6", features = ["trace", "fs", "catch-panic"] } +tower-http = { version = "0.6.6", features = ["trace", "fs", "catch-panic", "set-header"] } axum = { version = "0.8.4", features = ["macros", "ws"] } tokio = { version = "1.45.1", features = ["macros", "rt-multi-thread"] } axum-extra = { version = "0.10.1", features = ["cookie", "multipart"] } diff --git a/crates/app/src/main.rs b/crates/app/src/main.rs index b4f188c..77dff46 100644 --- a/crates/app/src/main.rs +++ b/crates/app/src/main.rs @@ -11,12 +11,16 @@ use assets::{init_dirs, write_assets}; use tetratto_core::model::{permissions::FinePermission, uploads::CustomEmoji}; pub use tetratto_core::*; -use axum::{Extension, Router}; +use axum::{ + http::{HeaderName, HeaderValue}, + Extension, Router, +}; use reqwest::Client; use tera::{Tera, Value}; use tower_http::{ - trace::{self, TraceLayer}, catch_panic::CatchPanicLayer, + set_header::SetResponseHeaderLayer, + trace::{self, TraceLayer}, }; use tracing::{Level, info}; @@ -115,6 +119,10 @@ async fn main() { .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) .on_response(trace::DefaultOnResponse::new().level(Level::INFO)), ) + .layer(SetResponseHeaderLayer::if_not_present( + HeaderName::from_static("X-Frame-Options"), + HeaderValue::from_static("SAMEORIGIN"), + )) .layer(CatchPanicLayer::new()); let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", config.port)) diff --git a/crates/app/src/routes/api/v1/auth/images.rs b/crates/app/src/routes/api/v1/auth/images.rs index 9a67da8..e062be1 100644 --- a/crates/app/src/routes/api/v1/auth/images.rs +++ b/crates/app/src/routes/api/v1/auth/images.rs @@ -82,14 +82,16 @@ pub async fn avatar_request( } }; + let mime = if user.settings.avatar_mime.is_empty() { + "image/avif" + } else { + &user.settings.avatar_mime + }; + let path = PathBufD::current().extend(&[ data.0.0.dirs.media.as_str(), "avatars", - &format!( - "{}.{}", - &(user.id as i64), - user.settings.avatar_mime.replace("image/", "") - ), + &format!("{}.{}", &(user.id as i64), mime.replace("image/", "")), ]); if !exists(&path).unwrap() { @@ -104,10 +106,7 @@ pub async fn avatar_request( } Ok(( - [( - "Content-Type".to_string(), - user.settings.avatar_mime.clone(), - )], + [("Content-Type".to_string(), mime.to_owned())], Body::from(read_image(path)), )) } @@ -134,14 +133,16 @@ pub async fn banner_request( } }; + let mime = if user.settings.banner_mime.is_empty() { + "image/avif" + } else { + &user.settings.banner_mime + }; + let path = PathBufD::current().extend(&[ data.0.0.dirs.media.as_str(), "banners", - &format!( - "{}.{}", - &(user.id as i64), - user.settings.banner_mime.replace("image/", "") - ), + &format!("{}.{}", &(user.id as i64), mime.replace("image/", "")), ]); if !exists(&path).unwrap() { @@ -156,10 +157,7 @@ pub async fn banner_request( } Ok(( - [( - "Content-Type".to_string(), - user.settings.banner_mime.clone(), - )], + [("Content-Type".to_string(), mime.to_owned())], Body::from(read_image(path)), )) } @@ -211,15 +209,6 @@ pub async fn upload_avatar_request( mime.replace("image/", "") ); - // update user settings - auth_user.settings.avatar_mime = mime.to_string(); - if let Err(e) = data - .update_user_settings(auth_user.id, auth_user.settings) - .await - { - return Json(e.into()); - } - // upload image (gif) if mime == "image/gif" { // gif image, don't encode @@ -256,11 +245,23 @@ pub async fn upload_avatar_request( image::ImageFormat::Avif }, ) { - Ok(_) => Json(ApiReturn { - ok: true, - message: "Avatar uploaded. It might take a bit to update".to_string(), - payload: (), - }), + Ok(_) => { + // update user settings + auth_user.settings.avatar_mime = mime.to_string(); + if let Err(e) = data + .update_user_settings(auth_user.id, auth_user.settings) + .await + { + return Json(e.into()); + } + + // ... + Json(ApiReturn { + ok: true, + message: "Avatar uploaded. It might take a bit to update".to_string(), + payload: (), + }) + } Err(e) => Json(Error::MiscError(e.to_string()).into()), } } @@ -309,15 +310,6 @@ pub async fn upload_banner_request( mime.replace("image/", "") ); - // update user settings - auth_user.settings.banner_mime = mime.to_string(); - if let Err(e) = data - .update_user_settings(auth_user.id, auth_user.settings) - .await - { - return Json(e.into()); - } - // upload image (gif) if mime == "image/gif" { // gif image, don't encode @@ -354,11 +346,23 @@ pub async fn upload_banner_request( image::ImageFormat::Avif }, ) { - Ok(_) => Json(ApiReturn { - ok: true, - message: "Banner uploaded. It might take a bit to update".to_string(), - payload: (), - }), + Ok(_) => { + // update user settings + auth_user.settings.banner_mime = mime.to_string(); + if let Err(e) = data + .update_user_settings(auth_user.id, auth_user.settings) + .await + { + return Json(e.into()); + } + + // ... + Json(ApiReturn { + ok: true, + message: "Banner uploaded. It might take a bit to update".to_string(), + payload: (), + }) + } Err(e) => Json(Error::MiscError(e.to_string()).into()), } }