Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3355775
D10987.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D10987.diff
View Options
diff --git a/native/backup/use-client-backup.js b/native/backup/use-client-backup.js
--- a/native/backup/use-client-backup.js
+++ b/native/backup/use-client-backup.js
@@ -1,25 +1,17 @@
// @flow
-import _isEqual from 'lodash/fp/isEqual.js';
import * as React from 'react';
import { isLoggedIn } from 'lib/selectors/user-selectors.js';
-import type { UserStore } from 'lib/types/user-types.js';
import { fetchNativeKeychainCredentials } from '../account/native-credentials.js';
import { commCoreModule } from '../native-modules.js';
import { useSelector } from '../redux/redux-utils.js';
import { getContentSigningKey } from '../utils/crypto-utils.js';
-type UserData = {
- +userStore: UserStore,
-};
-
type ClientBackup = {
+uploadBackupProtocol: () => Promise<void>,
- +restoreBackupProtocol: (
- expectedUserData: UserData,
- ) => Promise<{ +dataIntegritySuccess: boolean }>,
+ +restoreBackupProtocol: () => Promise<void>,
};
async function getBackupSecret(): Promise<string> {
@@ -37,11 +29,10 @@
);
const loggedIn = useSelector(isLoggedIn);
- const uploadBackupProtocol = React.useCallback(async () => {
- if (!loggedIn || !currentUserID) {
- throw new Error('Attempt to upload backup for not logged in user.');
+ const setMockCommServicesAuthMetadata = React.useCallback(async () => {
+ if (!currentUserID) {
+ return;
}
- console.info('Start uploading backup...');
const ed25519 = await getContentSigningKey();
await commCoreModule.setCommServicesAuthMetadata(
@@ -49,27 +40,35 @@
ed25519,
accessToken ? accessToken : '',
);
+ }, [accessToken, currentUserID]);
+
+ const uploadBackupProtocol = React.useCallback(async () => {
+ if (!loggedIn || !currentUserID) {
+ throw new Error('Attempt to upload backup for not logged in user.');
+ }
+ console.info('Start uploading backup...');
+
+ await setMockCommServicesAuthMetadata();
const backupSecret = await getBackupSecret();
await commCoreModule.createNewBackup(backupSecret);
console.info('Backup uploaded.');
- }, [accessToken, currentUserID, loggedIn]);
+ }, [currentUserID, loggedIn, setMockCommServicesAuthMetadata]);
- const restoreBackupProtocol = React.useCallback(
- async (expectedUserData: UserData) => {
- if (!loggedIn || !currentUserID) {
- throw new Error('Attempt to restore backup for not logged in user.');
- }
+ const restoreBackupProtocol = React.useCallback(async () => {
+ if (!loggedIn || !currentUserID) {
+ throw new Error('Attempt to restore backup for not logged in user.');
+ }
- const backupSecret = await getBackupSecret();
- const restoreResultStr = await commCoreModule.restoreBackup(backupSecret);
- const { userData }: { userData: UserData } = JSON.parse(restoreResultStr);
+ console.info('Start restoring backup...');
- return { dataIntegritySuccess: !!_isEqual(userData, expectedUserData) };
- },
- [currentUserID, loggedIn],
- );
+ await setMockCommServicesAuthMetadata();
+ const backupSecret = await getBackupSecret();
+ await commCoreModule.restoreBackup(backupSecret);
+
+ console.info('Backup restored.');
+ }, [currentUserID, loggedIn, setMockCommServicesAuthMetadata]);
return { uploadBackupProtocol, restoreBackupProtocol };
}
diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.h
--- a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.h
+++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.h
@@ -9,7 +9,8 @@
static void createMainCompaction(std::string backupID, size_t futureID);
static void restoreFromMainCompaction(
std::string mainCompactionPath,
- std::string mainCompactionEncryptionKey);
+ std::string mainCompactionEncryptionKey,
+ size_t futureID);
static void restoreFromBackupLog(const std::vector<std::uint8_t> &backupLog);
};
} // namespace comm
diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.cpp
--- a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.cpp
+++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.cpp
@@ -2,6 +2,7 @@
#include "DatabaseManager.h"
#include "GlobalDBSingleton.h"
#include "Logger.h"
+#include "RustPromiseManager.h"
#include "WorkerThread.h"
#include "lib.rs.h"
@@ -24,17 +25,18 @@
void BackupOperationsExecutor::restoreFromMainCompaction(
std::string mainCompactionPath,
- std::string mainCompactionEncryptionKey) {
- taskType job = [mainCompactionPath, mainCompactionEncryptionKey]() {
+ std::string mainCompactionEncryptionKey,
+ size_t futureID) {
+ taskType job = [mainCompactionPath, mainCompactionEncryptionKey, futureID]() {
try {
DatabaseManager::getQueryExecutor().restoreFromMainCompaction(
mainCompactionPath, mainCompactionEncryptionKey);
+ ::resolveUnitFuture(futureID);
} catch (const std::exception &e) {
- // TODO: Inform Rust networking about failure
- // of restoration from main compaction.
+ std::string errorDetails = std::string(e.what());
Logger::log(
- "Restore from main compaction failed. Details: " +
- std::string(e.what()));
+ "Restore from main compaction failed. Details: " + errorDetails);
+ ::rejectFuture(futureID, errorDetails);
}
};
GlobalDBSingleton::instance.scheduleOrRunCancellable(job);
diff --git a/native/native_rust_library/RustBackupExecutor.h b/native/native_rust_library/RustBackupExecutor.h
--- a/native/native_rust_library/RustBackupExecutor.h
+++ b/native/native_rust_library/RustBackupExecutor.h
@@ -11,8 +11,9 @@
rust::String getBackupUserKeysFilePath(rust::Str backupID);
void createMainCompaction(rust::Str backupID, size_t futureID);
void restoreFromMainCompaction(
- rust::String mainCompactionPath,
- rust::String mainCompactionEncryptionKey);
+ rust::Str mainCompactionPath,
+ rust::Str mainCompactionEncryptionKey,
+ size_t futureID);
void restoreFromBackupLog(rust::Vec<std::uint8_t> backupLog);
} // namespace comm
diff --git a/native/native_rust_library/RustBackupExecutor.cpp b/native/native_rust_library/RustBackupExecutor.cpp
--- a/native/native_rust_library/RustBackupExecutor.cpp
+++ b/native/native_rust_library/RustBackupExecutor.cpp
@@ -32,11 +32,13 @@
}
void restoreFromMainCompaction(
- rust::String mainCompactionPath,
- rust::String mainCompactionEncryptionKey) {
+ rust::Str mainCompactionPath,
+ rust::Str mainCompactionEncryptionKey,
+ size_t futureID) {
BackupOperationsExecutor::restoreFromMainCompaction(
std::string(mainCompactionPath),
- std::string(mainCompactionEncryptionKey));
+ std::string(mainCompactionEncryptionKey),
+ futureID);
}
void restoreFromBackupLog(rust::Vec<std::uint8_t> backupLog) {
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
@@ -5,10 +5,11 @@
use crate::argon2_tools::{compute_backup_key, compute_backup_key_str};
use crate::constants::{aes, secure_store};
use crate::ffi::{
- create_main_compaction, get_backup_user_keys_file_path, secure_store_get,
+ create_main_compaction, get_backup_directory_path,
+ get_backup_user_keys_file_path, restore_from_main_compaction,
+ secure_store_get, void_callback,
};
use crate::future_manager;
-use crate::handle_string_result_as_callback;
use crate::BACKUP_SOCKET_ADDR;
use crate::RUNTIME;
use backup_client::{
@@ -16,8 +17,8 @@
UserIdentity,
};
use serde::{Deserialize, Serialize};
-use serde_json::json;
use std::error::Error;
+use std::path::PathBuf;
pub mod ffi {
use super::*;
@@ -62,10 +63,33 @@
});
}
- pub fn restore_backup_sync(backup_secret: String, promise_id: u32) {
+ pub fn restore_backup(backup_secret: String, promise_id: u32) {
RUNTIME.spawn(async move {
- let result = restore_backup(backup_secret).await;
- handle_string_result_as_callback(result, promise_id);
+ let result = download_backup(backup_secret)
+ .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;
+ }
+
+ void_callback(String::new(), promise_id);
});
}
}
@@ -95,9 +119,9 @@
Ok(())
}
-pub async fn restore_backup(
+async fn download_backup(
backup_secret: String,
-) -> Result<String, Box<dyn Error>> {
+) -> Result<CompactionDownloadResult, Box<dyn Error>> {
let backup_client = BackupClient::new(BACKUP_SOCKET_ADDR)?;
let user_identity = get_user_identity_from_secure_store()?;
@@ -127,25 +151,20 @@
user_identity: user_identity.clone(),
};
- let mut encrypted_user_data = backup_client
+ let encrypted_user_data = backup_client
.download_backup_data(&backup_data_descriptor, RequestedData::UserData)
.await?;
- let user_data = decrypt(
- &mut user_keys.backup_data_key.as_bytes().to_vec(),
- &mut encrypted_user_data,
- )?;
-
- let user_data: serde_json::Value = serde_json::from_slice(&user_data)?;
-
- Ok(
- json!({
- "userData": user_data,
- "pickleKey": user_keys.pickle_key,
- "pickledAccount": user_keys.pickled_account,
- })
- .to_string(),
- )
+ let backup_restoration_path =
+ PathBuf::from(get_backup_directory_path()?).join("restore_compaction");
+
+ tokio::fs::write(&backup_restoration_path, encrypted_user_data).await?;
+
+ Ok(CompactionDownloadResult {
+ backup_id,
+ backup_restoration_path,
+ backup_data_key: user_keys.backup_data_key,
+ })
}
fn get_user_identity_from_secure_store() -> Result<UserIdentity, cxx::Exception>
@@ -157,6 +176,12 @@
})
}
+struct CompactionDownloadResult {
+ backup_id: String,
+ backup_restoration_path: PathBuf,
+ backup_data_key: String,
+}
+
#[derive(Debug, Serialize, Deserialize)]
struct UserKeys {
backup_data_key: String,
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
@@ -319,7 +319,7 @@
);
#[cxx_name = "restoreBackup"]
- fn restore_backup_sync(backup_secret: String, promise_id: u32);
+ fn restore_backup(backup_secret: String, promise_id: u32);
}
// Secure store
@@ -362,12 +362,12 @@
#[cxx_name = "createMainCompaction"]
fn create_main_compaction(backup_id: &str, future_id: usize);
- #[allow(unused)]
#[cxx_name = "restoreFromMainCompaction"]
fn restore_from_main_compaction(
- main_compaction_path: String,
- main_compaction_encryption_key: String,
- ) -> Result<()>;
+ main_compaction_path: &str,
+ main_compaction_encryption_key: &str,
+ future_id: usize,
+ );
#[allow(unused)]
#[cxx_name = "restoreFromBackupLog"]
diff --git a/native/profile/backup-menu.react.js b/native/profile/backup-menu.react.js
--- a/native/profile/backup-menu.react.js
+++ b/native/profile/backup-menu.react.js
@@ -5,7 +5,6 @@
import { ScrollView } from 'react-native-gesture-handler';
import { getMessageForException } from 'lib/utils/errors.js';
-import { entries } from 'lib/utils/objects.js';
import { useDispatch } from 'lib/utils/redux-utils.js';
import type { ProfileNavigationProp } from './profile.react.js';
@@ -26,7 +25,6 @@
const dispatch = useDispatch();
const colors = useColors();
- const userStore = useSelector(state => state.userStore);
const isBackupEnabled = useSelector(
state => state.localSettings.isBackupEnabled,
);
@@ -45,18 +43,15 @@
}, [uploadBackupProtocol]);
const testRestore = React.useCallback(async () => {
- let message;
+ let message = 'success';
try {
- const result = await restoreBackupProtocol({ userStore });
- message = entries(result)
- .map(([key, value]) => `${key}: ${String(value)}`)
- .join('\n');
+ await restoreBackupProtocol();
} catch (e) {
message = `Backup restore error: ${String(getMessageForException(e))}`;
console.error(message);
}
Alert.alert('Restore protocol result', message);
- }, [restoreBackupProtocol, userStore]);
+ }, [restoreBackupProtocol]);
const onBackupToggled = React.useCallback(
(value: boolean) => {
diff --git a/shared/backup_client/Cargo.lock b/shared/backup_client/Cargo.lock
--- a/shared/backup_client/Cargo.lock
+++ b/shared/backup_client/Cargo.lock
@@ -159,6 +159,7 @@
"reqwest",
"serde_json",
"sha2",
+ "tokio",
"tokio-tungstenite",
"url",
]
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 24, 3:27 PM (21 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2576564
Default Alt Text
D10987.diff (13 KB)
Attached To
Mode
D10987: [native] Download and restore compaction
Attached
Detach File
Event Timeline
Log In to Comment