aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/routes.rs')
-rw-r--r--server/src/routes.rs212
1 files changed, 212 insertions, 0 deletions
diff --git a/server/src/routes.rs b/server/src/routes.rs
new file mode 100644
index 0000000..4e452c3
--- /dev/null
+++ b/server/src/routes.rs
@@ -0,0 +1,212 @@
+/*
+ This file is part of jellything (https://codeberg.org/metamuffin/jellything)
+ which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
+ Copyright (C) 2025 metamuffin <metamuffin.org>
+*/
+use crate::database::Database;
+use crate::logic::playersync::{r_playersync, PlayersyncChannels};
+use crate::ui::{
+ account::{
+ r_account_login, r_account_login_post, r_account_logout, r_account_logout_post,
+ r_account_register, r_account_register_post,
+ settings::{r_account_settings, r_account_settings_post},
+ },
+ admin::{
+ log::{r_admin_log, r_admin_log_stream},
+ r_admin_dashboard, r_admin_delete_cache, r_admin_import, r_admin_invite,
+ r_admin_remove_invite, r_admin_transcode_posters, r_admin_update_search,
+ user::{r_admin_remove_user, r_admin_user, r_admin_user_permission, r_admin_users},
+ },
+ assets::{r_asset, r_item_backdrop, r_item_poster, r_node_thumbnail, r_person_asset},
+ browser::r_all_items_filter,
+ error::{r_api_catch, r_catch},
+ home::r_home,
+ node::r_library_node_filter,
+ player::r_player,
+ r_favicon, r_index,
+ search::r_search,
+ stats::r_stats,
+ style::{r_assets_font, r_assets_js, r_assets_js_map, r_assets_style},
+};
+use crate::{
+ api::{
+ r_api_account_login, r_api_asset_token_raw, r_api_nodes_modified_since, r_api_root,
+ r_api_version,
+ },
+ compat::{
+ jellyfin::{
+ r_jellyfin_artists, r_jellyfin_branding_configuration, r_jellyfin_branding_css,
+ r_jellyfin_displaypreferences_usersettings,
+ r_jellyfin_displaypreferences_usersettings_post, r_jellyfin_items,
+ r_jellyfin_items_image_primary, r_jellyfin_items_images_backdrop,
+ r_jellyfin_items_intros, r_jellyfin_items_item, r_jellyfin_items_playbackinfo,
+ r_jellyfin_items_similar, r_jellyfin_livetv_programs_recommended, r_jellyfin_persons,
+ r_jellyfin_playback_bitratetest, r_jellyfin_quickconnect_enabled,
+ r_jellyfin_sessions_capabilities_full, r_jellyfin_sessions_playing,
+ r_jellyfin_sessions_playing_progress, r_jellyfin_shows_nextup, r_jellyfin_socket,
+ r_jellyfin_system_endpoint, r_jellyfin_system_info, r_jellyfin_system_info_public,
+ r_jellyfin_system_info_public_case, r_jellyfin_users_authenticatebyname,
+ r_jellyfin_users_authenticatebyname_case, r_jellyfin_users_id, r_jellyfin_users_items,
+ r_jellyfin_users_items_item, r_jellyfin_users_public, r_jellyfin_users_views,
+ r_jellyfin_video_stream,
+ },
+ youtube::{r_youtube_channel, r_youtube_embed, r_youtube_watch},
+ },
+ logic::{
+ stream::r_stream,
+ userdata::{
+ r_node_userdata, r_node_userdata_progress, r_node_userdata_rating,
+ r_node_userdata_watched,
+ },
+ },
+};
+use base64::Engine;
+use jellybase::{federation::Federation, CONF, SECRETS};
+use log::warn;
+use rand::random;
+use rocket::{
+ catchers, config::SecretKey, fairing::AdHoc, fs::FileServer, http::Header, routes,
+ shield::Shield, Build, Config, Rocket,
+};
+
+#[macro_export]
+macro_rules! uri {
+ ($kk:stmt) => {
+ &rocket::uri!($kk).to_string()
+ };
+}
+
+pub fn build_rocket(database: Database, federation: Federation) -> Rocket<Build> {
+ rocket::build()
+ .configure(Config {
+ address: std::env::var("BIND_ADDR")
+ .map(|e| e.parse().unwrap())
+ .unwrap_or("127.0.0.1".parse().unwrap()),
+ port: std::env::var("PORT")
+ .map(|e| e.parse().unwrap())
+ .unwrap_or(8000),
+ secret_key: SecretKey::derive_from(
+ SECRETS
+ .cookie_key
+ .clone()
+ .unwrap_or_else(|| {
+ warn!("cookie_key not configured, generating a random one.");
+ base64::engine::general_purpose::STANDARD.encode([(); 32].map(|_| random()))
+ })
+ .as_bytes(),
+ ),
+ ip_header: Some("x-forwarded-for".into()),
+ ..Default::default()
+ })
+ .manage(database)
+ .manage(federation)
+ .manage(PlayersyncChannels::default())
+ .attach(AdHoc::on_response("set server header", |_req, res| {
+ res.set_header(Header::new("server", "jellything"));
+ Box::pin(async {})
+ }))
+ // TODO this would be useful but needs to handle not only the entry-point
+ // .attach(AdHoc::on_response("frame options", |req, resp| {
+ // if !req.uri().path().as_str().starts_with("/embed") {
+ // resp.set_raw_header("X-Frame-Options", "SAMEORIGIN");
+ // }
+ // Box::pin(async {})
+ // }))
+ .attach(Shield::new())
+ .register("/", catchers![r_catch])
+ .register("/api", catchers![r_api_catch])
+ .mount("/assets", FileServer::from(&CONF.asset_path))
+ .mount(
+ "/",
+ routes![
+ // Frontend
+ r_account_login_post,
+ r_account_login,
+ r_account_logout_post,
+ r_account_logout,
+ r_account_register_post,
+ r_account_register,
+ r_account_settings_post,
+ r_account_settings,
+ r_admin_dashboard,
+ r_admin_delete_cache,
+ r_admin_import,
+ r_admin_invite,
+ r_admin_log_stream,
+ r_admin_log,
+ r_admin_remove_invite,
+ r_admin_remove_user,
+ r_admin_transcode_posters,
+ r_admin_update_search,
+ r_admin_user_permission,
+ r_admin_user,
+ r_admin_users,
+ r_all_items_filter,
+ r_asset,
+ r_assets_font,
+ r_assets_js_map,
+ r_assets_js,
+ r_assets_style,
+ r_favicon,
+ r_home,
+ r_index,
+ r_item_backdrop,
+ r_item_poster,
+ r_library_node_filter,
+ r_node_thumbnail,
+ r_node_userdata_progress,
+ r_node_userdata_rating,
+ r_node_userdata_watched,
+ r_node_userdata,
+ r_person_asset,
+ r_player,
+ r_playersync,
+ r_search,
+ r_stats,
+ r_stream,
+ // API
+ r_api_account_login,
+ r_api_asset_token_raw,
+ r_api_nodes_modified_since,
+ r_api_root,
+ r_api_version,
+ // Compat
+ r_jellyfin_artists,
+ r_jellyfin_branding_configuration,
+ r_jellyfin_branding_css,
+ r_jellyfin_displaypreferences_usersettings_post,
+ r_jellyfin_displaypreferences_usersettings,
+ r_jellyfin_items_image_primary,
+ r_jellyfin_items_images_backdrop,
+ r_jellyfin_items_intros,
+ r_jellyfin_items_item,
+ r_jellyfin_items_playbackinfo,
+ r_jellyfin_items_similar,
+ r_jellyfin_items,
+ r_jellyfin_livetv_programs_recommended,
+ r_jellyfin_persons,
+ r_jellyfin_playback_bitratetest,
+ r_jellyfin_quickconnect_enabled,
+ r_jellyfin_sessions_capabilities_full,
+ r_jellyfin_sessions_playing_progress,
+ r_jellyfin_sessions_playing,
+ r_jellyfin_shows_nextup,
+ r_jellyfin_socket,
+ r_jellyfin_system_endpoint,
+ r_jellyfin_system_info_public_case,
+ r_jellyfin_system_info_public,
+ r_jellyfin_system_info,
+ r_jellyfin_users_authenticatebyname,
+ r_jellyfin_users_authenticatebyname_case,
+ r_jellyfin_users_id,
+ r_jellyfin_users_items_item,
+ r_jellyfin_users_items,
+ r_jellyfin_users_public,
+ r_jellyfin_users_views,
+ r_jellyfin_video_stream,
+ r_youtube_channel,
+ r_youtube_embed,
+ r_youtube_watch,
+ ],
+ )
+}