aboutsummaryrefslogtreecommitdiff
path: root/server/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/ui')
-rw-r--r--server/src/ui/account/mod.rs62
-rw-r--r--server/src/ui/admin/import.rs2
2 files changed, 54 insertions, 10 deletions
diff --git a/server/src/ui/account/mod.rs b/server/src/ui/account/mod.rs
index 1c44914..837d49a 100644
--- a/server/src/ui/account/mod.rs
+++ b/server/src/ui/account/mod.rs
@@ -9,16 +9,20 @@ pub mod settings;
use super::error::MyError;
use crate::{
- auth::login, request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse,
+ auth::{hash_password, login},
+ request_info::RequestInfo,
+ ui::error::MyResult,
+ ui_responder::UiResponse,
};
use anyhow::anyhow;
use jellycommon::{
- VIEW_ACCOUNT_LOGIN, VIEW_ACCOUNT_LOGOUT,
- jellyobject::OBB,
+ jellyobject::{OBB, Path},
routes::{u_account_login, u_home},
+ *,
};
+use jellydb::{Filter, Query, Sort};
use rocket::{
- FromForm,
+ Either, FromForm,
form::{Contextual, Form},
get,
http::{Cookie, CookieJar},
@@ -39,10 +43,14 @@ pub fn r_account_logout(ri: RequestInfo<'_>) -> UiResponse {
#[derive(FromForm, Serialize, Deserialize)]
pub struct LoginForm {
- #[field(validate = len(4..32))]
+ #[field(validate = len(..32))]
pub username: String,
#[field(validate = len(..64))]
pub password: String,
+ #[field(validate = len(..64))]
+ pub new_password: Option<String>,
+ #[field(validate = len(..64))]
+ pub display_name: Option<String>,
#[field(default = 604800)] // one week
pub expire: u64,
}
@@ -52,15 +60,51 @@ pub fn r_account_login_post(
ri: RequestInfo<'_>,
jar: &CookieJar,
form: Form<Contextual<LoginForm>>,
-) -> MyResult<Redirect> {
+) -> MyResult<Either<Redirect, UiResponse>> {
let form = match &form.value {
Some(v) => v,
None => return Err(MyError(anyhow!(format_form_error(form)))),
};
- let session = login(&ri.state, &form.username, &form.password, None)?;
- jar.add(Cookie::build(("session", session)).permanent().build());
- Ok(Redirect::found(u_home()))
+ let (session, need_pw_change) = login(&ri.state, &form.username, &form.password, None)?;
+
+ if need_pw_change {
+ if let Some(new_password) = &form.new_password {
+ let password_hash = hash_password(&form.username, &new_password);
+ ri.state.database.transaction(&mut |txn| {
+ let user_row = txn.query_single(Query {
+ filter: Filter::Match(Path(vec![USER_LOGIN.0]), form.username.clone().into()),
+ sort: Sort::None,
+ })?;
+ if let Some(ur) = user_row {
+ let mut user = txn.get(ur)?.unwrap();
+ user = user.as_object().remove(USER_PASSWORD_REQUIRE_CHANGE);
+ user = user.as_object().insert(USER_PASSWORD, &password_hash);
+ if let Some(name) = &form.display_name {
+ user = user.as_object().insert(USER_NAME, &name);
+ }
+ txn.update(ur, user)?;
+ }
+ Ok(())
+ })?;
+ } else {
+ return Ok(Either::Right(
+ ri.respond_ui(
+ OBB::new().with(
+ VIEW_ACCOUNT_SET_PASSWORD,
+ OBB::new()
+ .with(SETPW_USERNAME, &form.username)
+ .with(SETPW_PASSWORD, &form.password)
+ .finish()
+ .as_object(),
+ ),
+ ),
+ ));
+ }
+ }
+
+ jar.add(Cookie::build(("session", session)).permanent().build());
+ Ok(Either::Left(Redirect::found(u_home())))
}
#[post("/account/logout")]
diff --git a/server/src/ui/admin/import.rs b/server/src/ui/admin/import.rs
index eba2a3b..78db4a4 100644
--- a/server/src/ui/admin/import.rs
+++ b/server/src/ui/admin/import.rs
@@ -32,8 +32,8 @@ pub async fn r_admin_import(ri: RequestInfo<'_>) -> MyResult<UiResponse> {
.iter()
.map(|e| e.as_str())
.collect::<Vec<_>>();
- let mut data = ObjectBuffer::empty();
+ let mut data = ObjectBuffer::empty();
if is_importing() {
data = data.as_object().insert(ADMIN_IMPORT_BUSY, ());
}