diff options
| author | 魏曹先生 <1992414357@qq.com> | 2025-11-22 20:16:14 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2025-11-22 20:16:14 +0800 |
| commit | 97089d19a4b339a622d78e48a41f1d67273752fd (patch) | |
| tree | c149fb23c9d6ea6b4c54ad048891fc0f323ea345 /src/bin/jv.rs | |
| parent | 34abfcdc8e148c047ebb2e06539036e514df7046 (diff) | |
Add account key generation and public key export features
- Add `--keygen` flag to `account add` for automatic ED25519 key
generation - Add `account genpub` command to export public keys - Update
help documentation in both English and Chinese - Extend shell completion
for new commands - Add error handling for OpenSSL operations
Diffstat (limited to 'src/bin/jv.rs')
| -rw-r--r-- | src/bin/jv.rs | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/src/bin/jv.rs b/src/bin/jv.rs index 0057cf9..4245e6a 100644 --- a/src/bin/jv.rs +++ b/src/bin/jv.rs @@ -69,7 +69,7 @@ use just_enough_vcs_cli::{ }, }; use rust_i18n::{set_locale, t}; -use tokio::{fs, net::TcpSocket, time::Instant}; +use tokio::{fs, net::TcpSocket, process::Command, time::Instant}; // Import i18n files rust_i18n::i18n!("locales", fallback = "en"); @@ -227,6 +227,10 @@ enum AccountManage { /// Move private key file to account #[command(alias = "mvkey", alias = "mvk", alias = "movekey")] MoveKey(MoveKeyToAccountArgs), + + /// Output public key file to specified directory + #[command(alias = "genpub")] + GeneratePublicKey(GeneratePublicKeyArgs), } #[derive(Subcommand, Debug)] @@ -377,6 +381,10 @@ struct AccountAddArgs { /// Account name account_name: String, + + /// Auto generate ED25519 private key + #[arg(short = 'K', long = "keygen")] + keygen: bool, } #[derive(Parser, Debug)] @@ -423,6 +431,19 @@ struct MoveKeyToAccountArgs { key_path: PathBuf, } +#[derive(Parser, Debug)] +struct GeneratePublicKeyArgs { + /// Show help information + #[arg(short, long)] + help: bool, + + /// Account name + account_name: String, + + /// Private key file path + output_dir: Option<PathBuf>, +} + #[derive(Parser, Debug, Clone)] struct TrackFileArgs { /// Show help information @@ -736,6 +757,13 @@ async fn main() { } jv_account_move_key(user_dir, move_key_to_account_args).await; } + AccountManage::GeneratePublicKey(generate_public_key_args) => { + if generate_public_key_args.help { + println!("{}", md(t!("jv.account"))); + return; + } + jv_account_generate_pub_key(user_dir, generate_public_key_args).await; + } } } JustEnoughVcsWorkspaceCommand::Create(create_workspace_args) => { @@ -2248,6 +2276,40 @@ async fn jv_account_add(user_dir: UserDirectory, args: AccountAddArgs) { } Err(_) => { eprintln!("{}", t!("jv.fail.account.add", account = args.account_name)); + return; + } + } + if args.keygen { + let output_path = current_local_path().unwrap().join("tempkey.pem"); + + match Command::new("openssl") + .args([ + "genpkey", + "-algorithm", + "ed25519", + "-out", + &output_path.to_string_lossy(), + ]) + .status() + .await + { + Ok(status) if status.success() => { + jv_account_move_key( + user_dir, + MoveKeyToAccountArgs { + help: false, + account_name: args.account_name, + key_path: output_path, + }, + ) + .await + } + Ok(_) => { + eprintln!("{}", t!("jv.fail.account.keygen")); + } + Err(_) => { + eprintln!("{}", t!("jv.fail.account.keygen_exec")); + } } } } @@ -2373,6 +2435,43 @@ async fn jv_account_move_key(user_dir: UserDirectory, args: MoveKeyToAccountArgs } } +async fn jv_account_generate_pub_key(user_dir: UserDirectory, args: GeneratePublicKeyArgs) { + let private_key_path = user_dir.account_private_key_path(&args.account_name); + let target_path = args + .output_dir + .unwrap_or(current_dir().unwrap()) + .join(format!("{}.pem", args.account_name)); + + match Command::new("openssl") + .args([ + "pkey", + "-in", + &private_key_path.to_string_lossy(), + "-pubout", + "-out", + &target_path.to_string_lossy(), + ]) + .status() + .await + { + Ok(status) if status.success() => { + println!( + "{}", + t!( + "jv.success.account.generate_pub_key", + export = target_path.display() + ) + ); + } + Ok(_) => { + eprintln!("{}", t!("jv.fail.account.keygen")); + } + Err(_) => { + eprintln!("{}", t!("jv.fail.account.keygen_exec")); + } + } +} + async fn jv_update(_update_file_args: UpdateArgs) { let local_config = match precheck().await { Some(config) => config, |
