diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt --- a/native/android/app/CMakeLists.txt +++ b/native/android/app/CMakeLists.txt @@ -127,7 +127,10 @@ "../../cpp/CommonCpp/_generated/utilsJSI-generated.cpp" "../../cpp/CommonCpp/_generated/rustJSI-generated.cpp" ) -set(RUST_NATIVE_CODE "../../native_rust_library/RustCallback.cpp") +list(APPEND RUST_NATIVE_CODE + "../../native_rust_library/RustCallback.cpp" + "../../native_rust_library/RustSecureStore.cpp" +) file(GLOB CRYPTO_NATIVE_CODE "../../cpp/CommonCpp/CryptoTools/*.cpp") file(GLOB DB_NATIVE_CODE "../../cpp/CommonCpp/DatabaseManagers/*.cpp") file(GLOB DB_ENTITIES_NATIVE_CODE "../../cpp/CommonCpp/DatabaseManagers/entities/*.cpp") diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj --- a/native/ios/Comm.xcodeproj/project.pbxproj +++ b/native/ios/Comm.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ CBDEC69B28ED867000C17588 /* GlobalDBSingleton.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */; }; CBFE58292885852B003B94C9 /* ThreadOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBFE58282885852B003B94C9 /* ThreadOperations.cpp */; }; D7DB6E0F85B2DBE15B01EC21 /* libPods-Comm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 994BEBDD4E4959F69CEA0BC3 /* libPods-Comm.a */; }; + DFD5E77C2B05181400C32B6A /* RustSecureStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5E77B2B05181400C32B6A /* RustSecureStore.cpp */; }; F02C296C528B51ADAB5AA19D /* libPods-NotificationService.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3EE4DCB430B05EC9DE7D7B01 /* libPods-NotificationService.a */; }; /* End PBXBuildFile section */ @@ -269,6 +270,8 @@ CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = GlobalDBSingleton.mm; path = Comm/GlobalDBSingleton.mm; sourceTree = ""; }; CBFE58272885852B003B94C9 /* ThreadOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadOperations.h; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.h; sourceTree = ""; }; CBFE58282885852B003B94C9 /* ThreadOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadOperations.cpp; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp; sourceTree = ""; }; + DFD5E77A2B05181400C32B6A /* RustSecureStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RustSecureStore.h; sourceTree = ""; }; + DFD5E77B2B05181400C32B6A /* RustSecureStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RustSecureStore.cpp; sourceTree = ""; }; F53DA7B3F26C2798DCE74A94 /* Pods-Comm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Comm.debug.xcconfig"; path = "Target Support Files/Pods-Comm/Pods-Comm.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -574,6 +577,8 @@ 8B99AF6B28D50D4800EB5ADB /* native_rust_library */ = { isa = PBXGroup; children = ( + DFD5E77B2B05181400C32B6A /* RustSecureStore.cpp */, + DFD5E77A2B05181400C32B6A /* RustSecureStore.h */, 8B652FA4295EA9F1009F8163 /* RustCallback.h */, 8B99BAAD28D511FF00EB5ADB /* lib.rs.cc */, 8B99AF6D28D50D4800EB5ADB /* lib.rs.h */, @@ -1073,6 +1078,7 @@ 71762A75270D8AAE00F565ED /* PlatformSpecificTools.mm in Sources */, 71BF5B7126B3FF0900EDE27D /* Session.cpp in Sources */, 8EF7756E2A7513F40046A385 /* MessageStore.cpp in Sources */, + DFD5E77C2B05181400C32B6A /* RustSecureStore.cpp in Sources */, 71BF5B7526B401D300EDE27D /* Tools.cpp in Sources */, 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 7FE4D9F5291DFE9300667BF6 /* commJSI-generated.cpp in Sources */, diff --git a/native/native_rust_library/RustSecureStore.h b/native/native_rust_library/RustSecureStore.h new file mode 100644 --- /dev/null +++ b/native/native_rust_library/RustSecureStore.h @@ -0,0 +1,10 @@ +#pragma once + +#include "cxx.h" + +namespace comm { + +void secureStoreSet(rust::Str key, rust::String value, size_t promise); +void secureStoreGet(rust::Str key, size_t promise); + +} // namespace comm diff --git a/native/native_rust_library/RustSecureStore.cpp b/native/native_rust_library/RustSecureStore.cpp new file mode 100644 --- /dev/null +++ b/native/native_rust_library/RustSecureStore.cpp @@ -0,0 +1,27 @@ +#include "RustSecureStore.h" +#include "../cpp/CommonCpp/Tools/CommSecureStore.h" +#include "../cpp/CommonCpp/NativeModules/InternalModules/GlobalDBSingleton.h" +#include "lib.rs.h" + +namespace comm { + +void secureStoreSet(rust::Str key, rust::String value, size_t promise) { + GlobalDBSingleton::instance.scheduleOrRun([=]() { + CommSecureStore::set(std::string(key), std::string(value)); + unitPromiseResolve(promise); + }); +} + +void secureStoreGet(rust::Str key, size_t promise){ + GlobalDBSingleton::instance.scheduleOrRun([=]() { + folly::Optional value = CommSecureStore::get(std::string(key)); + + if(value.hasValue()){ + stringPromiseResolve(promise, value.value()); + }else{ + stringPromiseReject(promise, std::string("Value doesn't exist")); + } + }); +} + +} diff --git a/native/native_rust_library/src/cxx_promise_manager.rs b/native/native_rust_library/src/cxx_promise_manager.rs --- a/native/native_rust_library/src/cxx_promise_manager.rs +++ b/native/native_rust_library/src/cxx_promise_manager.rs @@ -1,3 +1,4 @@ +use cxx::CxxString; use lazy_static::lazy_static; use std::{collections::HashMap, future::Future, sync::Mutex}; use tokio::sync::oneshot; @@ -14,7 +15,6 @@ next_id: usize, } -#[allow(unused)] impl PromiseStore { pub fn new_promise( &mut self, @@ -44,6 +44,43 @@ } } +pub mod ffi { + use super::*; + + pub fn string_promise_resolve(id: usize, value: &CxxString) { + let value = value + .to_str() + .map(str::to_string) + .map_err(|err| err.to_string()); + + let Ok(mut store) = STRING_PROMISE_STORE.lock() else { + return; + }; + store.resolve_promise(id, value); + } + + pub fn string_promise_reject(id: usize, err: &CxxString) { + let Ok(mut store) = STRING_PROMISE_STORE.lock() else { + return; + }; + store.resolve_promise(id, Err(err.to_string_lossy().to_string())); + } + + pub fn unit_promise_resolve(id: usize) { + let Ok(mut store) = UNIT_PROMISE_STORE.lock() else { + return; + }; + store.resolve_promise(id, Ok(())); + } + + pub fn unit_promise_reject(id: usize, err: &CxxString) { + let Ok(mut store) = STRING_PROMISE_STORE.lock() else { + return; + }; + store.resolve_promise(id, Err(err.to_string_lossy().to_string())); + } +} + #[cfg(test)] mod test { use super::*; diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs --- a/native/native_rust_library/src/lib.rs +++ b/native/native_rust_library/src/lib.rs @@ -19,6 +19,7 @@ mod argon2_tools; mod cxx_promise_manager; +mod secure_store; use argon2_tools::compute_backup_key; @@ -45,6 +46,7 @@ ); } +use cxx_promise_manager::ffi::*; #[cxx::bridge] mod ffi { extern "Rust" { @@ -136,6 +138,33 @@ #[cxx_name = "voidCallback"] fn void_callback(error: String, promise_id: u32); } + + // cxx_promise_manager.rs callbacks + extern "Rust" { + #[cxx_name = "stringPromiseResolve"] + fn string_promise_resolve(id: usize, value: &CxxString); + + #[cxx_name = "stringPromiseReject"] + fn string_promise_reject(id: usize, err: &CxxString); + + #[cxx_name = "unitPromiseResolve"] + fn unit_promise_resolve(id: usize); + + #[cxx_name = "unitPromiseReject"] + fn unit_promise_reject(id: usize, err: &CxxString); + } + + // secure_store.rs implementations + #[namespace = "comm"] + unsafe extern "C++" { + include!("RustSecureStore.h"); + + #[cxx_name = "secureStoreSet"] + fn secure_store_set_sync(key: &str, value: String, promise: usize); + + #[cxx_name = "secureStoreGet"] + fn secure_store_get_sync(key: &str, promise: usize); + } } fn handle_string_result_as_callback( diff --git a/native/native_rust_library/src/secure_store.rs b/native/native_rust_library/src/secure_store.rs new file mode 100644 --- /dev/null +++ b/native/native_rust_library/src/secure_store.rs @@ -0,0 +1,15 @@ +#![allow(unused)] +use crate::cxx_promise_manager::{STRING_PROMISE_STORE, UNIT_PROMISE_STORE}; +use crate::ffi::{secure_store_get_sync, secure_store_set_sync}; + +pub async fn set(key: &str, value: String) -> Result<(), String> { + let (id, promise) = UNIT_PROMISE_STORE.lock().unwrap().new_promise(); + secure_store_set_sync(key, value, id); + promise.await +} + +pub async fn get(key: &str) -> Result { + let (id, promise) = STRING_PROMISE_STORE.lock().unwrap().new_promise(); + secure_store_get_sync(key, id); + promise.await +}