use super::AlterableField::{self, Login, Name, Pass}; use crate::{change_state, prelude::*}; use account::ActiveModel; use cryptography::account::Cipher; use futures::TryFutureExt; use sea_orm::ActiveValue::Set; use tokio::{task::spawn_blocking, try_join}; #[inline] async fn update_account( user_id: u64, db: &DatabaseConnection, name: String, field: AlterableField, field_value: String, master_pass: String, ) -> crate::Result<()> { if field == Name { Account::update_name(user_id, name, field_value, db).await?; return Ok(()); } let salt = Account::get_salt(user_id, name.clone(), db).await?.unwrap(); let field_value = spawn_blocking(move || { let cipher = Cipher::new(master_pass.as_bytes(), &salt); cipher.encrypt(field_value.as_bytes()).unwrap() }) .await?; let mut model = ActiveModel { user_id: Set(user_id), name: Set(name), ..Default::default() }; match field { Login => model.enc_login = Set(field_value), Pass => model.enc_password = Set(field_value), Name => unreachable!(), } model.update(db).await?; Ok(()) } #[inline] #[allow(clippy::too_many_arguments)] async fn get_master_pass( bot: Throttle, msg: Message, db: DatabaseConnection, dialogue: MainDialogue, mut ids: MessageIds, 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; update_account(user_id, &db, name, field, field_value, master_pass).await?; ids.alter_message( &bot, "Success. Choose the account to view", menu_markup("get", user_id, &db).await?, None, ) .await?; Ok(()) } handler!(get_field(name:String, field:AlterableField, field_value:String), "Send the master password", State::GetMasterPass, get_master_pass); #[inline] pub async fn alter( bot: Throttle, q: CallbackQuery, db: DatabaseConnection, dialogue: MainDialogue, (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) = name_from_hash(&db, user_id, &hash).await? else { try_join!( bot.send_message(ids.0, "Account wasn't found") .reply_markup(deletion_markup()) .send(), bot.answer_callback_query(q.id).send() )?; return Ok(()); }; let text = match field { Name => { change_state!(dialogue, ids, (name, field), State::GetNewName, get_field); "Send new account name" } Login => { change_state!(dialogue, ids, (name, field), State::GetLogin, get_field); "Send new account login" } Pass => { change_state!(dialogue, ids, (name, field), State::GetPassword, get_field); "Send new account password" } }; try_join!( ids.alter_message(&bot, text, None, None), bot.answer_callback_query(q.id).send().err_into() )?; Ok(()) }