diff --git a/crates/presentation/src/route/admin/asset.rs b/crates/presentation/src/route/admin/asset.rs index 60af07c..884b931 100644 --- a/crates/presentation/src/route/admin/asset.rs +++ b/crates/presentation/src/route/admin/asset.rs @@ -183,7 +183,7 @@ fn map_jacket_error(error: AssetUploadError) -> AppError { AssetUploadError::UnsupportedContentType => { AppError::bad_request("jacket must be JPEG, PNG, or WebP") } - AssetUploadError::TooLarge => AppError::bad_request("jacket exceeds 5 MiB"), + AssetUploadError::TooLarge => AppError::bad_request("jacket exceeds 20 MiB"), AssetUploadError::InvalidData => AppError::bad_request("jacket image is invalid"), AssetUploadError::InvalidFileName => AppError::bad_request("jacket file name is invalid"), } @@ -192,7 +192,7 @@ fn map_jacket_error(error: AssetUploadError) -> AppError { fn map_audio_error(error: AssetUploadError) -> AppError { match error { AssetUploadError::UnsupportedContentType => AppError::bad_request("audio must be WAV"), - AssetUploadError::TooLarge => AppError::bad_request("audio exceeds 30 MiB"), + AssetUploadError::TooLarge => AppError::bad_request("audio exceeds 60 MiB"), AssetUploadError::InvalidData => AppError::bad_request("audio is invalid"), AssetUploadError::InvalidFileName => AppError::bad_request("audio file name is invalid"), } diff --git a/crates/presentation/src/route/mod.rs b/crates/presentation/src/route/mod.rs index 6aa9d28..fe76b36 100644 --- a/crates/presentation/src/route/mod.rs +++ b/crates/presentation/src/route/mod.rs @@ -6,6 +6,7 @@ use axum::{ routing::{get, patch, post}, }; use tower_http::{cors::CorsLayer, trace::TraceLayer}; +use usecase::asset::MAX_AUDIO_SIZE; use crate::{ auth::{Authenticator, AuthorizationPolicy, PrincipalKind}, @@ -77,7 +78,7 @@ pub fn create_app(state: State, authenticator: Option) -> Router get(admin::asset::get_chart), ) .route("/db/synchronize", post(admin::handle_db_synchronization)); - let admin_routes = admin_routes.layer(DefaultBodyLimit::max(31 * 1024 * 1024)); + let admin_routes = admin_routes.layer(DefaultBodyLimit::max(MAX_AUDIO_SIZE)); let private_routes = Router::new() .nest("/users", users) diff --git a/crates/usecase/src/asset.rs b/crates/usecase/src/asset.rs index 484a3c0..3ed3890 100644 --- a/crates/usecase/src/asset.rs +++ b/crates/usecase/src/asset.rs @@ -4,8 +4,8 @@ use image::{ImageFormat, ImageReader, Limits}; use thiserror::Error; use tokio::io::AsyncRead; -pub const MAX_JACKET_SIZE: usize = 5 * 1024 * 1024; -pub const MAX_AUDIO_SIZE: usize = 30 * 1024 * 1024; +pub const MAX_JACKET_SIZE: usize = 20 * 1024 * 1024; +pub const MAX_AUDIO_SIZE: usize = 60 * 1024 * 1024; pub const MAX_CHART_SIZE: usize = 5 * 1024 * 1024; #[derive(Debug, Clone, Copy, Eq, PartialEq)] @@ -276,6 +276,16 @@ mod tests { assert_eq!(&upload.bytes[..8], b"\x89PNG\r\n\x1a\n"); } + #[test] + fn rejects_jacket_over_size_limit() { + let bytes = vec![0; MAX_JACKET_SIZE + 1]; + + assert!(matches!( + AssetUpload::jacket("image/png", bytes), + Err(AssetUploadError::TooLarge) + )); + } + #[test] fn accepts_wav_header() { let mut bytes = b"RIFF".to_vec(); @@ -288,6 +298,18 @@ mod tests { ); } + #[test] + fn rejects_audio_over_size_limit() { + let mut bytes = vec![0; MAX_AUDIO_SIZE + 1]; + bytes[..4].copy_from_slice(b"RIFF"); + bytes[8..12].copy_from_slice(b"WAVE"); + + assert!(matches!( + AssetUpload::audio("audio/wav", bytes), + Err(AssetUploadError::TooLarge) + )); + } + #[test] fn rejects_invalid_wav_header() { assert!(matches!(