use crate::domain::entities::*; use crate::domain::traits::*; use crate::application::error::ApplicationError; use ed25519_dalek::Signer; use crate::infrastructure::time; pub struct CreatePassportUseCase where MG: MnemonicGenerator, KD: KeyDeriver, FE: FileEncryptor, FS: FileStorage, { mnemonic_generator: MG, key_deriver: KD, file_encryptor: FE, file_storage: FS, } impl CreatePassportUseCase where MG: MnemonicGenerator, KD: KeyDeriver, FE: FileEncryptor, FS: FileStorage, { pub fn new( mnemonic_generator: MG, key_deriver: KD, file_encryptor: FE, file_storage: FS, ) -> Self { Self { mnemonic_generator, key_deriver, file_encryptor, file_storage, } } pub fn execute( &self, univ_id: &str, password: &str, output_path: &str, ) -> Result<(Passport, RecoveryPhrase), ApplicationError> { // Generate recovery phrase let recovery_phrase = self .mnemonic_generator .generate() .map_err(|e| ApplicationError::UseCaseError(format!("Failed to generate mnemonic: {}", e.into())))?; // Derive seed from mnemonic and universe let seed = self .key_deriver .derive_from_mnemonic(&recovery_phrase, univ_id) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to derive seed: {}", e.into())))?; // Derive keys from seed let (public_key, private_key) = self .key_deriver .derive_from_seed(&seed) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to derive keys: {}", e.into())))?; // Create passport (without storing recovery phrase) let passport = Passport::new( seed, public_key, private_key, univ_id.to_string(), ); // Encrypt and save file let passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to encrypt file: {}", e.into())))?; self.file_storage .save(&passport_file, output_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; Ok((passport, recovery_phrase)) } } pub struct ImportFromRecoveryUseCase where MG: MnemonicGenerator, KD: KeyDeriver, FE: FileEncryptor, FS: FileStorage, { mnemonic_generator: MG, key_deriver: KD, file_encryptor: FE, file_storage: FS, } impl ImportFromRecoveryUseCase where MG: MnemonicGenerator, KD: KeyDeriver, FE: FileEncryptor, FS: FileStorage, { pub fn new( mnemonic_generator: MG, key_deriver: KD, file_encryptor: FE, file_storage: FS, ) -> Self { Self { mnemonic_generator, key_deriver, file_encryptor, file_storage, } } pub fn execute( &self, univ_id: &str, recovery_words: &[String], password: &str, output_path: &str, ) -> Result { // Validate recovery phrase self.mnemonic_generator .validate(recovery_words) .map_err(|e| ApplicationError::UseCaseError(format!("Invalid recovery phrase: {}", e.into())))?; let recovery_phrase = RecoveryPhrase::new(recovery_words.to_vec()); // Derive seed from mnemonic and universe let seed = self .key_deriver .derive_from_mnemonic(&recovery_phrase, univ_id) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to derive seed: {}", e.into())))?; // Derive keys from seed let (public_key, private_key) = self .key_deriver .derive_from_seed(&seed) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to derive keys: {}", e.into())))?; // Create passport (without storing recovery phrase) let passport = Passport::new( seed, public_key, private_key, univ_id.to_string(), ); // Encrypt and save file let passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to encrypt file: {}", e.into())))?; self.file_storage .save(&passport_file, output_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; Ok(passport) } } pub struct ImportFromFileUseCase where FE: FileEncryptor, FS: FileStorage, { file_encryptor: FE, file_storage: FS, } impl ImportFromFileUseCase where FE: FileEncryptor, FS: FileStorage, { pub fn new( file_encryptor: FE, file_storage: FS, ) -> Self { Self { file_encryptor, file_storage, } } pub fn execute( &self, file_path: &str, password: &str, output_path: Option<&str>, ) -> Result { // Load encrypted file let passport_file = self .file_storage .load(file_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to load file: {}", e.into())))?; // Decrypt file let (seed, public_key, private_key, user_profiles, date_of_birth, default_user_profile_id) = self .file_encryptor .decrypt(&passport_file, password) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to decrypt file: {}", e.into())))?; // Create passport (without storing recovery phrase) let mut passport = Passport::new( seed, public_key, private_key, passport_file.univ_id.clone(), ); passport.user_profiles = user_profiles; passport.date_of_birth = date_of_birth; passport.default_user_profile_id = default_user_profile_id; // Re-encrypt and save if output path provided if let Some(output_path) = output_path { let new_passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to re-encrypt file: {}", e.into())))?; self.file_storage .save(&new_passport_file, output_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; } Ok(passport) } } pub struct ExportPassportUseCase where FE: FileEncryptor, FS: FileStorage, { file_encryptor: FE, file_storage: FS, } impl ExportPassportUseCase where FE: FileEncryptor, FS: FileStorage, { pub fn new(file_encryptor: FE, file_storage: FS) -> Self { Self { file_encryptor, file_storage, } } pub fn execute( &self, passport: &Passport, password: &str, output_path: &str, ) -> Result<(), ApplicationError> { let passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to encrypt file: {}", e.into())))?; self.file_storage .save(&passport_file, output_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; Ok(()) } } pub struct SignCardUseCase; impl SignCardUseCase { pub fn new() -> Self { Self } pub fn execute( &self, passport: &Passport, message: &str, ) -> Result, ApplicationError> { // Convert the private key bytes to an ed25519_dalek SigningKey let signing_key = ed25519_dalek::SigningKey::from_bytes( &passport.private_key.0[..] .try_into() .map_err(|_| ApplicationError::UseCaseError("Invalid private key length".to_string()))? ); // Create universe-bound message to sign let message_to_sign = format!("u:{}:{}", passport.univ_id, message); // Sign the universe-bound message let signature = signing_key.sign(message_to_sign.as_bytes()); // Return the signature as bytes Ok(signature.to_bytes().to_vec()) } } pub struct CreateUserProfileUseCase where FE: FileEncryptor, FS: FileStorage, { file_encryptor: FE, file_storage: FS, } impl CreateUserProfileUseCase where FE: FileEncryptor, FS: FileStorage, { pub fn new(file_encryptor: FE, file_storage: FS) -> Self { Self { file_encryptor, file_storage, } } pub fn execute( &self, passport: &mut Passport, hub_did: Option, identity: UserIdentity, preferences: UserPreferences, password: &str, file_path: &str, ) -> Result<(), ApplicationError> { let profile = UserProfile::new(hub_did, identity, preferences); passport.add_user_profile(profile) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to add user profile: {}", e)))?; // Save updated passport let passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to encrypt file: {}", e.into())))?; self.file_storage .save(&passport_file, file_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; Ok(()) } } pub struct UpdateUserProfileUseCase where FE: FileEncryptor, FS: FileStorage, { file_encryptor: FE, file_storage: FS, } impl UpdateUserProfileUseCase where FE: FileEncryptor, FS: FileStorage, { pub fn new(file_encryptor: FE, file_storage: FS) -> Self { Self { file_encryptor, file_storage, } } pub fn execute( &self, passport: &mut Passport, id: Option<&str>, hub_did: Option, identity: UserIdentity, preferences: UserPreferences, password: &str, file_path: &str, ) -> Result<(), ApplicationError> { // Find existing profile by ID to preserve its ID and created_at let id = id .ok_or_else(|| ApplicationError::UseCaseError("Profile ID is required".to_string()))?; let existing_profile = passport.user_profile_by_id(id) .ok_or_else(|| ApplicationError::UseCaseError("User profile not found".to_string()))?; let now = time::now_seconds() .map_err(|e| ApplicationError::UseCaseError(format!("Time error: {}", e)))?; // Use provided hub_did or keep existing let profile = UserProfile { id: existing_profile.id.clone(), hub_did: hub_did.or_else(|| existing_profile.hub_did.clone()), identity, preferences, created_at: existing_profile.created_at, updated_at: now, }; passport.update_user_profile_by_id(id, profile) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to update user profile: {}", e)))?; // Save updated passport let passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to encrypt file: {}", e.into())))?; self.file_storage .save(&passport_file, file_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; Ok(()) } } pub struct DeleteUserProfileUseCase where FE: FileEncryptor, FS: FileStorage, { file_encryptor: FE, file_storage: FS, } impl DeleteUserProfileUseCase where FE: FileEncryptor, FS: FileStorage, { pub fn new(file_encryptor: FE, file_storage: FS) -> Self { Self { file_encryptor, file_storage, } } pub fn execute( &self, passport: &mut Passport, id: Option<&str>, password: &str, file_path: &str, ) -> Result<(), ApplicationError> { let id = id .ok_or_else(|| ApplicationError::UseCaseError("Profile ID is required".to_string()))?; passport.remove_user_profile_by_id(id) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to remove user profile: {}", e)))?; // Save updated passport let passport_file = self .file_encryptor .encrypt( &passport.seed, password, &passport.public_key, &passport.did, &passport.univ_id, &passport.user_profiles, &passport.date_of_birth, &passport.default_user_profile_id, ) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to encrypt file: {}", e.into())))?; self.file_storage .save(&passport_file, file_path) .map_err(|e| ApplicationError::UseCaseError(format!("Failed to save file: {}", e.into())))?; Ok(()) } }