VNOX-Server/gateway/src/handler/channel/edit.rs
loki5512344 742cf03a5f
Phase 2: PostgreSQL, E2EE, channel CRUD, voice signaling, Slint migration
Server:
- PostgreSQL backend (Pool enum over Sqlite/PgPool, all storage methods dual-dialect)
- E2EE for DM (4 new protobuf packets, handlers, storage of ciphertext only)
- ChannelEdit packet + server-authoritative channel create/delete
- Gateway → voice-node membership signaling via broadcast channel

Client:
- E2EE crypto (X25519 from Ed25519, HKDF, ChaCha20-Poly1305) + UI lock icons
- E2EE net layer (PID 0x0071-0x0074, JSON payloads, dispatch, session handlers)
- Slint migration: all .slint files, bridge.rs, update.rs, main.rs rewritten
- Removed egui UI (~50 files) and all dead code (clean clippy -D warnings)
2026-07-14 13:25:14 +02:00

92 lines
2.4 KiB
Rust

use anyhow::Result;
use prost::Message;
use tokio::io::{AsyncRead, AsyncWrite};
use tracing::{info, warn};
use crate::{
domain::{channels, session},
net::{
io,
state::{BroadcastMsg, State},
},
proto::{ChannelEditPayload, PacketId, SessionCrypto, encode_packet, to_payload},
};
pub async fn handle_channel_edit(
stream: &mut (impl AsyncRead + AsyncWrite + Unpin),
seq: &mut u32,
session_id: &str,
payload: &[u8],
crypto: &SessionCrypto,
state: &State,
) -> Result<()> {
let req = ChannelEditPayload::decode(payload)?;
let sess = match session::get(&state.sessions, session_id).await {
Some(s) => s,
None => return Ok(()),
};
let channel_id = req.channel_id.trim().to_string();
let channel_name = req.channel_name.trim().to_string();
if channel_id.is_empty() || channel_name.is_empty() {
io::send_encrypted(
stream,
PacketId::Error,
seq,
&to_payload(&crate::proto::ErrorPayload {
code: crate::proto::ErrorCode::InvalidPacket as u32,
message: "channel_id and channel_name are required".into(),
}),
crypto,
)
.await?;
return Ok(());
}
let renamed = channels::rename(&state.channels, &channel_id, &channel_name).await;
if !renamed {
io::send_encrypted(
stream,
PacketId::Error,
seq,
&to_payload(&crate::proto::ErrorPayload {
code: crate::proto::ErrorCode::ChannelNotFound as u32,
message: "channel not found".into(),
}),
crypto,
)
.await?;
return Ok(());
}
if let Err(e) = state
.storage
.update_channel(&channel_id, &channel_name)
.await
{
warn!("failed to update channel in storage: {e}");
}
info!(
"channel_edit: '{}' renamed to '{}' by {}",
channel_id, channel_name, sess.nickname
);
let _ = state.broadcast.send(BroadcastMsg {
channel_id: Some(channel_id.clone()),
exclude_session: Some(session_id.into()),
target_session_id: None,
data: encode_packet(
PacketId::ChannelEdit,
0,
&to_payload(&ChannelEditPayload {
channel_id: channel_id.clone(),
channel_name: channel_name.clone(),
}),
),
});
Ok(())
}