personal settings: update username, name, email

This commit is contained in:
Philippe Loctaux 2023-04-05 23:41:25 +02:00
parent 1346b57b30
commit a47e4c204a
14 changed files with 247 additions and 5 deletions

View file

@ -14,6 +14,7 @@ identicon-rs = "4.0"
futures = "0.3"
base64 = "0.21.0"
rocket_cors = "0.6.0-alpha2"
email_address = { workspace = true }
# local crates
database_pool = { path = "../database_pool" }

View file

@ -31,7 +31,7 @@ impl UserMenu {
icon: Icon::Settings.svg,
sub: Some(vec![SubItem {
label: "Personal",
link: uri!(routes::settings::user_settings_personal).to_string(),
link: uri!(routes::settings::personal::user_settings_personal).to_string(),
}]),
},
]

View file

@ -1,11 +1,15 @@
use super::prelude::*;
pub use personal::*;
use personal::*;
use rocket::get;
pub mod personal;
pub fn routes() -> Vec<Route> {
routes![user_settings, user_settings_personal]
routes![
user_settings,
user_settings_personal,
user_settings_personal_form,
]
}
#[get("/settings")]

View file

@ -1,5 +1,8 @@
use crate::routes::prelude::*;
use rocket::get;
use crate::tokens::JWT_DURATION_MINUTES;
use email_address::EmailAddress;
use rocket::{get, post};
use std::str::FromStr;
use users::User;
#[get("/settings/personal")]
@ -23,3 +26,91 @@ pub async fn user_settings_personal(
.map(|flash| Page::with_flash(page.clone(), flash))
.unwrap_or_else(|| page.into()))
}
#[derive(Debug, FromForm)]
pub struct UpdatePersonalSettings<'r> {
pub username: &'r str,
pub name: &'r str,
pub email: &'r str,
}
#[post("/settings/personal", data = "<form>")]
pub async fn user_settings_personal_form(
mut db: Connection<Database>,
jwt_user: JwtUser,
form: Form<UpdatePersonalSettings<'_>>,
) -> Result<Flash<Redirect>> {
let mut transaction = db.begin().await?;
let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found(jwt_user.0.subject.to_string()))?;
if user.is_archived() {
return Err(Error::forbidden("User is archived"));
}
// Update username
if user.username() != form.username {
if let Err(e) = user.set_username(&mut transaction, form.username).await {
return Ok(Flash::new(
Redirect::to(uri!(user_settings_personal)),
FlashKind::Danger,
e.to_string(),
));
}
}
// Update name
if !form.name.is_empty()
&& user
.name()
// If it exists in database, check if provided value is different
.map(|current| current != form.name)
// If it does not exist, use provided value
.unwrap_or(true)
{
user.set_name(&mut transaction, form.name).await?;
}
// Update email
if !form.email.is_empty()
&& user
.email()
// If it exists in database, check if provided value is different
.map(|current| current != form.email)
// If it does not exist, use provided value
.unwrap_or(true)
{
// Parse email address
let email = match EmailAddress::from_str(form.email) {
Ok(email) => email,
Err(e) => {
return Ok(Flash::new(
Redirect::to(uri!(user_settings_personal)),
FlashKind::Danger,
e.to_string(),
));
}
};
if let Err(e) = user.set_email(&mut transaction, email).await {
return Ok(Flash::new(
Redirect::to(uri!(user_settings_personal)),
FlashKind::Danger,
e.to_string(),
));
}
}
transaction.commit().await?;
Ok(Flash::new(
Redirect::to(uri!(user_settings_personal)),
FlashKind::Success,
format!(
"Personal settings have been saved.\
<br>Some changes can take up to {JWT_DURATION_MINUTES} minutes to appear."
),
))
}