Merge branch 'feature/drop-yap-database-support' into feature/groups-rebuild

# Conflicts:
#	Session.xcodeproj/project.pbxproj
#	SessionMessagingKit/Database/Migrations/_003_YDBToGRDBMigration.swift
#	SessionMessagingKit/Messages/Control Messages/ConfigurationMessage.swift
#	SessionUtilitiesKit/Database/Storage.swift
This commit is contained in:
Morgan Pretty 2023-08-21 16:30:11 +10:00
commit 6c1b997e9b
43 changed files with 76 additions and 4333 deletions

View File

@ -16,9 +16,6 @@ abstract_target 'GlobalDependencies' do
# FIXME: Would be nice to migrate from CocoaPods to SwiftPackageManager (should allow us to speed up build time), haven't gone through all of the dependencies but currently unfortunately SQLCipher doesn't support SPM (for more info see: https://github.com/sqlcipher/sqlcipher/issues/371)
pod 'SQLCipher', '~> 4.5.3'
# FIXME: We want to remove this once it's been long enough since the migration to GRDB
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/oxen-io/session-ios-yap-database.git', branch: 'signal-release'
pod 'WebRTC-lib'
target 'Session' do

View File

@ -43,68 +43,6 @@ PODS:
- SwiftProtobuf (1.5.0)
- WebRTC-lib (114.0.0)
- xcbeautify (0.17.0)
- YapDatabase/SQLCipher (3.1.1):
- YapDatabase/SQLCipher/Core (= 3.1.1)
- YapDatabase/SQLCipher/Extensions (= 3.1.1)
- YapDatabase/SQLCipher/Core (3.1.1):
- CocoaLumberjack
- SQLCipher (>= 3.4.0)
- YapDatabase/SQLCipher/Extensions (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/ActionManager (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/AutoView (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/CloudCore (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/CloudKit (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/ConnectionPool (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/ConnectionProxy (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/CrossProcessNotification (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/FilteredView (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/FullTextSearch (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/Hooks (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/ManualView (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/Relationships (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/RTreeIndex (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/SearchResultsView (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/SecondaryIndex (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/View (= 3.1.1)
- YapDatabase/SQLCipher/Extensions/ActionManager (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/AutoView
- YapDatabase/SQLCipher/Extensions/AutoView (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/View
- YapDatabase/SQLCipher/Extensions/CloudCore (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/CloudKit (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/ConnectionPool (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/ConnectionProxy (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/CrossProcessNotification (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/FilteredView (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/View
- YapDatabase/SQLCipher/Extensions/FullTextSearch (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/Hooks (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/ManualView (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/View
- YapDatabase/SQLCipher/Extensions/Relationships (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/RTreeIndex (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/SearchResultsView (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/AutoView
- YapDatabase/SQLCipher/Extensions/FullTextSearch
- YapDatabase/SQLCipher/Extensions/SecondaryIndex (3.1.1):
- YapDatabase/SQLCipher/Core
- YapDatabase/SQLCipher/Extensions/View (3.1.1):
- YapDatabase/SQLCipher/Core
- YYImage/Core (1.0.4)
- YYImage/libwebp (1.0.4):
- libwebp
@ -126,7 +64,6 @@ DEPENDENCIES:
- SwiftProtobuf (~> 1.5.0)
- WebRTC-lib
- xcbeautify
- YapDatabase/SQLCipher (from `https://github.com/oxen-io/session-ios-yap-database.git`, branch `signal-release`)
- YYImage/libwebp (from `https://github.com/signalapp/YYImage`)
SPEC REPOS:
@ -158,9 +95,6 @@ EXTERNAL SOURCES:
Sodium:
:branch: session-build
:git: https://github.com/oxen-io/session-ios-swift-sodium.git
YapDatabase:
:branch: signal-release
:git: https://github.com/oxen-io/session-ios-yap-database.git
YYImage:
:git: https://github.com/signalapp/YYImage
@ -174,9 +108,6 @@ CHECKOUT OPTIONS:
Sodium:
:commit: 4ecfe2ddfd75e7b396c57975b4163e5c8cf4d5cc
:git: https://github.com/oxen-io/session-ios-swift-sodium.git
YapDatabase:
:commit: d84069e25e12a16ab4422e5258127a04b70489ad
:git: https://github.com/oxen-io/session-ios-yap-database.git
YYImage:
:commit: 62a4cede20bcf31da73d18163408e46a92f171c6
:git: https://github.com/signalapp/YYImage
@ -200,9 +131,8 @@ SPEC CHECKSUMS:
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
WebRTC-lib: d83df8976fa608b980f1d85796b3de66d60a1953
xcbeautify: 6e2f57af5c3a86d490376d5758030a8dcc201c1b
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
YYImage: f1ddd15ac032a58b78bbed1e012b50302d318331
PODFILE CHECKSUM: dd814a5a92577bb2a94dac6a1cc482f193721cdf
PODFILE CHECKSUM: a5e8cbfd90e94ce2afb8c687b96bceb93f658e2e
COCOAPODS: 1.12.1

View File

@ -498,12 +498,10 @@
FD16AB5F2A1DD98F0083D849 /* ProfilePictureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2A4255B6D93007E1867 /* ProfilePictureView.swift */; };
FD16AB612A1DD9B60083D849 /* ProfilePictureView+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD16AB602A1DD9B60083D849 /* ProfilePictureView+Convenience.swift */; };
FD17D79927F40AB800122BE0 /* _003_YDBToGRDBMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79827F40AB800122BE0 /* _003_YDBToGRDBMigration.swift */; };
FD17D79C27F40B2E00122BE0 /* SMKLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79B27F40B2E00122BE0 /* SMKLegacy.swift */; };
FD17D7A027F40CC800122BE0 /* _001_InitialSetupMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79F27F40CC800122BE0 /* _001_InitialSetupMigration.swift */; };
FD17D7A127F40D2500122BE0 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD28A4F527EAD44C00FF65E7 /* Storage.swift */; };
FD17D7A227F40F0500122BE0 /* _001_InitialSetupMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79527F3E04600122BE0 /* _001_InitialSetupMigration.swift */; };
FD17D7A427F40F8100122BE0 /* _003_YDBToGRDBMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A327F40F8100122BE0 /* _003_YDBToGRDBMigration.swift */; };
FD17D7A727F41AF000122BE0 /* SSKLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A627F41AF000122BE0 /* SSKLegacy.swift */; };
FD17D7AA27F41BF500122BE0 /* SnodeSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A927F41BF500122BE0 /* SnodeSet.swift */; };
FD17D7AE27F41C4300122BE0 /* SnodeReceivedMessageInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7AD27F41C4300122BE0 /* SnodeReceivedMessageInfo.swift */; };
FD17D7B327F51E5B00122BE0 /* SSKSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7B227F51E5B00122BE0 /* SSKSetting.swift */; };
@ -518,7 +516,6 @@
FD17D7CD27F546FF00122BE0 /* Setting.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7CC27F546FF00122BE0 /* Setting.swift */; };
FD17D7E527F6A09900122BE0 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E427F6A09900122BE0 /* Identity.swift */; };
FD17D7E727F6A16700122BE0 /* _003_YDBToGRDBMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E627F6A16700122BE0 /* _003_YDBToGRDBMigration.swift */; };
FD17D7EA27F6A1C600122BE0 /* SUKLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E927F6A1C600122BE0 /* SUKLegacy.swift */; };
FD1A94FB2900D1C2000D73D3 /* PersistableRecord+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1A94FA2900D1C2000D73D3 /* PersistableRecord+Utilities.swift */; };
FD1A94FE2900D2EA000D73D3 /* PersistableRecordUtilitiesSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1A94FD2900D2EA000D73D3 /* PersistableRecordUtilitiesSpec.swift */; };
FD1C98E4282E3C5B00B76F9E /* UINavigationBar+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1C98E3282E3C5B00B76F9E /* UINavigationBar+Utilities.swift */; };
@ -559,7 +556,7 @@
FD245C59285065FC00B966DD /* ControlMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A7702553A41E00C340D1 /* ControlMessage.swift */; };
FD245C5A2850660100B966DD /* LinkPreviewDraft.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBA8255A581500E217F9 /* LinkPreviewDraft.swift */; };
FD245C5B2850660500B966DD /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5BC2554B00D00555489 /* ReadReceipt.swift */; };
FD245C5C2850660A00B966DD /* ConfigurationMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DA9C0625AE7396008F7C7E /* ConfigurationMessage.swift */; };
FD245C5C2850660A00B966DD /* LegacyConfigurationMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DA9C0625AE7396008F7C7E /* LegacyConfigurationMessage.swift */; };
FD245C5D2850660F00B966DD /* OWSAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF2F7255B6DBC007E1867 /* OWSAudioPlayer.m */; };
FD245C5F2850662200B966DD /* OWSWindowManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C38EF306255B6DBE007E1867 /* OWSWindowManager.m */; };
FD245C632850664600B966DD /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD245C612850664300B966DD /* Configuration.swift */; };
@ -1606,7 +1603,7 @@
C3CA3ABD255CDB0D00F4C6D4 /* portuguese.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = portuguese.txt; sourceTree = "<group>"; };
C3CA3AC7255CDB2900F4C6D4 /* spanish.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = spanish.txt; sourceTree = "<group>"; };
C3D0972A2510499C00F6E3E4 /* BackgroundPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundPoller.swift; sourceTree = "<group>"; };
C3DA9C0625AE7396008F7C7E /* ConfigurationMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationMessage.swift; sourceTree = "<group>"; };
C3DA9C0625AE7396008F7C7E /* LegacyConfigurationMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyConfigurationMessage.swift; sourceTree = "<group>"; };
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; };
C3DB66AB260ACA42001EFC55 /* OpenGroupManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupManager.swift; sourceTree = "<group>"; };
C3DB66C2260ACCE6001EFC55 /* OpenGroupPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupPoller.swift; sourceTree = "<group>"; };
@ -1670,10 +1667,8 @@
FD16AB602A1DD9B60083D849 /* ProfilePictureView+Convenience.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfilePictureView+Convenience.swift"; sourceTree = "<group>"; };
FD17D79527F3E04600122BE0 /* _001_InitialSetupMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _001_InitialSetupMigration.swift; sourceTree = "<group>"; };
FD17D79827F40AB800122BE0 /* _003_YDBToGRDBMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _003_YDBToGRDBMigration.swift; sourceTree = "<group>"; };
FD17D79B27F40B2E00122BE0 /* SMKLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMKLegacy.swift; sourceTree = "<group>"; };
FD17D79F27F40CC800122BE0 /* _001_InitialSetupMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _001_InitialSetupMigration.swift; sourceTree = "<group>"; };
FD17D7A327F40F8100122BE0 /* _003_YDBToGRDBMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _003_YDBToGRDBMigration.swift; sourceTree = "<group>"; };
FD17D7A627F41AF000122BE0 /* SSKLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSKLegacy.swift; sourceTree = "<group>"; };
FD17D7A927F41BF500122BE0 /* SnodeSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnodeSet.swift; sourceTree = "<group>"; };
FD17D7AD27F41C4300122BE0 /* SnodeReceivedMessageInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnodeReceivedMessageInfo.swift; sourceTree = "<group>"; };
FD17D7AF27F4225C00122BE0 /* Set+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Set+Utilities.swift"; sourceTree = "<group>"; };
@ -1689,7 +1684,6 @@
FD17D7CC27F546FF00122BE0 /* Setting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Setting.swift; sourceTree = "<group>"; };
FD17D7E427F6A09900122BE0 /* Identity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Identity.swift; sourceTree = "<group>"; };
FD17D7E627F6A16700122BE0 /* _003_YDBToGRDBMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _003_YDBToGRDBMigration.swift; sourceTree = "<group>"; };
FD17D7E927F6A1C600122BE0 /* SUKLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SUKLegacy.swift; sourceTree = "<group>"; };
FD1A94FA2900D1C2000D73D3 /* PersistableRecord+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PersistableRecord+Utilities.swift"; sourceTree = "<group>"; };
FD1A94FD2900D2EA000D73D3 /* PersistableRecordUtilitiesSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistableRecordUtilitiesSpec.swift; sourceTree = "<group>"; };
FD1C98E3282E3C5B00B76F9E /* UINavigationBar+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+Utilities.swift"; sourceTree = "<group>"; };
@ -2559,7 +2553,6 @@
B8A582AB258C64E800AFD84C /* Database */ = {
isa = PBXGroup;
children = (
FD17D7E827F6A1B800122BE0 /* LegacyDatabase */,
FD17D7C827F546CE00122BE0 /* Migrations */,
FD17D7CB27F546F500122BE0 /* Models */,
FD17D7B427F51E6700122BE0 /* Types */,
@ -2771,7 +2764,7 @@
B8DE1FB526C22FCB0079C9CE /* CallMessage.swift */,
C34A977325A3E34A00852C71 /* ClosedGroupControlMessage.swift */,
FD8ECF8A2935DB4B00C0D1BB /* SharedConfigMessage.swift */,
C3DA9C0625AE7396008F7C7E /* ConfigurationMessage.swift */,
C3DA9C0625AE7396008F7C7E /* LegacyConfigurationMessage.swift */,
B8F5F60225EDE16F003BF8D4 /* DataExtractionNotification.swift */,
C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */,
7B93D06F27CF194000811CB6 /* MessageRequestResponse.swift */,
@ -2884,7 +2877,6 @@
C32C5BCB256DC818003C73A2 /* Database */ = {
isa = PBXGroup;
children = (
FD17D79A27F40ADA00122BE0 /* LegacyDatabase */,
FD17D79427F3E03300122BE0 /* Migrations */,
FD09796C27FA6C8B00936362 /* Models */,
);
@ -3652,18 +3644,9 @@
path = Migrations;
sourceTree = "<group>";
};
FD17D79A27F40ADA00122BE0 /* LegacyDatabase */ = {
isa = PBXGroup;
children = (
FD17D79B27F40B2E00122BE0 /* SMKLegacy.swift */,
);
path = LegacyDatabase;
sourceTree = "<group>";
};
FD17D79D27F40CAA00122BE0 /* Database */ = {
isa = PBXGroup;
children = (
FD17D7A527F41ADE00122BE0 /* LegacyDatabase */,
FD17D79E27F40CC000122BE0 /* Migrations */,
FD17D7A827F41BE300122BE0 /* Models */,
FD17D7B127F51E2B00122BE0 /* Types */,
@ -3682,14 +3665,6 @@
path = Migrations;
sourceTree = "<group>";
};
FD17D7A527F41ADE00122BE0 /* LegacyDatabase */ = {
isa = PBXGroup;
children = (
FD17D7A627F41AF000122BE0 /* SSKLegacy.swift */,
);
path = LegacyDatabase;
sourceTree = "<group>";
};
FD17D7A827F41BE300122BE0 /* Models */ = {
isa = PBXGroup;
children = (
@ -3760,14 +3735,6 @@
path = Models;
sourceTree = "<group>";
};
FD17D7E827F6A1B800122BE0 /* LegacyDatabase */ = {
isa = PBXGroup;
children = (
FD17D7E927F6A1C600122BE0 /* SUKLegacy.swift */,
);
path = LegacyDatabase;
sourceTree = "<group>";
};
FD1A94FC2900D2DB000D73D3 /* Utilities */ = {
isa = PBXGroup;
children = (
@ -5669,7 +5636,6 @@
FDF848ED29405E4F007DCAE5 /* Notification+OnionRequestAPI.swift in Sources */,
FDF848CD29405C5B007DCAE5 /* GetNetworkTimestampResponse.swift in Sources */,
FDF848DA29405C5B007DCAE5 /* GetMessagesResponse.swift in Sources */,
FD17D7A727F41AF000122BE0 /* SSKLegacy.swift in Sources */,
FD39353628F7C3390084DADA /* _004_FlagMessageHashAsDeletedOrInvalid.swift in Sources */,
FDF8489429405C1B007DCAE5 /* SnodeAPI.swift in Sources */,
FDF848C829405C5B007DCAE5 /* ONSResolveRequest.swift in Sources */,
@ -5701,7 +5667,6 @@
C3BBE0A82554D4DE0050F1E3 /* JSON.swift in Sources */,
FD17D7C127F5200100122BE0 /* TypedTableDefinition.swift in Sources */,
FD23CE1B2A651E6D0000B97C /* NetworkType.swift in Sources */,
FD17D7EA27F6A1C600122BE0 /* SUKLegacy.swift in Sources */,
FDA8EB10280F8238002B68E5 /* Codable+Utilities.swift in Sources */,
FDBB25E32988B13800F1508E /* _004_AddJobPriority.swift in Sources */,
C352A36D2557858E00338F3E /* NSTimer+Proxying.m in Sources */,
@ -5974,7 +5939,7 @@
C3DB66C3260ACCE6001EFC55 /* OpenGroupPoller.swift in Sources */,
FD716E722850647600C96BF4 /* Data+Utilities.swift in Sources */,
FD368A6829DE8F9C000DBF1E /* _012_AddFTSIfNeeded.swift in Sources */,
FD245C5C2850660A00B966DD /* ConfigurationMessage.swift in Sources */,
FD245C5C2850660A00B966DD /* LegacyConfigurationMessage.swift in Sources */,
FD5C7301284F0F7A0029977D /* MessageReceiver+UnsendRequests.swift in Sources */,
C3C2A75F2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift in Sources */,
FD245C642850664F00B966DD /* Threading.swift in Sources */,
@ -5999,8 +5964,6 @@
FD245C56285065EA00B966DD /* SNProto.swift in Sources */,
FD09798B27FD1CFE00936362 /* Capability.swift in Sources */,
C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */,
FD1D732A2A85AA2000E3F410 /* Setting+Utilities.swift in Sources */,
FD17D79C27F40B2E00122BE0 /* SMKLegacy.swift in Sources */,
FD09798127FCFEE800936362 /* SessionThread.swift in Sources */,
FD09C5EA282A1BB2000CE219 /* ThreadTypingIndicator.swift in Sources */,
FDF0B75E280AAF35004C14C5 /* Preferences.swift in Sources */,

View File

@ -421,18 +421,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// Offer the 'Restore' option if it was a migration error
case .databaseError:
alert.addAction(UIAlertAction(title: "vc_restore_title".localized(), style: .destructive) { _ in
if SUKLegacy.hasLegacyDatabaseFile {
// Remove the legacy database and any message hashes that have been migrated to the new DB
try? SUKLegacy.deleteLegacyDatabaseFilesAndKey()
Storage.shared.write { db in
try SnodeReceivedMessageInfo.deleteAll(db)
}
}
else {
// If we don't have a legacy database then reset the current database for a clean migration
Storage.resetForCleanMigration()
}
// Reset the current database for a clean migration
Storage.resetForCleanMigration()
// Hide the top banner if there was one
TopBannerController.hide()
@ -905,6 +895,7 @@ private enum StartupError: Error {
var name: String {
switch self {
case .databaseError(StorageError.startupFailed): return "Database startup failed"
case .databaseError(StorageError.migrationNoLongerSupported): return "Unsupported version"
case .failedToRestore: return "Failed to restore"
case .databaseError: return "Database error"
case .startupTimeout: return "Startup timeout"
@ -914,6 +905,8 @@ private enum StartupError: Error {
var message: String {
switch self {
case .databaseError(StorageError.startupFailed): return "DATABASE_STARTUP_FAILED".localized()
case .databaseError(StorageError.migrationNoLongerSupported):
return "DATABASE_UNSUPPORTED_MIGRATION".localized()
case .failedToRestore: return "DATABASE_RESTORE_FAILED".localized()
case .databaseError: return "DATABASE_MIGRATION_FAILED".localized()
case .startupTimeout: return "APP_STARTUP_TIMEOUT".localized()

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "هنگام بهینه‌سازی پایگاه داده خطایی روی داد\n\nشما می‌توانید گزارش‌های برنامه خود را صادر کنید تا بتوانید برای عیب‌یابی به اشتراک بگذارید یا می‌توانید دستگاه خود را بازیابی کنید\n\nهشدار: بازیابی دستگاه شما منجر به از دست رفتن داده‌های قدیمی‌تر از دو هفته می‌شود.";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "مشکلی پیش آمد. لطفاً عبارت بازیابی خود را بررسی کنید و دوباره امتحان کنید.";
"RECOVERY_PHASE_ERROR_LENGTH" = "به نظر می رسد کلمات کافی وارد نکرده اید. لطفاً عبارت بازیابی خود را بررسی کنید و دوباره امتحان کنید.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "به نظر می رسد که شما آخرین کلمه بازیابی حساب خود را وارد نکرده اید. لطفاً آنچه را وارد کرده‌اید بررسی کنید و دوباره امتحان کنید.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "Une erreur est survenue pendant l'optimisation de la base de données\n\nVous pouvez exporter votre journal d'application pour le partager et aider à régler le problème ou vous pouvez restaurer votre appareil\n\nAttention : restaurer votre appareil résultera en une perte des données des deux dernières semaines";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Quelque chose s'est mal passé. Vérifiez votre phrase de récupération et réessayez s'il vous plaît.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Il semble que vous n'avez pas saisi tous les mots. Vérifiez votre phrase de récupération et réessayez s'il vous plaît.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "Il semble qu'il vous manque le dernier mot de votre phrase de récupération. Vérifiez votre saisie et réessayez s'il vous plaît.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -419,6 +419,7 @@
"APP_STARTUP_EXIT" = "Exit";
"DATABASE_RESTORE_FAILED" = "An error occurred when opening the restored database\n\nYou can export your application logs to share for troubleshooting but to continue to use Session you may need to reinstall";
"DATABASE_MIGRATION_FAILED" = "An error occurred when optimising the database\n\nYou can export your application logs to be able to share for troubleshooting or you can restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"DATABASE_UNSUPPORTED_MIGRATION" = "You are trying to updated from a version which no longer supports upgrading\n\nIn order to continue to use session you need to restore your device\n\nWarning: Restoring your device will result in loss of any data older than two weeks";
"RECOVERY_PHASE_ERROR_GENERIC" = "Something went wrong. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LENGTH" = "Looks like you didn't enter enough words. Please check your recovery phrase and try again.";
"RECOVERY_PHASE_ERROR_LAST_WORD" = "You seem to be missing the last word of your recovery phrase. Please check what you entered and try again.";

View File

@ -33,7 +33,7 @@ enum Onboarding {
let userPublicKey: String = getUserHexEncodedPublicKey(using: dependencies)
return SnodeAPI.getSwarm(for: userPublicKey)
.tryFlatMapWithRandomSnode { snode -> AnyPublisher<Void, Error> in
.tryFlatMapWithRandomSnode { snode -> AnyPublisher<[Message], Error> in
CurrentUserPoller
.poll(
namespaces: [.configUserProfile],
@ -44,70 +44,9 @@ enum Onboarding {
calledFromBackgroundPoller: true,
isBackgroundPollValid: { true }
)
.tryFlatMap { receivedMessageTypes -> AnyPublisher<Void, Error> in
// FIXME: Remove this entire 'tryFlatMap' once the updated user config has been released for long enough
guard
receivedMessageTypes.isEmpty,
requestId == profileNameRetrievalIdentifier.wrappedValue
else {
return Just(())
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
SNLog("Onboarding failed to retrieve user config, checking for legacy config")
return CurrentUserPoller
.poll(
namespaces: [.default],
from: snode,
for: userPublicKey,
// Note: These values mean the received messages will be
// processed immediately rather than async as part of a Job
calledFromBackgroundPoller: true,
isBackgroundPollValid: { true }
)
.tryMap { receivedMessageTypes -> Void in
guard
let message: ConfigurationMessage = receivedMessageTypes
.last(where: { $0 is ConfigurationMessage })
.asType(ConfigurationMessage.self),
let displayName: String = message.displayName,
requestId == profileNameRetrievalIdentifier.wrappedValue
else { return () }
// Handle user profile changes
Storage.shared.write { db in
try ProfileManager.updateProfileIfNeeded(
db,
publicKey: userPublicKey,
name: displayName,
avatarUpdate: {
guard
let profilePictureUrl: String = message.profilePictureUrl,
let profileKey: Data = message.profileKey
else { return .none }
return .updateTo(
url: profilePictureUrl,
key: profileKey,
fileName: nil
)
}(),
sentTimestamp: TimeInterval((message.sentTimestamp ?? 0) / 1000),
calledFromConfigHandling: false,
using: dependencies
)
}
return ()
}
.eraseToAnyPublisher()
}
}
.map { _ -> String? in
guard requestId == profileNameRetrievalIdentifier.wrappedValue else {
return nil
}
guard requestId == profileNameRetrievalIdentifier.wrappedValue else { return nil }
return Storage.shared.read { db in
try Profile

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ import GRDB
import SessionUtilitiesKit
import SessionSnodeKit
/// This migration removes the legacy YapDatabase files
/// This migration used to remove the legacy YapDatabase files (the old logic has been removed and is no longer supported so it now does nothing)
enum _004_RemoveLegacyYDB: Migration {
static let target: TargetMigrations.Identifier = .messagingKit
static let identifier: String = "RemoveLegacyYDB"
@ -13,7 +13,6 @@ enum _004_RemoveLegacyYDB: Migration {
static let minExpectedRunDuration: TimeInterval = 0.1
static func migrate(_ db: Database) throws {
try? SUKLegacy.deleteLegacyDatabaseFilesAndKey()
Storage.update(progress: 1, for: self, in: target) // In case this is the last migration
}
}

View File

@ -114,7 +114,7 @@ public struct ControlMessageProcessRecord: Codable, FetchableRecord, Persistable
case is ClosedGroupControlMessage: return .closedGroupControlMessage
case is DataExtractionNotification: return .dataExtractionNotification
case is ExpirationTimerUpdate: return .expirationTimerUpdate
case is ConfigurationMessage, is SharedConfigMessage: return .configurationMessage
case is LegacyConfigurationMessage, is SharedConfigMessage: return .configurationMessage
case is UnsendRequest: return .unsendRequest
case is MessageRequestResponse: return .messageRequestResponse
case is CallMessage: return .call

View File

@ -1,85 +0,0 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import GRDB
import SessionUtilitiesKit
public final class ConfigurationMessage: ControlMessage {
private enum CodingKeys: String, CodingKey {
case displayName
case profilePictureUrl
case profileKey
}
public var displayName: String?
public var profilePictureUrl: String?
public var profileKey: Data?
public override var isSelfSendValid: Bool { true }
// MARK: - Initialization
public init(
displayName: String?,
profilePictureUrl: String?,
profileKey: Data?
) {
super.init()
self.displayName = displayName
self.profilePictureUrl = profilePictureUrl
self.profileKey = profileKey
}
// MARK: - Codable
required init(from decoder: Decoder) throws {
try super.init(from: decoder)
let container: KeyedDecodingContainer<CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
displayName = try? container.decode(String.self, forKey: .displayName)
profilePictureUrl = try? container.decode(String.self, forKey: .profilePictureUrl)
profileKey = try? container.decode(Data.self, forKey: .profileKey)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container: KeyedEncodingContainer<CodingKeys> = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(displayName, forKey: .displayName)
try container.encodeIfPresent(profilePictureUrl, forKey: .profilePictureUrl)
try container.encodeIfPresent(profileKey, forKey: .profileKey)
}
// MARK: - Proto Conversion
public override class func fromProto(_ proto: SNProtoContent, sender: String) -> ConfigurationMessage? {
guard let configurationProto = proto.configurationMessage else { return nil }
let displayName = configurationProto.displayName
let profilePictureUrl = configurationProto.profilePicture
let profileKey = configurationProto.profileKey
return ConfigurationMessage(
displayName: displayName,
profilePictureUrl: profilePictureUrl,
profileKey: profileKey
)
}
public override func toProto(_ db: Database, threadId: String) -> SNProtoContent? { return nil }
// MARK: - Description
public var description: String {
"""
LegacyConfigurationMessage(
displayName: \(displayName ?? "null"),
profilePictureUrl: \(profilePictureUrl ?? "null"),
profileKey: \(profileKey?.toHexString() ?? "null")
)
"""
}
}

View File

@ -0,0 +1,17 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import GRDB
public final class LegacyConfigurationMessage: ControlMessage {
public override var isSelfSendValid: Bool { true }
public override class func fromProto(_ proto: SNProtoContent, sender: String) -> LegacyConfigurationMessage? {
guard let configurationProto = proto.configurationMessage else { return nil }
return LegacyConfigurationMessage()
}
public override func toProto(_ db: Database) -> SNProtoContent? { return nil }
public var description: String { "LegacyConfigurationMessage()" }
}

View File

@ -89,7 +89,7 @@ public extension Message {
case closedGroupControlMessage
case dataExtractionNotification
case expirationTimerUpdate
case configurationMessage
case legacyConfigurationMessage = "configurationMessage"
case unsendRequest
case messageRequestResponse
case visibleMessage
@ -103,7 +103,7 @@ public extension Message {
case is ClosedGroupControlMessage: self = .closedGroupControlMessage
case is DataExtractionNotification: self = .dataExtractionNotification
case is ExpirationTimerUpdate: self = .expirationTimerUpdate
case is ConfigurationMessage: self = .configurationMessage
case is LegacyConfigurationMessage: self = .legacyConfigurationMessage
case is UnsendRequest: self = .unsendRequest
case is MessageRequestResponse: self = .messageRequestResponse
case is VisibleMessage: self = .visibleMessage
@ -120,7 +120,7 @@ public extension Message {
case .closedGroupControlMessage: return ClosedGroupControlMessage.self
case .dataExtractionNotification: return DataExtractionNotification.self
case .expirationTimerUpdate: return ExpirationTimerUpdate.self
case .configurationMessage: return ConfigurationMessage.self
case .legacyConfigurationMessage: return LegacyConfigurationMessage.self
case .unsendRequest: return UnsendRequest.self
case .messageRequestResponse: return MessageRequestResponse.self
case .visibleMessage: return VisibleMessage.self
@ -141,7 +141,10 @@ public extension Message {
return try container.decode(DataExtractionNotification.self, forKey: key)
case .expirationTimerUpdate: return try container.decode(ExpirationTimerUpdate.self, forKey: key)
case .configurationMessage: return try container.decode(ConfigurationMessage.self, forKey: key)
case .legacyConfigurationMessage:
return try container.decode(LegacyConfigurationMessage.self, forKey: key)
case .unsendRequest: return try container.decode(UnsendRequest.self, forKey: key)
case .messageRequestResponse: return try container.decode(MessageRequestResponse.self, forKey: key)
case .visibleMessage: return try container.decode(VisibleMessage.self, forKey: key)
@ -160,7 +163,7 @@ public extension Message {
.closedGroupControlMessage,
.dataExtractionNotification,
.expirationTimerUpdate,
.configurationMessage,
.legacyConfigurationMessage,
.unsendRequest,
.messageRequestResponse,
.visibleMessage,
@ -200,7 +203,7 @@ public extension Message {
switch message {
case is VisibleMessage: return true
case is ExpirationTimerUpdate: return true
case is ConfigurationMessage: return true
case is LegacyConfigurationMessage: return true
case is UnsendRequest: return true
case let controlMessage as ClosedGroupControlMessage:

View File

@ -293,8 +293,8 @@ public enum MessageReceiver {
)
// SharedConfigMessages should be handled by the 'SharedUtil' instead of this
case is ConfigurationMessage: TopBannerController.show(warning: .outdatedUserConfig)
case is SharedConfigMessage: throw MessageReceiverError.invalidSharedConfigMessageHandling
case is LegacyConfigurationMessage: TopBannerController.show(warning: .outdatedUserConfig)
default: fatalError()
}
@ -313,7 +313,7 @@ public enum MessageReceiver {
switch message {
case is ReadReceipt: break
case is TypingIndicator: break
case is ConfigurationMessage: break
case is LegacyConfigurationMessage: break
case is UnsendRequest: break
case let message as ClosedGroupControlMessage:

View File

@ -1,66 +0,0 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
public enum SSKLegacy {
// MARK: - Collections and Keys
internal static let swarmCollectionPrefix = "LokiSwarmCollection-"
internal static let lastSnodePoolRefreshDateKey = "lastSnodePoolRefreshDate"
internal static let snodePoolCollection = "LokiSnodePoolCollection"
internal static let onionRequestPathCollection = "LokiOnionRequestPathCollection"
internal static let lastSnodePoolRefreshDateCollection = "LokiLastSnodePoolRefreshDateCollection"
internal static let lastMessageHashCollection = "LokiLastMessageHashCollection"
internal static let receivedMessagesCollection = "LokiReceivedMessagesCollection"
// MARK: - Types
public typealias LegacyOnionRequestAPIPath = [Snode]
@objc(Snode)
public final class Snode: NSObject, NSCoding {
public let address: String
public let port: UInt16
public let publicKeySet: KeySet
// MARK: - Nested Types
public struct KeySet {
public let ed25519Key: String
public let x25519Key: String
}
// MARK: - NSCoding
public init?(coder: NSCoder) {
address = coder.decodeObject(forKey: "address") as! String
port = coder.decodeObject(forKey: "port") as! UInt16
guard
let idKey = coder.decodeObject(forKey: "idKey") as? String,
let encryptionKey = coder.decodeObject(forKey: "encryptionKey") as? String
else { return nil }
publicKeySet = KeySet(ed25519Key: idKey, x25519Key: encryptionKey)
super.init()
}
public func encode(with coder: NSCoder) {
fatalError("encode(with:) should never be called for legacy types")
}
// Note: The 'isEqual' and 'hash' overrides are both needed to ensure the migration
// doesn't try to insert duplicate SNode entries into the new database (which would
// result in unique key constraint violations)
override public func isEqual(_ other: Any?) -> Bool {
guard let other = other as? Snode else { return false }
return address == other.address && port == other.port
}
override public var hash: Int {
return address.hashValue ^ port.hashValue
}
}
}

View File

@ -2,213 +2,18 @@
import Foundation
import GRDB
import YapDatabase
import SessionUtilitiesKit
enum _003_YDBToGRDBMigration: Migration {
static let target: TargetMigrations.Identifier = .snodeKit
static let identifier: String = "YDBToGRDBMigration"
static let needsConfigSync: Bool = false
/// This migration can take a while if it's a very large database or there are lots of closed groups (want this to account
/// for about 10% of the progress bar so we intentionally have a higher `minExpectedRunDuration` so show more
/// progress during the migration)
static let minExpectedRunDuration: TimeInterval = 2.0
static let minExpectedRunDuration: TimeInterval = 0.1
static func migrate(_ db: Database) throws {
guard let dbConnection: YapDatabaseConnection = SUKLegacy.newDatabaseConnection() else {
SNLogNotTests("[Migration Warning] No legacy database, skipping \(target.key(with: self))")
return
}
guard !SNUtilitiesKit.isRunningTests else { return Storage.update(progress: 1, for: self, in: target) }
// MARK: - Read from Legacy Database
// Note: Want to exclude the Snode's we already added from the 'onionRequestPathResult'
var snodeResult: Set<SSKLegacy.Snode> = []
var snodeSetResult: [String: Set<SSKLegacy.Snode>] = [:]
var lastSnodePoolRefreshDate: Date? = nil
var lastMessageResults: [String: (hash: String, json: JSON)] = [:]
var receivedMessageResults: [String: Set<String>] = [:]
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
SSKLegacy.Snode.self,
forClassName: "SessionSnodeKit.Snode"
)
dbConnection.read { transaction in
// MARK: --lastSnodePoolRefreshDate
lastSnodePoolRefreshDate = transaction.object(
forKey: SSKLegacy.lastSnodePoolRefreshDateKey,
inCollection: SSKLegacy.lastSnodePoolRefreshDateCollection
) as? Date
// MARK: --OnionRequestPaths
if
let path0Snode0 = transaction.object(forKey: "0-0", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path0Snode1 = transaction.object(forKey: "0-1", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path0Snode2 = transaction.object(forKey: "0-2", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode
{
snodeResult.insert(path0Snode0)
snodeResult.insert(path0Snode1)
snodeResult.insert(path0Snode2)
snodeSetResult["\(SnodeSet.onionRequestPathPrefix)0"] = [ path0Snode0, path0Snode1, path0Snode2 ]
if
let path1Snode0 = transaction.object(forKey: "1-0", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path1Snode1 = transaction.object(forKey: "1-1", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path1Snode2 = transaction.object(forKey: "1-2", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode
{
snodeResult.insert(path1Snode0)
snodeResult.insert(path1Snode1)
snodeResult.insert(path1Snode2)
snodeSetResult["\(SnodeSet.onionRequestPathPrefix)1"] = [ path1Snode0, path1Snode1, path1Snode2 ]
}
}
Storage.update(progress: 0.02, for: self, in: target)
// MARK: --SnodePool
transaction.enumerateKeysAndObjects(inCollection: SSKLegacy.snodePoolCollection) { _, object, _ in
guard let snode = object as? SSKLegacy.Snode else { return }
snodeResult.insert(snode)
}
// MARK: --Swarms
/// **Note:** There is no index on the collection column so unfortunately it takes the same amount of time to enumerate through all
/// collections as it does to just get the count of collections, due to this, if the database is very large, importing thecollections can be
/// very slow (~15s with 2,000,000 rows) - we want to show some kind of progress while enumerating so the below code creates a
/// very rought guess of the number of collections based on the file size of the database (this shouldn't affect most users at all)
let roughMbPerCollection: CGFloat = 2.5
let oldDatabaseSizeBytes: CGFloat = (try? FileManager.default
.attributesOfItem(atPath: SUKLegacy.legacyDatabaseFilepath)[.size]
.asType(CGFloat.self))
.defaulting(to: 0)
let roughNumCollections: CGFloat = (((oldDatabaseSizeBytes / 1024) / 1024) / roughMbPerCollection)
let startProgress: CGFloat = 0.02
let swarmCompleteProgress: CGFloat = 0.90
var swarmCollections: Set<String> = []
var collectionIndex: CGFloat = 0
transaction.enumerateCollections { collectionName, _ in
if collectionName.starts(with: SSKLegacy.swarmCollectionPrefix) {
swarmCollections.insert(collectionName.substring(from: SSKLegacy.swarmCollectionPrefix.count))
}
collectionIndex += 1
Storage.update(
progress: min(
swarmCompleteProgress,
((collectionIndex / roughNumCollections) * (swarmCompleteProgress - startProgress))
),
for: self,
in: target
)
}
Storage.update(progress: swarmCompleteProgress, for: self, in: target)
for swarmCollection in swarmCollections {
let collection: String = "\(SSKLegacy.swarmCollectionPrefix)\(swarmCollection)"
transaction.enumerateKeysAndObjects(inCollection: collection) { _, object, _ in
guard let snode = object as? SSKLegacy.Snode else { return }
snodeResult.insert(snode)
snodeSetResult[swarmCollection] = (snodeSetResult[swarmCollection] ?? Set()).inserting(snode)
}
}
Storage.update(progress: 0.92, for: self, in: target)
// MARK: --Received message hashes
transaction.enumerateKeysAndObjects(inCollection: SSKLegacy.receivedMessagesCollection) { key, object, _ in
guard let hashSet = object as? Set<String> else { return }
receivedMessageResults[key] = hashSet
}
Storage.update(progress: 0.93, for: self, in: target)
// MARK: --Last message info
transaction.enumerateKeysAndObjects(inCollection: SSKLegacy.lastMessageHashCollection) { key, object, _ in
guard let lastMessageJson = object as? JSON else { return }
guard let lastMessageHash: String = lastMessageJson["hash"] as? String else { return }
// Note: We remove the value from 'receivedMessageResults' as we want to try and use
// it's actual 'expirationDate' value
lastMessageResults[key] = (lastMessageHash, lastMessageJson)
receivedMessageResults[key] = receivedMessageResults[key]?.removing(lastMessageHash)
}
Storage.update(progress: 0.94, for: self, in: target)
}
// MARK: - Insert into GRDB
try autoreleasepool {
// MARK: --lastSnodePoolRefreshDate
db[.lastSnodePoolRefreshDate] = lastSnodePoolRefreshDate
// MARK: --SnodePool
try snodeResult.forEach { legacySnode in
try Snode(
address: legacySnode.address,
port: legacySnode.port,
ed25519PublicKey: legacySnode.publicKeySet.ed25519Key,
x25519PublicKey: legacySnode.publicKeySet.x25519Key
).migrationSafeInsert(db)
}
Storage.update(progress: 0.96, for: self, in: target)
// MARK: --SnodeSets
try snodeSetResult.forEach { key, legacySnodeSet in
try legacySnodeSet.enumerated().forEach { nodeIndex, legacySnode in
// Note: In this case the 'nodeIndex' is irrelivant
try SnodeSet(
key: key,
nodeIndex: nodeIndex,
address: legacySnode.address,
port: legacySnode.port
).migrationSafeInsert(db)
}
}
Storage.update(progress: 0.98, for: self, in: target)
}
try autoreleasepool {
// MARK: --Received Messages
try receivedMessageResults.forEach { key, hashes in
try hashes.forEach { hash in
_ = try SnodeReceivedMessageInfo(
key: key,
hash: hash,
expirationDateMs: SnodeReceivedMessage.defaultExpirationSeconds
).migrationSafeInserted(db)
}
}
Storage.update(progress: 0.99, for: self, in: target)
// MARK: --Last Message Hash
try lastMessageResults.forEach { key, data in
let expirationDateMs: Int64 = ((data.json["expirationDate"] as? Int64) ?? 0)
_ = try SnodeReceivedMessageInfo(
key: key,
hash: data.hash,
expirationDateMs: (expirationDateMs > 0 ?
expirationDateMs :
SnodeReceivedMessage.defaultExpirationSeconds
)
).migrationSafeInserted(db)
}
}
Storage.update(progress: 1, for: self, in: target) // In case this is the last migration
SNLogNotTests("[Migration Error] Attempted to perform legacy migation")
throw StorageError.migrationNoLongerSupported
}
}

View File

@ -2,7 +2,6 @@
import Foundation
import GRDB
import YapDatabase
import SessionUtilitiesKit
enum _004_FlagMessageHashAsDeletedOrInvalid: Migration {

View File

@ -1,167 +0,0 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import YapDatabase
public enum SUKLegacy {
// MARK: - YapDatabase
private static let keychainService = "TSKeyChainService"
private static let keychainDBCipherKeySpec = "OWSDatabaseCipherKeySpec"
private static let sqlCipherKeySpecLength = 48
private static var database: Atomic<YapDatabase>?
// MARK: - Collections and Keys
internal static let userAccountRegisteredNumberKey = "TSStorageRegisteredNumberKey"
internal static let userAccountCollection = "TSStorageUserAccountCollection"
internal static let identityKeyStoreSeedKey = "LKLokiSeed"
internal static let identityKeyStoreEd25519SecretKey = "LKED25519SecretKey"
internal static let identityKeyStoreEd25519PublicKey = "LKED25519PublicKey"
internal static let identityKeyStoreIdentityKey = "TSStorageManagerIdentityKeyStoreIdentityKey"
internal static let identityKeyStoreCollection = "TSStorageManagerIdentityKeyStoreCollection"
// MARK: - Database Functions
public static var legacyDatabaseFilepath: String {
let sharedDirUrl: URL = URL(fileURLWithPath: OWSFileSystem.appSharedDataDirectoryPath())
return sharedDirUrl
.appendingPathComponent("database")
.appendingPathComponent("Signal.sqlite")
.path
}
private static let legacyDatabaseDeserializer: YapDatabaseDeserializer = {
return { (collection: String, key: String, data: Data) -> Any in
/// **Note:** The old `init(forReadingWith:)` method has been deprecated with `init(forReadingFrom:)`
/// and Apple changed the default of `requiresSecureCoding` to be true, this results in some of the types from failing
/// to decode, as a result we need to set it to false here
let unarchiver: NSKeyedUnarchiver? = try? NSKeyedUnarchiver(forReadingFrom: data)
unarchiver?.requiresSecureCoding = false
guard !data.isEmpty, let result = unarchiver?.decodeObject(forKey: "root") else {
return UnknownDBObject()
}
return result
}
}()
public static var hasLegacyDatabaseFile: Bool {
return FileManager.default.fileExists(atPath: legacyDatabaseFilepath)
}
@discardableResult public static func loadDatabaseIfNeeded() -> Bool {
guard SUKLegacy.database == nil else { return true }
/// Ensure the databaseKeySpec exists
var maybeKeyData: Data? = try? SSKDefaultKeychainStorage.shared.data(
forService: keychainService,
key: keychainDBCipherKeySpec
)
defer { if maybeKeyData != nil { maybeKeyData!.resetBytes(in: 0..<maybeKeyData!.count) } }
guard maybeKeyData != nil, maybeKeyData?.count == sqlCipherKeySpecLength else { return false }
// Setup the database options
let options: YapDatabaseOptions = YapDatabaseOptions()
options.corruptAction = .fail
options.enableMultiProcessSupport = true
options.cipherUnencryptedHeaderLength = kSqliteHeaderLength // Needed for iOS to support SQLite writes
options.legacyCipherCompatibilityVersion = 3 // Old DB was SQLCipher V3
options.cipherKeySpecBlock = {
/// To avoid holding the keySpec in memory too long we load it as needed, since we have already confirmed
/// it's existence we can force-try here (the database will crash if it's invalid anyway)
var keySpec: Data = try! SSKDefaultKeychainStorage.shared.data(
forService: keychainService,
key: keychainDBCipherKeySpec
)
defer { keySpec.resetBytes(in: 0..<keySpec.count) }
return keySpec
}
let maybeDatabase: YapDatabase? = YapDatabase(
path: legacyDatabaseFilepath,
serializer: nil,
deserializer: legacyDatabaseDeserializer,
options: options
)
guard let database: YapDatabase = maybeDatabase else { return false }
// Store the database instance atomically
SUKLegacy.database = Atomic(database)
return true
}
public static func newDatabaseConnection() -> YapDatabaseConnection? {
SUKLegacy.loadDatabaseIfNeeded()
return self.database?.wrappedValue.newConnection()
}
public static func clearLegacyDatabaseInstance() {
self.database = nil
}
public static func deleteLegacyDatabaseFilesAndKey() throws {
OWSFileSystem.deleteFile(legacyDatabaseFilepath)
OWSFileSystem.deleteFile("\(legacyDatabaseFilepath)-shm")
OWSFileSystem.deleteFile("\(legacyDatabaseFilepath)-wal")
try SSKDefaultKeychainStorage.shared.remove(service: keychainService, key: keychainDBCipherKeySpec)
}
// MARK: - UnknownDBObject
@objc(LegacyUnknownDBObject)
public class UnknownDBObject: NSObject, NSCoding {
override public init() {}
public required init?(coder: NSCoder) {}
public func encode(with coder: NSCoder) { fatalError("Shouldn't be encoding this type") }
}
// MARK: - LagacyKeyPair
@objc(LegacyKeyPair)
public class KeyPair: NSObject, NSCoding {
private static let keyLength: Int = 32
private static let publicKeyKey: String = "TSECKeyPairPublicKey"
private static let privateKeyKey: String = "TSECKeyPairPrivateKey"
public let publicKey: Data
public let privateKey: Data
public init(
publicKeyData: Data,
privateKeyData: Data
) {
publicKey = publicKeyData
privateKey = privateKeyData
}
public required init?(coder: NSCoder) {
var pubKeyLength: Int = 0
var privKeyLength: Int = 0
guard
let pubKeyBytes: UnsafePointer<UInt8> = coder.decodeBytes(forKey: KeyPair.publicKeyKey, returnedLength: &pubKeyLength),
let privateKeyBytes: UnsafePointer<UInt8> = coder.decodeBytes(forKey: KeyPair.privateKeyKey, returnedLength: &privKeyLength),
pubKeyLength == KeyPair.keyLength,
privKeyLength == KeyPair.keyLength
else {
// Fail if the keys aren't the correct length
return nil
}
publicKey = Data(bytes: pubKeyBytes, count: pubKeyLength)
privateKey = Data(bytes: privateKeyBytes, count: privKeyLength)
}
public func encode(with coder: NSCoder) { fatalError("Shouldn't be encoding this type") }
}
}

View File

@ -2,7 +2,6 @@
import Foundation
import GRDB
import YapDatabase
enum _003_YDBToGRDBMigration: Migration {
static let target: TargetMigrations.Identifier = .utilitiesKit
@ -11,109 +10,9 @@ enum _003_YDBToGRDBMigration: Migration {
static let minExpectedRunDuration: TimeInterval = 0.1
static func migrate(_ db: Database) throws {
guard let dbConnection: YapDatabaseConnection = SUKLegacy.newDatabaseConnection() else {
SNLogNotTests("[Migration Warning] No legacy database, skipping \(target.key(with: self))")
return
}
guard !SNUtilitiesKit.isRunningTests else { return Storage.update(progress: 1, for: self, in: target) }
// MARK: - Read from Legacy Database
// Note: Want to exclude the Snode's we already added from the 'onionRequestPathResult'
var registeredNumber: String?
var seedHexString: String?
var userEd25519SecretKeyHexString: String?
var userEd25519PublicKeyHexString: String?
var userX25519KeyPair: SUKLegacy.KeyPair?
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
SUKLegacy.KeyPair.self,
forClassName: "ECKeyPair"
)
dbConnection.read { transaction in
// MARK: --Identity keys
registeredNumber = transaction.object(
forKey: SUKLegacy.userAccountRegisteredNumberKey,
inCollection: SUKLegacy.userAccountCollection
) as? String
// Note: The 'seed', 'ed25519SecretKey' and 'ed25519PublicKey' were
// all previously stored as hex strings, so we need to convert them
// to data before we store them in the new database
seedHexString = transaction.object(
forKey: SUKLegacy.identityKeyStoreSeedKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userEd25519SecretKeyHexString = transaction.object(
forKey: SUKLegacy.identityKeyStoreEd25519SecretKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userEd25519PublicKeyHexString = transaction.object(
forKey: SUKLegacy.identityKeyStoreEd25519PublicKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userX25519KeyPair = transaction.object(
forKey: SUKLegacy.identityKeyStoreIdentityKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? SUKLegacy.KeyPair
}
// No need to continue if the user isn't registered
if registeredNumber == nil { return }
// If the user is registered then it's all-or-nothing for these values
guard
let seedHexString: String = seedHexString,
let userEd25519SecretKeyHexString: String = userEd25519SecretKeyHexString,
let userEd25519PublicKeyHexString: String = userEd25519PublicKeyHexString,
let userX25519KeyPair: SUKLegacy.KeyPair = userX25519KeyPair
else {
// If this is a fresh install then we would have created all of the Identity
// values directly within the 'Identity' table so this is actually a valid
// case and we don't need to throw
if try Identity.fetchCount(db) == Identity.Variant.allCases.count {
return
}
throw StorageError.migrationFailed
}
// MARK: - Insert into GRDB
try autoreleasepool {
// MARK: --Identity keys
try Identity(
variant: .seed,
data: Data(hex: seedHexString)
).migrationSafeInsert(db)
try Identity(
variant: .ed25519SecretKey,
data: Data(hex: userEd25519SecretKeyHexString)
).migrationSafeInsert(db)
try Identity(
variant: .ed25519PublicKey,
data: Data(hex: userEd25519PublicKeyHexString)
).migrationSafeInsert(db)
try Identity(
variant: .x25519PrivateKey,
data: userX25519KeyPair.privateKey
).migrationSafeInsert(db)
try Identity(
variant: .x25519PublicKey,
data: userX25519KeyPair.publicKey
).migrationSafeInsert(db)
}
Storage.update(progress: 1, for: self, in: target) // In case this is the last migration
SNLogNotTests("[Migration Error] Attempted to perform legacy migation")
throw StorageError.migrationNoLongerSupported
}
}

View File

@ -2,7 +2,6 @@
import Foundation
import GRDB
import YapDatabase
enum _004_AddJobPriority: Migration {
static let target: TargetMigrations.Identifier = .utilitiesKit

View File

@ -248,7 +248,6 @@ open class Storage {
self?.migrationsCompleted.mutate { $0 = true }
self?.migrationProgressUpdater = nil
self?.migrationRequirementProcesser = nil
SUKLegacy.clearLegacyDatabaseInstance()
// Reset in case there is a requirement on a migration which runs when returning from
// the background
@ -417,10 +416,6 @@ open class Storage {
}
public static func resetAllStorage() {
// Just in case they haven't been removed for some reason, delete the legacy database & keys
SUKLegacy.clearLegacyDatabaseInstance()
try? SUKLegacy.deleteLegacyDatabaseFilesAndKey()
Storage.shared.isValid = false
Storage.internalHasCreatedValidInstance.mutate { $0 = false }
Storage.shared.migrationsCompleted.mutate { $0 = false }

View File

@ -7,6 +7,7 @@ public enum StorageError: Error {
case databaseInvalid
case startupFailed
case migrationFailed
case migrationNoLongerSupported
case invalidKeySpec
case keySpecCreationFailed
case keySpecInaccessible