use clap::Args; use eyre::Result; use tokio::{fs::File, io::AsyncWriteExt}; use crate::atuin_client::{ encryption::{decode_key, generate_encoded_key, load_key}, record::sqlite_store::SqliteStore, settings::Settings, }; #[derive(Args, Debug)] pub(crate) struct Rekey { /// The new key to use for encryption. Omit for a randomly-generated key key: Option, } impl Rekey { pub(crate) async fn run(&self, settings: &Settings, store: SqliteStore) -> Result<()> { let key = if let Some(key) = self.key.clone() { println!("Re-encrypting store with specified key"); key } else { println!("Re-encrypting store with freshly-generated key"); let (_, encoded) = generate_encoded_key()?; encoded }; let current_key: [u8; 32] = load_key(settings)?.into(); let new_key: [u8; 32] = decode_key(&key)?.into(); store.re_encrypt(¤t_key, &new_key).await?; if let Some(key_path) = settings.sync.encryption_key_path.as_ref() { println!("Store rewritten. Saving new key"); let mut file = File::create(key_path).await?; file.write_all(key.as_bytes()).await?; } else { println!( "No key-path (settings.sync.encryption_key_path) set in config, will not save new key." ); } Ok(()) } }