diff options
author | metamuffin <metamuffin@disroot.org> | 2023-01-29 18:23:30 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-01-29 18:23:30 +0100 |
commit | 15d0a83247c3b6091f006df967f54f8399030cf6 (patch) | |
tree | ea99621ec7c6f58417c56bf671b2937e37487888 /server/src/routes/ui/account/settings.rs | |
parent | de8d69d2886ae50e28da210fc690c99457a804bb (diff) | |
download | jellything-15d0a83247c3b6091f006df967f54f8399030cf6.tar jellything-15d0a83247c3b6091f006df967f54f8399030cf6.tar.bz2 jellything-15d0a83247c3b6091f006df967f54f8399030cf6.tar.zst |
user settings page
Diffstat (limited to 'server/src/routes/ui/account/settings.rs')
-rw-r--r-- | server/src/routes/ui/account/settings.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/server/src/routes/ui/account/settings.rs b/server/src/routes/ui/account/settings.rs new file mode 100644 index 0000000..c95c4bb --- /dev/null +++ b/server/src/routes/ui/account/settings.rs @@ -0,0 +1,103 @@ +use std::ops::Range; + +use rocket::{ + form::{self, validate::len, Contextual, Form}, + get, post, FromForm, State, +}; + +use super::{format_form_error, hash_password}; +use crate::{ + database::Database, + routes::ui::{ + account::session::Session, + error::MyResult, + layout::{DynLayoutPage, LayoutPage}, + }, + uri, +}; + +#[derive(FromForm)] +pub struct SettingsForm { + #[field(validate = option_len(4..64))] + password: Option<String>, + #[field(validate = option_len(4..32))] + display_name: Option<String>, +} + +fn option_len<'v>(value: &Option<String>, range: Range<usize>) -> form::Result<'v, ()> { + value.as_ref().map(|v| len(v, range)).unwrap_or(Ok(())) +} + +fn settings_page(session: Session, flash: Option<MyResult<String>>) -> DynLayoutPage<'static> { + LayoutPage { + title: "Settings".to_string(), + content: markup::new! { + h1 { "Settings" } + @if let Some(flash) = &flash { + @match flash { + Ok(mesg) => { section.message { p.success { @mesg } } } + Err(err) => { section.message { p.error { @format!("{err}") } } } + } + } + h2 { "Account" } + form[method="POST", action=uri!(r_account_settings_post())] { + label[for="username"] { "Username" } + input[type="text", id="username", disabled, value=&session.user.name]; + input[type="submit", disabled, value="Immutable"]; + } + form[method="POST", action=uri!(r_account_settings_post())] { + label[for="display_name"] { "Display Name" } + input[type="text", id="display_name", name="display_name", value=&session.user.display_name]; + input[type="submit", value="Update"]; + } + form[method="POST", action=uri!(r_account_settings_post())] { + label[for="password"] { "Password" } + input[type="password", id="password", name="password"]; + input[type="submit", value="Update"]; + } + h2 { "Appearance" } + p.error { "TODO: theming" } + }, + } +} + +#[get("/account/settings")] +pub fn r_account_settings(session: Session) -> DynLayoutPage<'static> { + settings_page(session, None) +} + +#[post("/account/settings", data = "<form>")] +pub fn r_account_settings_post( + session: Session, + database: &State<Database>, + form: Form<Contextual<SettingsForm>>, +) -> MyResult<DynLayoutPage<'static>> { + let form = match &form.value { + Some(v) => v, + None => return Ok(settings_page(session, Some(Err(format_form_error(form))))), + }; + + let mut out = String::new(); + database.users.fetch_and_update(&session.user.name, |k| { + k.map(|mut k| { + if let Some(password) = &form.password { + k.password = hash_password(&session.user.name, password); + out += "Password updated\n"; + } + if let Some(display_name) = &form.display_name { + k.display_name = display_name.clone(); + out += "Display name updated\n"; + } + k + }) + })?; + + Ok(settings_page( + session, + Some(Ok(if out.is_empty() { + "Nothing changed :)".to_string() + } else { + out + })), + )) +} |