diff --git a/Cargo.lock b/Cargo.lock index cbc90fe..4894707 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,18 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -456,6 +468,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -1429,6 +1450,7 @@ dependencies = [ name = "mailauth" version = "0.1.0" dependencies = [ + "argon2", "axum", "axum-extra", "dotenvy", @@ -1736,6 +1758,17 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + [[package]] name = "paste" version = "1.0.15" diff --git a/Cargo.toml b/Cargo.toml index 5ccb340..adaefa8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,3 +36,4 @@ sea-orm = { version = "1.1.0", features = [ "sqlx-sqlite", "runtime-tokio-native migration = { path = "migration" } minijinja = "2.4.0" thiserror = "2.0.3" +argon2 = {version = "0.5.3", features = ["password-hash"]} diff --git a/src/routes/user.rs b/src/routes/user.rs index 72ef021..8bb3998 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -1,5 +1,9 @@ +use argon2::password_hash::SaltString; +use argon2::{Argon2, PasswordHasher}; use axum::Form; use axum::{extract::State, Extension}; +use rand::rngs::OsRng; +use reqwest::StatusCode; use sea_orm::{ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, QueryFilter}; use serde::{Deserialize, Serialize}; @@ -22,16 +26,24 @@ pub async fn update_password( .one(&state.conn) .await?; + let salt = SaltString::generate(&mut OsRng); + let password = Argon2::default() + .hash_password(form.password.as_ref(), &salt) + .map_err(|e| ThisError::Generic { + code: StatusCode::INTERNAL_SERVER_ERROR, + message: e.to_string(), + })?; + match user_option { Some(user) => { let mut user: user::ActiveModel = user.into(); - user.password = ActiveValue::Set(form.password); + user.password = ActiveValue::Set(password.to_string()); user.update(&state.conn).await?; } None => { let user = user::ActiveModel { userid: ActiveValue::Set(session.name.to_owned()), - password: ActiveValue::Set(form.password), + password: ActiveValue::Set(password.to_string()), ..Default::default() }; user.insert(&state.conn).await?;