From 226c2e02b57b479d5f5b894ceccdd0667ffb7d2b59fecf9daf95ca9bc600ac50 Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Mon, 19 Jan 2026 01:03:46 -0600 Subject: [PATCH] fix: feature gate some guest features in the backend --- crates/chattyness-db/src/models.rs | 7 +++++++ crates/chattyness-user-ui/src/api/avatars.rs | 14 ++++++++++++++ crates/chattyness-user-ui/src/api/websocket.rs | 12 ++++++++++++ 3 files changed, 33 insertions(+) diff --git a/crates/chattyness-db/src/models.rs b/crates/chattyness-db/src/models.rs index 5d40fea..1378e00 100644 --- a/crates/chattyness-db/src/models.rs +++ b/crates/chattyness-db/src/models.rs @@ -451,6 +451,13 @@ pub struct User { pub updated_at: DateTime, } +impl User { + /// Check if this user is a guest (has the Guest tag). + pub fn is_guest(&self) -> bool { + self.tags.contains(&UserTag::Guest) + } +} + /// Minimal user info for display purposes. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserSummary { diff --git a/crates/chattyness-user-ui/src/api/avatars.rs b/crates/chattyness-user-ui/src/api/avatars.rs index c3c344d..c1b99ba 100644 --- a/crates/chattyness-user-ui/src/api/avatars.rs +++ b/crates/chattyness-user-ui/src/api/avatars.rs @@ -53,6 +53,13 @@ pub async fn assign_slot( Path(slug): Path, Json(req): Json, ) -> Result, AppError> { + // Guests cannot customize their avatar + if user.is_guest() { + return Err(AppError::Forbidden( + "Avatar customization is disabled for guests, please register first.".to_string(), + )); + } + req.validate()?; let mut conn = rls_conn.acquire().await; @@ -93,6 +100,13 @@ pub async fn clear_slot( Path(slug): Path, Json(req): Json, ) -> Result, AppError> { + // Guests cannot customize their avatar + if user.is_guest() { + return Err(AppError::Forbidden( + "Avatar customization is disabled for guests, please register first.".to_string(), + )); + } + req.validate()?; let mut conn = rls_conn.acquire().await; diff --git a/crates/chattyness-user-ui/src/api/websocket.rs b/crates/chattyness-user-ui/src/api/websocket.rs index fa958dc..32a5274 100644 --- a/crates/chattyness-user-ui/src/api/websocket.rs +++ b/crates/chattyness-user-ui/src/api/websocket.rs @@ -353,6 +353,7 @@ async fn handle_socket( let _ = channel_state.tx.send(join_msg); let user_id = user.id; + let is_guest = user.is_guest(); let tx = channel_state.tx.clone(); // Acquire a second dedicated connection for the receive task @@ -509,6 +510,17 @@ async fn handle_socket( // Handle whisper (direct message) vs broadcast if let Some(target_name) = target_display_name { + // Check if guest is trying to whisper + if is_guest { + let _ = direct_tx + .send(ServerMessage::Error { + code: "GUEST_FEATURE_DISABLED".to_string(), + message: "Private messaging is disabled for guests, please register first.".to_string(), + }) + .await; + continue; + } + // Whisper: send directly to target user if let Some((_target_user_id, target_conn)) = ws_state .find_user_by_display_name(realm_id, &target_name)