Files
furumi-ng/furumi-web-player/src/web/mod.rs
2026-03-23 12:34:27 +03:00

69 lines
2.2 KiB
Rust

pub mod api;
pub mod auth;
use std::sync::Arc;
use std::path::PathBuf;
use std::time::Duration;
use axum::{Router, routing::get, middleware};
use axum::http::{header, Method};
use sqlx::PgPool;
use tower_http::cors::{Any, CorsLayer};
#[derive(Clone)]
pub struct AppState {
pub pool: PgPool,
#[allow(dead_code)]
pub storage_dir: Arc<PathBuf>,
pub oidc: Option<Arc<auth::OidcState>>,
pub api_key: Option<String>,
}
pub fn build_router(state: Arc<AppState>) -> Router {
let library = Router::new()
.route("/artists", get(api::list_artists))
.route("/artists/:slug", get(api::get_artist))
.route("/artists/:slug/albums", get(api::list_artist_albums))
.route("/artists/:slug/tracks", get(api::list_artist_all_tracks))
.route("/albums/:slug", get(api::get_album_tracks))
.route("/albums/:slug/cover", get(api::album_cover))
.route("/tracks/:slug", get(api::get_track_detail))
.route("/tracks/:slug/cover", get(api::track_cover))
.route("/stream/:slug", get(api::stream_track))
.route("/search", get(api::search));
let authed = Router::new()
.route("/", get(player_html))
.nest("/api", library);
let requires_auth = state.oidc.is_some();
let app = if requires_auth {
authed
.route_layer(middleware::from_fn_with_state(state.clone(), auth::require_auth))
} else {
authed
};
let cors = CorsLayer::new()
.allow_origin(Any)
.allow_methods([Method::GET, Method::OPTIONS, Method::HEAD])
.allow_headers([header::ACCEPT, header::CONTENT_TYPE, header::HeaderName::from_static("x-api-key")])
.max_age(Duration::from_secs(600));
Router::new()
.route("/login", get(auth::login_page))
.route("/logout", get(auth::logout))
.route("/auth/login", get(auth::oidc_login))
.route("/auth/callback", get(auth::oidc_callback))
.merge(app)
.layer(cors)
.with_state(state)
}
async fn player_html() -> axum::response::Html<String> {
let html = include_str!("player.html")
.replace("<!-- VERSION_PLACEHOLDER -->", option_env!("FURUMI_VERSION").unwrap_or(env!("CARGO_PKG_VERSION")));
axum::response::Html(html)
}