diff --git a/sable_history/src/pg_history_service.rs b/sable_history/src/pg_history_service.rs index 368b27b..d4602d5 100644 --- a/sable_history/src/pg_history_service.rs +++ b/sable_history/src/pg_history_service.rs @@ -320,7 +320,7 @@ fn make_historical_event( source: format!("{}!{}@{}", source_nick, source_ident, source_vhost), source_account, message_type: message_type.into(), - target: channel.name.clone(), // assume it's the same + target: Some(channel.name.clone()), // assume it's the same text, } } diff --git a/sable_ircd/src/command/handlers/chathistory.rs b/sable_ircd/src/command/handlers/chathistory.rs index 07498e3..667c478 100644 --- a/sable_ircd/src/command/handlers/chathistory.rs +++ b/sable_ircd/src/command/handlers/chathistory.rs @@ -204,7 +204,7 @@ async fn list_targets<'a>( } fn send_history_entries( - _server: &ClientServer, + server: &ClientServer, conn: impl MessageSink, target: &str, entries: impl IntoIterator, @@ -221,10 +221,38 @@ fn send_history_entries( timestamp, source, source_account, - target: _, // assume it's the same as the one we got as parameter + target, message_type, text, } => { + let target = match target { + None => { + // DM sent by the user requesting history + let Some(user_id) = conn.user_id() else { + return Err(CommandError::Fail { + command: "CHATHISTORY", + code: "MESSAGE_ERROR", + context: "".to_owned(), + description: "Could not format chathistory for non-user".to_owned(), + }); + }; + server + .network() + .user(user_id) + .map_err(|e| CommandError::Fail { + command: "CHATHISTORY", + code: "MESSAGE_ERROR", + context: "".to_owned(), + description: e.to_string(), + })? + .nick() + .to_string() + } + Some(target) => { + // Not a DM, or not sent by the user requesting history + target + } + }; let msg = message::Message::new(&source, &target, message_type, &text) .with_tag(server_time::server_time_tag(timestamp)) .with_tag(OutboundMessageTag::new( diff --git a/sable_network/src/history/local_service.rs b/sable_network/src/history/local_service.rs index 9907878..dd0766c 100644 --- a/sable_network/src/history/local_service.rs +++ b/sable_network/src/history/local_service.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use tracing::instrument; use crate::network::state::HistoricMessageTargetId; +use crate::network::wrapper::MessageTarget; use crate::prelude::*; /// Helper to extract the target name for chathistory purposes from a given event. @@ -113,13 +114,17 @@ impl<'a, NetworkPolicy: policy::PolicyService> LocalHistoryService<'a, NetworkPo .into_iter() .rev() .chain(forward_entries) - .flat_map(move |entry| Self::translate_log_entry(entry, &net))) + .flat_map(move |entry| Self::translate_log_entry(entry, &net, source))) } else { Err(HistoryError::InvalidTarget(target)) } } - fn translate_log_entry(entry: HistoryLogEntry, net: &Network) -> Option { + fn translate_log_entry( + entry: HistoryLogEntry, + net: &Network, + history_request_source: UserId, + ) -> Option { match entry.details { NetworkStateChange::NewMessage(update::NewMessage { message, @@ -129,6 +134,28 @@ impl<'a, NetworkPolicy: policy::PolicyService> LocalHistoryService<'a, NetworkPo let message = net.message(message).ok()?; let source = message.source().ok()?; let target = message.target().ok()?; + tracing::error!( + "requested by {:?}, source: {:?}, target: {}", + history_request_source, + source, + target + ); + let target = if let MessageTarget::User(target_user) = &target { + tracing::error!("target: {:?}", target_user.id()); + if target_user.id() == history_request_source { + tracing::error!("equal"); + // This is a DM, and the message was sent by the user this history item will be sent to, + // so the the target needs to be rewritten + None + } else { + tracing::error!("not equal"); + // This is a DM, and the message was sent to the user this history item will be sent to + Some(target.to_string()) + } + } else { + // Not a DM + Some(target.to_string()) + }; Some(HistoricalEvent::Message { id: message.id(), @@ -136,7 +163,7 @@ impl<'a, NetworkPolicy: policy::PolicyService> LocalHistoryService<'a, NetworkPo message_type: message.message_type(), source: source.nuh(), source_account: source.account_name().map(|n| n.to_string()), - target: target.to_string(), + target, text: message.text().to_string(), }) } diff --git a/sable_network/src/history/service.rs b/sable_network/src/history/service.rs index 4af67f0..f37f10a 100644 --- a/sable_network/src/history/service.rs +++ b/sable_network/src/history/service.rs @@ -113,7 +113,8 @@ pub enum HistoricalEvent { timestamp: i64, source: String, source_account: Option, - target: String, + /// If `None`, it should be replaced by the recipient's current nick + target: Option, message_type: MessageType, text: String, }, diff --git a/sable_network/src/network/wrapper/message.rs b/sable_network/src/network/wrapper/message.rs index b804745..c3a4453 100644 --- a/sable_network/src/network/wrapper/message.rs +++ b/sable_network/src/network/wrapper/message.rs @@ -60,7 +60,7 @@ impl MessageTarget<'_> { impl std::fmt::Display for MessageTarget<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::User(u) => u.nuh().fmt(f), + Self::User(u) => u.nick().fmt(f), Self::Channel(c) => c.name().fmt(f), } } diff --git a/sable_network/src/network/wrapper/user.rs b/sable_network/src/network/wrapper/user.rs index d580d94..99e00f7 100644 --- a/sable_network/src/network/wrapper/user.rs +++ b/sable_network/src/network/wrapper/user.rs @@ -2,6 +2,7 @@ use super::*; use crate::prelude::*; /// A wrapper around a [`state::User`] +#[derive(Debug)] pub struct User<'a> { network: &'a Network, data: &'a state::User,