54c45cbfca
Add client_tokens table with auto-generated sk-{hex} tokens so clients
created in the dashboard get working API keys. Auth flow: DB token lookup
first, then env token fallback, then permissive mode. Includes token
management CRUD endpoints and copy-once reveal modal in the frontend.
114 lines
3.6 KiB
Rust
114 lines
3.6 KiB
Rust
// Dashboard module for LLM Proxy Gateway
|
|
|
|
mod auth;
|
|
mod clients;
|
|
mod models;
|
|
mod providers;
|
|
pub mod sessions;
|
|
mod system;
|
|
mod usage;
|
|
mod websocket;
|
|
|
|
use axum::{
|
|
Router,
|
|
routing::{delete, get, post, put},
|
|
};
|
|
use serde::Serialize;
|
|
|
|
use crate::state::AppState;
|
|
use sessions::SessionManager;
|
|
|
|
// Dashboard state
|
|
#[derive(Clone)]
|
|
struct DashboardState {
|
|
app_state: AppState,
|
|
session_manager: SessionManager,
|
|
}
|
|
|
|
// API Response types
|
|
#[derive(Serialize)]
|
|
struct ApiResponse<T> {
|
|
success: bool,
|
|
data: Option<T>,
|
|
error: Option<String>,
|
|
}
|
|
|
|
impl<T> ApiResponse<T> {
|
|
fn success(data: T) -> Self {
|
|
Self {
|
|
success: true,
|
|
data: Some(data),
|
|
error: None,
|
|
}
|
|
}
|
|
|
|
fn error(error: String) -> Self {
|
|
Self {
|
|
success: false,
|
|
data: None,
|
|
error: Some(error),
|
|
}
|
|
}
|
|
}
|
|
|
|
// Dashboard routes
|
|
pub fn router(state: AppState) -> Router {
|
|
let session_manager = SessionManager::new(24); // 24-hour session TTL
|
|
let dashboard_state = DashboardState {
|
|
app_state: state,
|
|
session_manager,
|
|
};
|
|
|
|
Router::new()
|
|
// Static file serving
|
|
.fallback_service(tower_http::services::ServeDir::new("static"))
|
|
// WebSocket endpoint
|
|
.route("/ws", get(websocket::handle_websocket))
|
|
// API endpoints
|
|
.route("/api/auth/login", post(auth::handle_login))
|
|
.route("/api/auth/status", get(auth::handle_auth_status))
|
|
.route("/api/auth/change-password", post(auth::handle_change_password))
|
|
.route("/api/usage/summary", get(usage::handle_usage_summary))
|
|
.route("/api/usage/time-series", get(usage::handle_time_series))
|
|
.route("/api/usage/clients", get(usage::handle_clients_usage))
|
|
.route("/api/usage/providers", get(usage::handle_providers_usage))
|
|
.route("/api/usage/detailed", get(usage::handle_detailed_usage))
|
|
.route("/api/analytics/breakdown", get(usage::handle_analytics_breakdown))
|
|
.route("/api/models", get(models::handle_get_models))
|
|
.route("/api/models/{id}", put(models::handle_update_model))
|
|
.route(
|
|
"/api/clients",
|
|
get(clients::handle_get_clients).post(clients::handle_create_client),
|
|
)
|
|
.route(
|
|
"/api/clients/{id}",
|
|
get(clients::handle_get_client)
|
|
.put(clients::handle_update_client)
|
|
.delete(clients::handle_delete_client),
|
|
)
|
|
.route("/api/clients/{id}/usage", get(clients::handle_client_usage))
|
|
.route(
|
|
"/api/clients/{id}/tokens",
|
|
get(clients::handle_get_client_tokens).post(clients::handle_create_client_token),
|
|
)
|
|
.route(
|
|
"/api/clients/{id}/tokens/{token_id}",
|
|
delete(clients::handle_delete_client_token),
|
|
)
|
|
.route("/api/providers", get(providers::handle_get_providers))
|
|
.route(
|
|
"/api/providers/{name}",
|
|
get(providers::handle_get_provider).put(providers::handle_update_provider),
|
|
)
|
|
.route("/api/providers/{name}/test", post(providers::handle_test_provider))
|
|
.route("/api/system/health", get(system::handle_system_health))
|
|
.route("/api/system/metrics", get(system::handle_system_metrics))
|
|
.route("/api/system/logs", get(system::handle_system_logs))
|
|
.route("/api/system/backup", post(system::handle_system_backup))
|
|
.route(
|
|
"/api/system/settings",
|
|
get(system::handle_get_settings).post(system::handle_update_settings),
|
|
)
|
|
.with_state(dashboard_state)
|
|
}
|