diff --git a/src/mastodon_api/accounts/types.rs b/src/mastodon_api/accounts/types.rs index 56b1398..cceee93 100644 --- a/src/mastodon_api/accounts/types.rs +++ b/src/mastodon_api/accounts/types.rs @@ -95,18 +95,23 @@ impl Account { /// https://docs.joinmastodon.org/methods/accounts/ #[derive(Deserialize)] pub struct AccountCreateData { - username: String, - password: String, + pub username: String, + pub password: String, - wallet_address: Option, - invite_code: Option, + pub wallet_address: Option, + pub invite_code: Option, } impl AccountCreateData { - pub fn into_user_data(self) -> UserCreateData { + pub fn into_user_data( + self, + password_hash: String, + private_key_pem: String, + ) -> UserCreateData { UserCreateData { username: self.username, - password: self.password, + password_hash, + private_key_pem, wallet_address: self.wallet_address, invite_code: self.invite_code, } diff --git a/src/mastodon_api/accounts/views.rs b/src/mastodon_api/accounts/views.rs index ef8de75..43d76db 100644 --- a/src/mastodon_api/accounts/views.rs +++ b/src/mastodon_api/accounts/views.rs @@ -40,6 +40,7 @@ use crate::models::users::queries::{ is_valid_invite_code, create_user, }; +use crate::models::users::types::UserCreateData; use crate::utils::crypto::{ hash_password, generate_private_key, @@ -60,11 +61,10 @@ pub async fn create_account( account_data: web::Json, ) -> Result { let db_client = &mut **get_database_client(&db_pool).await?; - let user_data = account_data.into_inner().into_user_data(); // Validate - user_data.clean()?; + UserCreateData::clean(&account_data.username)?; if !config.registrations_open { - let invite_code = user_data.invite_code.as_ref() + let invite_code = account_data.invite_code.as_ref() .ok_or(ValidationError("invite code is required"))?; if !is_valid_invite_code(db_client, invite_code).await? { return Err(ValidationError("invalid invite code").into()); @@ -72,7 +72,7 @@ pub async fn create_account( } if config.ethereum_contract.is_some() { // Wallet address is required only if ethereum integration is enabled - let wallet_address = user_data.wallet_address.as_ref() + let wallet_address = account_data.wallet_address.as_ref() .ok_or(ValidationError("wallet address is required"))?; let is_allowed = is_allowed_user(&config, wallet_address).await .map_err(|_| HttpError::InternalError)?; @@ -81,7 +81,7 @@ pub async fn create_account( } } // Hash password and generate private key - let password_hash = hash_password(&user_data.password) + let password_hash = hash_password(&account_data.password) .map_err(|_| HttpError::InternalError)?; let private_key = match web::block(generate_private_key).await { Ok(private_key) => private_key, @@ -90,12 +90,9 @@ pub async fn create_account( let private_key_pem = serialize_private_key(private_key) .map_err(|_| HttpError::InternalError)?; - let user = create_user( - db_client, - user_data, - password_hash, - private_key_pem, - ).await?; + let user_data = account_data.into_inner() + .into_user_data(password_hash, private_key_pem); + let user = create_user(db_client, user_data).await?; let account = Account::from_user(user, &config.instance_url()); Ok(HttpResponse::Created().json(account)) } diff --git a/src/models/users/queries.rs b/src/models/users/queries.rs index a9c0ec9..c6b2577 100644 --- a/src/models/users/queries.rs +++ b/src/models/users/queries.rs @@ -56,8 +56,6 @@ pub async fn is_valid_invite_code( pub async fn create_user( db_client: &mut impl GenericClient, user_data: UserCreateData, - password_hash: String, - private_key_pem: String, ) -> Result { let transaction = db_client.transaction().await?; // Use invite code @@ -98,8 +96,8 @@ pub async fn create_user( &[ &profile.id, &user_data.wallet_address, - &password_hash, - &private_key_pem, + &user_data.password_hash, + &user_data.private_key_pem, &user_data.invite_code, ], ).await.map_err(catch_unique_violation("user"))?; diff --git a/src/models/users/types.rs b/src/models/users/types.rs index 66a9abd..6eec234 100644 --- a/src/models/users/types.rs +++ b/src/models/users/types.rs @@ -1,7 +1,6 @@ use chrono::{DateTime, Utc}; use postgres_types::FromSql; use regex::Regex; -use serde::Deserialize; use uuid::Uuid; use crate::errors::ValidationError; @@ -46,10 +45,10 @@ impl User { } } -#[derive(Deserialize)] pub struct UserCreateData { pub username: String, - pub password: String, + pub password_hash: String, + pub private_key_pem: String, pub wallet_address: Option, pub invite_code: Option, } @@ -65,9 +64,9 @@ fn validate_local_username(username: &str) -> Result<(), ValidationError> { impl UserCreateData { /// Validate and clean. - pub fn clean(&self) -> Result<(), ValidationError> { - validate_username(&self.username)?; - validate_local_username(&self.username)?; + pub fn clean(username: &str) -> Result<(), ValidationError> { + validate_username(username)?; + validate_local_username(username)?; Ok(()) } }