diff --git a/lib/components/secondary-device-qr-auth-context-provider.react.js b/lib/components/secondary-device-qr-auth-context-provider.react.js --- a/lib/components/secondary-device-qr-auth-context-provider.react.js +++ b/lib/components/secondary-device-qr-auth-context-provider.react.js @@ -31,7 +31,7 @@ import { getContentSigningKey } from '../utils/crypto-utils.js'; import { getMessageForException } from '../utils/errors.js'; import { useSelector } from '../utils/redux-utils.js'; -import { fullBackupSupport } from '../utils/services-utils.js'; +import { fullBackupSupportEnabled } from '../utils/services-utils.js'; import { waitUntilDatabaseDeleted } from '../utils/wait-until-db-deleted.js'; type QRAuthErrorCallback = ( @@ -240,7 +240,7 @@ backupData: ?QRAuthBackupData, identityAuthResult: ?IdentityAuthResult, ) => { - if (!fullBackupSupport) { + if (!fullBackupSupportEnabled(identityAuthResult?.userID)) { return; } try { diff --git a/lib/handlers/restore-backup-handler.react.js b/lib/handlers/restore-backup-handler.react.js --- a/lib/handlers/restore-backup-handler.react.js +++ b/lib/handlers/restore-backup-handler.react.js @@ -10,9 +10,11 @@ import { getForeignPeerDeviceIDs } from '../selectors/user-selectors.js'; import { useTunnelbroker } from '../tunnelbroker/tunnelbroker-context.js'; import { useSelector, useDispatch } from '../utils/redux-utils.js'; -import { fullBackupSupport } from '../utils/services-utils.js'; +import { useFullBackupSupportEnabled } from '../utils/services-utils.js'; function RestoreBackupHandler(): React.Node { + const fullBackupSupport = useFullBackupSupportEnabled(); + const persistedStateLoaded = usePersistedStateLoaded(); const restoreBackupState = useSelector(state => state.restoreBackupState); const userID = useSelector(state => state.currentUserInfo?.id); @@ -57,6 +59,7 @@ persistedStateLoaded, shouldNotifyPeers, socketState.isAuthorized, + fullBackupSupport, ]); // - Restoration retry handler @@ -89,6 +92,7 @@ restoreBackupState.status, userDataRestore, userID, + fullBackupSupport, ]); return null; diff --git a/lib/hooks/backup-hooks.js b/lib/hooks/backup-hooks.js --- a/lib/hooks/backup-hooks.js +++ b/lib/hooks/backup-hooks.js @@ -4,7 +4,7 @@ import type { RestoreBackupState } from '../types/backup-types.js'; import { useSelector } from '../utils/redux-utils.js'; -import { fullBackupSupport } from '../utils/services-utils.js'; +import { useFullBackupSupportEnabled } from '../utils/services-utils.js'; // list of states for which user data is considered ready const loggedInStates: $ReadOnlyArray = [ @@ -19,12 +19,13 @@ const restoreBackupState = useSelector( state => state.restoreBackupState.status, ); + const fullBackupSupport = useFullBackupSupportEnabled(); return React.useMemo(() => { if (!fullBackupSupport) { return true; } return loggedInStates.includes(restoreBackupState); - }, [restoreBackupState]); + }, [fullBackupSupport, restoreBackupState]); } export { useIsUserDataReady }; 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 @@ -23,7 +23,8 @@ restoreUserDataStepsOrder, } from '../types/backup-types.js'; import type { BaseAction } from '../types/redux-types.js'; -import { fullBackupSupport } from '../utils/services-utils.js'; +import type { CurrentUserInfo } from '../types/user-types'; +import { fullBackupSupportEnabled } from '../utils/services-utils.js'; function reduceBackupStore( store: BackupStore, @@ -73,9 +74,16 @@ function reduceRestoreBackupState( store: RestoreBackupState, + currentUserInfo: ?CurrentUserInfo, action: BaseAction, ): RestoreBackupState { - if (!fullBackupSupport) { + const currentUserID = + currentUserInfo?.id ?? + (action.type === restoreUserActionTypes.success + ? action.payload.userID + : null); + + if (!fullBackupSupportEnabled(currentUserID)) { return store; } diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js --- a/lib/reducers/master-reducer.js +++ b/lib/reducers/master-reducer.js @@ -283,6 +283,7 @@ holderStore, restoreBackupState: reduceRestoreBackupState( state.restoreBackupState, + currentUserInfo, action, ), }, diff --git a/lib/tunnelbroker/use-peer-to-peer-message-handler.js b/lib/tunnelbroker/use-peer-to-peer-message-handler.js --- a/lib/tunnelbroker/use-peer-to-peer-message-handler.js +++ b/lib/tunnelbroker/use-peer-to-peer-message-handler.js @@ -66,7 +66,7 @@ import { getClientMessageIDFromTunnelbrokerMessageID } from '../utils/peer-to-peer-communication-utils.js'; import { useDispatchActionPromise } from '../utils/redux-promise-utils.js'; import { useDispatch, useSelector } from '../utils/redux-utils.js'; -import { fullBackupSupport } from '../utils/services-utils.js'; +import { useFullBackupSupportEnabled } from '../utils/services-utils.js'; // When logout is requested by primary device, logging out of Identity Service // is already handled by the primary device @@ -109,6 +109,8 @@ const setLocalFID = useSetLocalFID(); const setLocalDCsSupport = useSetLocalCurrentUserSupportsDCs(); + const fullBackupSupport = useFullBackupSupportEnabled(); + return React.useCallback( async ( decryptedMessageContent: string, @@ -243,6 +245,7 @@ setLocalDCsSupport, setLocalFID, userDataRestore, + fullBackupSupport, ], ); } diff --git a/lib/utils/services-utils.js b/lib/utils/services-utils.js --- a/lib/utils/services-utils.js +++ b/lib/utils/services-utils.js @@ -28,7 +28,13 @@ // and apply compaction and logs. App is able to generate and upload // compaction and logs. // Keep in sync with native/cpp/CommonCpp/Tools/ServicesUtils.h -const fullBackupSupport = false; +function useFullBackupSupportEnabled(): boolean { + return false; +} +// eslint-disable-next-line no-unused-vars +function fullBackupSupportEnabled(userID: ?string): boolean { + return false; +} function createHTTPAuthorizationHeader(authMetadata: AuthMetadata): string { // explicit destructure to make it future-proof @@ -65,6 +71,7 @@ createDefaultHTTPRequestHeaders, httpResponseIsInvalidCSAT, errorMessageIsInvalidCSAT, - fullBackupSupport, + fullBackupSupportEnabled, + useFullBackupSupportEnabled, supportsFarcasterDCs, }; diff --git a/native/account/restore-backup-screen.react.js b/native/account/restore-backup-screen.react.js --- a/native/account/restore-backup-screen.react.js +++ b/native/account/restore-backup-screen.react.js @@ -6,7 +6,7 @@ import type { SignedMessage } from 'lib/types/siwe-types.js'; import { getMessageForException } from 'lib/utils/errors.js'; -import { fullBackupSupport } from 'lib/utils/services-utils.js'; +import { useFullBackupSupportEnabled } from 'lib/utils/services-utils.js'; import AuthContainer from './auth-components/auth-container.react.js'; import AuthContentContainer from './auth-components/auth-content-container.react.js'; @@ -64,6 +64,7 @@ const restore = useRestore(); const performV1Login = useV1Login(); + const fullBackupSupport = useFullBackupSupportEnabled(); const restoreHasStarted = useSelector( state => state.restoreBackupState.status !== 'no_backup', diff --git a/native/account/restore.js b/native/account/restore.js --- a/native/account/restore.js +++ b/native/account/restore.js @@ -29,7 +29,7 @@ } from 'lib/utils/errors.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { useSelector } from 'lib/utils/redux-utils.js'; -import { fullBackupSupport } from 'lib/utils/services-utils.js'; +import { fullBackupSupportEnabled } from 'lib/utils/services-utils.js'; import { setNativeCredentials } from './native-credentials.js'; import { useClientBackup } from '../backup/use-client-backup.js'; @@ -211,7 +211,7 @@ const { userDataRestore } = useUserDataRestoreContext(); const restoreUserData = React.useCallback( async (identityAuthResult: ?IdentityAuthResult) => { - if (!fullBackupSupport) { + if (!fullBackupSupportEnabled(identityAuthResult?.userID)) { return; } try { 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 @@ -29,7 +29,7 @@ import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { - fullBackupSupport, + useFullBackupSupportEnabled, useIsRestoreFlowEnabled, } from 'lib/utils/services-utils.js'; @@ -44,6 +44,7 @@ function checkIfCompactionNeeded( latestBackupInfo: ?LocalLatestBackupInfo, + fullBackupSupport: boolean, ): boolean { if (!fullBackupSupport) { return false; @@ -169,13 +170,20 @@ handlerStartedRef.current = false; }, []); + const fullBackupSupport = useFullBackupSupportEnabled(); + React.useEffect(() => { if (fullBackupSupport && canPerformBackupOperation) { startBackupHandler(); } else if (!canPerformBackupOperation) { stopBackupHandler(); } - }, [canPerformBackupOperation, startBackupHandler, stopBackupHandler]); + }, [ + canPerformBackupOperation, + startBackupHandler, + stopBackupHandler, + fullBackupSupport, + ]); const usingRestoreFlow = useIsRestoreFlowEnabled(); @@ -262,7 +270,8 @@ // Check if another compaction is needed, but only when the // device is in a state where this is possible. const compactionNeeded = - (checkIfCompactionNeeded(latestBackupInfo) || databaseSchemaChanged) && + (checkIfCompactionNeeded(latestBackupInfo, fullBackupSupport) || + databaseSchemaChanged) && userDataCompactionPossible; const shouldUploadUserData = @@ -327,6 +336,7 @@ socketState.isAuthorized, startBackupHandler, usingRestoreFlow, + fullBackupSupport, ]); React.useEffect(() => { diff --git a/native/backup/secondary-devices-backup-handler.react.js b/native/backup/secondary-devices-backup-handler.react.js --- a/native/backup/secondary-devices-backup-handler.react.js +++ b/native/backup/secondary-devices-backup-handler.react.js @@ -16,7 +16,7 @@ } from 'lib/types/tunnelbroker/user-actions-peer-to-peer-message-types.js'; import { getConfig } from 'lib/utils/config.js'; import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; -import { fullBackupSupport } from 'lib/utils/services-utils.js'; +import { useFullBackupSupportEnabled } from 'lib/utils/services-utils.js'; import { commCoreModule } from '../native-modules.js'; import { useSelector } from '../redux/redux-utils.js'; @@ -103,6 +103,7 @@ ]); const executed = React.useRef(false); + const fullBackupSupport = useFullBackupSupportEnabled(); React.useEffect(() => { if ( !fullBackupSupport || @@ -131,6 +132,7 @@ restoreBackupState.status, sendBackupDataToSecondaryDevices, socketState.isAuthorized, + fullBackupSupport, ]); return null; diff --git a/native/backup/use-migration-to-new-flow.js b/native/backup/use-migration-to-new-flow.js --- a/native/backup/use-migration-to-new-flow.js +++ b/native/backup/use-migration-to-new-flow.js @@ -22,7 +22,7 @@ rawDeviceListFromSignedList, } from 'lib/utils/device-list-utils.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; -import { fullBackupSupport } from 'lib/utils/services-utils.js'; +import { useFullBackupSupportEnabled } from 'lib/utils/services-utils.js'; import { useClientBackup } from './use-client-backup.js'; import { useSelector } from '../redux/redux-utils.js'; @@ -73,6 +73,8 @@ const broadcastDeviceListUpdates = useBroadcastDeviceListUpdates(); const dispatch = useDispatch(); + const fullBackupSupport = useFullBackupSupportEnabled(); + return React.useCallback( async ( currentIdentityUserState: CurrentIdentityUserState, @@ -155,6 +157,7 @@ identityClient, retrieveLatestBackupInfo, userIdentifier, + fullBackupSupport, ], ); } diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp @@ -64,7 +64,7 @@ DatabaseManager::indicateQueryExecutorCreation(); std::string currentBackupID = mainQueryExecutor.getMetadata("backupID"); const auto userID = CommSecureStore::get(CommSecureStore::userID); - if (!ServicesUtils::fullBackupSupport || !currentBackupID.size() || + if (!ServicesUtils::fullBackupSupport() || !currentBackupID.size() || !userID.hasValue()) { return; } @@ -290,7 +290,7 @@ } void DatabaseManager::captureBackupLogForLastOperation() { - if (!ServicesUtils::fullBackupSupport) { + if (!ServicesUtils::fullBackupSupport()) { return; } std::string backupID = @@ -315,7 +315,7 @@ } void DatabaseManager::triggerBackupFileUpload() { - if (!ServicesUtils::fullBackupSupport) { + if (!ServicesUtils::fullBackupSupport()) { return; } ::triggerBackupFileUpload(); @@ -455,7 +455,7 @@ DatabaseManager::mainConnectionManager->setLogsMonitoringEnabled(false); DatabaseManager::getQueryExecutor().setMetadata("backupID", backupID); DatabaseManager::getQueryExecutor().clearMetadata("logID"); - if (ServicesUtils::fullBackupSupport) { + if (ServicesUtils::fullBackupSupport()) { DatabaseManager::setUserDataKeys( mainCompactionEncryptionKey, newLogEncryptionKey); DatabaseManager::mainConnectionManager->setLogsMonitoringEnabled(true); diff --git a/native/cpp/CommonCpp/Tools/CMakeLists.txt b/native/cpp/CommonCpp/Tools/CMakeLists.txt --- a/native/cpp/CommonCpp/Tools/CMakeLists.txt +++ b/native/cpp/CommonCpp/Tools/CMakeLists.txt @@ -14,6 +14,7 @@ "Base64.cpp" "WorkerThread.cpp" "StaffUtils.cpp" + "ServicesUtils.cpp" "OlmUtils.cpp" ) diff --git a/native/cpp/CommonCpp/Tools/ServicesUtils.h b/native/cpp/CommonCpp/Tools/ServicesUtils.h --- a/native/cpp/CommonCpp/Tools/ServicesUtils.h +++ b/native/cpp/CommonCpp/Tools/ServicesUtils.h @@ -1,5 +1,7 @@ #pragma once +#include "StaffUtils.h" + namespace comm { class ServicesUtils { @@ -9,7 +11,7 @@ // and apply compaction and logs. App is able to generate and upload // compaction and logs. // Keep in sync with lib/utils/services-utils.js - const static bool fullBackupSupport = false; + static bool fullBackupSupport(); }; } // namespace comm diff --git a/native/cpp/CommonCpp/Tools/ServicesUtils.cpp b/native/cpp/CommonCpp/Tools/ServicesUtils.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/Tools/ServicesUtils.cpp @@ -0,0 +1,7 @@ +#include "ServicesUtils.h" + +namespace comm { +bool ServicesUtils::fullBackupSupport() { + return false; +} +} // namespace comm diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj --- a/native/ios/Comm.xcodeproj/project.pbxproj +++ b/native/ios/Comm.xcodeproj/project.pbxproj @@ -47,6 +47,8 @@ 7FDFC0FE2DC0FEBD00B1D87F /* OlmUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FDFC0FD2DC0FEBD00B1D87F /* OlmUtils.cpp */; }; 7FDFC0FF2DC0FEBD00B1D87F /* OlmUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FDFC0FD2DC0FEBD00B1D87F /* OlmUtils.cpp */; }; 7FDFC1002DC105E500B1D87F /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FBB2A7A29EEA2A4002C6493 /* Base64.cpp */; }; + 7FE179022E43980200973CAF /* ServicesUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FE179012E43980200973CAF /* ServicesUtils.cpp */; }; + 7FE179032E43980200973CAF /* ServicesUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FE179012E43980200973CAF /* ServicesUtils.cpp */; }; 7FE4D9F5291DFE9300667BF6 /* commJSI-generated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7FE4D9F4291DFE9300667BF6 /* commJSI-generated.cpp */; }; 816D2D5A2C480E60001C0B67 /* MessageSearchStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 816D2D582C480E60001C0B67 /* MessageSearchStore.cpp */; }; 8B38121629CE5742000C52E9 /* RustPromiseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B38121529CE5742000C52E9 /* RustPromiseManager.cpp */; }; @@ -240,6 +242,8 @@ 7FCFD8BD1E81B8DF00629B0E /* Comm.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Comm.entitlements; path = Comm/Comm.entitlements; sourceTree = ""; }; 7FDFC0FC2DC0FEBD00B1D87F /* OlmUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OlmUtils.h; sourceTree = ""; }; 7FDFC0FD2DC0FEBD00B1D87F /* OlmUtils.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OlmUtils.cpp; sourceTree = ""; }; + 7FE179002E43980200973CAF /* ServicesUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ServicesUtils.h; sourceTree = ""; }; + 7FE179012E43980200973CAF /* ServicesUtils.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ServicesUtils.cpp; sourceTree = ""; }; 7FE4D9F3291DFE9300667BF6 /* commJSI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = commJSI.h; sourceTree = ""; }; 7FE4D9F4291DFE9300667BF6 /* commJSI-generated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "commJSI-generated.cpp"; sourceTree = ""; }; 816D2D582C480E60001C0B67 /* MessageSearchStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MessageSearchStore.cpp; path = PersistentStorageUtilities/DataStores/MessageSearchStore.cpp; sourceTree = ""; }; @@ -514,6 +518,8 @@ 71BE84382636A944002849D2 /* Tools */ = { isa = PBXGroup; children = ( + 7FE179002E43980200973CAF /* ServicesUtils.h */, + 7FE179012E43980200973CAF /* ServicesUtils.cpp */, 7FDFC0FC2DC0FEBD00B1D87F /* OlmUtils.h */, 7FDFC0FD2DC0FEBD00B1D87F /* OlmUtils.cpp */, CBB0DF5E2B767FDF008E22FF /* CommMMKV.h */, @@ -1293,6 +1299,7 @@ 8B652FA6295EAA5B009F8163 /* RustCallback.cpp in Sources */, 71142A7726C2650B0039DCBD /* CommSecureStoreIOSWrapper.mm in Sources */, 7FBB2A7B29EEA2A4002C6493 /* Base64.cpp in Sources */, + 7FE179022E43980200973CAF /* ServicesUtils.cpp in Sources */, CB38F2B1286C6C870010535C /* MessageOperationsUtilities.cpp in Sources */, DFD5E7862B052B1400C32B6A /* RustAESCrypto.cpp in Sources */, 816D2D5A2C480E60001C0B67 /* MessageSearchStore.cpp in Sources */, @@ -1344,6 +1351,7 @@ 7FDFC1002DC105E500B1D87F /* Base64.cpp in Sources */, CBB0DF612B768007008E22FF /* CommMMKV.mm in Sources */, CB4821A927CFB153001AB7E1 /* WorkerThread.cpp in Sources */, + 7FE179032E43980200973CAF /* ServicesUtils.cpp in Sources */, CB4821AA27CFB153001AB7E1 /* Tools.mm in Sources */, CB3C621227CE65030054F24C /* CommSecureStoreIOSWrapper.mm in Sources */, CB3C621127CE4A320054F24C /* Logger.mm in Sources */, diff --git a/native/root.react.js b/native/root.react.js --- a/native/root.react.js +++ b/native/root.react.js @@ -53,6 +53,7 @@ import KeyserverConnectionsHandler from 'lib/keyserver-conn/keyserver-connections-handler.js'; import { TunnelbrokerProvider } from 'lib/tunnelbroker/tunnelbroker-context.js'; import { actionLogger } from 'lib/utils/action-logger.js'; +import { useFullBackupSupportEnabled } from 'lib/utils/services-utils.js'; import { RegistrationContextProvider } from './account/registration/registration-context-provider.react.js'; import NativeEditThreadAvatarProvider from './avatars/native-edit-thread-avatar-provider.react.js'; @@ -160,6 +161,12 @@ __DEV__ ? undefined : defaultNavigationState, ); + const fullBackupSupport = useFullBackupSupportEnabled(); + const handleQRAuthError = React.useCallback( + (error: mixed) => handleSecondaryDeviceLogInError(error, fullBackupSupport), + [fullBackupSupport], + ); + React.useEffect(() => { Orientation.lockToPortrait(); void (async () => { @@ -367,7 +374,7 @@ composeTunnelbrokerQRAuthMessage } generateAESKey={generateQRAuthAESKey} - onLogInError={handleSecondaryDeviceLogInError} + onLogInError={handleQRAuthError} > diff --git a/native/utils/qr-code-utils.js b/native/utils/qr-code-utils.js --- a/native/utils/qr-code-utils.js +++ b/native/utils/qr-code-utils.js @@ -13,7 +13,6 @@ BackupIsNewerError, getMessageForException, } from 'lib/utils/errors.js'; -import { fullBackupSupport } from 'lib/utils/services-utils.js'; import * as AES from './aes-crypto-module.js'; import { @@ -64,7 +63,10 @@ return Promise.resolve(payload); } -function handleSecondaryDeviceLogInError(error: mixed): void { +function handleSecondaryDeviceLogInError( + error: mixed, + fullBackupSupport: boolean, +): void { console.error('Secondary device log in error:', error); if (fullBackupSupport) { // for full backup, errors are handled in the restore UI diff --git a/web/account/log-in-form.react.js b/web/account/log-in-form.react.js --- a/web/account/log-in-form.react.js +++ b/web/account/log-in-form.react.js @@ -16,7 +16,7 @@ import { useDispatch } from 'lib/utils/redux-utils.js'; import { useIsRestoreFlowEnabled, - fullBackupSupport, + useFullBackupSupportEnabled, } from 'lib/utils/services-utils.js'; import HeaderSeparator from './header-separator.react.js'; @@ -169,6 +169,8 @@ const [errorUIShown, setErrorUIShown] = React.useState(false); + const fullBackupSupport = useFullBackupSupportEnabled(); + if ( fullBackupSupport && (qrAuthInProgress || userDataRestoreStarted || errorUIShown) diff --git a/web/utils/qr-code-utils.js b/web/utils/qr-code-utils.js --- a/web/utils/qr-code-utils.js +++ b/web/utils/qr-code-utils.js @@ -22,7 +22,7 @@ BackupIsNewerError, getMessageForException, } from 'lib/utils/errors.js'; -import { fullBackupSupport } from 'lib/utils/services-utils.js'; +import { useFullBackupSupportEnabled } from 'lib/utils/services-utils.js'; import { base64DecodeBuffer, base64EncodeBuffer } from './base64-utils.js'; import { getBackupIsNewerThanAppError } from './version-utils.js'; @@ -66,6 +66,8 @@ isUserDataRestoreError?: boolean, ) => void { const { pushModal } = useModalContext(); + + const fullBackupSupport = useFullBackupSupportEnabled(); return React.useCallback( (error: mixed, isUserDataRestoreError?: boolean) => { console.error('Secondary device log in error:', error); @@ -97,7 +99,7 @@ pushModal(Uhh... try again?); } }, - [pushModal], + [pushModal, fullBackupSupport], ); }