diff --git a/src/server/main.rs b/src/server/main.rs index 2927dd6..d2c434e 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -4,7 +4,7 @@ use dioxus::{ server::axum::Extension, }; use tokio::net::TcpListener; -use tower_http::services::ServeFile; +use tower_http::services::{ServeDir, ServeFile}; use crate::App; use crate::app::LOGO_ICO; @@ -17,6 +17,7 @@ use crate::server::{ }; use crate::util::error::{Contextualize, Error, ErrorType, Result}; +// Build the `axum::Router` and attach config, database, and key/val store as extensions pub fn build_router(config: Config, db_pool: DbPool, key_val_pool: KeyValPool) -> Router { let favicon_path = { // Resolve the favicon path @@ -32,13 +33,34 @@ pub fn build_router(config: Config, db_pool: DbPool, key_val_pool: KeyValPool) - let auth_layer = build_auth_layer(db_pool.clone(), key_val_pool, config.auth.cookies_secure); - Router::new() - .serve_dioxus_application(ServeConfig::new(), App) + let public_path = config.server.public_path.clone(); + + let serve_assets = ServeDir::new(public_path.join("assets")); + let serve_index = ServeFile::new(public_path.join("index.html")); + let serve_favicon = ServeFile::new(favicon_path); + + let router = Router::new() + .serve_api_application(ServeConfig::new(), App) .layer(from_fn(require_auth_middleware)) .layer(Extension(config)) .layer(Extension(db_pool)) - .layer(auth_layer) - .nest_service("/favicon.ico", ServeFile::new(favicon_path)) + .layer(auth_layer); + + // In release mode, serve precompressed assets. In debug mode, serve WASM patch files. + if cfg!(debug_assertions) { + let serve_wasm = ServeDir::new(public_path.join("wasm")); + + router + .nest_service("/wasm", serve_wasm) + .nest_service("/assets", serve_assets) + .nest_service("/index.html", serve_index) + .nest_service("/favicon.ico", serve_favicon) + } else { + router + .nest_service("/assets", serve_assets.precompressed_br()) + .nest_service("/index.html", serve_index) + .nest_service("/favicon.ico", serve_favicon.precompressed_br()) + } } pub async fn main() -> Result { @@ -54,14 +76,6 @@ pub async fn main() -> Result { tracing::debug!("Loaded configuration: {config:#?}"); config.log_warnings(); - // Dioxus doesn't expose a way to configure the public path other than this environment - // variable, and also doesn't provide a way to read what the public path is. As a workaround we - // expose a config option and set this variable that Dioxus expects. - // SAFETY: "This function is safe to call in a single-threaded program." - unsafe { - std::env::set_var("DIOXUS_PUBLIC_PATH", config.server.public_path.clone()); - } - let db_pool = database::setup(config.database.connection_uri()) .await .err_context("Failed database setup")?; diff --git a/src/server/require_auth_mw.rs b/src/server/require_auth_mw.rs index 5df402c..3a3d92d 100644 --- a/src/server/require_auth_mw.rs +++ b/src/server/require_auth_mw.rs @@ -7,12 +7,6 @@ use dioxus::prelude::*; use crate::server::auth::AuthSession; -#[cfg(not(debug_assertions))] -const ALLOWED_PATH_PREFIX: [&str; 1] = ["/assets/"]; - -#[cfg(debug_assertions)] -const ALLOWED_PATH_PREFIX: [&str; 2] = ["/assets/", "/wasm/"]; - const ALLOWED_PATHS: [&str; 6] = [ "/login", "/signup", @@ -29,11 +23,7 @@ pub async fn require_auth_middleware( ) -> Result, (StatusCode, &'static str)> { let path = req.uri().path(); - if ALLOWED_PATH_PREFIX - .iter() - .any(|prefix| path.starts_with(prefix)) - || ALLOWED_PATHS.contains(&path) - { + if ALLOWED_PATHS.contains(&path) { let response = next.run(req).await; return Ok(response); }