server: Allow custom path to front-end assets

This commit is contained in:
tyami94
2025-01-28 13:37:12 -05:00
committed by GitHub
parent 722464daf4
commit f46e5375df
3 changed files with 41 additions and 12 deletions
+3
View File
@@ -33,6 +33,9 @@
## The public URL of the server, for password reset links.
#http_url = "http://localhost"
## The path to the front-end assets (relative to the working directory).
#assets_path = "./app"
## Random secret for JWT signature.
## This secret should be random, and should be shared with application
## servers that need to consume the JWTs.
+3
View File
@@ -22,6 +22,7 @@ use figment_file_provider_adapter::FileAdapter;
use lldap_auth::opaque::{server::ServerSetup, KeyPair};
use secstr::SecUtf8;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use url::Url;
#[derive(
@@ -125,6 +126,8 @@ pub struct Configuration {
// "***SECRET***".
#[builder(default)]
pub key_seed: Option<SecUtf8>,
#[builder(default = r#"PathBuf::from("./app")"#)]
pub assets_path: PathBuf,
#[builder(default)]
pub smtp_options: MailOptions,
#[builder(default)]
+35 -12
View File
@@ -21,11 +21,12 @@ use anyhow::{Context, Result};
use hmac::Hmac;
use sha2::Sha512;
use std::collections::HashSet;
use std::path::PathBuf;
use std::sync::RwLock;
use tracing::info;
use tracing::{info, warn};
async fn index<Backend>(data: web::Data<AppState<Backend>>) -> actix_web::Result<impl Responder> {
let mut file = std::fs::read_to_string(r"./app/index.html")?;
let mut file = std::fs::read_to_string(data.assets_path.join("index.html"))?;
if data.server_url.path() != "/" {
file = file.replace(
@@ -80,7 +81,7 @@ pub(crate) fn error_to_http_response(error: TcpError) -> HttpResponse {
async fn main_js_handler<Backend>(
data: web::Data<AppState<Backend>>,
) -> actix_web::Result<impl Responder> {
let mut file = std::fs::read_to_string(r"./app/static/main.js")?;
let mut file = std::fs::read_to_string(data.assets_path.join("static/main.js"))?;
if data.server_url.path() != "/" {
file = file.replace("/pkg/", format!("{}/pkg/", data.server_url.path()).as_str());
@@ -91,13 +92,20 @@ async fn main_js_handler<Backend>(
.insert_header((header::CONTENT_TYPE, "text/javascript")))
}
async fn wasm_handler() -> actix_web::Result<impl Responder> {
Ok(actix_files::NamedFile::open_async("./app/pkg/lldap_app_bg.wasm").await?)
async fn wasm_handler<Backend>(
data: web::Data<AppState<Backend>>,
) -> actix_web::Result<impl Responder> {
Ok(
actix_files::NamedFile::open_async(data.assets_path.join("pkg/lldap_app_bg.wasm.gz"))
.await?,
)
}
async fn wasm_handler_compressed() -> actix_web::Result<impl Responder> {
async fn wasm_handler_compressed<Backend>(
data: web::Data<AppState<Backend>>,
) -> actix_web::Result<impl Responder> {
Ok(
actix_files::NamedFile::open_async("./app/pkg/lldap_app_bg.wasm.gz")
actix_files::NamedFile::open_async(data.assets_path.join("pkg/lldap_app_bg.wasm.gz"))
.await?
.customize()
.insert_header(header::ContentEncoding::Gzip)
@@ -111,6 +119,7 @@ fn http_config<Backend>(
jwt_secret: secstr::SecUtf8,
jwt_blacklist: HashSet<u64>,
server_url: url::Url,
assets_path: PathBuf,
mail_options: MailOptions,
) where
Backend: TcpBackendHandler + BackendHandler + LoginHandler + OpaqueHandler + Clone + 'static,
@@ -121,6 +130,7 @@ fn http_config<Backend>(
jwt_key: hmac::Mac::new_from_slice(jwt_secret.unsecure().as_bytes()).unwrap(),
jwt_blacklist: RwLock::new(jwt_blacklist),
server_url,
assets_path: assets_path.clone(),
mail_options,
}))
.route(
@@ -138,16 +148,22 @@ fn http_config<Backend>(
.configure(super::graphql::api::configure_endpoint::<Backend>),
)
.service(
web::resource("/pkg/lldap_app_bg.wasm.gz").route(web::route().to(wasm_handler_compressed)),
web::resource("/pkg/lldap_app_bg.wasm.gz")
.route(web::route().to(wasm_handler_compressed::<Backend>)),
)
.service(
web::resource("/pkg/lldap_app_bg.wasm").route(web::route().to(wasm_handler::<Backend>)),
)
.service(web::resource("/pkg/lldap_app_bg.wasm").route(web::route().to(wasm_handler)))
.service(web::resource("/static/main.js").route(web::route().to(main_js_handler::<Backend>)))
// Serve the /pkg path with the compiled WASM app.
.service(Files::new("/pkg", "./app/pkg"))
.service(Files::new("/pkg", assets_path.join("pkg")))
// Serve static files
.service(Files::new("/static", "./app/static"))
.service(Files::new("/static", assets_path.join("static")))
// Serve static fonts
.service(Files::new("/static/fonts", "./app/static/fonts"))
.service(Files::new(
"/static/fonts",
assets_path.join("static/fonts"),
))
// Default to serve index.html for unknown routes, to support routing.
.default_service(web::route().guard(guard::Get()).to(index::<Backend>));
}
@@ -157,6 +173,7 @@ pub(crate) struct AppState<Backend> {
pub jwt_key: Hmac<Sha512>,
pub jwt_blacklist: RwLock<HashSet<u64>>,
pub server_url: url::Url,
pub assets_path: PathBuf,
pub mail_options: MailOptions,
}
@@ -195,8 +212,12 @@ where
.await
.context("while getting the jwt blacklist")?;
let server_url = config.http_url.0.clone();
let assets_path = config.assets_path.clone();
let mail_options = config.smtp_options.clone();
let verbose = config.verbose;
if !assets_path.join("index.html").exists() {
warn!("Cannot find {}, please ensure that assets_path is set correctly and that the front-end files exist.", assets_path.to_string_lossy())
}
info!("Starting the API/web server on port {}", config.http_port);
server_builder
.bind(
@@ -207,6 +228,7 @@ where
let jwt_secret = jwt_secret.clone();
let jwt_blacklist = jwt_blacklist.clone();
let server_url = server_url.clone();
let assets_path = assets_path.clone();
let mail_options = mail_options.clone();
HttpServiceBuilder::default()
.finish(map_config(
@@ -222,6 +244,7 @@ where
jwt_secret,
jwt_blacklist,
server_url,
assets_path,
mail_options,
)
}),