diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6723d3a..7a71c12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,8 +35,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev @@ -89,8 +89,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev @@ -117,8 +117,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev @@ -149,8 +149,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev @@ -183,8 +183,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev @@ -218,8 +218,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev @@ -266,8 +266,8 @@ jobs: libssl-dev \ pkg-config \ libgtk-3-dev \ - libwebkit2gtk-4.0-dev \ - libjavascriptcoregtk-4.0-dev \ + libwebkit2gtk-4.1-dev \ + libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ libayatana-appindicator3-dev \ librsvg2-dev diff --git a/Cargo.toml b/Cargo.toml index d54dec5..4446a5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cfost" version = "0.1.0" -edition = "2024" +edition = "2021" authors = ["CFOST Contributors"] license = "MIT OR Apache-2.0" description = "CFOST (Conflict-Free Offline Synchronization Tool) - Cross-platform database synchronization infrastructure with P2P networking, CRDT conflict resolution, and offline-first architecture" diff --git a/src/auth.rs b/src/auth.rs index 5a25731..f553bdb 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -5,8 +5,8 @@ /// from an already authorized device. use crate::models::Device; use chrono::{DateTime, Duration, Utc}; -use libp2p::PeerId; use libp2p::identity::Keypair; +use libp2p::PeerId; use rusqlite::Connection; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/src/cli/commands/daemon.rs b/src/cli/commands/daemon.rs index 76cd256..3e056ab 100644 --- a/src/cli/commands/daemon.rs +++ b/src/cli/commands/daemon.rs @@ -3,7 +3,7 @@ use crate::cli::daemon as daemon_utils; use crate::cli::errors::{CliError, CliResult}; use crate::cli::output; use crate::db::operations::initialize_database; -use crate::logic::sync::{P2PConfig, create_swarm}; +use crate::logic::sync::{create_swarm, P2PConfig}; use crate::logic::sync_manager::SyncManager; use std::sync::{Arc, Mutex}; use std::time::Duration; diff --git a/src/cli/commands/logs.rs b/src/cli/commands/logs.rs index f5a2e16..a8b9602 100644 --- a/src/cli/commands/logs.rs +++ b/src/cli/commands/logs.rs @@ -4,7 +4,7 @@ use crate::cli::output; use std::fs::File; use std::io::{BufRead, BufReader, Seek, SeekFrom}; use std::path::Path; -use tokio::time::{Duration, sleep}; +use tokio::time::{sleep, Duration}; pub async fn view( follow: bool, diff --git a/src/crdt.rs b/src/crdt.rs index 9f5fded..c6679a2 100644 --- a/src/crdt.rs +++ b/src/crdt.rs @@ -113,7 +113,7 @@ impl HybridLogicalClock { impl PartialOrd for HybridLogicalClock { fn partial_cmp(&self, other: &Self) -> Option { - self.timestamp.partial_cmp(&other.timestamp) + Some(self.cmp(other)) } } diff --git a/src/db/operations.rs b/src/db/operations.rs index d817c56..a5da4e5 100644 --- a/src/db/operations.rs +++ b/src/db/operations.rs @@ -8,7 +8,7 @@ use crate::models::{Device, OplogEntry, Peer, User}; use chrono::{DateTime, Utc}; -use rusqlite::{Connection, Result, Row, params, types::Type}; +use rusqlite::{params, types::Type, Connection, Result, Row}; use uuid::Uuid; /// Initialize the database with migrations diff --git a/src/ffi.rs b/src/ffi.rs index 4a67985..aada411 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -16,12 +16,12 @@ pub type DbConnection = Connection; /// The caller is responsible for calling `nexus_close_database` to free the connection. /// The `db_path` must be a valid, null-terminated C string. #[unsafe(no_mangle)] -pub extern "C" fn nexus_initialize_database(db_path: *const c_char) -> *mut DbConnection { +pub unsafe extern "C" fn nexus_initialize_database(db_path: *const c_char) -> *mut DbConnection { if db_path.is_null() { return ptr::null_mut(); } - let c_str = unsafe { CStr::from_ptr(db_path) }; + let c_str = CStr::from_ptr(db_path); let path = match c_str.to_str() { Ok(s) => s, Err(_) => return ptr::null_mut(), @@ -56,22 +56,20 @@ pub unsafe extern "C" fn nexus_close_database(conn_ptr: *mut DbConnection) { /// The `username`, `email`, and `password` must be valid, null-terminated C strings. /// The caller is responsible for calling `nexus_free_string` on the returned pointer. #[unsafe(no_mangle)] -pub extern "C" fn nexus_register_user( +pub unsafe extern "C" fn nexus_register_user( conn_ptr: *mut DbConnection, username: *const c_char, email: *const c_char, password: *const c_char, ) -> *mut c_char { - let conn = unsafe { - if conn_ptr.is_null() { - return ptr::null_mut(); - } - &*conn_ptr - }; + if conn_ptr.is_null() { + return ptr::null_mut(); + } + let conn = &*conn_ptr; - let username = unsafe { CStr::from_ptr(username).to_str().unwrap() }; - let email = unsafe { CStr::from_ptr(email).to_str().unwrap() }; - let password = unsafe { CStr::from_ptr(password).to_str().unwrap() }; + let username = CStr::from_ptr(username).to_str().unwrap(); + let email = CStr::from_ptr(email).to_str().unwrap(); + let password = CStr::from_ptr(password).to_str().unwrap(); match crate::logic::register_user( conn, @@ -109,20 +107,18 @@ pub unsafe extern "C" fn nexus_free_string(s_ptr: *mut c_char) { /// The `username` and `password` must be valid, null-terminated C strings. /// The caller is responsible for calling `nexus_free_string` on the returned pointer. #[unsafe(no_mangle)] -pub extern "C" fn nexus_login_user( +pub unsafe extern "C" fn nexus_login_user( conn_ptr: *mut DbConnection, username: *const c_char, password: *const c_char, ) -> *mut c_char { - let conn = unsafe { - if conn_ptr.is_null() { - return ptr::null_mut(); - } - &*conn_ptr - }; + if conn_ptr.is_null() { + return ptr::null_mut(); + } + let conn = &*conn_ptr; - let username = unsafe { CStr::from_ptr(username).to_str().unwrap() }; - let password = unsafe { CStr::from_ptr(password).to_str().unwrap() }; + let username = CStr::from_ptr(username).to_str().unwrap(); + let password = CStr::from_ptr(password).to_str().unwrap(); match crate::logic::login_user(conn, username, password) { Ok(user) => { diff --git a/src/lib.rs b/src/lib.rs index b9d055d..b2a920c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,9 +105,9 @@ pub use logic::build_oplog_entry; // ============================================================================ pub use logic::sync::{ - NexusBehaviour, P2PConfig, SyncMessage, connect_to_bootstrap_nodes, connect_to_relay_servers, - create_swarm, create_swarm_default, decode_sync_message, encode_sync_message, - generate_device_id, handle_sync_message, parse_multiaddr_peer_id, update_peer_info, + connect_to_bootstrap_nodes, connect_to_relay_servers, create_swarm, create_swarm_default, + decode_sync_message, encode_sync_message, generate_device_id, handle_sync_message, + parse_multiaddr_peer_id, update_peer_info, NexusBehaviour, P2PConfig, SyncMessage, }; // Sync manager for orchestrating P2P operations @@ -118,15 +118,15 @@ pub use logic::sync_manager::SyncManager; // ============================================================================ pub use auth::{ - AuthChallenge, AuthResponse, AuthResult, AuthorizerWorkflow, DeviceAuthManager, - NewDeviceWorkflow, PairingSession, create_auth_response, + create_auth_response, AuthChallenge, AuthResponse, AuthResult, AuthorizerWorkflow, + DeviceAuthManager, NewDeviceWorkflow, PairingSession, }; // ============================================================================ // CRDT Operations // ============================================================================ -pub use crdt::{HybridLogicalClock, local_apply, merge}; +pub use crdt::{local_apply, merge, HybridLogicalClock}; // ============================================================================ // Tests diff --git a/src/logic/mod.rs b/src/logic/mod.rs index c75d8c4..230d921 100644 --- a/src/logic/mod.rs +++ b/src/logic/mod.rs @@ -12,7 +12,7 @@ pub mod sync_manager; use crate::crdt; use crate::db::operations; use crate::models::{Device, OplogEntry, User}; -use argon2::password_hash::{SaltString, rand_core::OsRng}; +use argon2::password_hash::{rand_core::OsRng, SaltString}; use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; use chrono::Utc; use rusqlite::Connection; diff --git a/src/logic/sync.rs b/src/logic/sync.rs index cdf8abf..7fe6a46 100644 --- a/src/logic/sync.rs +++ b/src/logic/sync.rs @@ -4,8 +4,8 @@ use crate::models::{OplogEntry, Peer}; use chrono::Utc; use libp2p::gossipsub::{MessageAuthenticity, ValidationMode}; use libp2p::{ - PeerId, Swarm, Transport, core::upgrade, dcutr, gossipsub, identity, mdns, multiaddr::Protocol, - noise, relay, swarm::NetworkBehaviour, tcp, yamux, + core::upgrade, dcutr, gossipsub, identity, mdns, multiaddr::Protocol, noise, relay, + swarm::NetworkBehaviour, tcp, yamux, PeerId, Swarm, Transport, }; use rusqlite::Connection; use std::time::Duration; @@ -275,7 +275,7 @@ pub fn update_peer_info( conn: &Connection, user_id: Uuid, device_id: Uuid, - peer_id: String, + _peer_id: String, ip_address: Option, ) -> Result<(), String> { // Check if peer exists diff --git a/src/logic/sync_manager.rs b/src/logic/sync_manager.rs index a0bf2da..51d358e 100644 --- a/src/logic/sync_manager.rs +++ b/src/logic/sync_manager.rs @@ -1,12 +1,12 @@ use crate::logic::sync::{ - NexusBehaviour, NexusBehaviourEvent, P2PConfig, SyncMessage, connect_to_bootstrap_nodes, - connect_to_relay_servers, create_swarm, encode_sync_message, + connect_to_bootstrap_nodes, connect_to_relay_servers, create_swarm, encode_sync_message, + NexusBehaviour, NexusBehaviourEvent, P2PConfig, SyncMessage, }; use crate::models::OplogEntry; use chrono::{DateTime, Utc}; -use libp2p::PeerId; use libp2p::swarm::SwarmEvent; -use libp2p::{Swarm, gossipsub, identity, mdns}; +use libp2p::PeerId; +use libp2p::{gossipsub, identity, mdns, Swarm}; use rusqlite::Connection; use std::collections::VecDeque; use std::sync::{Arc, Mutex}; @@ -23,7 +23,7 @@ pub struct SyncManager { /// Device ID for this device device_id: Uuid, /// Database connection (thread-safe) - conn: Arc>, + _conn: Arc>, /// Gossipsub topic for sync messages topic: gossipsub::IdentTopic, /// Is the manager currently actively syncing/connected to peers @@ -59,7 +59,7 @@ impl SyncManager { swarm, user_id, device_id, - conn, + _conn: conn, topic, is_syncing: false, last_sync_time: None, @@ -85,7 +85,7 @@ impl SyncManager { swarm, user_id, device_id, - conn, + _conn: conn, topic, is_syncing: false, last_sync_time: None, @@ -128,7 +128,7 @@ impl SyncManager { peer_id: peer_id.to_string(), }; - let encoded = encode_sync_message(&message).map_err(|e| std::io::Error::other(e))?; + let encoded = encode_sync_message(&message).map_err(std::io::Error::other)?; self.swarm .behaviour_mut() @@ -149,7 +149,7 @@ impl SyncManager { since_timestamp: since_timestamp.timestamp(), }; - let encoded = encode_sync_message(&message).map_err(|e| std::io::Error::other(e))?; + let encoded = encode_sync_message(&message).map_err(std::io::Error::other)?; self.swarm .behaviour_mut() @@ -170,7 +170,7 @@ impl SyncManager { entries, }; - let encoded = encode_sync_message(&message).map_err(|e| std::io::Error::other(e))?; + let encoded = encode_sync_message(&message).map_err(std::io::Error::other)?; self.swarm .behaviour_mut() @@ -212,7 +212,7 @@ impl SyncManager { #[cfg(not(feature = "tauri-api"))] fn emit_sync_status(&self) { // No-op when tauri feature is not enabled - let _ = (&self.connected_peers); + let _ = &self.connected_peers; } #[cfg(feature = "tauri-api")] @@ -349,12 +349,9 @@ impl SyncManager { message: gossipsub::Message, ) -> Result<(), Box> { let sync_message = crate::logic::sync::decode_sync_message(&message.data)?; - match sync_message { - SyncMessage::SyncData { .. } => { - self.last_sync_time = Some(Utc::now()); - self.emit_sync_status(); - } - _ => {} + if let SyncMessage::SyncData { .. } = sync_message { + self.last_sync_time = Some(Utc::now()); + self.emit_sync_status(); } Ok(()) } diff --git a/tests/logic_test.rs b/tests/logic_test.rs index 5b07f4f..45f81c8 100644 --- a/tests/logic_test.rs +++ b/tests/logic_test.rs @@ -239,7 +239,7 @@ fn test_generate_device_id() { #[test] fn test_sync_message_encode_decode() { - use cfost::logic::sync::{SyncMessage, decode_sync_message, encode_sync_message}; + use cfost::logic::sync::{decode_sync_message, encode_sync_message, SyncMessage}; let user_id = Uuid::new_v4(); let device_id = Uuid::new_v4();