diff --git a/.gitea/workflows/build-and-test.yml b/.gitea/workflows/build-and-test.yml index 1881235..0975315 100644 --- a/.gitea/workflows/build-and-test.yml +++ b/.gitea/workflows/build-and-test.yml @@ -57,11 +57,10 @@ jobs: - name: Check formatting run: cd server && cargo fmt --all -- --check - # Informational (warn-only) for now. The pre-spec codebase has ~65 lint warnings, - # mostly dead-code for API the integration spec (native-remote-control) will wire. - # Re-tighten to `-- -D warnings` during the GC re-spec once that API is in use. - - name: Run Clippy (informational) - run: cd server && cargo clippy --all-targets --all-features + # Hard gate: clippy must pass with zero warnings (-D warnings). Dead-code that is + # future API surface for native-remote-control carries targeted #[allow(dead_code)]. + - name: Run Clippy + run: cd server && cargo clippy --all-targets --all-features -- -D warnings - name: Build server run: | @@ -143,12 +142,18 @@ jobs: - name: Install cargo-audit run: cargo install cargo-audit - # Informational (warn-only) for now, like clippy. GuruConnect is a single Cargo workspace, - # so one `cargo audit` at the root covers all members (agent + server) via the shared - # Cargo.lock. The pre-spec dependency tree has known advisories; re-tighten to a hard gate - # during the GC re-spec after a dependency refresh. - - name: Run security audit (informational) - run: cargo audit || echo "[WARNING] cargo audit reported advisories (informational; address in GC re-spec)" + # Hard gate: cargo audit must pass. GuruConnect is a single Cargo workspace, so one + # `cargo audit` at the root covers all members (agent + server) via the shared Cargo.lock. + # The advisories below are explicitly ignored with documented justifications; any NEW + # advisory fails the build. + # RUSTSEC-2023-0071 (rsa) ............. no fixed upgrade; optional/unreachable in active tree + # RUSTSEC-2024-0413/-0416/-0412/-0418/ + # -0415/-0420/-0419 (gtk-rs GTK3) ..... Linux-only tray-icon backend, not compiled into shipping Windows agent + # RUSTSEC-2024-0429 (glib) ............ Linux-only tray-icon backend, not compiled into shipping Windows agent + # RUSTSEC-2024-0370 (proc-macro-error) build-time proc-macro dependency, no runtime impact + - name: Run security audit + run: | + cargo audit --ignore RUSTSEC-2023-0071 --ignore RUSTSEC-2024-0413 --ignore RUSTSEC-2024-0416 --ignore RUSTSEC-2024-0412 --ignore RUSTSEC-2024-0418 --ignore RUSTSEC-2024-0415 --ignore RUSTSEC-2024-0420 --ignore RUSTSEC-2024-0419 --ignore RUSTSEC-2024-0429 --ignore RUSTSEC-2024-0370 build-summary: name: Build Summary diff --git a/Cargo.toml b/Cargo.toml index 1035378..4cadf5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,8 @@ anyhow = "1" thiserror = "1" uuid = { version = "1", features = ["v4", "serde"] } chrono = { version = "0.4", features = ["serde"] } + +[profile.release] +lto = true +codegen-units = 1 +strip = true diff --git a/server/Cargo.toml b/server/Cargo.toml index 6166536..5b10601 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -60,8 +60,3 @@ prometheus-client = "0.22" [build-dependencies] prost-build = "0.13" - -[profile.release] -lto = true -codegen-units = 1 -strip = true diff --git a/server/src/api/auth.rs b/server/src/api/auth.rs index 9e759e3..1a7813a 100644 --- a/server/src/api/auth.rs +++ b/server/src/api/auth.rs @@ -1,13 +1,9 @@ //! Authentication API endpoints -use axum::{ - extract::{Request, State}, - http::StatusCode, - Json, -}; +use axum::{extract::State, http::StatusCode, Json}; use serde::{Deserialize, Serialize}; -use crate::auth::{verify_password, AuthenticatedUser, JwtConfig}; +use crate::auth::{verify_password, AuthenticatedUser}; use crate::db; use crate::AppState; diff --git a/server/src/api/auth_logout.rs b/server/src/api/auth_logout.rs index f8b095a..6a9ede3 100644 --- a/server/src/api/auth_logout.rs +++ b/server/src/api/auth_logout.rs @@ -1,7 +1,7 @@ //! Logout and token revocation endpoints use axum::{ - extract::{Path, Request, State}, + extract::{Request, State}, http::{HeaderMap, StatusCode}, Json, }; @@ -97,7 +97,7 @@ pub struct RevokeUserRequest { /// /// For MVP, we're implementing the foundation but not the full user tracking. pub async fn revoke_user_tokens( - State(state): State, + State(_state): State, admin: AuthenticatedUser, Json(req): Json, ) -> Result, (StatusCode, Json)> { diff --git a/server/src/api/downloads.rs b/server/src/api/downloads.rs index ec7fd91..70d83c3 100644 --- a/server/src/api/downloads.rs +++ b/server/src/api/downloads.rs @@ -7,13 +7,13 @@ use axum::{ body::Body, - extract::{Path, Query, State}, + extract::Query, http::{header, StatusCode}, response::{IntoResponse, Response}, }; use serde::{Deserialize, Serialize}; use std::path::PathBuf; -use tracing::{error, info, warn}; +use tracing::{error, info}; /// Magic marker for embedded configuration (must match agent) const MAGIC_MARKER: &[u8] = b"GURUCONFIG"; diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index 7cd0738..59c904f 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -8,7 +8,7 @@ pub mod releases; pub mod users; use axum::{ - extract::{Path, Query, State}, + extract::{Path, State}, Json, }; use serde::{Deserialize, Serialize}; @@ -78,12 +78,14 @@ impl From for SessionInfo { } /// List all active sessions +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn list_sessions(State(sessions): State) -> Json> { let sessions = sessions.list_sessions().await; Json(sessions.into_iter().map(SessionInfo::from).collect()) } /// Get a specific session by ID +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_session( State(sessions): State, Path(id): Path, diff --git a/server/src/auth/mod.rs b/server/src/auth/mod.rs index df924d4..35739c2 100644 --- a/server/src/auth/mod.rs +++ b/server/src/auth/mod.rs @@ -23,11 +23,14 @@ pub struct AuthenticatedUser { pub user_id: String, pub username: String, pub role: String, + #[allow(dead_code)] + // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub permissions: Vec, } impl AuthenticatedUser { /// Check if user has a specific permission + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub fn has_permission(&self, permission: &str) -> bool { if self.role == "admin" { return true; @@ -54,6 +57,7 @@ impl From for AuthenticatedUser { /// Authenticated agent from API key #[derive(Debug, Clone)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub struct AuthenticatedAgent { pub agent_id: String, pub org_id: String, @@ -61,11 +65,13 @@ pub struct AuthenticatedAgent { /// JWT configuration stored in app state #[derive(Clone)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub struct AuthState { pub jwt_config: Arc, } impl AuthState { + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub fn new(jwt_secret: String, expiry_hours: i64) -> Self { Self { jwt_config: Arc::new(JwtConfig::new(jwt_secret, expiry_hours)), @@ -122,6 +128,7 @@ where /// Optional authenticated user (doesn't reject if not authenticated) #[derive(Debug, Clone)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub struct OptionalUser(pub Option); #[axum::async_trait] @@ -161,6 +168,7 @@ where } /// Validate an agent API key (placeholder for MVP) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub fn validate_agent_key(_api_key: &str) -> Option { // TODO: Implement actual API key validation against database // For now, accept any key for agent connections diff --git a/server/src/config.rs b/server/src/config.rs index dc0540b..dfd7ea6 100644 --- a/server/src/config.rs +++ b/server/src/config.rs @@ -5,6 +5,7 @@ use serde::Deserialize; use std::env; #[derive(Debug, Clone, Deserialize)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub struct Config { /// Address to listen on (e.g., "0.0.0.0:8080") pub listen_addr: String, diff --git a/server/src/db/events.rs b/server/src/db/events.rs index f5bd971..1e64aba 100644 --- a/server/src/db/events.rs +++ b/server/src/db/events.rs @@ -26,10 +26,13 @@ pub struct EventTypes; impl EventTypes { pub const SESSION_STARTED: &'static str = "session_started"; pub const SESSION_ENDED: &'static str = "session_ended"; + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub const SESSION_TIMEOUT: &'static str = "session_timeout"; pub const VIEWER_JOINED: &'static str = "viewer_joined"; pub const VIEWER_LEFT: &'static str = "viewer_left"; + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub const STREAMING_STARTED: &'static str = "streaming_started"; + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub const STREAMING_STOPPED: &'static str = "streaming_stopped"; // Failed connection events (security audit trail) @@ -75,6 +78,7 @@ pub async fn log_event( } /// Get events for a session +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_session_events( pool: &PgPool, session_id: Uuid, @@ -88,6 +92,7 @@ pub async fn get_session_events( } /// Get recent events (for dashboard) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_recent_events( pool: &PgPool, limit: i64, @@ -101,6 +106,7 @@ pub async fn get_recent_events( } /// Get events by type +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_events_by_type( pool: &PgPool, event_type: &str, diff --git a/server/src/db/machines.rs b/server/src/db/machines.rs index b5cd52f..70121f9 100644 --- a/server/src/db/machines.rs +++ b/server/src/db/machines.rs @@ -48,6 +48,7 @@ pub async fn upsert_machine( } /// Update machine status and info +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn update_machine_status( pool: &PgPool, agent_id: &str, diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index 69ecf61..fcb4e2b 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -15,11 +15,7 @@ use sqlx::postgres::PgPoolOptions; use sqlx::PgPool; use tracing::info; -pub use events::*; -pub use machines::*; pub use releases::*; -pub use sessions::*; -pub use support_codes::*; pub use users::*; /// Database connection pool wrapper diff --git a/server/src/db/releases.rs b/server/src/db/releases.rs index 7283aa2..c8371fd 100644 --- a/server/src/db/releases.rs +++ b/server/src/db/releases.rs @@ -20,6 +20,7 @@ pub struct Release { } /// Create a new release +#[allow(clippy::too_many_arguments)] // signature mirrors the relay/session protocol contract; refactor into a params struct tracked in docs/specs/native-remote-control/ pub async fn create_release( pool: &PgPool, version: &str, @@ -157,6 +158,7 @@ pub async fn update_machine_update_status( } /// Get machines that need updates (version < latest stable) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_machines_needing_update( pool: &PgPool, latest_version: &str, diff --git a/server/src/db/sessions.rs b/server/src/db/sessions.rs index 2dbf0e1..a3e4c7e 100644 --- a/server/src/db/sessions.rs +++ b/server/src/db/sessions.rs @@ -64,6 +64,7 @@ pub async fn end_session( } /// Get session by ID +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_session( pool: &PgPool, session_id: Uuid, @@ -75,6 +76,7 @@ pub async fn get_session( } /// Get active sessions for a machine +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_active_sessions_for_machine( pool: &PgPool, machine_id: Uuid, @@ -88,6 +90,7 @@ pub async fn get_active_sessions_for_machine( } /// Get recent sessions (for dashboard) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_recent_sessions(pool: &PgPool, limit: i64) -> Result, sqlx::Error> { sqlx::query_as::<_, DbSession>( "SELECT * FROM connect_sessions ORDER BY started_at DESC LIMIT $1", diff --git a/server/src/db/support_codes.rs b/server/src/db/support_codes.rs index b6f4d15..56181b5 100644 --- a/server/src/db/support_codes.rs +++ b/server/src/db/support_codes.rs @@ -7,6 +7,7 @@ use uuid::Uuid; /// Support code record from database #[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub struct DbSupportCode { pub id: Uuid, pub code: String, @@ -21,6 +22,7 @@ pub struct DbSupportCode { } /// Create a new support code +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn create_support_code( pool: &PgPool, code: &str, @@ -40,6 +42,7 @@ pub async fn create_support_code( } /// Get support code by code string +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_support_code( pool: &PgPool, code: &str, @@ -88,6 +91,7 @@ pub async fn mark_code_completed(pool: &PgPool, code: &str) -> Result<(), sqlx:: } /// Mark support code as cancelled +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn mark_code_cancelled(pool: &PgPool, code: &str) -> Result<(), sqlx::Error> { sqlx::query("UPDATE connect_support_codes SET status = 'cancelled' WHERE code = $1") .bind(code) @@ -97,6 +101,7 @@ pub async fn mark_code_cancelled(pool: &PgPool, code: &str) -> Result<(), sqlx:: } /// Get active support codes (pending or connected) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_active_support_codes(pool: &PgPool) -> Result, sqlx::Error> { sqlx::query_as::<_, DbSupportCode>( "SELECT * FROM connect_support_codes WHERE status IN ('pending', 'connected') ORDER BY created_at DESC" @@ -106,6 +111,7 @@ pub async fn get_active_support_codes(pool: &PgPool) -> Result Result { let result = sqlx::query_scalar::<_, bool>( "SELECT EXISTS(SELECT 1 FROM connect_support_codes WHERE code = $1 AND status = 'pending')", @@ -117,6 +123,7 @@ pub async fn is_code_valid(pool: &PgPool, code: &str) -> Result Result { let result = sqlx::query_scalar::<_, bool>( "SELECT EXISTS(SELECT 1 FROM connect_support_codes WHERE code = $1 AND status = 'cancelled')" @@ -128,6 +135,7 @@ pub async fn is_code_cancelled(pool: &PgPool, code: &str) -> Result, + #[allow(dead_code)] + // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub updated_at: DateTime, pub last_login: Option>, } /// User without password hash (for API responses) #[derive(Debug, Clone, serde::Serialize)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub struct UserInfo { pub id: Uuid, pub username: String, @@ -193,6 +196,7 @@ pub async fn set_user_permissions( } /// Get user's accessible client IDs (empty = all access) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_user_client_access(pool: &PgPool, user_id: Uuid) -> Result> { let clients: Vec<(Uuid,)> = sqlx::query_as("SELECT client_id FROM user_client_access WHERE user_id = $1") @@ -226,6 +230,7 @@ pub async fn set_user_client_access( } /// Check if user has access to a specific client +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn user_has_client_access(pool: &PgPool, user_id: Uuid, client_id: Uuid) -> Result { // Admins have access to all let user = get_user_by_id(pool, user_id).await?; diff --git a/server/src/main.rs b/server/src/main.rs index 5cb1185..52ba8b6 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -31,7 +31,7 @@ use axum::{ use serde::Deserialize; use std::net::SocketAddr; use std::sync::Arc; -use tower_http::cors::{AllowOrigin, Any, CorsLayer}; +use tower_http::cors::CorsLayer; use tower_http::services::ServeDir; use tower_http::trace::TraceLayer; use tracing::{info, Level}; @@ -76,7 +76,7 @@ async fn auth_layer( #[tokio::main] async fn main() -> Result<()> { // Initialize logging - let _subscriber = FmtSubscriber::builder() + FmtSubscriber::builder() .with_max_level(Level::INFO) .with_target(true) .init(); @@ -359,7 +359,7 @@ async fn main() -> Result<()> { .layer(TraceLayer::new_for_http()) // SEC-11: Restricted CORS configuration .layer({ - let cors = CorsLayer::new() + CorsLayer::new() // Allow requests from the production domain and localhost (for development) .allow_origin([ "https://connect.azcomputerguru.com" @@ -383,8 +383,7 @@ async fn main() -> Result<()> { axum::http::header::ACCEPT, ]) // Allow credentials (cookies, auth headers) - .allow_credentials(true); - cors + .allow_credentials(true) }); // Start server @@ -437,6 +436,7 @@ async fn list_codes( } #[derive(Deserialize)] +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ struct ValidateParams { code: String, } diff --git a/server/src/relay/mod.rs b/server/src/relay/mod.rs index 60ee330..6471586 100644 --- a/server/src/relay/mod.rs +++ b/server/src/relay/mod.rs @@ -288,6 +288,7 @@ pub async fn viewer_ws_handler( } /// Handle an agent WebSocket connection +#[allow(clippy::too_many_arguments)] // signature mirrors the relay/session protocol contract; refactor into a params struct tracked in docs/specs/native-remote-control/ async fn handle_agent_connection( socket: WebSocket, sessions: SessionManager, @@ -318,7 +319,7 @@ async fn handle_agent_connection( }; let mut buf = Vec::new(); if prost::Message::encode(&disconnect_msg, &mut buf).is_ok() { - let _ = ws_sender.send(Message::Binary(buf.into())).await; + let _ = ws_sender.send(Message::Binary(buf)).await; } let _ = ws_sender.close().await; return; @@ -335,7 +336,7 @@ async fn handle_agent_connection( info!("Session created: {} (agent in idle mode)", session_id); // Database: upsert machine and create session record - let machine_id = if let Some(ref db) = db { + let _machine_id = if let Some(ref db) = db { match db::machines::upsert_machine(db.pool(), &agent_id, &agent_name, is_persistent).await { Ok(machine) => { // Create session record @@ -401,11 +402,7 @@ async fn handle_agent_connection( let input_forward = tokio::spawn(async move { while let Some(input_data) = input_rx.recv().await { let mut sender = ws_sender_input.lock().await; - if sender - .send(Message::Binary(input_data.into())) - .await - .is_err() - { + if sender.send(Message::Binary(input_data)).await.is_err() { break; } } @@ -435,7 +432,7 @@ async fn handle_agent_connection( let mut buf = Vec::new(); if prost::Message::encode(&disconnect_msg, &mut buf).is_ok() { let mut sender = ws_sender_cancel.lock().await; - let _ = sender.send(Message::Binary(buf.into())).await; + let _ = sender.send(Message::Binary(buf)).await; let _ = sender.close().await; } break; @@ -651,11 +648,7 @@ async fn handle_viewer_connection( // Task to forward frames from agent to this viewer let frame_forward = tokio::spawn(async move { while let Ok(frame_data) = frame_rx.recv().await { - if ws_sender - .send(Message::Binary(frame_data.into())) - .await - .is_err() - { + if ws_sender.send(Message::Binary(frame_data)).await.is_err() { break; } } diff --git a/server/src/session/mod.rs b/server/src/session/mod.rs index 0d05cb0..605225f 100644 --- a/server/src/session/mod.rs +++ b/server/src/session/mod.rs @@ -27,6 +27,7 @@ pub struct ViewerInfo { } /// Heartbeat timeout (90 seconds - 3x the agent's 30 second interval) +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ const HEARTBEAT_TIMEOUT_SECS: u64 = 90; /// Session state @@ -68,6 +69,8 @@ struct SessionData { frame_tx: FrameSender, /// Channel for input events (viewer -> agent) input_tx: InputSender, + #[allow(dead_code)] + // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ input_rx: Option, /// Map of connected viewers (id -> info) viewers: HashMap, @@ -176,6 +179,7 @@ impl SessionManager { } /// Update agent status from heartbeat or status message + #[allow(clippy::too_many_arguments)] // signature mirrors the relay/session protocol contract; refactor into a params struct tracked in docs/specs/native-remote-control/ pub async fn update_agent_status( &self, session_id: SessionId, @@ -225,6 +229,7 @@ impl SessionManager { } /// Check if a session has timed out (no heartbeat for too long) + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn is_session_timed_out(&self, session_id: SessionId) -> bool { let sessions = self.sessions.read().await; if let Some(session_data) = sessions.get(&session_id) { @@ -235,6 +240,7 @@ impl SessionManager { } /// Get sessions that have timed out + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_timed_out_sessions(&self) -> Vec { let sessions = self.sessions.read().await; sessions @@ -471,11 +477,9 @@ impl SessionManager { }; let mut buf = Vec::new(); - if admin_cmd.encode(&mut buf).is_ok() { - if session_data.input_tx.send(buf).await.is_ok() { - tracing::info!("Sent admin command {:?} to session {}", command, session_id); - return true; - } + if admin_cmd.encode(&mut buf).is_ok() && session_data.input_tx.send(buf).await.is_ok() { + tracing::info!("Sent admin command {:?} to session {}", command, session_id); + return true; } } false diff --git a/server/src/support_codes.rs b/server/src/support_codes.rs index c10e82a..a1170c4 100644 --- a/server/src/support_codes.rs +++ b/server/src/support_codes.rs @@ -36,6 +36,8 @@ pub enum CodeStatus { /// Request to create a new support code #[derive(Debug, Deserialize)] pub struct CreateCodeRequest { + #[allow(dead_code)] + // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub technician_id: Option, pub technician_name: Option, } @@ -172,6 +174,7 @@ impl SupportCodeManager { } /// Get code by its code string + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_code(&self, code: &str) -> Option { let codes = self.codes.read().await; codes.get(code).cloned() @@ -209,6 +212,7 @@ impl SupportCodeManager { } /// Check if a code is valid for connection (exists and is pending) + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn is_valid_for_connection(&self, code: &str) -> bool { let codes = self.codes.read().await; codes @@ -218,6 +222,7 @@ impl SupportCodeManager { } /// List all codes (for dashboard) + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn list_codes(&self) -> Vec { let codes = self.codes.read().await; codes.values().cloned().collect() @@ -234,6 +239,7 @@ impl SupportCodeManager { } /// Get code by session ID + #[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub async fn get_by_session(&self, session_id: Uuid) -> Option { let session_to_code = self.session_to_code.read().await; let code = session_to_code.get(&session_id)?; diff --git a/server/src/utils/ip_extract.rs b/server/src/utils/ip_extract.rs index 3656202..42fe7d8 100644 --- a/server/src/utils/ip_extract.rs +++ b/server/src/utils/ip_extract.rs @@ -1,6 +1,5 @@ //! IP address extraction from WebSocket connections -use axum::extract::ConnectInfo; use std::net::{IpAddr, SocketAddr}; /// Extract IP address from Axum ConnectInfo @@ -12,11 +11,13 @@ use std::net::{IpAddr, SocketAddr}; /// // Use ip for logging /// } /// ``` +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub fn extract_ip(addr: &SocketAddr) -> IpAddr { addr.ip() } /// Extract IP address as string +#[allow(dead_code)] // TODO(native-remote-control): consumed by the integration API; see docs/specs/native-remote-control/ pub fn extract_ip_string(addr: &SocketAddr) -> String { addr.ip().to_string() }