diff options
Diffstat (limited to 'filamento/src/logic/process_stanza.rs')
-rw-r--r-- | filamento/src/logic/process_stanza.rs | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/filamento/src/logic/process_stanza.rs b/filamento/src/logic/process_stanza.rs index e9787a9..182fb43 100644 --- a/filamento/src/logic/process_stanza.rs +++ b/filamento/src/logic/process_stanza.rs @@ -8,13 +8,13 @@ use stanza::{ iq::{self, Iq, IqType}, }, stanza_error::Error as StanzaError, - xep_0030, + xep_0030::{self, info}, }; use tracing::{debug, error, info, warn}; use uuid::Uuid; use crate::{ - UpdateMessage, + UpdateMessage, caps, chat::{Body, Message}, error::{DatabaseError, Error, IqError, MessageRecvError, PresenceError, RosterError}, presence::{Offline, Online, Presence, PresenceType, Show}, @@ -220,22 +220,58 @@ pub async fn recv_iq( .unwrap_or_else(|| connection.server().clone()); if let Some(query) = iq.query { match query { - stanza::client::iq::Query::DiscoInfo(_query) => { - // TODO: should this only be replied to server? + stanza::client::iq::Query::DiscoInfo(query) => { info!("received disco#info request from {}", from); - let disco = xep_0030::info::Query { - node: None, - features: vec![xep_0030::info::Feature { - var: "http://jabber.org/protocol/disco#info".to_string(), - }], - identities: vec![xep_0030::info::Identity { - category: "client".to_string(), - name: Some("filamento".to_string()), - r#type: "pc".to_string(), - lang: None, - }], - extensions: Vec::new(), - }; + let current_caps_node = caps::caps_node(); + let disco: info::Query = + if query.node.is_none() || query.node == Some(current_caps_node) { + let mut info = caps::client_info(); + info.node = query.node; + info.into() + } else { + match logic + .db() + .read_capabilities(&query.node.clone().unwrap()) + .await + { + Ok(c) => match caps::decode_info_base64(c) { + Ok(mut i) => { + i.node = query.node; + i.into() + } + Err(_e) => { + let iq = Iq { + from: Some(connection.jid().clone()), + id: iq.id, + to: iq.from, + r#type: IqType::Error, + lang: None, + query: Some(iq::Query::DiscoInfo(query)), + errors: vec![StanzaError::ItemNotFound.into()], + }; + // TODO: log error + connection.write_handle().write(Stanza::Iq(iq)).await?; + info!("replied to disco#info request from {}", from); + return Ok(None); + } + }, + Err(_e) => { + let iq = Iq { + from: Some(connection.jid().clone()), + id: iq.id, + to: iq.from, + r#type: IqType::Error, + lang: None, + query: Some(iq::Query::DiscoInfo(query)), + errors: vec![StanzaError::ItemNotFound.into()], + }; + // TODO: log error + connection.write_handle().write(Stanza::Iq(iq)).await?; + info!("replied to disco#info request from {}", from); + return Ok(None); + } + } + }; let iq = Iq { from: Some(connection.jid().clone()), id: iq.id, |