use super::AlterableField::{self, Login, Name, Pass}; use crate::{change_state, prelude::*}; use cryptography::account::Cipher; use tokio::task::spawn_blocking; #[inline] async fn update_account( user_id: u64, db: &Pool, name: String, field: AlterableField, field_value: String, master_pass: String, ) -> crate::Result { if field == Name { return Account::update_name(user_id, &name, &field_value, db) .await .map_err(Into::into); } let Some(salt) = Account::get_salt(user_id, &name, db).await? else { return Ok(false); }; let field_value = spawn_blocking(move || { let cipher = Cipher::new(master_pass.as_bytes(), &salt); let mut field = field_value.into_bytes(); cipher.encrypt(&mut field); field }) .await?; let updated = match field { Login => Account::update_login(user_id, &name, field_value, db).await?, Pass => Account::update_password(user_id, &name, field_value, db).await?, Name => unreachable!(), }; Ok(updated) } #[inline] #[allow(clippy::too_many_arguments)] async fn get_master_pass( bot: Throttle, msg: Message, db: Pool, dialogue: MainDialogue, mut ids: MessageIds, locale: LocaleRef, name: String, field: AlterableField, field_value: String, master_pass: String, ) -> crate::Result<()> { dialogue.exit().await?; let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let text = match update_account(user_id, &db, name, field, field_value, master_pass).await { Ok(true) => locale.success.as_str(), Ok(false) => &locale.account_not_found, Err(err) => { log::error!("{err:?}"); &locale.something_went_wrong } }; ids.alter_message(&bot, text, deletion_markup(locale), None) .await?; Ok(()) } handler!(get_field(name:String, field:AlterableField, field_value:String),send_master_password, State::GetMasterPass, get_master_pass); #[inline] pub async fn alter( bot: Throttle, q: CallbackQuery, db: Pool, dialogue: MainDialogue, locale: LocaleRef, (hash, field): (super::NameHash, AlterableField), ) -> crate::Result<()> { let user_id = q.from.id.0; let mut ids: MessageIds = q.message.as_ref().unwrap().into(); let Some(name) = Account::get_name_by_hash(user_id, &hash, &db).await? else { bot.send_message(ids.0, &locale.account_not_found) .reply_markup(deletion_markup(locale)) .await?; bot.answer_callback_query(q.id).await?; return Ok(()); }; let text: &str = match field { Name => { change_state!(dialogue, ids, (name, field), State::GetNewName, get_field); &locale.send_new_name } Login => { change_state!(dialogue, ids, (name, field), State::GetLogin, get_field); &locale.send_new_login } Pass => { change_state!(dialogue, ids, (name, field), State::GetPassword, get_field); &locale.send_new_password } }; ids.alter_message(&bot, text, None, None).await?; bot.answer_callback_query(q.id).await?; Ok(()) }