diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h @@ -144,6 +144,13 @@ createNewBackup(jsi::Runtime &rt, jsi::String backupSecret) override; virtual jsi::Value restoreBackup(jsi::Runtime &rt, jsi::String backupSecret) override; + virtual jsi::Value restoreBackupData( + jsi::Runtime &rt, + jsi::String backupID, + jsi::String backupDataKey, + jsi::String backupLogDataKey) override; + virtual jsi::Value + retrieveBackupKeys(jsi::Runtime &rt, jsi::String backupSecret) override; public: CommCoreModule(std::shared_ptr jsInvoker); diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp @@ -1501,4 +1501,35 @@ ::restoreBackup(rust::string(backupSecretStr), currentID); }); } + +jsi::Value CommCoreModule::restoreBackupData( + jsi::Runtime &rt, + jsi::String backupID, + jsi::String backupDataKey, + jsi::String backupLogDataKey) { + std::string backupIDStr = backupSecret.utf8(rt); + std::string backupDataKeyStr = backupDataKey.utf8(rt); + std::string backupLogDataKeyStr = backupLogDataKey.utf8(rt); + return createPromiseAsJSIValue( + rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { + auto currentID = RustPromiseManager::instance.addPromise( + {promise, this->jsInvoker_, innerRt}); + ::restoreBackupData( + rust::string(backupIDStr), + rust::string(backupDataKeyStr), + rust::string(backupLogDataKeyStr), + currentID); + }); +} + +jsi::Value +CommCoreModule::retrieveBackupKeys(jsi::Runtime &rt, jsi::String backupSecret) { + std::string backupSecretStr = backupSecret.utf8(rt); + return createPromiseAsJSIValue( + rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { + auto currentID = RustPromiseManager::instance.addPromise( + {promise, this->jsInvoker_, innerRt}); + ::retrieveBackupKeys(rust::string(backupSecretStr), currentID); + }); +} } // namespace comm diff --git a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp --- a/native/cpp/CommonCpp/_generated/commJSI-generated.cpp +++ b/native/cpp/CommonCpp/_generated/commJSI-generated.cpp @@ -163,6 +163,12 @@ static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_restoreBackup(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->restoreBackup(rt, args[0].asString(rt)); } +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_restoreBackupData(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->restoreBackupData(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt)); +} +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_retrieveBackupKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->retrieveBackupKeys(rt, args[0].asString(rt)); +} CommCoreModuleSchemaCxxSpecJSI::CommCoreModuleSchemaCxxSpecJSI(std::shared_ptr jsInvoker) : TurboModule("CommTurboModule", jsInvoker) { @@ -214,6 +220,8 @@ methodMap_["stopBackupHandler"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_stopBackupHandler}; methodMap_["createNewBackup"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_createNewBackup}; methodMap_["restoreBackup"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_restoreBackup}; + methodMap_["restoreBackupData"] = MethodMetadata {3, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_restoreBackupData}; + methodMap_["retrieveBackupKeys"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_retrieveBackupKeys}; } diff --git a/native/cpp/CommonCpp/_generated/commJSI.h b/native/cpp/CommonCpp/_generated/commJSI.h --- a/native/cpp/CommonCpp/_generated/commJSI.h +++ b/native/cpp/CommonCpp/_generated/commJSI.h @@ -68,6 +68,8 @@ virtual void stopBackupHandler(jsi::Runtime &rt) = 0; virtual jsi::Value createNewBackup(jsi::Runtime &rt, jsi::String backupSecret) = 0; virtual jsi::Value restoreBackup(jsi::Runtime &rt, jsi::String backupSecret) = 0; + virtual jsi::Value restoreBackupData(jsi::Runtime &rt, jsi::String backupID, jsi::String backupDataKey, jsi::String backupLogDataKey) = 0; + virtual jsi::Value retrieveBackupKeys(jsi::Runtime &rt, jsi::String backupSecret) = 0; }; @@ -473,6 +475,22 @@ return bridging::callFromJs( rt, &T::restoreBackup, jsInvoker_, instance_, std::move(backupSecret)); } + jsi::Value restoreBackupData(jsi::Runtime &rt, jsi::String backupID, jsi::String backupDataKey, jsi::String backupLogDataKey) override { + static_assert( + bridging::getParameterCount(&T::restoreBackupData) == 4, + "Expected restoreBackupData(...) to have 4 parameters"); + + return bridging::callFromJs( + rt, &T::restoreBackupData, jsInvoker_, instance_, std::move(backupID), std::move(backupDataKey), std::move(backupLogDataKey)); + } + jsi::Value retrieveBackupKeys(jsi::Runtime &rt, jsi::String backupSecret) override { + static_assert( + bridging::getParameterCount(&T::retrieveBackupKeys) == 2, + "Expected retrieveBackupKeys(...) to have 2 parameters"); + + return bridging::callFromJs( + rt, &T::retrieveBackupKeys, jsInvoker_, instance_, std::move(backupSecret)); + } private: T *instance_; diff --git a/native/native_rust_library/src/backup.rs b/native/native_rust_library/src/backup.rs --- a/native/native_rust_library/src/backup.rs +++ b/native/native_rust_library/src/backup.rs @@ -7,9 +7,11 @@ use crate::ffi::{ create_main_compaction, get_backup_directory_path, get_backup_user_keys_file_path, restore_from_backup_log, - restore_from_main_compaction, secure_store_get, void_callback, + restore_from_main_compaction, secure_store_get, string_callback, + void_callback, }; use crate::future_manager; +use crate::handle_string_result_as_callback; use crate::BACKUP_SOCKET_ADDR; use crate::RUNTIME; use backup_client::{ @@ -100,6 +102,73 @@ void_callback(String::new(), promise_id); }); } + + pub fn retrieve_backup_keys(backup_secret: String, promise_id: u32) { + RUNTIME.spawn(async move { + let result = download_backup_keys(backup_secret) + .await + .map_err(|err| err.to_string()); + + let result = match result { + Ok(result) => result, + Err(error) => { + string_callback(error, promise_id, "".to_string()); + return; + } + }; + + let serialize_result = serde_json::to_string(&result); + handle_string_result_as_callback(serialize_result, promise_id); + }); + } + + pub fn restore_backup_data( + backup_id: String, + backup_data_key: String, + backup_log_data_key: String, + promise_id: u32, + ) { + RUNTIME.spawn(async move { + let backup_keys = BackupKeysResult { + backup_id, + backup_data_key, + backup_log_data_key, + }; + let result = download_backup_data(backup_keys) + .await + .map_err(|err| err.to_string()); + + let result = match result { + Ok(result) => result, + Err(error) => { + void_callback(error, promise_id); + return; + } + }; + + let (future_id, future) = future_manager::new_future::<()>().await; + restore_from_main_compaction( + &result.backup_restoration_path.to_string_lossy(), + &result.backup_data_key, + future_id, + ); + + if let Err(error) = future.await { + void_callback(error, promise_id); + return; + } + + if let Err(error) = + download_and_apply_logs(&result.backup_id, result.backup_log_data_key) + .await + { + void_callback(error.to_string(), promise_id); + return; + } + + void_callback(String::new(), promise_id); + }); + } } pub async fn create_userkeys_compaction( 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 @@ -320,6 +320,17 @@ #[cxx_name = "restoreBackup"] fn restore_backup(backup_secret: String, promise_id: u32); + + #[cxx_name = "restoreBackupData"] + fn restore_backup_data( + backup_id: String, + backup_data_key: String, + backup_log_data_key: String, + promise_id: u32, + ); + + #[cxx_name = "retrieveBackupKeys"] + fn retrieve_backup_keys(backup_secret: String, promise_id: u32); } // Secure store diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js --- a/native/schema/CommCoreModuleSchema.js +++ b/native/schema/CommCoreModuleSchema.js @@ -129,6 +129,12 @@ +stopBackupHandler: () => void; +createNewBackup: (backupSecret: string) => Promise; +restoreBackup: (backupSecret: string) => Promise; + +restoreBackupData: ( + backupID: string, + backupDataKey: string, + backupLogDataKey: string, + ) => Promise; + +retrieveBackupKeys: (backupSecret: string) => Promise; } export interface CoreModuleSpec extends Spec {