diff --git a/crates/tranquil-api/src/common.rs b/crates/tranquil-api/src/common.rs index 3ca7368..fde79f8 100644 --- a/crates/tranquil-api/src/common.rs +++ b/crates/tranquil-api/src/common.rs @@ -5,7 +5,7 @@ use tracing::error; use tranquil_db_traits::{CommsChannel, DidWebOverrides, SessionRepository, UserRepository}; use tranquil_pds::api::error::ApiError; use tranquil_pds::api::error::DbResultExt; -use tranquil_pds::types::{AtIdentifier, Did, Handle}; +use tranquil_pds::types::{AtIdentifier, Did, Handle, PasswordHash}; pub struct ResolvedRepo { pub user_id: uuid::Uuid, @@ -216,7 +216,7 @@ pub async fn verify_credential( session_repo: &dyn SessionRepository, user_id: uuid::Uuid, password: &str, - password_hash: Option<&str>, + password_hash: Option<&PasswordHash>, ) -> Option { let main_valid = password_hash .map(|h| bcrypt::verify(password, h).unwrap_or(false)) @@ -230,7 +230,7 @@ pub async fn verify_credential( .unwrap_or_default(); app_passwords .into_iter() - .find(|app| bcrypt::verify(password, &app.password_hash).unwrap_or(false)) + .find(|app| bcrypt::verify(password, app.password_hash.as_str()).unwrap_or(false)) .map(|app| { let scopes = app.scopes.unwrap_or_else(|| { if app.privilege.is_privileged() { @@ -247,14 +247,16 @@ pub async fn verify_credential( }) } -pub fn hash_or_internal_error(value: &str) -> Result { - bcrypt::hash(value, DEFAULT_COST).map_err(|e| { - error!("Bcrypt hash error: {:?}", e); - ApiError::InternalError(None) - }) +pub fn hash_or_internal_error(value: &str) -> Result { + bcrypt::hash(value, DEFAULT_COST) + .map(PasswordHash::new) + .map_err(|e| { + error!("Bcrypt hash error: {:?}", e); + ApiError::InternalError(None) + }) } -pub async fn hash_password_async(password: &str) -> Result { +pub async fn hash_password_async(password: &str) -> Result { let password = password.to_string(); tokio::task::spawn_blocking(move || hash(password, DEFAULT_COST)) .await @@ -262,6 +264,7 @@ pub async fn hash_password_async(password: &str) -> Result { error!("Failed to spawn blocking task: {:?}", e); ApiError::InternalError(None) })? + .map(PasswordHash::new) .map_err(|e| { error!("Failed to hash password: {:?}", e); ApiError::InternalError(None) diff --git a/crates/tranquil-api/src/server/account_status.rs b/crates/tranquil-api/src/server/account_status.rs index 33de10d..e0e64f7 100644 --- a/crates/tranquil-api/src/server/account_status.rs +++ b/crates/tranquil-api/src/server/account_status.rs @@ -637,7 +637,7 @@ pub async fn delete_account( state.repos.session.as_ref(), user_id, password, - password_hash.as_deref(), + password_hash.as_ref(), ) .await .is_none() diff --git a/crates/tranquil-api/src/server/reauth.rs b/crates/tranquil-api/src/server/reauth.rs index 54d7dec..0b721b5 100644 --- a/crates/tranquil-api/src/server/reauth.rs +++ b/crates/tranquil-api/src/server/reauth.rs @@ -74,7 +74,7 @@ pub async fn reauth_password( .log_db_err("fetching password hash")? .ok_or(ApiError::AccountNotFound)?; - let password_valid = bcrypt::verify(&input.password, &password_hash).unwrap_or(false); + let password_valid = bcrypt::verify(&input.password, password_hash.as_str()).unwrap_or(false); if !password_valid { let app_password_hashes = state diff --git a/crates/tranquil-api/src/server/session.rs b/crates/tranquil-api/src/server/session.rs index caad7c5..9246a0b 100644 --- a/crates/tranquil-api/src/server/session.rs +++ b/crates/tranquil-api/src/server/session.rs @@ -112,7 +112,7 @@ pub async fn create_session( state.repos.session.as_ref(), row.id, &input.password, - row.password_hash.as_deref(), + row.password_hash.as_ref(), ) .await; let (app_password_name, app_password_scopes, app_password_controller) = match credential { diff --git a/crates/tranquil-db-traits/src/session.rs b/crates/tranquil-db-traits/src/session.rs index dac4702..beeed75 100644 --- a/crates/tranquil-db-traits/src/session.rs +++ b/crates/tranquil-db-traits/src/session.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use chrono::{DateTime, Utc}; -use tranquil_types::Did; +use tranquil_types::{Did, Jti, PasswordHash}; use uuid::Uuid; use crate::DbError; @@ -134,7 +134,7 @@ pub struct AppPasswordRecord { pub id: Uuid, pub user_id: Uuid, pub name: String, - pub password_hash: String, + pub password_hash: PasswordHash, pub created_at: DateTime, pub privilege: AppPasswordPrivilege, pub scopes: Option, @@ -145,7 +145,7 @@ pub struct AppPasswordRecord { pub struct AppPasswordCreate { pub user_id: Uuid, pub name: String, - pub password_hash: String, + pub password_hash: PasswordHash, pub privilege: AppPasswordPrivilege, pub scopes: Option, pub created_by_controller_did: Option, diff --git a/crates/tranquil-db-traits/src/user.rs b/crates/tranquil-db-traits/src/user.rs index dcf3abd..a7063db 100644 --- a/crates/tranquil-db-traits/src/user.rs +++ b/crates/tranquil-db-traits/src/user.rs @@ -1,7 +1,9 @@ use async_trait::async_trait; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use tranquil_types::{Did, Handle}; +use tranquil_types::{ + AtIdentifier, CidLink, Did, Handle, InviteCode, Jti, PasswordHash, Tid, TokenId, +}; use uuid::Uuid; use crate::{ChannelVerificationStatus, CommsChannel, DbError, SsoProviderType}; @@ -78,7 +80,7 @@ pub struct UserEmailInfo { #[derive(Debug, Clone)] pub struct UserLoginCheck { pub did: Did, - pub password_hash: Option, + pub password_hash: Option, } #[derive(Debug, Clone)] @@ -86,7 +88,7 @@ pub struct UserLoginInfo { pub id: Uuid, pub did: Did, pub email: Option, - pub password_hash: Option, + pub password_hash: Option, pub password_required: bool, pub two_factor_enabled: bool, pub preferred_comms_channel: CommsChannel, @@ -313,7 +315,7 @@ pub trait UserRepository: Send + Sync { async fn has_passkeys(&self, did: &Did) -> Result; - async fn get_password_hash_by_did(&self, did: &Did) -> Result, DbError>; + async fn get_password_hash_by_did(&self, did: &Did) -> Result, DbError>; async fn get_passkeys_for_user(&self, did: &Did) -> Result, DbError>; @@ -466,13 +468,16 @@ pub trait UserRepository: Send + Sync { did: &Did, ) -> Result, DbError>; - async fn update_password_hash(&self, user_id: Uuid, password_hash: &str) - -> Result<(), DbError>; + async fn update_password_hash( + &self, + user_id: Uuid, + password_hash: &PasswordHash, + ) -> Result<(), DbError>; async fn reset_password_with_sessions( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result; async fn activate_account(&self, did: &Did) -> Result; @@ -495,7 +500,7 @@ pub trait UserRepository: Send + Sync { async fn set_new_user_password( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result<(), DbError>; async fn get_user_key_by_did(&self, did: &Did) -> Result, DbError>; @@ -699,7 +704,7 @@ pub struct AccountSearchResult { pub struct UserAuthInfo { pub id: Uuid, pub did: Did, - pub password_hash: Option, + pub password_hash: Option, pub deactivated_at: Option>, pub takedown_ref: Option, pub channel_verification: ChannelVerificationStatus, @@ -863,7 +868,7 @@ pub struct UserLoginFull { pub id: Uuid, pub did: Did, pub handle: Handle, - pub password_hash: Option, + pub password_hash: Option, pub email: Option, pub deactivated_at: Option>, pub takedown_ref: Option, @@ -914,13 +919,13 @@ pub struct UserResetCodeInfo { #[derive(Debug, Clone)] pub struct UserPasswordInfo { pub id: Uuid, - pub password_hash: Option, + pub password_hash: Option, } #[derive(Debug, Clone)] pub struct UserIdAndPasswordHash { pub id: Uuid, - pub password_hash: String, + pub password_hash: PasswordHash, } #[derive(Debug, Clone)] @@ -932,7 +937,7 @@ pub struct PasswordResetResult { #[derive(Debug, Clone)] pub struct UserForDeletion { pub id: Uuid, - pub password_hash: Option, + pub password_hash: Option, pub handle: Handle, } @@ -988,7 +993,7 @@ pub struct CreatePasswordAccountInput { pub handle: Handle, pub email: Option, pub did: Did, - pub password_hash: String, + pub password_hash: PasswordHash, pub preferred_comms_channel: CommsChannel, pub discord_username: Option, pub telegram_username: Option, @@ -1044,7 +1049,7 @@ pub struct CreatePasskeyAccountInput { pub discord_username: Option, pub telegram_username: Option, pub signal_username: Option, - pub setup_token_hash: String, + pub setup_token_hash: PasswordHash, pub setup_expires_at: DateTime, pub deactivated_at: Option>, pub encrypted_key_bytes: Vec, @@ -1086,13 +1091,13 @@ pub struct CompletePasskeySetupInput { pub user_id: Uuid, pub did: Did, pub app_password_name: String, - pub app_password_hash: String, + pub app_password_hash: PasswordHash, } #[derive(Debug, Clone)] pub struct RecoverPasskeyAccountInput { pub did: Did, - pub password_hash: String, + pub password_hash: PasswordHash, } #[derive(Debug, Clone)] diff --git a/crates/tranquil-db/src/postgres/session.rs b/crates/tranquil-db/src/postgres/session.rs index 2560131..a36cbc3 100644 --- a/crates/tranquil-db/src/postgres/session.rs +++ b/crates/tranquil-db/src/postgres/session.rs @@ -7,7 +7,7 @@ use tranquil_db_traits::{ SessionForRefresh, SessionId, SessionListItem, SessionMfaStatus, SessionRefreshData, SessionRepository, SessionToken, SessionTokenCreate, }; -use tranquil_types::Did; +use tranquil_types::{Did, Jti, PasswordHash}; use uuid::Uuid; use super::user::map_sqlx_error; @@ -318,7 +318,7 @@ impl SessionRepository for PostgresSessionRepository { id: r.id, user_id: r.user_id, name: r.name, - password_hash: r.password_hash, + password_hash: PasswordHash::new(r.password_hash), created_at: r.created_at, privilege: AppPasswordPrivilege::from_privileged_flag(r.privileged), scopes: r.scopes, @@ -351,7 +351,7 @@ impl SessionRepository for PostgresSessionRepository { id: r.id, user_id: r.user_id, name: r.name, - password_hash: r.password_hash, + password_hash: PasswordHash::new(r.password_hash), created_at: r.created_at, privilege: AppPasswordPrivilege::from_privileged_flag(r.privileged), scopes: r.scopes, @@ -382,7 +382,7 @@ impl SessionRepository for PostgresSessionRepository { id: r.id, user_id: r.user_id, name: r.name, - password_hash: r.password_hash, + password_hash: PasswordHash::new(r.password_hash), created_at: r.created_at, privilege: AppPasswordPrivilege::from_privileged_flag(r.privileged), scopes: r.scopes, @@ -399,7 +399,7 @@ impl SessionRepository for PostgresSessionRepository { "#, data.user_id, data.name, - data.password_hash, + data.password_hash.as_str(), data.privilege.is_privileged(), data.scopes, data.created_by_controller_did.as_ref().map(|d| d.as_str()) @@ -510,7 +510,7 @@ impl SessionRepository for PostgresSessionRepository { .await .map_err(map_sqlx_error)?; - Ok(rows) + Ok(rows.into_iter().map(PasswordHash::new).collect()) } async fn refresh_session_atomic( diff --git a/crates/tranquil-db/src/postgres/user.rs b/crates/tranquil-db/src/postgres/user.rs index fe4e29e..b7f2840 100644 --- a/crates/tranquil-db/src/postgres/user.rs +++ b/crates/tranquil-db/src/postgres/user.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use chrono::{DateTime, Utc}; use sqlx::PgPool; -use tranquil_types::{Did, Handle}; +use tranquil_types::{AtIdentifier, Did, Handle, Jti, PasswordHash, TokenId}; use uuid::Uuid; use tranquil_db_traits::{ @@ -314,7 +314,7 @@ impl UserRepository for PostgresUserRepository { Ok(row.map(|r| UserAuthInfo { id: r.id, did: Did::from(r.did), - password_hash: r.password_hash, + password_hash: r.password_hash.map(PasswordHash::new), deactivated_at: r.deactivated_at, takedown_ref: r.takedown_ref, channel_verification: ChannelVerificationStatus::from_db_row( @@ -654,7 +654,7 @@ impl UserRepository for PostgresUserRepository { async fn admin_update_password(&self, did: &Did, password_hash: &str) -> Result { let result = sqlx::query!( "UPDATE users SET password_hash = $1 WHERE did = $2", - password_hash, + password_hash.as_str(), did.as_str() ) .execute(&self.pool) @@ -927,7 +927,7 @@ impl UserRepository for PostgresUserRepository { Ok(count.unwrap_or(0) > 0) } - async fn get_password_hash_by_did(&self, did: &Did) -> Result, DbError> { + async fn get_password_hash_by_did(&self, did: &Did) -> Result, DbError> { let row = sqlx::query_scalar!( "SELECT password_hash FROM users WHERE did = $1", did.as_str() @@ -936,7 +936,7 @@ impl UserRepository for PostgresUserRepository { .await .map_err(map_sqlx_error)?; - Ok(row.flatten()) + Ok(row.flatten().map(PasswordHash::new)) } async fn get_passkeys_for_user(&self, did: &Did) -> Result, DbError> { @@ -1431,7 +1431,7 @@ impl UserRepository for PostgresUserRepository { .map(|opt| { opt.map(|r| UserLoginCheck { did: Did::from(r.did), - password_hash: r.password_hash, + password_hash: r.password_hash.map(PasswordHash::new), }) }) } @@ -1460,7 +1460,7 @@ impl UserRepository for PostgresUserRepository { id: row.id, did: Did::from(row.did), email: row.email, - password_hash: row.password_hash, + password_hash: row.password_hash.map(PasswordHash::new), password_required: row.password_required, two_factor_enabled: row.two_factor_enabled, preferred_comms_channel: row.preferred_comms_channel, @@ -1622,7 +1622,7 @@ impl UserRepository for PostgresUserRepository { id: row.id, did: Did::from(row.did), handle: Handle::from(row.handle), - password_hash: row.password_hash, + password_hash: row.password_hash.map(PasswordHash::new), email: row.email, deactivated_at: row.deactivated_at, takedown_ref: row.takedown_ref, @@ -1831,7 +1831,7 @@ impl UserRepository for PostgresUserRepository { opt.and_then(|row| { row.password_hash.map(|hash| UserIdAndPasswordHash { id: row.id, - password_hash: hash, + password_hash: PasswordHash::new(hash), }) }) }) @@ -1840,11 +1840,11 @@ impl UserRepository for PostgresUserRepository { async fn update_password_hash( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result<(), DbError> { sqlx::query!( "UPDATE users SET password_hash = $1 WHERE id = $2", - password_hash, + password_hash.as_str(), user_id ) .execute(&self.pool) @@ -1856,13 +1856,13 @@ impl UserRepository for PostgresUserRepository { async fn reset_password_with_sessions( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result { let mut tx = self.pool.begin().await.map_err(map_sqlx_error)?; sqlx::query!( "UPDATE users SET password_hash = $1, password_reset_code = NULL, password_reset_code_expires_at = NULL, password_required = TRUE WHERE id = $2", - password_hash, + password_hash.as_str(), user_id ) .execute(&mut *tx) @@ -1950,7 +1950,7 @@ impl UserRepository for PostgresUserRepository { .map(|opt| { opt.map(|row| UserPasswordInfo { id: row.id, - password_hash: row.password_hash, + password_hash: row.password_hash.map(PasswordHash::new), }) }) } @@ -1969,11 +1969,11 @@ impl UserRepository for PostgresUserRepository { async fn set_new_user_password( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result<(), DbError> { sqlx::query!( "UPDATE users SET password_hash = $1, password_required = TRUE WHERE id = $2", - password_hash, + password_hash.as_str(), user_id ) .execute(&self.pool) @@ -2004,7 +2004,7 @@ impl UserRepository for PostgresUserRepository { .map(|opt| { opt.map(|row| UserForDeletion { id: row.id, - password_hash: row.password_hash, + password_hash: row.password_hash.map(PasswordHash::new), handle: Handle::from(row.handle), }) }) @@ -3113,7 +3113,7 @@ impl UserRepository for PostgresUserRepository { "INSERT INTO app_passwords (user_id, name, password_hash, privileged) VALUES ($1, $2, $3, FALSE)", input.user_id, input.app_password_name, - input.app_password_hash + input.app_password_hash.as_str() ) .execute(&mut *tx) .await @@ -3140,7 +3140,7 @@ impl UserRepository for PostgresUserRepository { sqlx::query!( "UPDATE users SET password_hash = $1, password_required = TRUE, recovery_token = NULL, recovery_token_expires_at = NULL WHERE did = $2", - input.password_hash, + input.password_hash.as_str(), input.did.as_str() ) .execute(&mut *tx) diff --git a/crates/tranquil-pds/tests/store_parity.rs b/crates/tranquil-pds/tests/store_parity.rs index 39625a2..ef803db 100644 --- a/crates/tranquil-pds/tests/store_parity.rs +++ b/crates/tranquil-pds/tests/store_parity.rs @@ -144,7 +144,7 @@ async fn seed_user(repos: &PostgresRepositories, did: &Did, handle: &Handle) -> handle: handle.clone(), email: None, did: did.clone(), - password_hash: "parity-test-hash".to_string(), + password_hash: tranquil_types::PasswordHash::new("parity-test-hash"), preferred_comms_channel: CommsChannel::Email, discord_username: None, telegram_username: None, diff --git a/crates/tranquil-store/src/metastore/client.rs b/crates/tranquil-store/src/metastore/client.rs index ef4c93f..0b2f1fe 100644 --- a/crates/tranquil-store/src/metastore/client.rs +++ b/crates/tranquil-store/src/metastore/client.rs @@ -29,7 +29,7 @@ use tranquil_db_traits::{ use tranquil_oauth::{AuthorizedClientData, DeviceData, RequestData, TokenData}; use tranquil_types::{ AtUri, AuthorizationCode, CidLink, ClientId, DPoPProofId, DeviceId, Did, Handle, Nsid, - RefreshToken, RequestId, Rkey, TokenId, + InviteCode, Jti, Nsid, PasswordHash, RefreshToken, RequestId, Rkey, Tid, TokenId, }; use uuid::Uuid; @@ -1734,7 +1734,9 @@ impl tranquil_db_traits::SessionRepository for Metastore tx, }, ))?; - recv(rx).await + recv(rx) + .await + .map(|hashes: Vec| hashes.into_iter().map(PasswordHash::new).collect()) } async fn refresh_session_atomic( @@ -3733,7 +3735,7 @@ impl tranquil_db_traits::UserRepository for MetastoreCli self.pool .send(MetastoreRequest::User(UserRequest::AdminUpdatePassword { did: did.clone(), - password_hash: password_hash.to_owned(), + password_hash: password_hash.as_str().to_owned(), tx, }))?; recv(rx).await @@ -4032,14 +4034,16 @@ impl tranquil_db_traits::UserRepository for MetastoreCli recv(rx).await } - async fn get_password_hash_by_did(&self, did: &Did) -> Result, DbError> { + async fn get_password_hash_by_did(&self, did: &Did) -> Result, DbError> { let (tx, rx) = oneshot::channel(); self.pool .send(MetastoreRequest::User(UserRequest::GetPasswordHashByDid { did: did.clone(), tx, }))?; - recv(rx).await + recv(rx) + .await + .map(|hash: Option| hash.map(PasswordHash::new)) } async fn get_passkeys_for_user(&self, did: &Did) -> Result, DbError> { @@ -4556,13 +4560,13 @@ impl tranquil_db_traits::UserRepository for MetastoreCli async fn update_password_hash( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result<(), DbError> { let (tx, rx) = oneshot::channel(); self.pool .send(MetastoreRequest::User(UserRequest::UpdatePasswordHash { user_id, - password_hash: password_hash.to_owned(), + password_hash: password_hash.as_str().to_owned(), tx, }))?; recv(rx).await @@ -4571,13 +4575,13 @@ impl tranquil_db_traits::UserRepository for MetastoreCli async fn reset_password_with_sessions( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result { let (tx, rx) = oneshot::channel(); self.pool.send(MetastoreRequest::User( UserRequest::ResetPasswordWithSessions { user_id, - password_hash: password_hash.to_owned(), + password_hash: password_hash.as_str().to_owned(), tx, }, ))?; @@ -4645,13 +4649,13 @@ impl tranquil_db_traits::UserRepository for MetastoreCli async fn set_new_user_password( &self, user_id: Uuid, - password_hash: &str, + password_hash: &PasswordHash, ) -> Result<(), DbError> { let (tx, rx) = oneshot::channel(); self.pool .send(MetastoreRequest::User(UserRequest::SetNewUserPassword { user_id, - password_hash: password_hash.to_owned(), + password_hash: password_hash.as_str().to_owned(), tx, }))?; recv(rx).await diff --git a/crates/tranquil-store/src/metastore/mod.rs b/crates/tranquil-store/src/metastore/mod.rs index 83d397a..3ac00cd 100644 --- a/crates/tranquil-store/src/metastore/mod.rs +++ b/crates/tranquil-store/src/metastore/mod.rs @@ -455,7 +455,7 @@ mod tests { handle: tranquil_types::Handle::new(handle.to_string()).unwrap(), email: None, did: tranquil_types::Did::new(did.to_string()).unwrap(), - password_hash: "test-hash".to_string(), + password_hash: tranquil_types::PasswordHash::new("test-hash"), preferred_comms_channel: tranquil_db_traits::CommsChannel::Email, discord_username: None, telegram_username: None, diff --git a/crates/tranquil-store/src/metastore/session_ops.rs b/crates/tranquil-store/src/metastore/session_ops.rs index a1e005d..07aefc3 100644 --- a/crates/tranquil-store/src/metastore/session_ops.rs +++ b/crates/tranquil-store/src/metastore/session_ops.rs @@ -24,7 +24,7 @@ use tranquil_db_traits::{ RefreshGraceReplay, RefreshSessionResult, SessionForRefresh, SessionId, SessionListItem, SessionMfaStatus, SessionRefreshData, SessionToken, SessionTokenCreate, }; -use tranquil_types::Did; +use tranquil_types::{Did, Jti, PasswordHash}; pub struct SessionOps { db: Database, @@ -112,7 +112,7 @@ impl SessionOps { id: v.id, user_id: v.user_id, name: v.name.clone(), - password_hash: v.password_hash.clone(), + password_hash: PasswordHash::new(v.password_hash.clone()), created_at: DateTime::from_timestamp_millis(v.created_at_ms).unwrap_or_default(), privilege: u8_to_privilege(v.privilege) .unwrap_or(tranquil_db_traits::AppPasswordPrivilege::Standard), @@ -620,7 +620,7 @@ impl SessionOps { id, user_id: data.user_id, name: data.name.clone(), - password_hash: data.password_hash.clone(), + password_hash: data.password_hash.as_str().to_owned(), created_at_ms: now_ms, privilege: privilege_to_u8(data.privilege), scopes: data.scopes.clone(), diff --git a/crates/tranquil-store/src/metastore/user_ops.rs b/crates/tranquil-store/src/metastore/user_ops.rs index 3b49a43..b9209e1 100644 --- a/crates/tranquil-store/src/metastore/user_ops.rs +++ b/crates/tranquil-store/src/metastore/user_ops.rs @@ -38,7 +38,7 @@ use tranquil_db_traits::{ UserResetCodeInfo, UserRow, UserSessionInfo, UserStatus, UserVerificationInfo, UserWithKey, WebauthnChallengeType, }; -use tranquil_types::{CidLink, Did, Handle}; +use tranquil_types::{CidLink, Did, Handle, Jti, PasswordHash}; pub struct UserOps { db: Database, @@ -440,7 +440,7 @@ impl UserOps { id: v.id, did: Did::new(v.did.clone()) .map_err(|_| MetastoreError::CorruptData("invalid user did"))?, - password_hash: v.password_hash.clone(), + password_hash: v.password_hash.clone().map(PasswordHash::new), deactivated_at: v .deactivated_at_ms .and_then(DateTime::from_timestamp_millis), @@ -476,7 +476,7 @@ impl UserOps { Ok(UserLoginCheck { did: Did::new(v.did.clone()) .map_err(|_| MetastoreError::CorruptData("invalid user did"))?, - password_hash: v.password_hash.clone(), + password_hash: v.password_hash.clone().map(PasswordHash::new), }) }) .transpose() @@ -493,7 +493,7 @@ impl UserOps { did: Did::new(v.did.clone()) .map_err(|_| MetastoreError::CorruptData("invalid user did"))?, email: v.email.clone(), - password_hash: v.password_hash.clone(), + password_hash: v.password_hash.clone().map(PasswordHash::new), password_required: v.password_required, two_factor_enabled: v.two_factor_enabled, preferred_comms_channel: Self::comms_channel(&v), @@ -625,7 +625,7 @@ impl UserOps { .map(|v| { Ok(UserForDeletion { id: v.id, - password_hash: v.password_hash.clone(), + password_hash: v.password_hash.clone().map(PasswordHash::new), handle: Handle::new(v.handle.clone()) .map_err(|_| MetastoreError::CorruptData("invalid user handle"))?, }) @@ -1956,7 +1956,7 @@ impl UserOps { .map_err(|_| MetastoreError::CorruptData("invalid user did"))?, handle: Handle::new(v.handle.clone()) .map_err(|_| MetastoreError::CorruptData("invalid user handle"))?, - password_hash: v.password_hash.clone(), + password_hash: v.password_hash.clone().map(PasswordHash::new), email: v.email.clone(), deactivated_at: v .deactivated_at_ms @@ -2160,7 +2160,7 @@ impl UserOps { .map(|(id, ph)| { Ok(UserIdAndPasswordHash { id, - password_hash: ph, + password_hash: PasswordHash::new(ph), }) }) .transpose() @@ -2279,7 +2279,7 @@ impl UserOps { .load_user_by_did(did.as_str())? .map(|v| UserPasswordInfo { id: v.id, - password_hash: v.password_hash.clone(), + password_hash: v.password_hash.clone().map(PasswordHash::new), })) } @@ -2854,7 +2854,7 @@ impl UserOps { &input.did, &input.handle, input.email.as_deref(), - Some(&input.password_hash), + Some(input.password_hash.as_str()), input.preferred_comms_channel, input.discord_username.as_deref(), input.telegram_username.as_deref(), @@ -3135,7 +3135,7 @@ impl UserOps { let user_hash = self.resolve_hash(input.did.as_str()); self.mutate_user(user_hash, |u| { - u.password_hash = Some(input.app_password_hash.clone()); + u.password_hash = Some(input.app_password_hash.as_str().to_owned()); u.password_required = false; })?; @@ -3173,7 +3173,7 @@ impl UserOps { batch.remove(&self.users, recovery_token_key(user_hash).as_slice()); if let Some(mut user) = self.load_user(user_hash)? { - user.password_hash = Some(input.password_hash.clone()); + user.password_hash = Some(input.password_hash.as_str().to_owned()); user.password_required = true; batch.insert( &self.users,