VNOX-Client/src/net/internal/dispatch/dm.rs
loki5512344 03d94e0465
Phase 2: E2EE for DM + Slint migration + dead code cleanup
- E2EE crypto (src/e2ee.rs) with X25519 key derivation from Ed25519,
  HKDF shared secret, ChaCha20-Poly1305 encrypt/decrypt
- E2EE net layer: PID 0x0071-0x0074, JSON payloads, dispatch, session handlers
- E2EE UI: lock icons in DM header and sidebar
- Slint migration: all .slint files, bridge.rs, update.rs, main.rs
- Removed egui UI (~50 files), cleaned all dead code
- Clean cargo clippy -- -D warnings
2026-07-14 13:25:15 +02:00

187 lines
6.6 KiB
Rust

use anyhow::Result;
use serde_json;
use tokio::sync::mpsc;
use tracing::debug;
use super::super::super::payloads::*;
use super::super::super::types::*;
pub async fn handle(pid: u16, payload: &[u8], tx: &mpsc::Sender<NetEvent>) -> Result<()> {
match pid {
PID_DM_START => {
let p: DmStartResponsePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::DmStart {
dm_id: p.dm_id,
other_user_id: p.other_user_id,
other_nickname: p.other_nickname,
messages: p
.messages
.into_iter()
.map(|m| ChatMsg {
message_id: String::new(),
sender_id: m.sender_id,
content: m.content,
timestamp: m.timestamp,
reply_to: None,
})
.collect(),
unread_count: p.unread_count,
})
.await;
}
PID_DM_MESSAGE => {
let p: DmMessagePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::DmMessage {
dm_id: p.dm_id,
sender_id: p.sender_id,
content: p.content,
timestamp: p.timestamp,
})
.await;
}
PID_DM_HISTORY => {
let p: DmHistoryPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::DmHistory {
dm_id: p.dm_id,
messages: p
.messages
.into_iter()
.map(|m| ChatMsg {
message_id: String::new(),
sender_id: m.sender_id,
content: m.content,
timestamp: m.timestamp,
reply_to: None,
})
.collect(),
})
.await;
}
PID_FRIEND_LIST => {
let p: FriendListPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::FriendList {
friends: p
.friends
.into_iter()
.map(|f| FriendInfo {
user_id: f.user_id,
nickname: f.nickname,
status: f.status,
since: f.since,
})
.collect(),
})
.await;
}
PID_MESSAGE_REACTION_ADD => {
let p: ReactionPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ReactionAdded {
channel_id: p.channel_id,
message_id: p.message_id,
user_id: p.user_id,
emoji: p.emoji,
})
.await;
}
PID_MESSAGE_REACTION_REMOVE => {
let p: ReactionPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::ReactionRemoved {
channel_id: p.channel_id,
message_id: p.message_id,
user_id: p.user_id,
emoji: p.emoji,
})
.await;
}
PID_MESSAGE_EDIT => {
let p: ChatMessagePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::MessageEdited {
channel_id: p.channel_id,
message_id: p.message_id,
content: p.content,
edited: p.edited,
})
.await;
}
PID_MESSAGE_DELETE => {
let p: MessageDeletePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::MessageDeleted {
channel_id: p.channel_id,
message_id: p.message_id,
})
.await;
}
PID_FRIEND_EVENT => {
let p: FriendEventPayload = serde_json::from_slice(payload)?;
match p.event_type.as_str() {
"request" => {
let _ = tx
.send(NetEvent::FriendRequested {
user_id: p.user_id,
nickname: p.nickname.unwrap_or_default(),
})
.await;
}
"accepted" => {
let _ = tx
.send(NetEvent::FriendAccepted {
user_id: p.user_id,
nickname: p.nickname.unwrap_or_default(),
})
.await;
}
"removed" => {
let _ = tx
.send(NetEvent::FriendRemoved { user_id: p.user_id })
.await;
}
_ => debug!("unhandled friend event: {}", p.event_type),
}
}
PID_E2EE_DM_KEY_EXCHANGE => {
let p: E2eeDmKeyExchangePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::E2eeDmKeyExchange {
dm_id: p.dm_id,
e2ee_public_key: p.e2ee_public_key,
})
.await;
}
PID_E2EE_DM_KEY_EXCHANGE_ACK => {
let p: E2eeDmKeyExchangeAckPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::E2eeDmKeyExchangeAck { dm_id: p.dm_id })
.await;
}
PID_E2EE_DM_MESSAGE => {
let p: E2eeDmMessagePayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::E2eeDmMessage {
dm_id: p.dm_id,
sender_id: p.sender_id,
ciphertext: p.ciphertext,
timestamp: p.timestamp,
})
.await;
}
PID_E2EE_DM_HISTORY => {
let p: E2eeDmHistoryPayload = serde_json::from_slice(payload)?;
let _ = tx
.send(NetEvent::E2eeDmHistory {
dm_id: p.dm_id,
messages: p.messages,
})
.await;
}
_ => {}
}
Ok(())
}