From 4f1be7fc294cca05772a79fbff22d9a35ba9abdb Mon Sep 17 00:00:00 2001 From: lxien Date: Mon, 31 Aug 2026 18:00:20 +0800 Subject: [PATCH] refactor: Delete management panel staticDir --- conf/orbien-server-full.toml | 1 - core/src/config/server.rs | 7 --- docs/docs/features/dashboard.md | 1 - .../current/features/dashboard.md | 1 - server/src/dashboard/routes.rs | 44 ++++--------------- 5 files changed, 8 insertions(+), 46 deletions(-) diff --git a/conf/orbien-server-full.toml b/conf/orbien-server-full.toml index 5539b51..9a9eb6a 100644 --- a/conf/orbien-server-full.toml +++ b/conf/orbien-server-full.toml @@ -36,4 +36,3 @@ addr = "0.0.0.0" port = 8020 user = "admin" password = "123456" -staticDir = "" diff --git a/core/src/config/server.rs b/core/src/config/server.rs index 9f6fef3..ded7e6b 100644 --- a/core/src/config/server.rs +++ b/core/src/config/server.rs @@ -103,9 +103,6 @@ pub struct DashboardConfig { pub user: String, #[serde(default)] pub password: String, - - #[serde(default, rename = "staticDir", alias = "static_dir")] - pub static_dir: String, } impl DashboardConfig { @@ -319,10 +316,6 @@ impl ServerConfig { tls.cert_file = super::resolve_maybe_relative(base, &tls.cert_file); tls.key_file = super::resolve_maybe_relative(base, &tls.key_file); tls.trusted_ca_file = super::resolve_maybe_relative(base, &tls.trusted_ca_file); - if !self.dashboard.static_dir.trim().is_empty() { - self.dashboard.static_dir = - super::resolve_maybe_relative(base, &self.dashboard.static_dir); - } } pub fn from_defaults() -> Self { diff --git a/docs/docs/features/dashboard.md b/docs/docs/features/dashboard.md index 96eb6a3..41bd04b 100644 --- a/docs/docs/features/dashboard.md +++ b/docs/docs/features/dashboard.md @@ -38,4 +38,3 @@ password = "123456" | `dashboard.port` | 是 | `0` | 监听端口;`0` 表示关闭 | | `dashboard.user` | 是 | | 登录用户名 | | `dashboard.password` | 是 | | 登录密码 | -| `dashboard.staticDir` | 否 | | 静态资源目录;空则使用内置前端 | diff --git a/docs/i18n/en/docusaurus-plugin-content-docs/current/features/dashboard.md b/docs/i18n/en/docusaurus-plugin-content-docs/current/features/dashboard.md index d4f31cc..c606cc7 100644 --- a/docs/i18n/en/docusaurus-plugin-content-docs/current/features/dashboard.md +++ b/docs/i18n/en/docusaurus-plugin-content-docs/current/features/dashboard.md @@ -37,4 +37,3 @@ Open `http://SERVER_IP:8020` in a browser and sign in with username and password | `dashboard.port` | Yes | `0` | Listen port; `0` disables the dashboard | | `dashboard.user` | Yes | | Login username | | `dashboard.password` | Yes | | Login password | -| `dashboard.staticDir` | No | | Static assets directory; empty uses the built-in frontend | diff --git a/server/src/dashboard/routes.rs b/server/src/dashboard/routes.rs index 84e4b99..a8d34eb 100644 --- a/server/src/dashboard/routes.rs +++ b/server/src/dashboard/routes.rs @@ -15,7 +15,6 @@ use base64::Engine; use orbien_core::VERSION; use rust_embed::Embed; use serde::Deserialize; -use std::path::{Component, Path as FsPath, PathBuf}; use std::sync::Arc; #[derive(Embed)] @@ -79,33 +78,22 @@ fn authorized(state: &DashState, headers: &HeaderMap) -> bool { u == state.cfg.user && p == state.cfg.password } -async fn index_html(State(state): State>) -> Response { - if let Some(bytes) = load_override(&state.cfg.static_dir, "index.html") { - return bytes_response("text/html; charset=utf-8", bytes); - } +async fn index_html() -> Response { serve_asset("index.html") } -async fn favicon(State(state): State>) -> Response { - if let Some(bytes) = load_override(&state.cfg.static_dir, "favicon.ico") { - return bytes_response("image/x-icon", bytes); - } - if let Some(res) = try_embedded("favicon.ico") { - return res; - } - StatusCode::NOT_FOUND.into_response() +async fn favicon() -> Response { + try_embedded("favicon.ico").unwrap_or_else(|| StatusCode::NOT_FOUND.into_response()) } -async fn static_file(State(state): State>, Path(path): Path) -> Response { +async fn static_file(Path(path): Path) -> Response { let rel = path.trim_start_matches('/'); - if let Some(bytes) = load_override(&state.cfg.static_dir, rel) { - return bytes_response(content_type(rel), bytes); + if !is_safe_asset_path(rel) { + return StatusCode::NOT_FOUND.into_response(); } - if let Some(res) = try_embedded(rel) { return res; } - serve_asset("index.html") } @@ -350,24 +338,8 @@ fn from_hex(b: u8) -> Option { } } -fn load_override(static_dir: &str, rel: &str) -> Option> { - if static_dir.trim().is_empty() { - return None; - } - let path = safe_join(FsPath::new(static_dir), rel)?; - std::fs::read(path).ok() -} - -fn safe_join(base: &FsPath, rel: &str) -> Option { - let mut out = base.to_path_buf(); - for c in FsPath::new(rel).components() { - match c { - Component::Normal(x) => out.push(x), - Component::CurDir => {} - _ => return None, - } - } - Some(out) +fn is_safe_asset_path(path: &str) -> bool { + !path.is_empty() && !path.contains("..") } fn content_type(path: &str) -> &'static str {