From e16398071597d947056c8254368411bf7b811d33 Mon Sep 17 00:00:00 2001 From: Jazz Turner-Baggs <473256+jazzz@users.noreply.github.com> Date: Wed, 17 Jun 2026 08:27:39 -0700 Subject: [PATCH] Move Ephemeral registry to submodule (#136) --- extensions/components/src/contact_registry.rs | 114 +----------------- .../src/contact_registry/ephemeral.rs | 112 +++++++++++++++++ extensions/components/src/lib.rs | 2 +- 3 files changed, 114 insertions(+), 114 deletions(-) create mode 100644 extensions/components/src/contact_registry/ephemeral.rs diff --git a/extensions/components/src/contact_registry.rs b/extensions/components/src/contact_registry.rs index acb42c7..6d63e33 100644 --- a/extensions/components/src/contact_registry.rs +++ b/extensions/components/src/contact_registry.rs @@ -1,114 +1,2 @@ -use std::{ - collections::HashMap, - fmt::Debug, - sync::{Arc, Mutex}, -}; - -use crypto::Ed25519VerifyingKey; -use libchat::{ - AccountDirectory, DeviceSet, IdentityProvider, RegistrationService, SignedDeviceBundle, - verify_bundle, -}; - +pub mod ephemeral; pub mod http; - -/// A Contact Registry used for Tests. -/// This implementation stores bundle bytes and then returns them when -/// retrieved. -/// -/// Like the real `keypackage-registry`, one object serves both roles: a -/// keypackage store ([`RegistrationService`]) keyed by `device_id`, and an -/// account → device directory ([`AccountDirectory`]) keyed by the hex account key. -#[derive(Clone, Default)] -pub struct EphemeralRegistry { - key_packages: Arc>>>, - installations: Arc>>, -} - -impl EphemeralRegistry { - pub fn new() -> Self { - Self::default() - } -} - -impl Debug for EphemeralRegistry { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let registry = self.key_packages.lock().unwrap(); - let truncated: Vec<(&String, String)> = registry - .iter() - .map(|(k, v)| { - let hex = if v.len() <= 8 { - hex::encode(v) - } else { - format!( - "{}..{}", - hex::encode(&v[..4]), - hex::encode(&v[v.len() - 4..]) - ) - }; - (k, hex) - }) - .collect(); - f.debug_struct("EphemeralRegistry") - .field("registry", &truncated) - .finish() - } -} - -impl RegistrationService for EphemeralRegistry { - type Error = String; - - fn register( - &mut self, - identity: &dyn IdentityProvider, - key_bundle: Vec, - ) -> Result<(), ::Error> { - self.key_packages - .lock() - .unwrap() - .insert(identity.id().to_string(), key_bundle); - Ok(()) - } - - fn retrieve( - &self, - device_id: &str, - ) -> Result>, ::Error> { - Ok(self.key_packages.lock().unwrap().get(device_id).cloned()) - } -} - -/// Account → device directory, verifying each bundle on `fetch` exactly as the -/// HTTP client does so callers exercise the same trust path without a server. -impl AccountDirectory for EphemeralRegistry { - type Error = String; - - fn publish( - &mut self, - bundle: &SignedDeviceBundle, - ) -> Result<(), ::Error> { - self.installations - .lock() - .unwrap() - .insert(hex::encode(bundle.account_pub.as_ref()), bundle.clone()); - Ok(()) - } - - fn fetch( - &self, - account: &Ed25519VerifyingKey, - ) -> Result, ::Error> { - let Some(bundle) = self - .installations - .lock() - .unwrap() - .get(&hex::encode(account.as_ref())) - .cloned() - else { - return Ok(None); - }; - verify_bundle(account, &bundle) - .map(Some) - .map_err(|e| e.to_string()) - } -} diff --git a/extensions/components/src/contact_registry/ephemeral.rs b/extensions/components/src/contact_registry/ephemeral.rs new file mode 100644 index 0000000..8b28c70 --- /dev/null +++ b/extensions/components/src/contact_registry/ephemeral.rs @@ -0,0 +1,112 @@ +use std::{ + collections::HashMap, + fmt::Debug, + sync::{Arc, Mutex}, +}; + +use crypto::Ed25519VerifyingKey; +use libchat::{ + AccountDirectory, DeviceSet, IdentityProvider, RegistrationService, SignedDeviceBundle, + verify_bundle, +}; + +/// A Contact Registry used for Tests. +/// This implementation stores bundle bytes and then returns them when +/// retrieved. +/// +/// Like the real `keypackage-registry`, one object serves both roles: a +/// keypackage store ([`RegistrationService`]) keyed by `device_id`, and an +/// account → device directory ([`AccountDirectory`]) keyed by the hex account key. +#[derive(Clone, Default)] +pub struct EphemeralRegistry { + key_packages: Arc>>>, + installations: Arc>>, +} + +impl EphemeralRegistry { + pub fn new() -> Self { + Self::default() + } +} + +impl Debug for EphemeralRegistry { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let registry = self.key_packages.lock().unwrap(); + let truncated: Vec<(&String, String)> = registry + .iter() + .map(|(k, v)| { + let hex = if v.len() <= 8 { + hex::encode(v) + } else { + format!( + "{}..{}", + hex::encode(&v[..4]), + hex::encode(&v[v.len() - 4..]) + ) + }; + (k, hex) + }) + .collect(); + f.debug_struct("EphemeralRegistry") + .field("registry", &truncated) + .finish() + } +} + +impl RegistrationService for EphemeralRegistry { + type Error = String; + + fn register( + &mut self, + identity: &dyn IdentityProvider, + key_bundle: Vec, + ) -> Result<(), ::Error> { + self.key_packages + .lock() + .unwrap() + .insert(identity.id().to_string(), key_bundle); + Ok(()) + } + + fn retrieve( + &self, + device_id: &str, + ) -> Result>, ::Error> { + Ok(self.key_packages.lock().unwrap().get(device_id).cloned()) + } +} + +/// Account → device directory, verifying each bundle on `fetch` exactly as the +/// HTTP client does so callers exercise the same trust path without a server. +impl AccountDirectory for EphemeralRegistry { + type Error = String; + + fn publish( + &mut self, + bundle: &SignedDeviceBundle, + ) -> Result<(), ::Error> { + self.installations + .lock() + .unwrap() + .insert(hex::encode(bundle.account_pub.as_ref()), bundle.clone()); + Ok(()) + } + + fn fetch( + &self, + account: &Ed25519VerifyingKey, + ) -> Result, ::Error> { + let Some(bundle) = self + .installations + .lock() + .unwrap() + .get(&hex::encode(account.as_ref())) + .cloned() + else { + return Ok(None); + }; + verify_bundle(account, &bundle) + .map(Some) + .map_err(|e| e.to_string()) + } +} diff --git a/extensions/components/src/lib.rs b/extensions/components/src/lib.rs index 25ae825..d7cb449 100644 --- a/extensions/components/src/lib.rs +++ b/extensions/components/src/lib.rs @@ -3,7 +3,7 @@ mod delivery; mod storage; mod wakeup; -pub use contact_registry::EphemeralRegistry; +pub use contact_registry::ephemeral::EphemeralRegistry; pub use contact_registry::http::{HttpRegistry, HttpRegistryError}; pub use delivery::*; pub use storage::*;