163 lines
No EOL
5.7 KiB
Rust
163 lines
No EOL
5.7 KiB
Rust
use sharenet_passport::{
|
|
application::use_cases::*,
|
|
infrastructure::*,
|
|
ApplicationError,
|
|
FileStorage,
|
|
};
|
|
use rpassword::prompt_password;
|
|
use hex;
|
|
|
|
pub struct CliInterface;
|
|
|
|
impl CliInterface {
|
|
pub fn new() -> Self {
|
|
Self
|
|
}
|
|
|
|
pub fn handle_create(&self, output: &str) -> Result<(), ApplicationError> {
|
|
let password = prompt_password("Enter password for new passport: ").unwrap();
|
|
let confirm_password = prompt_password("Confirm password: ").unwrap();
|
|
|
|
if password != confirm_password {
|
|
return Err(ApplicationError::UseCaseError("Passwords do not match".to_string()));
|
|
}
|
|
|
|
let use_case = CreatePassportUseCase::new(
|
|
Bip39MnemonicGenerator,
|
|
Ed25519KeyDeriver,
|
|
XChaCha20FileEncryptor,
|
|
FileSystemStorage,
|
|
);
|
|
|
|
let (passport, recovery_phrase) = use_case.execute(&password, output)?;
|
|
|
|
println!("✅ Passport created successfully!");
|
|
println!("📄 Saved to: {}", output);
|
|
println!("🔑 Public Key: {}", hex::encode(&passport.public_key().0));
|
|
println!("🆔 DID: {}", passport.did().as_str());
|
|
println!("\n📝 IMPORTANT: Save your recovery phrase in a secure location!");
|
|
println!("Recovery phrase: {}", recovery_phrase.to_string());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn handle_import_recovery(&self, output: &str) -> Result<(), ApplicationError> {
|
|
println!("Enter your 24-word recovery phrase:");
|
|
let mut recovery_words = Vec::new();
|
|
|
|
for i in 1..=24 {
|
|
let word = prompt_password(&format!("Word {}: ", i)).unwrap();
|
|
recovery_words.push(word);
|
|
}
|
|
|
|
let password = prompt_password("Enter new password for passport file: ").unwrap();
|
|
let confirm_password = prompt_password("Confirm password: ").unwrap();
|
|
|
|
if password != confirm_password {
|
|
return Err(ApplicationError::UseCaseError("Passwords do not match".to_string()));
|
|
}
|
|
|
|
let use_case = ImportFromRecoveryUseCase::new(
|
|
Bip39MnemonicGenerator,
|
|
Ed25519KeyDeriver,
|
|
XChaCha20FileEncryptor,
|
|
FileSystemStorage,
|
|
);
|
|
|
|
let passport = use_case.execute(&recovery_words, &password, output)?;
|
|
|
|
println!("✅ Passport imported successfully!");
|
|
println!("📄 Saved to: {}", output);
|
|
println!("🔑 Public Key: {}", hex::encode(&passport.public_key().0));
|
|
println!("🆔 DID: {}", passport.did().as_str());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn handle_import_file(&self, input: &str, output: Option<&str>) -> Result<(), ApplicationError> {
|
|
let password = prompt_password("Enter password for passport file: ").unwrap();
|
|
|
|
let use_case = ImportFromFileUseCase::new(
|
|
XChaCha20FileEncryptor,
|
|
FileSystemStorage,
|
|
);
|
|
|
|
let passport = use_case.execute(input, &password, output)?;
|
|
|
|
println!("✅ Passport imported successfully!");
|
|
if let Some(output_path) = output {
|
|
println!("📄 Re-encrypted to: {}", output_path);
|
|
}
|
|
println!("🔑 Public Key: {}", hex::encode(&passport.public_key().0));
|
|
println!("🆔 DID: {}", passport.did().as_str());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn handle_export(&self, input: &str, output: &str) -> Result<(), ApplicationError> {
|
|
let password = prompt_password("Enter password for passport file: ").unwrap();
|
|
let new_password = prompt_password("Enter new password for exported file: ").unwrap();
|
|
let confirm_password = prompt_password("Confirm new password: ").unwrap();
|
|
|
|
if new_password != confirm_password {
|
|
return Err(ApplicationError::UseCaseError("Passwords do not match".to_string()));
|
|
}
|
|
|
|
// First import to get the passport
|
|
let import_use_case = ImportFromFileUseCase::new(
|
|
XChaCha20FileEncryptor,
|
|
FileSystemStorage,
|
|
);
|
|
|
|
let passport = import_use_case.execute(input, &password, None)?;
|
|
|
|
// Then export with new password
|
|
let export_use_case = ExportPassportUseCase::new(
|
|
XChaCha20FileEncryptor,
|
|
FileSystemStorage,
|
|
);
|
|
|
|
export_use_case.execute(&passport, &new_password, output)?;
|
|
|
|
println!("✅ Passport exported successfully!");
|
|
println!("📄 Saved to: {}", output);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn handle_info(&self, file: &str) -> Result<(), ApplicationError> {
|
|
let passport_file = FileSystemStorage.load(file)
|
|
.map_err(|e| ApplicationError::UseCaseError(format!("Failed to load file: {}", e)))?;
|
|
|
|
println!("📄 Passport File Information:");
|
|
println!(" File: {}", file);
|
|
println!(" Version: {}", passport_file.version);
|
|
println!(" Created: {}", passport_file.created_at);
|
|
println!(" DID: {}", passport_file.did);
|
|
println!(" Public Key: {}", hex::encode(&passport_file.public_key));
|
|
println!(" KDF: {}", passport_file.kdf);
|
|
println!(" Cipher: {}", passport_file.cipher);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn handle_sign(&self, file: &str, message: &str) -> Result<(), ApplicationError> {
|
|
let password = prompt_password("Enter password for passport file: ").unwrap();
|
|
|
|
let import_use_case = ImportFromFileUseCase::new(
|
|
XChaCha20FileEncryptor,
|
|
FileSystemStorage,
|
|
);
|
|
|
|
let passport = import_use_case.execute(file, &password, None)?;
|
|
|
|
let sign_use_case = SignCardUseCase::new();
|
|
let signature = sign_use_case.execute(&passport, message)?;
|
|
|
|
println!("✅ Message signed successfully!");
|
|
println!("📝 Message: {}", message);
|
|
println!("🔏 Signature: {}", hex::encode(&signature));
|
|
|
|
Ok(())
|
|
}
|
|
} |