diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 52d6f714c..aa0170db9 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -14,6 +14,17 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "ahash" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -596,6 +607,12 @@ dependencies = [ "syn 1.0.74", ] +[[package]] +name = "data-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" + [[package]] name = "deflate" version = "0.7.20" @@ -729,6 +746,18 @@ dependencies = [ "syn 1.0.74", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "1.5.0" @@ -1198,6 +1227,24 @@ dependencies = [ "system-deps", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown", +] + [[package]] name = "heck" version = "0.3.3" @@ -1401,6 +1448,16 @@ version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +[[package]] +name = "libsqlite3-sys" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "lock_api" version = "0.4.4" @@ -1604,6 +1661,21 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nexus" +version = "0.1.0" +dependencies = [ + "chrono", + "data-encoding", + "rebind", + "ring", + "rusqlite", + "serde", + "serde_json", + "tauri", + "tauri-build", +] + [[package]] name = "nix" version = "0.17.0" @@ -2369,6 +2441,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "ring" +version = "0.17.0-alpha.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ae9a4d2975bdd8254d7bcdd2261be62b42b8920f903ec682b08cdc11b87af2" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rusqlite" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57adcf67c8faaf96f3248c2a7b419a0dbc52ebe36ba83dd57fe83827c1ea4eb3" +dependencies = [ + "bitflags 1.3.1", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "memchr", + "smallvec", +] + [[package]] name = "rust-argon2" version = "0.8.3" @@ -2654,15 +2756,10 @@ dependencies = [ ] [[package]] -name = "spacedrop" -version = "0.1.0" -dependencies = [ - "rebind", - "serde", - "serde_json", - "tauri", - "tauri-build", -] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "stable_deref_trait" @@ -3143,6 +3240,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.2.2" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index fa9c322ee..0849d01ff 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "spacedrop" +name = "nexus" version = "0.1.0" -description = "Share files with a keybind" +description = "The next gen private virtual filesystem." authors = ["you"] license = "" repository = "" -default-run = "spacedrop" +default-run = "nexus" edition = "2018" build = "src/build.rs" @@ -19,6 +19,10 @@ serde_json = "1.0" rebind = "0.2.1" serde = { version = "1.0", features = ["derive"] } tauri = { version = "1.0.0-beta.5", features = ["api-all", "menu"] } +data-encoding = "2.3.2" +ring = "0.17.0-alpha.10" +rusqlite = "0.25.3" +chrono = "0.4.0" [features] default = [ "custom-protocol" ] diff --git a/src-tauri/default.db3 b/src-tauri/default.db3 new file mode 100644 index 000000000..e69de29bb diff --git a/src-tauri/src/app/config.rs b/src-tauri/src/app/config.rs new file mode 100644 index 000000000..7621bca87 --- /dev/null +++ b/src-tauri/src/app/config.rs @@ -0,0 +1,23 @@ +use std::fs; +use tauri::api::path; + +pub struct AppConfig { + pub primary_db: std::path::PathBuf, + pub data_dir: std::path::PathBuf, +} + +// returns the app config struct with complete values +pub fn get_config() -> AppConfig { + let app_name = "Nexus"; + let data_dir = path::data_dir() + .unwrap_or(std::path::PathBuf::from("./")) + .join(app_name); + + // create the data directory if not exists + fs::create_dir_all(&data_dir).unwrap(); + + AppConfig { + primary_db: data_dir.join("primary.db3"), + data_dir, + } +} diff --git a/src-tauri/src/menu.rs b/src-tauri/src/app/menu.rs similarity index 92% rename from src-tauri/src/menu.rs rename to src-tauri/src/app/menu.rs index 7d5cca61b..6131c5512 100644 --- a/src-tauri/src/menu.rs +++ b/src-tauri/src/app/menu.rs @@ -1,6 +1,6 @@ use tauri::{CustomMenuItem, Menu, Submenu}; -pub fn get_menu() -> Menu { +pub(crate) fn get_menu() -> Menu { let quit = CustomMenuItem::new("quit".to_string(), "Quit"); let close = CustomMenuItem::new("close".to_string(), "Close"); let submenu = Submenu::new("File", Menu::new().add_item(quit).add_item(close)); diff --git a/src-tauri/src/app/mod.rs b/src-tauri/src/app/mod.rs new file mode 100644 index 000000000..7ec73fad1 --- /dev/null +++ b/src-tauri/src/app/mod.rs @@ -0,0 +1,2 @@ +pub mod config; +pub mod menu; diff --git a/src-tauri/src/crypto/mod.rs b/src-tauri/src/crypto/mod.rs new file mode 100644 index 000000000..3d352a1f8 --- /dev/null +++ b/src-tauri/src/crypto/mod.rs @@ -0,0 +1,6 @@ +pub enum Encryption { + NONE, + AES128, + AES192, + AES256, +} diff --git a/src-tauri/src/db/init.rs b/src-tauri/src/db/init.rs new file mode 100644 index 000000000..4366c4230 --- /dev/null +++ b/src-tauri/src/db/init.rs @@ -0,0 +1,9 @@ +use rusqlite; +// use tauri::api::path; +use crate::app::config; + +pub fn create_connection() -> Result { + let config = config::get_config(); + + rusqlite::Connection::open(config.primary_db) +} diff --git a/src-tauri/src/db/mod.rs b/src-tauri/src/db/mod.rs new file mode 100644 index 000000000..9816cc198 --- /dev/null +++ b/src-tauri/src/db/mod.rs @@ -0,0 +1,2 @@ +pub mod init; +// pub mod util; diff --git a/src-tauri/src/db/util.rs b/src-tauri/src/db/util.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src-tauri/src/db/util.rs @@ -0,0 +1 @@ + diff --git a/src-tauri/src/filestuff.rs b/src-tauri/src/filestuff.rs deleted file mode 100644 index 1d4fe6832..000000000 --- a/src-tauri/src/filestuff.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::fs::{self, DirEntry}; -use std::io; -use std::path::Path; - -struct User { - username: String, - email: String, - sign_in_count: u64, - active: bool, -} - -// one possible implementation of walking a directory only visiting files -pub fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> { - if dir.is_dir() { - for entry in fs::read_dir(dir)? { - let entry = entry?; - let path = entry.path(); - if path.is_dir() { - visit_dirs(&path, cb)?; - } else { - cb(&entry); - } - } - } - Ok(()) -} - -pub fn current_dir() -> io::Result<()> { - let raw_entries = fs::read_dir(".")? - .map(|res| res.map(|e| e.path())) - .collect::, io::Error>>()?; - - println!("Entries: {:?}", raw_entries); - - Ok(()) -} diff --git a/src-tauri/src/filesystem/file.rs b/src-tauri/src/filesystem/file.rs new file mode 100644 index 000000000..acba41327 --- /dev/null +++ b/src-tauri/src/filesystem/file.rs @@ -0,0 +1,41 @@ +use crate::crypto; +use chrono::prelude::*; + +pub struct File { + // identity + pub id: u32, + pub checksum: String, + // metadata + pub name: String, + pub extension: String, + pub size_in_bytes: u32, + pub mime: String, + pub encryption: crypto::Encryption, + pub ipfs_id: Option, + // ownership + pub user_id: u32, + pub storage_device_id: u32, + pub capture_device_id: Option, + pub parent_object_id: Option, + // date + pub date_created: DateTime, + pub date_modified: DateTime, + pub date_indexed: DateTime, +} + +pub struct Directory { + // identity + pub id: u32, + pub name: String, + // calculations + pub calculated_size_in_bytes: u32, + pub calculated_file_count: u32, + // ownership + pub user_id: u32, + pub storage_device_id: u32, + pub parent_directory_id: Option, + // date + pub date_created: DateTime, + pub date_modified: DateTime, + pub date_indexed: DateTime, +} diff --git a/src-tauri/src/filesystem/hash.rs b/src-tauri/src/filesystem/hash.rs new file mode 100644 index 000000000..04fd9037e --- /dev/null +++ b/src-tauri/src/filesystem/hash.rs @@ -0,0 +1,27 @@ +use data_encoding::HEXUPPER; +use ring::digest::{Context, Digest, SHA256}; +use std::fs::File; +use std::io; +use std::io::{BufReader, Read}; + +fn sha256_digest(mut reader: R) -> io::Result { + let mut context = Context::new(&SHA256); + let mut buffer = [0; 1024]; + + loop { + let count = reader.read(&mut buffer)?; + if count == 0 { + break; + } + context.update(&buffer[..count]); + } + + Ok(context.finish()) +} + +pub fn create_hash(path: &str) -> io::Result { + let input = File::open(path)?; + let reader = BufReader::new(input); + let digest = sha256_digest(reader)?; + Ok(HEXUPPER.encode(digest.as_ref())) +} diff --git a/src-tauri/src/filesystem/mod.rs b/src-tauri/src/filesystem/mod.rs new file mode 100644 index 000000000..d13ac9d34 --- /dev/null +++ b/src-tauri/src/filesystem/mod.rs @@ -0,0 +1,2 @@ +mod file; +mod hash; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 8d22021d6..446d0e48d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -3,8 +3,11 @@ windows_subsystem = "windows" )] -// mod filestuff; -mod menu; +mod app; +mod crypto; +mod db; +mod filesystem; +use crate::app::menu; #[derive(serde::Serialize)] struct CustomResponse { @@ -12,18 +15,20 @@ struct CustomResponse { } #[tauri::command] -async fn message_from_rust(window: tauri::Window) -> Result { - println!("Called from {}", window.label()); +async fn fn_exposed_to_js(window: tauri::Window) -> Result { + println!("Called from window {}", window.label()); Ok(CustomResponse { message: "Hello from rust!".to_string(), }) } fn main() { - // filestuff::current_dir(); + let connection = db::init::create_connection(); + // let hash = filestuff::create_hash("/Users/jamie/Desktop/jeff.MP4"); + println!("jeff {:?}", connection); tauri::Builder::default() - .invoke_handler(tauri::generate_handler![message_from_rust]) + .invoke_handler(tauri::generate_handler![fn_exposed_to_js]) .menu(menu::get_menu()) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/transfer.rs b/src-tauri/src/transfer.rs deleted file mode 100644 index b3ef1c1e0..000000000 --- a/src-tauri/src/transfer.rs +++ /dev/null @@ -1,17 +0,0 @@ - -use std::fs; - -struct Transfer { - id: &str, -}; - -struct File { - id: &str -}; - -pub fn run() { - let path = "users/jamie"; - std::fs::read_dir(path: P) { - - } -}; diff --git a/src-tauri/src/util/filestuff.rs b/src-tauri/src/util/filestuff.rs new file mode 100644 index 000000000..9b5ba2cb2 --- /dev/null +++ b/src-tauri/src/util/filestuff.rs @@ -0,0 +1,25 @@ +// one possible implementation of walking a directory only visiting files +// pub fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> { +// if dir.is_dir() { +// for entry in fs::read_dir(dir)? { +// let entry = entry?; +// let path = entry.path(); +// if path.is_dir() { +// visit_dirs(&path, cb)?; +// } else { +// cb(&entry); +// } +// } +// } +// Ok(()) +// } + +// pub fn current_dir() -> io::Result<()> { +// let raw_entries = fs::read_dir(".")? +// .map(|res| res.map(|e| e.path())) +// .collect::, io::Error>>()?; + +// println!("Entries: {:?}", raw_entries); + +// Ok(()) +// } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 647e9fb78..522560232 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "package": { - "productName": "spacedrop", + "productName": "nexus", "version": "0.1.0" }, "build": { diff --git a/src/App.tsx b/src/App.tsx index 6c85d56fa..9b0b71596 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -31,36 +31,11 @@ export default function App() { return (
+
- - - - - -
-
- -
-
- - -
-
- - - -
diff --git a/src/types/filesystem.ts b/src/types/filesystem.ts index 82c0ecf09..3231c502f 100644 --- a/src/types/filesystem.ts +++ b/src/types/filesystem.ts @@ -7,7 +7,7 @@ export interface Object { type: ObjectType; uri: string; - file_name: string; + name: string; extension: string; size: number; mime: string; @@ -16,7 +16,6 @@ export interface Object { date_created: Date; date_modified: Date; date_indexed: Date; - geolocation: string; directory_id: string; storage_device_id: string; @@ -24,6 +23,7 @@ export interface Object { parent_object_id: string; user_id: string; + geolocation: string; extra_data: null | ImageMeta | VideoMeta; ipfs_id: string; }