Page MenuHomePhabricator

D14005.diff
No OneTemporary

D14005.diff

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 = commCoreModule.getBackupUserKeys(
+ userIdentifier,
+ signature,
+ backupID,
+ );
+ const userKeys = assertWithValidator(
+ 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

Mime Type
text/plain
Expires
Sat, Nov 23, 6:42 AM (15 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2569490
Default Alt Text
D14005.diff (15 KB)

Event Timeline