refactor: Delete management panel staticDir

This commit is contained in:
lxien
2026-08-31 18:00:20 +08:00
parent 870dfba88b
commit 4f1be7fc29
5 changed files with 8 additions and 46 deletions
-1
View File
@@ -36,4 +36,3 @@ addr = "0.0.0.0"
port = 8020
user = "admin"
password = "123456"
staticDir = ""
-7
View File
@@ -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 {
-1
View File
@@ -38,4 +38,3 @@ password = "123456"
| `dashboard.port` | 是 | `0` | 监听端口;`0` 表示关闭 |
| `dashboard.user` | 是 | | 登录用户名 |
| `dashboard.password` | 是 | | 登录密码 |
| `dashboard.staticDir` | 否 | | 静态资源目录;空则使用内置前端 |
@@ -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 |
+8 -36
View File
@@ -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<Arc<DashState>>) -> 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<Arc<DashState>>) -> 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<Arc<DashState>>, Path(path): Path<String>) -> Response {
async fn static_file(Path(path): Path<String>) -> 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<u8> {
}
}
fn load_override(static_dir: &str, rel: &str) -> Option<Vec<u8>> {
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<PathBuf> {
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 {