diff --git a/Cargo.toml b/Cargo.toml index 1668f1080..a96b6b9e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ either = "1" void = "1" #ipfs dependency -rust-ipfs = "0.5.0" +rust-ipfs = "0.6.0" # Blink related crates # av-data is needed to use libaom. need to ensure that Warp and libaom use the same version of av-data diff --git a/extensions/warp-ipfs/src/lib.rs b/extensions/warp-ipfs/src/lib.rs index ff8e30b2a..5d9f80eb3 100644 --- a/extensions/warp-ipfs/src/lib.rs +++ b/extensions/warp-ipfs/src/lib.rs @@ -272,18 +272,7 @@ impl WarpIpfs { info!("Starting ipfs"); let mut uninitialized = UninitializedIpfs::empty() - .set_listening_addrs(config.listen_on.clone()) - .set_custom_behaviour(behaviour) - .set_keypair(keypair) - .enable_rendezvous_client() - .set_transport_configuration(TransportConfig { - yamux_update_mode: UpdateMode::Read, - ..Default::default() - }) - .listen_as_external_addr() - .enable_relay(true) - .set_swarm_configuration(swarm_configuration) - .set_identify_configuration({ + .with_identify(Some({ let mut idconfig = IdentifyConfiguration { protocol_version: "/satellite/warp/0.1".into(), ..Default::default() @@ -292,21 +281,35 @@ impl WarpIpfs { idconfig.agent_version = agent.clone(); } idconfig - }) - .set_kad_configuration( - KadConfig { + })) + .with_autonat() + .with_bitswap(None) + .with_kademlia( + Some(either::Either::Left(KadConfig { query_timeout: std::time::Duration::from_secs(60), publication_interval: Some(Duration::from_secs(30 * 60)), provider_record_ttl: Some(Duration::from_secs(60 * 60)), insert_method: KadInserts::Manual, ..Default::default() - }, + })), Default::default(), ) - .set_pubsub_configuration(PubsubConfig { + .with_ping(None) + .with_pubsub(Some(PubsubConfig { max_transmit_size: config.ipfs_setting.pubsub.max_transmit_size, ..Default::default() - }); + })) + .with_relay(true) + .set_listening_addrs(config.listen_on.clone()) + .with_custom_behaviour(behaviour) + .set_keypair(keypair) + .with_rendezvous_client() + .set_transport_configuration(TransportConfig { + yamux_update_mode: UpdateMode::Read, + ..Default::default() + }) + .listen_as_external_addr() + .set_swarm_configuration(swarm_configuration); if let Some(path) = self.config.path.as_ref() { info!("Instance will be persistent"); @@ -324,7 +327,7 @@ impl WarpIpfs { } if config.ipfs_setting.memory_transport { - uninitialized = uninitialized.set_custom_transport(Box::new( + uninitialized = uninitialized.with_custom_transport(Box::new( |keypair, relay| -> std::io::Result> { let noise_config = rust_ipfs::libp2p::noise::Config::new(keypair) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; @@ -350,11 +353,11 @@ impl WarpIpfs { } if config.ipfs_setting.portmapping { - uninitialized = uninitialized.enable_upnp(); + uninitialized = uninitialized.with_upnp(); } if config.ipfs_setting.mdns.enable { - uninitialized = uninitialized.enable_mdns(); + uninitialized = uninitialized.with_mdns(); } let ipfs = uninitialized.start().await?; diff --git a/extensions/warp-ipfs/src/store/document/root.rs b/extensions/warp-ipfs/src/store/document/root.rs index b05f475d6..4d616197f 100644 --- a/extensions/warp-ipfs/src/store/document/root.rs +++ b/extensions/warp-ipfs/src/store/document/root.rs @@ -7,13 +7,14 @@ use futures::{ use libipld::Cid; use rust_ipfs::{Ipfs, IpfsPath}; use uuid::Uuid; -use warp::{crypto::DID, error::Error}; +use warp::{crypto::DID, error::Error, multipass::identity::IdentityStatus}; -use crate::store::{identity::Request, keystore::Keystore, VecExt}; +use crate::store::{ecdh_encrypt, identity::Request, keystore::Keystore, VecExt}; use super::{ + identity::IdentityDocument, utils::{GetLocalDag, ToCid}, - RootDocument, + ExtractedRootDocument, RootDocument, }; #[allow(clippy::large_enum_variant)] @@ -25,6 +26,13 @@ pub enum RootDocumentCommand { document: RootDocument, response: oneshot::Sender>, }, + Identity { + response: oneshot::Sender>, + }, + SetIdentityStatus { + status: IdentityStatus, + response: oneshot::Sender>, + }, AddFriend { did: DID, response: oneshot::Sender>, @@ -80,6 +88,12 @@ pub enum RootDocumentCommand { id: Uuid, response: oneshot::Sender>, }, + Export { + response: oneshot::Sender>, + }, + ExportEncrypted { + response: oneshot::Sender, Error>>, + }, } #[derive(Debug, Clone)] @@ -150,6 +164,29 @@ impl RootDocumentMap { rx.await.map_err(anyhow::Error::from)? } + pub async fn identity(&self) -> Result { + let (tx, rx) = oneshot::channel(); + let _ = self + .tx + .clone() + .send(RootDocumentCommand::Identity { response: tx }) + .await; + rx.await.map_err(anyhow::Error::from)? + } + + pub async fn set_status_indicator(&self, status: IdentityStatus) -> Result<(), Error> { + let (tx, rx) = oneshot::channel(); + let _ = self + .tx + .clone() + .send(RootDocumentCommand::SetIdentityStatus { + status, + response: tx, + }) + .await; + rx.await.map_err(anyhow::Error::from)? + } + pub async fn add_friend(&self, did: &DID) -> Result<(), Error> { let (tx, rx) = oneshot::channel(); let _ = self @@ -294,6 +331,26 @@ impl RootDocumentMap { rx.await.map_err(anyhow::Error::from)? } + pub async fn export(&self) -> Result { + let (tx, rx) = oneshot::channel(); + let _ = self + .tx + .clone() + .send(RootDocumentCommand::Export { response: tx }) + .await; + rx.await.map_err(anyhow::Error::from)? + } + + pub async fn export_bytes(&self) -> Result, Error> { + let (tx, rx) = oneshot::channel(); + let _ = self + .tx + .clone() + .send(RootDocumentCommand::ExportEncrypted { response: tx }) + .await; + rx.await.map_err(anyhow::Error::from)? + } + pub async fn get_conversation_keystore_map(&self) -> Result, Error> { let (tx, rx) = oneshot::channel(); let _ = self @@ -349,6 +406,9 @@ impl RootDocumentTask { RootDocumentCommand::Set { document, response } => { let _ = response.send(self.set_root_document(document).await); } + RootDocumentCommand::Identity { response } => { + let _ = response.send(self.identity().await); + } RootDocumentCommand::AddFriend { did, response } => { let _ = response.send(self.add_friend(did).await); } @@ -394,6 +454,15 @@ impl RootDocumentTask { RootDocumentCommand::GetKeystoreMap { response } => { let _ = response.send(self.get_conversation_keystore_map().await); } + RootDocumentCommand::Export { response } => { + let _ = response.send(self.export().await); + } + RootDocumentCommand::ExportEncrypted { response } => { + let _ = response.send(self.export_bytes().await); + } + RootDocumentCommand::SetIdentityStatus { status, response } => { + let _ = response.send(self.set_identity_status(status).await); + } } } } @@ -411,6 +480,15 @@ impl RootDocumentTask { Ok(document) } + async fn identity(&self) -> Result { + let root = self.get_root_document().await?; + let path = IpfsPath::from(root.identity); + let document: IdentityDocument = path.get_local_dag(&self.ipfs).await?; + document.verify()?; + + Ok(document) + } + async fn set_root_document(&mut self, document: RootDocument) -> Result<(), Error> { let old_cid = self.cid; @@ -444,6 +522,18 @@ impl RootDocumentTask { Ok(()) } + async fn set_identity_status(&mut self, status: IdentityStatus) -> Result<(), Error> { + let mut root = self.get_root_document().await?; + let mut identity = self.identity().await?; + root.status = Some(status); + identity.status = Some(status); + + let identity = identity.sign(&self.keypair)?; + root.identity = identity.to_cid(&self.ipfs).await?; + + self.set_root_document(root).await + } + async fn request_list(&self) -> Result, Error> { let cid = match self.cid { Some(cid) => cid, @@ -708,4 +798,16 @@ impl RootDocumentTask { let path = IpfsPath::from(cid).sub_path(&id.to_string())?; path.get_local_dag(&self.ipfs).await } + + async fn export(&self) -> Result { + let document = self.get_root_document().await?; + document.export(&self.ipfs).await + } + + async fn export_bytes(&self) -> Result, Error> { + let export = self.export().await?; + + let bytes = serde_json::to_vec(&export)?; + ecdh_encrypt(&self.keypair, None, bytes) + } } diff --git a/extensions/warp-ipfs/src/store/identity.rs b/extensions/warp-ipfs/src/store/identity.rs index d3e14ff4e..b06dcf9a5 100644 --- a/extensions/warp-ipfs/src/store/identity.rs +++ b/extensions/warp-ipfs/src/store/identity.rs @@ -47,7 +47,7 @@ use super::{ cache::IdentityCache, identity::IdentityDocument, image_dag::get_image, root::RootDocumentMap, utils::GetLocalDag, ExtractedRootDocument, RootDocument, ToCid, }, - ecdh_decrypt, ecdh_encrypt, libp2p_pub_to_did, + ecdh_decrypt, ecdh_encrypt, phonebook::PhoneBook, queue::Queue, }; @@ -1542,9 +1542,7 @@ impl IdentityStore { #[tracing::instrument(skip(self))] pub async fn set_identity_status(&mut self, status: IdentityStatus) -> Result<(), Error> { - let mut root_document = self.root_document.get().await?; - root_document.status = Some(status); - self.root_document.set(root_document).await?; + self.root_document.set_status_indicator(status).await?; *self.online_status.write().await = Some(status); self.push_to_all().await; Ok(()) @@ -1606,31 +1604,15 @@ impl IdentityStore { } pub async fn own_identity_document(&self) -> Result { - let root_document = self.root_document.get().await?; - let path = IpfsPath::from(root_document.identity); - let identity: IdentityDocument = path.get_local_dag(&self.ipfs).await?; + let identity = self.root_document.identity().await?; identity.verify()?; Ok(identity) } pub async fn own_identity(&self) -> Result { - let root_document = self.root_document.get().await?; - - let path = IpfsPath::from(root_document.identity); - let identity = self - .get_local_dag::(path) - .await? - .resolve()?; - - let public_key = identity.did_key(); - let kp_public_key = libp2p_pub_to_did(&self.get_keypair()?.public())?; - if public_key != kp_public_key { - //Note if we reach this point, the identity would need to be reconstructed - return Err(Error::IdentityDoesntExist); - } - - *self.online_status.write().await = root_document.status; - Ok(identity) + let identity = self.own_identity_document().await?; + *self.online_status.write().await = identity.status; + Ok(identity.into()) } #[tracing::instrument(skip(self))] diff --git a/extensions/warp-ipfs/src/store/message.rs b/extensions/warp-ipfs/src/store/message.rs index 51da70fed..cb6a31d76 100644 --- a/extensions/warp-ipfs/src/store/message.rs +++ b/extensions/warp-ipfs/src/store/message.rs @@ -1725,9 +1725,9 @@ impl MessageStore { } //Temporary limit - if self.list_conversations().await.unwrap_or_default().len() >= 32 { - return Err(Error::ConversationLimitReached); - } + // if self.list_conversations().await.unwrap_or_default().len() >= 256 { + // return Err(Error::ConversationLimitReached); + // } if !self.discovery.contains(did_key).await { self.discovery.insert(did_key).await?; @@ -1836,9 +1836,9 @@ impl MessageStore { } //Temporary limit - if self.list_conversations().await.unwrap_or_default().len() >= 32 { - return Err(Error::ConversationLimitReached); - } + // if self.list_conversations().await.unwrap_or_default().len() >= 256 { + // return Err(Error::ConversationLimitReached); + // } for recipient in &recipients { if !self.discovery.contains(recipient).await {