Page MenuHomePhabricator

D14060.diff
No OneTemporary

D14060.diff

diff --git a/native/backup/backup-handler.js b/native/backup/backup-handler.js
--- a/native/backup/backup-handler.js
+++ b/native/backup/backup-handler.js
@@ -9,11 +9,14 @@
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import { useClientBackup } from './use-client-backup.js';
+import { useGetBackupSecretForLoggedInUser } from './use-get-backup-secret.js';
import { commCoreModule } from '../native-modules.js';
import { useSelector } from '../redux/redux-utils.js';
import Alert from '../utils/alert.js';
import { useStaffCanSee } from '../utils/staff-utils.js';
+const millisecondsPerDay = 24 * 60 * 60 * 1000;
+
function BackupHandler(): null {
const loggedIn = useSelector(isLoggedIn);
const staffCanSee = useStaffCanSee();
@@ -26,7 +29,9 @@
state => state.backupStore.latestBackupInfo,
);
const dispatchActionPromise = useDispatchActionPromise();
- const { createUserKeysBackup } = useClientBackup();
+ const { createUserKeysBackup, retrieveLatestBackupInfo, getBackupUserKeys } =
+ useClientBackup();
+ const getBackupSecret = useGetBackupSecretForLoggedInUser();
const backupUploadInProgress = React.useRef<boolean>(false);
const [handlerStarted, setHandlerStarted] = React.useState(false);
@@ -73,13 +78,58 @@
handlerStarted,
]);
+ const testUserKeysRestore = React.useCallback(async () => {
+ if (!latestBackupInfo?.backupID) {
+ return;
+ }
+ const {
+ latestBackupInfo: { backupID },
+ userIdentifier,
+ } = await retrieveLatestBackupInfo();
+
+ const backupSecret = await getBackupSecret();
+ const {
+ backupDataKey: backupDataKeyFromBackup,
+ backupLogDataKey: backupLogDataKeyFromBackup,
+ } = await getBackupUserKeys(userIdentifier, backupSecret, backupID);
+
+ const {
+ backupID: localBackupID,
+ backupDataKey: localBackupDataKey,
+ backupLogDataKey: localBackupLogDataKey,
+ } = await commCoreModule.getQRAuthBackupData();
+
+ const backupIDCheck =
+ latestBackupInfo.backupID === backupID && backupID === localBackupID;
+ const keysCheck =
+ backupDataKeyFromBackup === localBackupDataKey &&
+ backupLogDataKeyFromBackup === localBackupLogDataKey;
+
+ if (!backupIDCheck || !keysCheck) {
+ throw new Error(
+ '\n' +
+ `backupID: ${backupID}\n` +
+ `latestBackupInfo.backupID: ${latestBackupInfo.backupID}\n` +
+ `localBackupID: ${localBackupID}\n` +
+ `backupDataKeyFromBackup: ${backupDataKeyFromBackup}\n` +
+ `backupLogDataKeyFromBackup: ${backupLogDataKeyFromBackup}\n` +
+ `localBackupDataKey: ${localBackupDataKey}\n` +
+ `localBackupLogDataKey: ${localBackupLogDataKey}\n`,
+ );
+ }
+ }, [
+ getBackupSecret,
+ getBackupUserKeys,
+ latestBackupInfo?.backupID,
+ retrieveLatestBackupInfo,
+ ]);
+
React.useEffect(() => {
if (
!staffCanSee ||
!canPerformBackupOperation ||
!handlerStarted ||
- backupUploadInProgress.current ||
- !!latestBackupInfo
+ backupUploadInProgress.current
) {
return;
}
@@ -92,6 +142,22 @@
return;
}
+ if (latestBackupInfo) {
+ const timestamp = latestBackupInfo.timestamp;
+ // If last upload one less than 24h ago ignore it
+ if (timestamp >= Date.now() - millisecondsPerDay) {
+ return;
+ }
+
+ try {
+ await testUserKeysRestore();
+ } catch (err) {
+ const message = getMessageForException(err) ?? 'unknown error';
+ Alert.alert('Error restoring User Keys backup', message);
+ console.log('Error restoring User Keys backup:', message);
+ }
+ }
+
try {
const promise = createUserKeysBackup();
void dispatchActionPromise(createUserKeysBackupActionTypes, promise);
@@ -111,6 +177,7 @@
handlerStarted,
latestBackupInfo,
staffCanSee,
+ testUserKeysRestore,
]);
return null;

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 28, 3:31 PM (22 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2594326
Default Alt Text
D14060.diff (3 KB)

Event Timeline