Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3523275
D14005.id46191.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D14005.id46191.diff
View Options
diff --git a/lib/types/backup-types.js b/lib/types/backup-types.js
--- a/lib/types/backup-types.js
+++ b/lib/types/backup-types.js
@@ -32,3 +32,20 @@
userID: t.String,
siweBackupData: t.maybe(siweBackupDataValidator),
});
+
+// This type should match `UserKeys` in
+// `native/native_rust_library/src/backup.rs`
+export type UserKeys = {
+ +backupDataKey: string,
+ +backupLogDataKey: string,
+ +pickleKey: string,
+ +pickledAccount: string,
+};
+export const userKeysResponseValidator: TInterface<UserKeys> = tShape<UserKeys>(
+ {
+ backupDataKey: t.String,
+ backupLogDataKey: t.String,
+ pickleKey: t.String,
+ pickledAccount: t.String,
+ },
+);
diff --git a/native/backup/restore-siwe-backup.react.js b/native/backup/restore-siwe-backup.react.js
--- a/native/backup/restore-siwe-backup.react.js
+++ b/native/backup/restore-siwe-backup.react.js
@@ -4,8 +4,10 @@
import { Alert } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
+import { userKeysResponseValidator } from 'lib/types/backup-types.js';
import { type SIWEResult } from 'lib/types/siwe-types.js';
import { getMessageForException } from 'lib/utils/errors.js';
+import { assertWithValidator } from 'lib/utils/validation-utils.js';
import { SignSIWEBackupMessageForRestore } from '../account/registration/siwe-backup-message-creation.react.js';
import { commCoreModule } from '../native-modules.js';
@@ -19,6 +21,7 @@
+siweNonce: string,
+siweStatement: string,
+siweIssuedAt: string,
+ +userIdentifier: string,
};
type Props = {
@@ -31,21 +34,34 @@
const { goBack } = props.navigation;
const { route } = props;
const {
- params: { siweStatement, siweIssuedAt, siweNonce },
+ params: {
+ backupID,
+ siweStatement,
+ siweIssuedAt,
+ siweNonce,
+ userIdentifier,
+ },
} = route;
const onSuccessfulWalletSignature = React.useCallback(
(result: SIWEResult) => {
void (async () => {
- // eslint-disable-next-line no-unused-vars
const { signature } = result;
let message = 'success';
try {
- //TODO add backup keys
+ const userKeysResponse = await commCoreModule.getBackupUserKeys(
+ userIdentifier,
+ signature,
+ backupID,
+ );
+ const userKeys = assertWithValidator(
+ JSON.parse(userKeysResponse),
+ userKeysResponseValidator,
+ );
await commCoreModule.restoreBackupData(
- '',
- '',
- '',
+ backupID,
+ userKeys.backupDataKey,
+ userKeys.backupLogDataKey,
persistConfig.version.toString(),
);
} catch (e) {
@@ -58,7 +74,7 @@
goBack();
})();
},
- [goBack],
+ [backupID, goBack, userIdentifier],
);
return (
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
@@ -16,7 +16,10 @@
type ClientBackup = {
+createFullBackup: () => Promise<string>,
+createUserKeysBackup: () => Promise<string>,
- +retrieveLatestBackupInfo: () => Promise<LatestBackupInfo>,
+ +retrieveLatestBackupInfo: () => Promise<{
+ +latestBackupInfo: LatestBackupInfo,
+ +userIdentifier: string,
+ }>,
};
function useClientBackup(): ClientBackup {
@@ -49,15 +52,16 @@
if (!loggedIn || !currentUserID || !currentUserInfo?.username) {
throw new Error('Attempt to restore backup for not logged in user.');
}
- const userIdentitifer = currentUserInfo?.username;
+ const userIdentifier = currentUserInfo?.username;
const response =
- await commCoreModule.retrieveLatestBackupInfo(userIdentitifer);
+ await commCoreModule.retrieveLatestBackupInfo(userIdentifier);
- return assertWithValidator<LatestBackupInfo>(
+ const latestBackupInfo = assertWithValidator<LatestBackupInfo>(
JSON.parse(response),
latestBackupInfoResponseValidator,
);
+ return { latestBackupInfo, userIdentifier };
}, [currentUserID, currentUserInfo, loggedIn]);
return React.useMemo(
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
@@ -225,6 +225,11 @@
jsi::String backupLogDataKey,
jsi::String maxVersion) override;
virtual jsi::Value getQRAuthBackupData(jsi::Runtime &rt) override;
+ virtual jsi::Value getBackupUserKeys(
+ jsi::Runtime &rt,
+ jsi::String userIdentifier,
+ jsi::String backupSecret,
+ jsi::String backupID) override;
virtual jsi::Value retrieveLatestBackupInfo(
jsi::Runtime &rt,
jsi::String userIdentifier) override;
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
@@ -2724,6 +2724,26 @@
});
}
+jsi::Value CommCoreModule::getBackupUserKeys(
+ jsi::Runtime &rt,
+ jsi::String userIdentifier,
+ jsi::String backupSecret,
+ jsi::String backupID) {
+ std::string userIdentifierStr = userIdentifier.utf8(rt);
+ std::string backupSecretStr = backupSecret.utf8(rt);
+ std::string backupIDStr = backupID.utf8(rt);
+ return createPromiseAsJSIValue(
+ rt, [=](jsi::Runtime &innerRt, std::shared_ptr<Promise> promise) {
+ auto currentID = RustPromiseManager::instance.addPromise(
+ {promise, this->jsInvoker_, innerRt});
+ ::getBackupUserKeys(
+ rust::string(userIdentifierStr),
+ rust::string(backupSecretStr),
+ rust::string(backupIDStr),
+ currentID);
+ });
+}
+
jsi::Value CommCoreModule::retrieveLatestBackupInfo(
jsi::Runtime &rt,
jsi::String userIdentifier) {
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
@@ -196,6 +196,9 @@
static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_retrieveLatestBackupInfo(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->retrieveLatestBackupInfo(rt, args[0].asString(rt));
}
+static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getBackupUserKeys(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+ return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->getBackupUserKeys(rt, args[0].asString(rt), args[1].asString(rt), args[2].asString(rt));
+}
static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_setSIWEBackupSecrets(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<CommCoreModuleSchemaCxxSpecJSI *>(&turboModule)->setSIWEBackupSecrets(rt, args[0].asObject(rt));
}
@@ -303,6 +306,7 @@
methodMap_["restoreBackupData"] = MethodMetadata {4, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_restoreBackupData};
methodMap_["getQRAuthBackupData"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getQRAuthBackupData};
methodMap_["retrieveLatestBackupInfo"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_retrieveLatestBackupInfo};
+ methodMap_["getBackupUserKeys"] = MethodMetadata {3, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getBackupUserKeys};
methodMap_["setSIWEBackupSecrets"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_setSIWEBackupSecrets};
methodMap_["getSIWEBackupSecrets"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getSIWEBackupSecrets};
methodMap_["getAllInboundP2PMessages"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getAllInboundP2PMessages};
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
@@ -79,6 +79,7 @@
virtual jsi::Value restoreBackupData(jsi::Runtime &rt, jsi::String backupID, jsi::String backupDataKey, jsi::String backupLogDataKey, jsi::String maxVersion) = 0;
virtual jsi::Value getQRAuthBackupData(jsi::Runtime &rt) = 0;
virtual jsi::Value retrieveLatestBackupInfo(jsi::Runtime &rt, jsi::String userIdentifier) = 0;
+ virtual jsi::Value getBackupUserKeys(jsi::Runtime &rt, jsi::String userIdentifier, jsi::String backupSecret, jsi::String backupID) = 0;
virtual jsi::Value setSIWEBackupSecrets(jsi::Runtime &rt, jsi::Object siweBackupSecrets) = 0;
virtual jsi::Value getSIWEBackupSecrets(jsi::Runtime &rt) = 0;
virtual jsi::Value getAllInboundP2PMessages(jsi::Runtime &rt) = 0;
@@ -587,6 +588,14 @@
return bridging::callFromJs<jsi::Value>(
rt, &T::retrieveLatestBackupInfo, jsInvoker_, instance_, std::move(userIdentifier));
}
+ jsi::Value getBackupUserKeys(jsi::Runtime &rt, jsi::String userIdentifier, jsi::String backupSecret, jsi::String backupID) override {
+ static_assert(
+ bridging::getParameterCount(&T::getBackupUserKeys) == 4,
+ "Expected getBackupUserKeys(...) to have 4 parameters");
+
+ return bridging::callFromJs<jsi::Value>(
+ rt, &T::getBackupUserKeys, jsInvoker_, instance_, std::move(userIdentifier), std::move(backupSecret), std::move(backupID));
+ }
jsi::Value setSIWEBackupSecrets(jsi::Runtime &rt, jsi::Object siweBackupSecrets) override {
static_assert(
bridging::getParameterCount(&T::setSIWEBackupSecrets) == 2,
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
@@ -138,15 +138,17 @@
});
}
- pub fn retrieve_backup_keys(
+ pub fn get_backup_user_keys(
+ user_identifier: String,
backup_secret: String,
backup_id: String,
promise_id: u32,
) {
RUNTIME.spawn(async move {
- let result = download_backup_keys(backup_id, backup_secret)
- .await
- .map_err(|err| err.to_string());
+ let result =
+ download_backup_keys(user_identifier, backup_secret, backup_id)
+ .await
+ .map_err(|err| err.to_string());
let result = match result {
Ok(result) => result,
@@ -342,16 +344,13 @@
}
async fn download_backup_keys(
- backup_id: String,
+ user_identifier: String,
backup_secret: String,
+ backup_id: String,
) -> Result<UserKeys, Box<dyn Error>> {
let backup_client = BackupClient::new(BACKUP_SOCKET_ADDR)?;
- let user_identity = get_user_identity_from_secure_store()?;
- let backup_descriptor = BackupDescriptor::BackupID {
- backup_id: backup_id.clone(),
- user_identity: user_identity.clone(),
- };
+ let backup_descriptor = BackupDescriptor::Latest { user_identifier };
let mut encrypted_user_keys = backup_client
.download_backup_data(&backup_descriptor, RequestedData::UserKeys)
@@ -450,7 +449,9 @@
/// The reasoning behind this decision is that the backed-up Olm account
/// is primarily used for signing an update to the device list. For these
/// operations only the identity signing key is necessary.
+// This struct should match `UserKeys` in `lib/types/backup-types.js`
#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
struct UserKeys {
backup_data_key: String,
backup_log_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
@@ -455,8 +455,9 @@
promise_id: u32,
);
- #[cxx_name = "retrieveBackupKeys"]
- fn retrieve_backup_keys(
+ #[cxx_name = "getBackupUserKeys"]
+ fn get_backup_user_keys(
+ user_identifier: String,
backup_secret: String,
backup_id: String,
promise_id: u32,
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
@@ -6,8 +6,10 @@
import { ScrollView } from 'react-native-gesture-handler';
import { accountHasPassword } from 'lib/shared/account-utils.js';
+import { userKeysResponseValidator } from 'lib/types/backup-types.js';
import { getMessageForException } from 'lib/utils/errors.js';
import { useDispatch } from 'lib/utils/redux-utils.js';
+import { assertWithValidator } from 'lib/utils/validation-utils.js';
import type { ProfileNavigationProp } from './profile.react.js';
import { useClientBackup } from '../backup/use-client-backup.js';
@@ -69,16 +71,21 @@
const testRestoreForPasswordUser = React.useCallback(async () => {
let message = 'success';
try {
- // eslint-disable-next-line no-unused-vars
- const [latestBackupInfo, backupSecret] = await Promise.all([
- retrieveLatestBackupInfo(),
- getBackupSecret(),
- ]);
- //TODO add backup keys
+ const [{ latestBackupInfo, userIdentifier }, backupSecret] =
+ await Promise.all([retrieveLatestBackupInfo(), getBackupSecret()]);
+ const userKeysResponse = await commCoreModule.getBackupUserKeys(
+ userIdentifier,
+ backupSecret,
+ latestBackupInfo.backupID,
+ );
+ const userKeys = assertWithValidator(
+ JSON.parse(userKeysResponse),
+ userKeysResponseValidator,
+ );
await commCoreModule.restoreBackupData(
latestBackupInfo.backupID,
- '',
- '',
+ userKeys.backupDataKey,
+ userKeys.backupLogDataKey,
persistConfig.version.toString(),
);
console.info('Backup restored.');
@@ -92,8 +99,8 @@
const testLatestBackupInfo = React.useCallback(async () => {
let message;
try {
- const backupInfo = await retrieveLatestBackupInfo();
- const { backupID, userID } = backupInfo;
+ const { latestBackupInfo } = await retrieveLatestBackupInfo();
+ const { backupID, userID } = latestBackupInfo;
message =
`Success!\n` +
`Backup ID: ${backupID},\n` +
@@ -111,8 +118,9 @@
const testRestoreForSIWEUser = React.useCallback(async () => {
let message = 'success';
try {
- const backupInfo = await retrieveLatestBackupInfo();
- const { siweBackupData, backupID } = backupInfo;
+ const { latestBackupInfo, userIdentifier } =
+ await retrieveLatestBackupInfo();
+ const { siweBackupData, backupID } = latestBackupInfo;
if (!siweBackupData) {
throw new Error('Missing SIWE message for Wallet user backup');
@@ -131,6 +139,7 @@
siweNonce: siweBackupMsgNonce,
siweStatement: siweBackupMsgStatement,
siweIssuedAt: siweBackupMsgIssuedAt,
+ userIdentifier,
},
});
} catch (e) {
diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js
--- a/native/schema/CommCoreModuleSchema.js
+++ b/native/schema/CommCoreModuleSchema.js
@@ -167,6 +167,11 @@
) => Promise<void>;
+getQRAuthBackupData: () => Promise<Object>;
+retrieveLatestBackupInfo: (userIdentifier: string) => Promise<string>;
+ +getBackupUserKeys: (
+ userIdentifier: string,
+ backupSecret: string,
+ backupID: string,
+ ) => Promise<string>;
+setSIWEBackupSecrets: (siweBackupSecrets: Object) => Promise<void>;
+getSIWEBackupSecrets: () => Promise<?Object>;
+getAllInboundP2PMessages: () => Promise<Array<InboundP2PMessage>>;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Dec 24, 8:51 AM (11 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2698043
Default Alt Text
D14005.id46191.diff (15 KB)
Attached To
Mode
D14005: [CommCoreModule][native] expose getting User Keys
Attached
Detach File
Event Timeline
Log In to Comment