aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-23 17:25:28 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-23 17:25:28 +0100
commit064a7906f6c6e18ad4ce5fb5a19e5e3d02144358 (patch)
treec7e62f961ab5638aa36b1c669bc49d03939bcc41 /server
parent807cde3a096a6e87d13a98d2ee78578732b1fb45 (diff)
downloadjellything-064a7906f6c6e18ad4ce5fb5a19e5e3d02144358.tar
jellything-064a7906f6c6e18ad4ce5fb5a19e5e3d02144358.tar.bz2
jellything-064a7906f6c6e18ad4ce5fb5a19e5e3d02144358.tar.zst
user settings page
Diffstat (limited to 'server')
-rw-r--r--server/src/routes.rs9
-rw-r--r--server/src/ui/account/mod.rs2
-rw-r--r--server/src/ui/account/settings.rs115
3 files changed, 79 insertions, 47 deletions
diff --git a/server/src/routes.rs b/server/src/routes.rs
index 334fb39..2b7fed9 100644
--- a/server/src/routes.rs
+++ b/server/src/routes.rs
@@ -12,7 +12,10 @@ use crate::{
stream::r_stream,
},
ui::{
- account::{r_account_login, r_account_login_post, r_account_logout, r_account_logout_post},
+ account::{
+ r_account_login, r_account_login_post, r_account_logout, r_account_logout_post,
+ settings::{r_account_settings, r_account_settings_post},
+ },
admin::{
import::{r_admin_import, r_admin_import_post, r_admin_import_stream},
log::{r_admin_log, r_admin_log_stream},
@@ -78,8 +81,8 @@ pub(super) fn build_rocket(state: Arc<State>) -> Rocket<Build> {
r_account_logout,
// r_account_register_post,
// r_account_register,
- // r_account_settings_post,
- // r_account_settings,
+ r_account_settings_post,
+ r_account_settings,
r_admin_dashboard,
r_admin_import,
r_admin_import_post,
diff --git a/server/src/ui/account/mod.rs b/server/src/ui/account/mod.rs
index 8c60a2d..448f91e 100644
--- a/server/src/ui/account/mod.rs
+++ b/server/src/ui/account/mod.rs
@@ -5,6 +5,8 @@
*/
// pub mod settings;
+pub mod settings;
+
use super::error::MyError;
use crate::{
auth::login, request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse,
diff --git a/server/src/ui/account/settings.rs b/server/src/ui/account/settings.rs
index 167731f..2e9fcbe 100644
--- a/server/src/ui/account/settings.rs
+++ b/server/src/ui/account/settings.rs
@@ -5,24 +5,23 @@
*/
use super::format_form_error;
use crate::{
- request_info::{RequestInfo, A},
- ui::error::MyResult,
+ auth::hash_password, request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse,
};
+use anyhow::anyhow;
use jellycommon::{
+ MESSAGE_KIND, MESSAGE_TEXT, USER_LOGIN, USER_NAME, USER_PASSWORD, VIEW_MESSAGE,
+ VIEW_USER_SETTINGS,
+ jellyobject::{Object, ObjectBuffer, ObjectBufferBuilder, Path},
routes::u_account_settings,
- user::{PlayerKind, Theme},
};
-use jellylogic::account::{
- update_user_display_name, update_user_native_secret, update_user_password,
- update_user_player_preference, update_user_theme,
-};
-use jellyui::{account::settings::SettingsPage, locale::tr, render_page, scaffold::SessionInfo};
+use jellydb::{Filter, Query, Sort};
+use jellyui::tr;
use rocket::{
- form::{self, validate::len, Contextual, Form},
+ FromForm,
+ form::{self, Contextual, Form, validate::len},
get, post,
request::FlashMessage,
- response::{content::RawHtml, Flash, Redirect},
- FromForm,
+ response::{Flash, Redirect},
};
use std::ops::Range;
@@ -31,10 +30,7 @@ pub struct SettingsForm {
#[field(validate = option_len(4..64))]
password: Option<String>,
#[field(validate = option_len(4..32))]
- display_name: Option<String>,
- theme: Option<A<Theme>>,
- player_preference: Option<A<PlayerKind>>,
- native_secret: Option<String>,
+ name: Option<String>,
}
fn option_len<'v>(value: &Option<String>, range: Range<usize>) -> form::Result<'v, ()> {
@@ -42,17 +38,21 @@ fn option_len<'v>(value: &Option<String>, range: Range<usize>) -> form::Result<'
}
#[get("/account/settings")]
-pub fn r_account_settings(ri: RequestInfo, flash: Option<FlashMessage>) -> RawHtml<String> {
- RawHtml(render_page(
- &SettingsPage {
- flash: &flash.map(FlashMessage::into_inner),
- session: &SessionInfo {
- user: ri.session.user.clone(),
- },
- lang: &ri.lang,
- },
- ri.render_info(),
- ))
+pub fn r_account_settings(ri: RequestInfo, flash: Option<FlashMessage>) -> MyResult<UiResponse> {
+ let user = ri.require_user()?;
+ let mut view = ObjectBufferBuilder::default();
+ view.push(VIEW_USER_SETTINGS, user);
+ if let Some(flash) = flash {
+ view.push(
+ VIEW_MESSAGE,
+ ObjectBuffer::new(&mut [
+ (MESSAGE_KIND.0, &flash.kind()),
+ (MESSAGE_TEXT.0, &flash.message()),
+ ])
+ .as_object(),
+ );
+ }
+ Ok(ri.respond_ui(view.finish()))
}
#[post("/account/settings", data = "<form>")]
@@ -73,30 +73,35 @@ pub fn r_account_settings_post(
let mut out = String::new();
if let Some(password) = &form.password {
- update_user_password(&ri.session, password)?;
+ let login = ri
+ .require_user()?
+ .get(USER_LOGIN)
+ .ok_or(anyhow!("user has no login"))?;
+ let password = hash_password(login, password);
+ update_user(&ri, |user| user.insert(USER_PASSWORD, &password))?;
out += &*tr(ri.lang, "settings.account.password.changed");
out += "\n";
}
- if let Some(display_name) = &form.display_name {
- update_user_display_name(&ri.session, display_name)?;
+ if let Some(name) = &form.name {
+ update_user(&ri, |user| user.insert(USER_NAME, name))?;
out += &*tr(ri.lang, "settings.account.display_name.changed");
out += "\n";
}
- if let Some(theme) = form.theme {
- update_user_theme(&ri.session, theme.0)?;
- out += &*tr(ri.lang, "settings.account.theme.changed");
- out += "\n";
- }
- if let Some(player_preference) = form.player_preference {
- update_user_player_preference(&ri.session, player_preference.0)?;
- out += &*tr(ri.lang, "settings.player_preference.changed");
- out += "\n";
- }
- if let Some(native_secret) = &form.native_secret {
- update_user_native_secret(&ri.session, native_secret)?;
- out += &*tr(ri.lang, "settings.native_secret.changed");
- out += "\n";
- }
+ // if let Some(theme) = form.theme {
+ // update_user_theme(&ri.session, theme.0)?;
+ // out += &*tr(ri.lang, "settings.account.theme.changed");
+ // out += "\n";
+ // }
+ // if let Some(player_preference) = form.player_preference {
+ // update_user_player_preference(&ri.session, player_preference.0)?;
+ // out += &*tr(ri.lang, "settings.player_preference.changed");
+ // out += "\n";
+ // }
+ // if let Some(native_secret) = &form.native_secret {
+ // update_user_native_secret(&ri.session, native_secret)?;
+ // out += &*tr(ri.lang, "settings.native_secret.changed");
+ // out += "\n";
+ // }
let out = if out.is_empty() {
tr(ri.lang, "settings.no_change").to_string()
} else {
@@ -105,3 +110,25 @@ pub fn r_account_settings_post(
Ok(Flash::success(Redirect::to(u_account_settings()), out))
}
+
+fn update_user(ri: &RequestInfo, update: impl Fn(Object) -> ObjectBuffer) -> MyResult<()> {
+ let login = ri
+ .require_user()?
+ .get(USER_LOGIN)
+ .ok_or(anyhow!("user has no login"))?;
+ ri.state.database.transaction(&mut |txn| {
+ let user_row = txn
+ .query_single(Query {
+ filter: Filter::Match(Path(vec![USER_LOGIN.0]), login.into()),
+ sort: Sort::None,
+ })?
+ .ok_or(anyhow!("user vanished"))?;
+
+ let user = txn.get(user_row)?.unwrap();
+ let new_user = update(user.as_object());
+ txn.update(user_row, new_user)?;
+
+ Ok(())
+ })?;
+ Ok(())
+}