diff --git a/lib/actions/backup-actions.js b/lib/actions/backup-actions.js --- a/lib/actions/backup-actions.js +++ b/lib/actions/backup-actions.js @@ -1,9 +1,22 @@ // @flow +import type { LocalLatestBackupInfo } from '../types/backup-types.js'; + const createUserKeysBackupActionTypes = Object.freeze({ started: 'CREATE_USER_KEYS_BACKUP_STARTED', success: 'CREATE_USER_KEYS_BACKUP_SUCCESS', failed: 'CREATE_USER_KEYS_BACKUP_FAILED', }); -export { createUserKeysBackupActionTypes }; +const createUserDataBackupActionTypes = Object.freeze({ + started: 'CREATE_USER_DATA_BACKUP_STARTED', + success: 'CREATE_USER_DATA_BACKUP_SUCCESS', + failed: 'CREATE_USER_DATA_BACKUP_FAILED', +}); + +export type CreateUserDataBackupPayload = { + +latestBackupInfo: LocalLatestBackupInfo, + +latestDatabaseVersion: number, +}; + +export { createUserKeysBackupActionTypes, createUserDataBackupActionTypes }; diff --git a/lib/reducers/backup-reducer.js b/lib/reducers/backup-reducer.js --- a/lib/reducers/backup-reducer.js +++ b/lib/reducers/backup-reducer.js @@ -1,6 +1,9 @@ // @flow -import { createUserKeysBackupActionTypes } from '../actions/backup-actions.js'; +import { + createUserDataBackupActionTypes, + createUserKeysBackupActionTypes, +} from '../actions/backup-actions.js'; import { changeIdentityUserPasswordActionTypes } from '../actions/user-actions.js'; import type { BackupStore } from '../types/backup-types.js'; import type { BaseAction } from '../types/redux-types.js'; @@ -15,6 +18,13 @@ ...store, latestBackupInfo, }; + } else if (action.type === createUserDataBackupActionTypes.success) { + const { latestBackupInfo, latestDatabaseVersion } = action.payload; + return { + ...store, + latestBackupInfo, + latestDatabaseVersion, + }; } else if (action.type === changeIdentityUserPasswordActionTypes.success) { return { ...store, diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -165,6 +165,7 @@ UserStore, UserInfo, } from './user-types.js'; +import type { CreateUserDataBackupPayload } from '../actions/backup-actions.js'; import type { SetDeviceTokenActionPayload, SetDeviceTokenStartedPayload, @@ -1625,6 +1626,22 @@ +payload: Error, +loadingInfo: LoadingInfo, } + | { + +type: 'CREATE_USER_DATA_BACKUP_STARTED', + +loadingInfo?: LoadingInfo, + +payload?: void, + } + | { + +type: 'CREATE_USER_DATA_BACKUP_SUCCESS', + +payload: CreateUserDataBackupPayload, + +loadingInfo: LoadingInfo, + } + | { + +type: 'CREATE_USER_DATA_BACKUP_FAILED', + +error: true, + +payload: Error, + +loadingInfo: LoadingInfo, + } | { +type: 'RESTORE_USER_STARTED', +loadingInfo: LoadingInfo, diff --git a/native/backup/backup-handler-context-provider.js b/native/backup/backup-handler-context-provider.js --- a/native/backup/backup-handler-context-provider.js +++ b/native/backup/backup-handler-context-provider.js @@ -3,7 +3,11 @@ import * as React from 'react'; import { setPeerDeviceListsActionType } from 'lib/actions/aux-user-actions.js'; -import { createUserKeysBackupActionTypes } from 'lib/actions/backup-actions.js'; +import { + createUserDataBackupActionTypes, + type CreateUserDataBackupPayload, + createUserKeysBackupActionTypes, +} from 'lib/actions/backup-actions.js'; import { useCurrentIdentityUserState, type CurrentIdentityUserState, @@ -91,13 +95,9 @@ [dispatchActionPromise, migrateToNewFlow], ); - const performBackupUpload = React.useCallback(async () => { + const performUserKeysUpload = React.useCallback(async () => { const promise = (async () => { - const backupMethod = fullBackupSupport - ? createUserDataBackup - : createUserKeysBackup; - - const backupID = await backupMethod(); + const backupID = await createUserKeysBackup(); return { backupID, timestamp: Date.now(), @@ -105,7 +105,26 @@ })(); void dispatchActionPromise(createUserKeysBackupActionTypes, promise); await promise; - }, [createUserDataBackup, createUserKeysBackup, dispatchActionPromise]); + }, [createUserKeysBackup, dispatchActionPromise]); + + const performUserDataUpload = React.useCallback(async () => { + const promise: Promise = (async () => { + const { sqliteAPI } = getConfig(); + const databaseVersion = await sqliteAPI.getDatabaseVersion( + databaseIdentifier.MAIN, + ); + const backupID = await createUserDataBackup(); + return { + latestBackupInfo: { + backupID, + timestamp: Date.now(), + }, + latestDatabaseVersion: databaseVersion, + }; + })(); + void dispatchActionPromise(createUserDataBackupActionTypes, promise); + await promise; + }, [createUserDataBackup, dispatchActionPromise]); const startBackupHandler = React.useCallback(() => { if (handlerStartedRef.current) { @@ -226,12 +245,12 @@ if (shouldDoMigration) { step = 'migrating to signed device lists'; await performMigrationToNewFlow(currentIdentityUserState); - } else if (shouldUploadUserData) { + } else if (shouldUploadUserData && fullBackupSupport) { step = 'creating User Data backup'; - await performBackupUpload(); + await performUserDataUpload(); } else if (shouldUploadUserKeys) { step = 'creating User Keys backup'; - await performBackupUpload(); + await performUserKeysUpload(); } } catch (err) { const errorMessage = getMessageForException(err) ?? 'unknown error'; @@ -253,9 +272,10 @@ getCurrentIdentityUserState, latestBackupInfo, latestDatabaseVersion, - ownRawDeviceList?.devices, - performBackupUpload, + ownRawDeviceList, performMigrationToNewFlow, + performUserDataUpload, + performUserKeysUpload, showAlertToStaff, socketState.isAuthorized, startBackupHandler,