diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-01-25 15:01:38 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-01-25 15:01:38 +0100 |
| commit | 5075aede44cb8ab2df10e6debba38483e8d11e96 (patch) | |
| tree | f719e4b4a0c29f3a27b4fa7cf0a6ee6f7739125c /server/src | |
| parent | 53361f4c6027d1569a707ce58889bc2c2ea3749c (diff) | |
| download | jellything-5075aede44cb8ab2df10e6debba38483e8d11e96.tar jellything-5075aede44cb8ab2df10e6debba38483e8d11e96.tar.bz2 jellything-5075aede44cb8ab2df10e6debba38483e8d11e96.tar.zst | |
remove some unused imports; css reload; port login logic
Diffstat (limited to 'server/src')
| -rw-r--r-- | server/src/api.rs | 14 | ||||
| -rw-r--r-- | server/src/auth.rs | 63 | ||||
| -rw-r--r-- | server/src/routes.rs | 3 | ||||
| -rw-r--r-- | server/src/ui/account/mod.rs | 15 | ||||
| -rw-r--r-- | server/src/ui/admin/import.rs | 10 | ||||
| -rw-r--r-- | server/src/ui/admin/log.rs | 13 | ||||
| -rw-r--r-- | server/src/ui/admin/mod.rs | 2 | ||||
| -rw-r--r-- | server/src/ui/admin/user.rs | 15 | ||||
| -rw-r--r-- | server/src/ui/assets.rs | 3 | ||||
| -rw-r--r-- | server/src/ui/error.rs | 2 | ||||
| -rw-r--r-- | server/src/ui/home.rs | 3 | ||||
| -rw-r--r-- | server/src/ui/items.rs | 6 | ||||
| -rw-r--r-- | server/src/ui/mod.rs | 12 | ||||
| -rw-r--r-- | server/src/ui/node.rs | 12 | ||||
| -rw-r--r-- | server/src/ui/player.rs | 19 | ||||
| -rw-r--r-- | server/src/ui/search.rs | 5 | ||||
| -rw-r--r-- | server/src/ui/stats.rs | 5 | ||||
| -rw-r--r-- | server/src/ui/style.rs | 47 |
18 files changed, 87 insertions, 162 deletions
diff --git a/server/src/api.rs b/server/src/api.rs index 45bcd90..2b3d016 100644 --- a/server/src/api.rs +++ b/server/src/api.rs @@ -4,8 +4,7 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::ui::error::MyResult; -use rocket::{get, post, response::Redirect, serde::json::Json}; -use serde_json::{Value, json}; +use rocket::{get, response::Redirect, serde::json::Json}; #[get("/api")] pub fn r_api_root() -> Redirect { @@ -38,17 +37,6 @@ pub fn r_version() -> &'static str { // } // } -#[post("/api/create_session", data = "<data>")] -pub fn r_api_account_login(data: Json<CreateSessionParams>) -> MyResult<Value> { - let token = login_logic( - &data.username, - &data.password, - data.expire, - data.drop_permissions.clone(), - )?; - Ok(json!(token)) -} - #[get("/nodes_modified?<since>")] pub fn r_nodes_modified_since(session: A<Session>, since: u64) -> MyResult<Json<Vec<NodeID>>> { let nodes = get_nodes_modified_since(&session.0, since)?; diff --git a/server/src/auth.rs b/server/src/auth.rs index e84c4d1..0e523ed 100644 --- a/server/src/auth.rs +++ b/server/src/auth.rs @@ -5,8 +5,13 @@ */ use crate::State; -use anyhow::{Result, anyhow}; -use jellycommon::jellyobject::ObjectBuffer; +use anyhow::{Result, anyhow, bail}; +use argon2::{Argon2, PasswordHasher, password_hash::Salt}; +use jellycommon::{ + USER_LOGIN, USER_PASSWORD, + jellyobject::{ObjectBuffer, Path}, +}; +use jellydb::query::{Filter, Query, Sort}; pub fn token_to_user(state: &State, token: &str) -> Result<ObjectBuffer> { let user_row = token::validate(&state.session_key, token)?; @@ -20,6 +25,55 @@ pub fn token_to_user(state: &State, token: &str) -> Result<ObjectBuffer> { user.ok_or(anyhow!("user was deleted")) } +pub fn login(state: &State, username: &str, password: &str, expire: Option<i64>) -> Result<String> { + let password = hash_password(username, password); + + let mut user_row = None; + let mut user = None; + state.database.read_transaction(&mut |txn| { + user_row = state.users.query_single( + txn, + Query { + filter: Filter::Match(Path(vec![USER_LOGIN.0]), username.as_bytes().to_vec()), + sort: Sort::None, + }, + )?; + if let Some(ur) = user_row { + user = state.users.get(txn, ur)?; + } + Ok(()) + }); + + let (Some(user_row), Some(user)) = (user_row, user) else { + bail!("unknown user"); + }; + let Some(correct_pw) = user.as_object().get(USER_PASSWORD) else { + bail!("password login is disabled") + }; + if password != correct_pw { + bail!("incorrect password") + } + + Ok(token::create( + &state.session_key, + user_row, + expire.unwrap_or(60 * 60 * 24 * 30), + )) +} + +pub fn hash_password(username: &str, password: &str) -> Vec<u8> { + Argon2::default() + .hash_password( + format!("{username}\0{password}").as_bytes(), + <&str as TryInto<Salt>>::try_into("IYMa13osbNeLJKnQ1T8LlA").unwrap(), + ) + .unwrap() + .hash + .unwrap() + .as_bytes() + .to_vec() +} + pub mod token { use aes_gcm_siv::{ Aes256GcmSiv, KeyInit, @@ -32,7 +86,6 @@ pub mod token { }; use chrono::Utc; use jellydb::table::RowNum; - use std::time::Duration; pub struct SessionKey(Aes256GcmSiv); @@ -43,8 +96,8 @@ pub mod token { } } - pub fn create(sk: &SessionKey, user: RowNum, expire: Duration) -> String { - let expire_ts = Utc::now().timestamp() + expire.as_secs() as i64; + pub fn create(sk: &SessionKey, user: RowNum, expire: i64) -> String { + let expire_ts = Utc::now().timestamp() + expire; let mut plain = Vec::new(); plain.extend(user.to_be_bytes()); plain.extend(expire_ts.to_be_bytes()); diff --git a/server/src/routes.rs b/server/src/routes.rs index 62a70b7..19c76b2 100644 --- a/server/src/routes.rs +++ b/server/src/routes.rs @@ -5,7 +5,7 @@ */ use crate::{ State, - api::{r_api_account_login, r_api_root, r_nodes_modified_since, r_version}, + api::{r_api_root, r_nodes_modified_since, r_version}, compat::youtube::{r_youtube_channel, r_youtube_embed, r_youtube_watch}, logic::{ playersync::{PlayersyncChannels, r_playersync}, @@ -127,7 +127,6 @@ pub fn build_rocket(state: Arc<State>) -> Rocket<Build> { r_stats, r_stream, // API - r_api_account_login, r_nodes_modified_since, r_api_root, r_version, diff --git a/server/src/ui/account/mod.rs b/server/src/ui/account/mod.rs index 35cf52e..429b70a 100644 --- a/server/src/ui/account/mod.rs +++ b/server/src/ui/account/mod.rs @@ -6,25 +6,16 @@ pub mod settings; use super::error::MyError; -use crate::{ - request_info::{language::AcceptLanguage, A}, - ui::{error::MyResult, home::rocket_uri_macro_r_home}, -}; +use crate::ui::{error::MyResult, home::rocket_uri_macro_r_home}; use anyhow::anyhow; use jellyimport::is_importing; -use jellylogic::{account::register_user, login::login_logic, session::Session}; -use jellyui::{ - account::{AccountLogin, AccountLogout, AccountRegister, AccountRegisterSuccess}, - render_page, - scaffold::{RenderInfo, SessionInfo}, -}; use rocket::{ + FromForm, form::{Contextual, Form}, get, http::{Cookie, CookieJar}, post, - response::{content::RawHtml, Redirect}, - FromForm, + response::{Redirect, content::RawHtml}, }; use serde::{Deserialize, Serialize}; diff --git a/server/src/ui/admin/import.rs b/server/src/ui/admin/import.rs index fb33c67..79b8374 100644 --- a/server/src/ui/admin/import.rs +++ b/server/src/ui/admin/import.rs @@ -4,25 +4,19 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use std::time::Duration; - -use crate::{ - request_info::{A, RequestInfo}, - ui::error::MyResult, -}; +use crate::{request_info::RequestInfo, ui::error::MyResult}; use jellycommon::routes::u_admin_import; use jellyimport::{ is_importing, reporting::{IMPORT_ERRORS, IMPORT_PROGRESS}, }; -use jellylogic::{admin::do_import, session::Session}; -use jellyui::{admin::import::AdminImportPage, locale::tr, render_page}; use rocket::{ get, post, request::FlashMessage, response::{Flash, Redirect, content::RawHtml}, }; use rocket_ws::{Message, Stream, WebSocket}; +use std::time::Duration; use tokio::time::sleep; #[get("/admin/import", rank = 2)] diff --git a/server/src/ui/admin/log.rs b/server/src/ui/admin/log.rs index e948daa..da70360 100644 --- a/server/src/ui/admin/log.rs +++ b/server/src/ui/admin/log.rs @@ -3,18 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{ - request_info::{A, RequestInfo}, - ui::error::MyResult, -}; -use jellylogic::{ - admin::log::{get_log_buffer, get_log_stream}, - session::Session, -}; -use jellyui::{ - admin::log::{ServerLogPage, render_log_line}, - render_page, -}; +use crate::{request_info::RequestInfo, ui::error::MyResult}; use rocket::{get, response::content::RawHtml}; use rocket_ws::{Message, Stream, WebSocket}; use serde_json::json; diff --git a/server/src/ui/admin/mod.rs b/server/src/ui/admin/mod.rs index 9759627..5ee05b7 100644 --- a/server/src/ui/admin/mod.rs +++ b/server/src/ui/admin/mod.rs @@ -11,8 +11,6 @@ use super::error::MyResult; use crate::request_info::RequestInfo; use jellycommon::routes::u_admin_dashboard; use jellyimport::is_importing; -use jellylogic::admin::{create_invite, delete_invite, list_invites, update_search_index}; -use jellyui::{admin::AdminDashboardPage, locale::tr, render_page}; use rocket::{ FromForm, form::Form, diff --git a/server/src/ui/admin/user.rs b/server/src/ui/admin/user.rs index 03950df..b4770c8 100644 --- a/server/src/ui/admin/user.rs +++ b/server/src/ui/admin/user.rs @@ -5,21 +5,12 @@ */ use crate::{request_info::RequestInfo, ui::error::MyResult}; use anyhow::Context; -use jellycommon::{ - routes::{u_admin_user, u_admin_users}, - user::UserPermission, -}; -use jellylogic::admin::user::{admin_users, delete_user, get_user, update_user_perms, GrantState}; -use jellyui::{ - admin::user::{AdminUserPage, AdminUsersPage}, - locale::tr, - render_page, -}; +use jellycommon::routes::{u_admin_user, u_admin_users}; use rocket::{ + FromForm, FromFormField, form::Form, get, post, - response::{content::RawHtml, Flash, Redirect}, - FromForm, FromFormField, + response::{Flash, Redirect, content::RawHtml}, }; #[get("/admin/users")] diff --git a/server/src/ui/assets.rs b/server/src/ui/assets.rs index 6dc6731..8f3fb4a 100644 --- a/server/src/ui/assets.rs +++ b/server/src/ui/assets.rs @@ -4,10 +4,7 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::error::MyResult; -use crate::request_info::{A, cache::CacheControlImage}; use anyhow::{Context, anyhow}; -use jellycommon::{Asset, NodeID, PictureSlot, api::NodeFilterSort}; -use jellylogic::{assets::get_node_thumbnail, node::get_node, session::Session}; use rocket::{get, http::ContentType, response::Redirect}; use std::str::FromStr; diff --git a/server/src/ui/error.rs b/server/src/ui/error.rs index d94639a..0f279fc 100644 --- a/server/src/ui/error.rs +++ b/server/src/ui/error.rs @@ -3,8 +3,6 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::CONF; -use jellyui::{error::ErrorPage, locale::Language, render_page, scaffold::RenderInfo}; use log::info; use rocket::{ catch, diff --git a/server/src/ui/home.rs b/server/src/ui/home.rs index 499c3cd..4e9fd28 100644 --- a/server/src/ui/home.rs +++ b/server/src/ui/home.rs @@ -5,9 +5,6 @@ */ use super::error::MyResult; -use crate::request_info::{accept::Accept, RequestInfo}; -use jellycommon::api::ApiHomeResponse; -use jellyui::{home::HomePage, render_page}; use rocket::{get, response::content::RawHtml, serde::json::Json, Either}; #[get("/home")] diff --git a/server/src/ui/items.rs b/server/src/ui/items.rs index 86aaf12..cc8c18f 100644 --- a/server/src/ui/items.rs +++ b/server/src/ui/items.rs @@ -4,11 +4,7 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::error::MyError; -use crate::request_info::{accept::Accept, filter_sort::ANodeFilterSort, RequestInfo}; -use jellycommon::api::ApiItemsResponse; -use jellylogic::items::all_items; -use jellyui::{items::ItemsPage, render_page}; -use rocket::{get, response::content::RawHtml, serde::json::Json, Either}; +use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; #[get("/items?<page>&<filter..>")] pub fn r_items( diff --git a/server/src/ui/mod.rs b/server/src/ui/mod.rs index 946401e..92b93fe 100644 --- a/server/src/ui/mod.rs +++ b/server/src/ui/mod.rs @@ -3,23 +3,17 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{ - request_info::{language::AcceptLanguage, A}, - CONF, -}; use error::MyResult; use home::rocket_uri_macro_r_home; -use jellylogic::session::Session; -use jellyui::{render_page, scaffold::RenderInfo, CustomPage}; use rocket::{ + Either, futures::FutureExt, get, - response::{content::RawHtml, Redirect}, - Either, + response::{Redirect, content::RawHtml}, }; use std::{future::Future, pin::Pin}; use tokio::{ - fs::{read_to_string, File}, + fs::{File, read_to_string}, io::AsyncRead, }; diff --git a/server/src/ui/node.rs b/server/src/ui/node.rs index fac1909..85beac6 100644 --- a/server/src/ui/node.rs +++ b/server/src/ui/node.rs @@ -4,18 +4,12 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::error::MyResult; -use crate::request_info::{filter_sort::ANodeFilterSort, RequestInfo, A}; -use jellycommon::{ - api::{ApiNodeResponse, NodeFilterSort}, - NodeID, -}; -use jellylogic::node::get_node; -use jellyui::{node_page::NodePage, render_page}; -use rocket::{get, response::content::RawHtml, serde::json::Json, Either}; +use crate::request_info::RequestInfo; +use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; #[get("/n/<id>?<parents>&<children>&<filter..>")] pub async fn r_node( - ri: RequestInfo, + ri: RequestInfo<'_>, id: A<NodeID>, filter: Option<ANodeFilterSort>, parents: bool, diff --git a/server/src/ui/player.rs b/server/src/ui/player.rs index d43f3ea..b9d7d2e 100644 --- a/server/src/ui/player.rs +++ b/server/src/ui/player.rs @@ -4,22 +4,11 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::error::MyResult; -use crate::{ - request_info::{RequestInfo, A}, - CONF, -}; -use jellycommon::{ - api::NodeFilterSort, - stream::{StreamContainer, StreamSpec}, - user::{PermissionSet, PlayerKind}, - NodeID, -}; -use jellylogic::node::get_node; -use jellyui::{node_page::NodePage, render_page}; +use crate::request_info::RequestInfo; +use jellycommon::stream::{StreamContainer, StreamSpec}; use rocket::{ - get, - response::{content::RawHtml, Redirect}, - Either, + Either, get, + response::{Redirect, content::RawHtml}, }; use std::time::Duration; diff --git a/server/src/ui/search.rs b/server/src/ui/search.rs index 8a67672..fce79e3 100644 --- a/server/src/ui/search.rs +++ b/server/src/ui/search.rs @@ -6,10 +6,7 @@ use super::error::MyResult; use crate::request_info::RequestInfo; use anyhow::anyhow; -use jellycommon::api::ApiSearchResponse; -use jellylogic::search::search; -use jellyui::{render_page, search::SearchPage}; -use rocket::{get, response::content::RawHtml, serde::json::Json, Either}; +use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; #[get("/search?<query>&<page>")] pub async fn r_search( diff --git a/server/src/ui/stats.rs b/server/src/ui/stats.rs index b0225e6..fc4ae64 100644 --- a/server/src/ui/stats.rs +++ b/server/src/ui/stats.rs @@ -5,10 +5,7 @@ */ use super::error::MyError; use crate::request_info::RequestInfo; -use jellycommon::api::ApiStatsResponse; -use jellylogic::stats::stats; -use jellyui::{render_page, stats::StatsPage}; -use rocket::{get, response::content::RawHtml, serde::json::Json, Either}; +use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; #[get("/stats")] pub fn r_stats( diff --git a/server/src/ui/style.rs b/server/src/ui/style.rs index 5226b6a..2b7d2de 100644 --- a/server/src/ui/style.rs +++ b/server/src/ui/style.rs @@ -4,50 +4,13 @@ Copyright (C) 2026 metamuffin <metamuffin.org> Copyright (C) 2023 tpart */ +use jellyui::{css_bundle, js_bundle, js_bundle_map}; use rocket::{ get, http::{ContentType, Header}, response::Responder, }; - -macro_rules! concat_files { - ([$base: expr], $($files:literal),*) => {{ - #[cfg(any(debug_assertions, feature = "hot-css"))] - { - use std::{fs::read_to_string, path::PathBuf, str::FromStr}; - [ $($files),* ] - .into_iter() - .map(|n| { - read_to_string({ - let p = PathBuf::from_str(file!()).unwrap().parent().unwrap().join($base).join(n); - log::info!("load {p:?}"); - p - }) - .unwrap() - }) - .collect::<Vec<_>>() - .join("\n") - } - #[cfg(not(any(debug_assertions, feature = "hot-css")))] - concat!($(include_str!(concat!($base, "/", $files))),*).to_string() - }}; -} - -fn css_bundle() -> String { - concat_files!( - ["../../../web/style"], - "layout.css", - "player.css", - "nodepage.css", - "nodecard.css", - "js-player.css", - "js-transition.css", - "forms.css", - "props.css", - "themes.css", - "navbar.css" - ) -} +use std::borrow::Cow; pub struct CachedAsset<T>(pub T); impl<'r, 'o: 'r, T: Responder<'r, 'o>> Responder<'r, 'o> for CachedAsset<T> { @@ -61,7 +24,7 @@ impl<'r, 'o: 'r, T: Responder<'r, 'o>> Responder<'r, 'o> for CachedAsset<T> { } #[get("/assets/style.css")] -pub fn r_assets_style() -> CachedAsset<(ContentType, String)> { +pub fn r_assets_style() -> CachedAsset<(ContentType, Cow<'static, str>)> { CachedAsset((ContentType::CSS, css_bundle())) } @@ -74,10 +37,10 @@ pub fn r_assets_font() -> CachedAsset<(ContentType, &'static [u8])> { } #[get("/assets/bundle.js")] -pub fn r_assets_js() -> CachedAsset<(ContentType, String)> { +pub fn r_assets_js() -> CachedAsset<(ContentType, Cow<'static, str>)> { CachedAsset((ContentType::JavaScript, js_bundle())) } #[get("/assets/bundle.js.map")] -pub fn r_assets_js_map() -> CachedAsset<(ContentType, String)> { +pub fn r_assets_js_map() -> CachedAsset<(ContentType, Cow<'static, str>)> { CachedAsset((ContentType::JSON, js_bundle_map())) } |