diff --git a/Cargo.lock b/Cargo.lock index e92aa5a..d5a7535 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1172,6 +1172,7 @@ dependencies = [ "color-eyre", "eyre", "foxchat", + "futures", "rand", "reqwest", "rsa", @@ -1180,6 +1181,7 @@ dependencies = [ "sha256", "sqlx", "tokio", + "tokio-tungstenite", "toml", "tower-http", "tracing", @@ -1833,10 +1835,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.1", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -1846,6 +1862,12 @@ dependencies = [ "base64", ] +[[package]] +name = "rustls-pki-types" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048a63e5b3ac996d78d402940b5fa47973d2d080c6c6fffa1d0f19c4445310b7" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -1856,6 +1878,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -2135,7 +2168,7 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls", + "rustls 0.21.10", "rustls-pemfile", "serde", "serde_json", @@ -2484,6 +2517,7 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", + "rustls 0.22.2", "tokio", "tungstenite", ] diff --git a/chat/src/http/ws/mod.rs b/chat/src/http/ws/mod.rs index 1590a7d..1aa2065 100644 --- a/chat/src/http/ws/mod.rs +++ b/chat/src/http/ws/mod.rs @@ -165,9 +165,7 @@ async fn read( tx.send(Payload::Hello {}).await.ok(); while let Some(msg) = receiver.next().await { - let msg = if let Ok(msg) = msg { - msg - } else { + let Ok(msg) = msg else { return; }; @@ -289,10 +287,35 @@ async fn filter_events( socket_state: Arc>, evt: &Dispatch, ) -> Result<(bool, Vec)> { - // If we're not authenticated yet, don't send anything - if socket_state.read().await.instance.is_none() { + let Some(instance) = &socket_state.read().await.instance else { return Ok((false, vec![])); - } + }; - Ok((true, vec![])) + match evt { + Dispatch::MessageCreate { + id: _, + channel_id: _, + guild_id, + author: _, + content: _, + created_at: _, + } => { + let users = sqlx::query!( + r#"SELECT ARRAY( + SELECT u.remote_user_id FROM users u + JOIN guilds_users gu ON gu.user_id = u.id + WHERE u.instance_id = $1 AND gu.guild_id = $2 + )"#, + instance.id, + guild_id + ) + .fetch_one(&app_state.pool) + .await?; + + if let Some(users) = users.array { + return Ok((users.len() > 0, users)); + } + return Ok((false, vec![])); + } + } } diff --git a/foxchat/src/c2s/event.rs b/foxchat/src/c2s/event.rs new file mode 100644 index 0000000..6181aba --- /dev/null +++ b/foxchat/src/c2s/event.rs @@ -0,0 +1,22 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +#[serde(tag = "t", content = "d", rename_all = "SCREAMING_SNAKE_CASE")] +pub enum Payload { + Dispatch { + #[serde(rename = "e")] + event: String, + #[serde(rename = "s")] + server: String, + }, + Error { + message: String, + }, + /// Hello message, sent after authentication succeeds + Hello { + guilds: Vec, + }, + Identify { + token: String, + }, +} \ No newline at end of file diff --git a/foxchat/src/c2s/mod.rs b/foxchat/src/c2s/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/foxchat/src/lib.rs b/foxchat/src/lib.rs index 03ad1c1..b30451f 100644 --- a/foxchat/src/lib.rs +++ b/foxchat/src/lib.rs @@ -3,6 +3,7 @@ pub mod fed; pub mod http; pub mod model; pub mod s2s; +pub mod c2s; pub mod id; pub use error::FoxError; diff --git a/identity/Cargo.toml b/identity/Cargo.toml index da31cf7..e9b6254 100644 --- a/identity/Cargo.toml +++ b/identity/Cargo.toml @@ -27,3 +27,5 @@ base64 = "0.21.7" sha256 = "1.5.0" reqwest = { version = "0.11.23", features = ["json", "gzip", "brotli", "multipart"] } chrono = "0.4.31" +futures = "0.3.30" +tokio-tungstenite = { version = "0.21.0", features = ["rustls"] } diff --git a/identity/src/http/mod.rs b/identity/src/http/mod.rs index 926283b..7490413 100644 --- a/identity/src/http/mod.rs +++ b/identity/src/http/mod.rs @@ -2,6 +2,7 @@ mod account; mod auth; mod node; mod proxy; +mod ws; use std::sync::Arc; diff --git a/identity/src/http/ws/mod.rs b/identity/src/http/ws/mod.rs new file mode 100644 index 0000000..c716906 --- /dev/null +++ b/identity/src/http/ws/mod.rs @@ -0,0 +1,23 @@ +use std::sync::Arc; + +use axum::{extract::{ws::WebSocket, WebSocketUpgrade}, response::Response, Extension}; +use futures::{ + stream::{SplitSink, SplitStream, StreamExt}, + SinkExt, +}; + +use crate::{app_state::AppState, model::account::Account}; + +pub async fn handler(ws: WebSocketUpgrade, Extension(state): Extension>) -> Response { + ws.on_upgrade(|socket| handle_socket(state, socket)) +} + +struct SocketState { + user: Option, +} + +async fn handle_socket(app_state: Arc, socket: WebSocket) { + let (sender, receiver) = socket.split(); + + +}