mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Update the SDK.
Handles changes that removed support for the sliding sync proxy.
This commit is contained in:
parent
f77faee981
commit
8c07ee35c4
@ -67,7 +67,6 @@
|
|||||||
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
|
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
|
||||||
09AAF04B27732046C755D914 /* SoftLogoutViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */; };
|
09AAF04B27732046C755D914 /* SoftLogoutViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */; };
|
||||||
09D3D7D115318CAD131B4FE7 /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57084488B03BDB33C7B7CA0E /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift */; };
|
09D3D7D115318CAD131B4FE7 /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57084488B03BDB33C7B7CA0E /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift */; };
|
||||||
0A0625A271EE5B06D2AAA069 /* HomeScreenSlidingSyncMigrationBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4691B8DE1D51DE152680098A /* HomeScreenSlidingSyncMigrationBanner.swift */; };
|
|
||||||
0A194F5E70B5A628C1BF4476 /* AdvancedSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */; };
|
0A194F5E70B5A628C1BF4476 /* AdvancedSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */; };
|
||||||
0ACAA31FD0399CEEBA3ECC21 /* UserDetailsEditScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85149F56BA333619900E2410 /* UserDetailsEditScreenViewModelProtocol.swift */; };
|
0ACAA31FD0399CEEBA3ECC21 /* UserDetailsEditScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85149F56BA333619900E2410 /* UserDetailsEditScreenViewModelProtocol.swift */; };
|
||||||
0AD8EF040A60D62F488C18B5 /* KnockRequestProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F957320D0EB7D7B4E30C79D /* KnockRequestProxyMock.swift */; };
|
0AD8EF040A60D62F488C18B5 /* KnockRequestProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F957320D0EB7D7B4E30C79D /* KnockRequestProxyMock.swift */; };
|
||||||
@ -1399,6 +1398,7 @@
|
|||||||
0B0E0B55E2EE75AF67029924 /* SwipeToReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeToReplyView.swift; sourceTree = "<group>"; };
|
0B0E0B55E2EE75AF67029924 /* SwipeToReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeToReplyView.swift; sourceTree = "<group>"; };
|
||||||
0B32BBA8887BD7A5C4ECF16F /* RoomModerationRole.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomModerationRole.swift; sourceTree = "<group>"; };
|
0B32BBA8887BD7A5C4ECF16F /* RoomModerationRole.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomModerationRole.swift; sourceTree = "<group>"; };
|
||||||
0B987FC3FDBAA0E1C5AA235C /* PaginationIndicatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIndicatorRoomTimelineItem.swift; sourceTree = "<group>"; };
|
0B987FC3FDBAA0E1C5AA235C /* PaginationIndicatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIndicatorRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
|
0BA7D6C94A50428463D09AF0 /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenViewModel.swift; sourceTree = "<group>"; };
|
0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0BD116096CAA9139B95EEA9C /* UserProfileScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenViewModel.swift; sourceTree = "<group>"; };
|
0BD116096CAA9139B95EEA9C /* UserProfileScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
@ -1694,7 +1694,6 @@
|
|||||||
4629710C0337ADD9C8909542 /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4629710C0337ADD9C8909542 /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = "<group>"; };
|
466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
467498BEA681758BE2F80826 /* TimelineMediaPreviewDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewDetailsView.swift; sourceTree = "<group>"; };
|
467498BEA681758BE2F80826 /* TimelineMediaPreviewDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewDetailsView.swift; sourceTree = "<group>"; };
|
||||||
4691B8DE1D51DE152680098A /* HomeScreenSlidingSyncMigrationBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenSlidingSyncMigrationBanner.swift; sourceTree = "<group>"; };
|
|
||||||
46A2AD86F7E618F468F6FAF5 /* VoiceMessageRecordingButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingButton.swift; sourceTree = "<group>"; };
|
46A2AD86F7E618F468F6FAF5 /* VoiceMessageRecordingButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingButton.swift; sourceTree = "<group>"; };
|
||||||
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
46D0BA44B1838E65B507B277 /* NotificationPermissionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPermissionsScreen.swift; sourceTree = "<group>"; };
|
46D0BA44B1838E65B507B277 /* NotificationPermissionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPermissionsScreen.swift; sourceTree = "<group>"; };
|
||||||
@ -1752,6 +1751,7 @@
|
|||||||
52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = "<group>"; };
|
52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = "<group>"; };
|
||||||
5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = "<group>"; };
|
5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = "<group>"; };
|
||||||
5281C5CDC4A712265A0B5FBF /* PollRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineItem.swift; sourceTree = "<group>"; };
|
5281C5CDC4A712265A0B5FBF /* PollRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
|
529513218340CC8419273165 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
52BD6ED18E2EB61E28C340AD /* AttributedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedString.swift; sourceTree = "<group>"; };
|
52BD6ED18E2EB61E28C340AD /* AttributedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedString.swift; sourceTree = "<group>"; };
|
||||||
52F5EE5DE3B55D59299DB5BC /* AppLockSetupBiometricsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
52F5EE5DE3B55D59299DB5BC /* AppLockSetupBiometricsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewAdapter.swift; sourceTree = "<group>"; };
|
53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewAdapter.swift; sourceTree = "<group>"; };
|
||||||
@ -2315,6 +2315,7 @@
|
|||||||
C9F893F4A111CB7BA5C96949 /* AppLockSetupBiometricsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModel.swift; sourceTree = "<group>"; };
|
C9F893F4A111CB7BA5C96949 /* AppLockSetupBiometricsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
CA28F29C9F93E93CC3C2C715 /* NavigationRootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinator.swift; sourceTree = "<group>"; };
|
CA28F29C9F93E93CC3C2C715 /* NavigationRootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinator.swift; sourceTree = "<group>"; };
|
||||||
CA29952595B804DA221A0C1D /* ComposerToolbarViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbarViewModelTests.swift; sourceTree = "<group>"; };
|
CA29952595B804DA221A0C1D /* ComposerToolbarViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbarViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
|
CA46BDF38F87118939BDF659 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
CA4F6D7000EDCD187E0989E7 /* PinnedEventsTimelineScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineScreen.swift; sourceTree = "<group>"; };
|
CA4F6D7000EDCD187E0989E7 /* PinnedEventsTimelineScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineScreen.swift; sourceTree = "<group>"; };
|
||||||
CA89A2DD51B6BBE1DA55E263 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
CA89A2DD51B6BBE1DA55E263 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||||
CA90BD288E5AE6BC643AFDDF /* TemplateScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenCoordinator.swift; sourceTree = "<group>"; };
|
CA90BD288E5AE6BC643AFDDF /* TemplateScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@ -2409,6 +2410,7 @@
|
|||||||
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
||||||
E0FF9CB3EFA753277291F609 /* EncryptionResetScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreenCoordinator.swift; sourceTree = "<group>"; };
|
E0FF9CB3EFA753277291F609 /* EncryptionResetScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
E10DA51DBC8C7E1460DBCCBD /* UserProfileListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileListRow.swift; sourceTree = "<group>"; };
|
E10DA51DBC8C7E1460DBCCBD /* UserProfileListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileListRow.swift; sourceTree = "<group>"; };
|
||||||
|
E157152B11E347F735C3FD6E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
E1573D28C8A9FB6399D0EEFB /* SecureBackupLogoutConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
|
E1573D28C8A9FB6399D0EEFB /* SecureBackupLogoutConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
E1A5FEF17ED7E6176D922D4F /* RoomDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreen.swift; sourceTree = "<group>"; };
|
E1A5FEF17ED7E6176D922D4F /* RoomDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreen.swift; sourceTree = "<group>"; };
|
||||||
E1E0B4A34E69BD2132BEC521 /* MessageText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageText.swift; sourceTree = "<group>"; };
|
E1E0B4A34E69BD2132BEC521 /* MessageText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageText.swift; sourceTree = "<group>"; };
|
||||||
@ -3764,7 +3766,6 @@
|
|||||||
05512FB13987D221B7205DE0 /* HomeScreenRecoveryKeyConfirmationBanner.swift */,
|
05512FB13987D221B7205DE0 /* HomeScreenRecoveryKeyConfirmationBanner.swift */,
|
||||||
ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */,
|
ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */,
|
||||||
C7661EFFCAA307A97D71132A /* HomeScreenRoomList.swift */,
|
C7661EFFCAA307A97D71132A /* HomeScreenRoomList.swift */,
|
||||||
4691B8DE1D51DE152680098A /* HomeScreenSlidingSyncMigrationBanner.swift */,
|
|
||||||
84AF32E4136FD6F159D86C2C /* RoomDirectorySearchView.swift */,
|
84AF32E4136FD6F159D86C2C /* RoomDirectorySearchView.swift */,
|
||||||
037A5661B26EC6BE068188D7 /* Filters */,
|
037A5661B26EC6BE068188D7 /* Filters */,
|
||||||
);
|
);
|
||||||
@ -6296,6 +6297,7 @@
|
|||||||
ru,
|
ru,
|
||||||
sk,
|
sk,
|
||||||
sv,
|
sv,
|
||||||
|
tr,
|
||||||
uk,
|
uk,
|
||||||
uz,
|
uz,
|
||||||
"zh-Hans",
|
"zh-Hans",
|
||||||
@ -7077,7 +7079,6 @@
|
|||||||
B04E9EB589CE99C3929E817A /* HomeScreenRecoveryKeyConfirmationBanner.swift in Sources */,
|
B04E9EB589CE99C3929E817A /* HomeScreenRecoveryKeyConfirmationBanner.swift in Sources */,
|
||||||
0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */,
|
0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */,
|
||||||
A10D6CCDE2010C09EEA1A593 /* HomeScreenRoomList.swift in Sources */,
|
A10D6CCDE2010C09EEA1A593 /* HomeScreenRoomList.swift in Sources */,
|
||||||
0A0625A271EE5B06D2AAA069 /* HomeScreenSlidingSyncMigrationBanner.swift in Sources */,
|
|
||||||
DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */,
|
DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */,
|
||||||
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */,
|
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */,
|
||||||
2BBE320EE426A347AAE5C7DA /* IdentityConfirmationScreen.swift in Sources */,
|
2BBE320EE426A347AAE5C7DA /* IdentityConfirmationScreen.swift in Sources */,
|
||||||
@ -7832,6 +7833,7 @@
|
|||||||
E5F2B6443D1ED8602F328539 /* ru */,
|
E5F2B6443D1ED8602F328539 /* ru */,
|
||||||
667DD3A9D932D7D9EB380CAA /* sk */,
|
667DD3A9D932D7D9EB380CAA /* sk */,
|
||||||
0EE9EAF0309A2A1D67D8FAF5 /* sv */,
|
0EE9EAF0309A2A1D67D8FAF5 /* sv */,
|
||||||
|
E157152B11E347F735C3FD6E /* tr */,
|
||||||
5F12E996BFBEB43815189ABF /* uk */,
|
5F12E996BFBEB43815189ABF /* uk */,
|
||||||
DFFB0E7C6D8E190AFA0176DC /* uz */,
|
DFFB0E7C6D8E190AFA0176DC /* uz */,
|
||||||
AB26D5444A4A7E095222DE8B /* zh-Hans */,
|
AB26D5444A4A7E095222DE8B /* zh-Hans */,
|
||||||
@ -7868,6 +7870,7 @@
|
|||||||
E8294DB9E95C0C0630418466 /* ru */,
|
E8294DB9E95C0C0630418466 /* ru */,
|
||||||
AD378D580A41E42560C60E9C /* sk */,
|
AD378D580A41E42560C60E9C /* sk */,
|
||||||
ACA11F7F50A4A3887A18CA5A /* sv */,
|
ACA11F7F50A4A3887A18CA5A /* sv */,
|
||||||
|
529513218340CC8419273165 /* tr */,
|
||||||
ADCB8A232D3A8FB3E16A7303 /* uk */,
|
ADCB8A232D3A8FB3E16A7303 /* uk */,
|
||||||
475EB595D7527E9A8A14043E /* uz */,
|
475EB595D7527E9A8A14043E /* uz */,
|
||||||
284FEEB0789B8894E52A7F34 /* zh-Hans */,
|
284FEEB0789B8894E52A7F34 /* zh-Hans */,
|
||||||
@ -7892,6 +7895,7 @@
|
|||||||
1D652E78832289CD9EB64488 /* hu */,
|
1D652E78832289CD9EB64488 /* hu */,
|
||||||
7199693797B66245EF97BCF5 /* id */,
|
7199693797B66245EF97BCF5 /* id */,
|
||||||
44C314C00533E2C297796B60 /* it */,
|
44C314C00533E2C297796B60 /* it */,
|
||||||
|
0BA7D6C94A50428463D09AF0 /* ka */,
|
||||||
E60757AFE04391B43EA568B8 /* nl */,
|
E60757AFE04391B43EA568B8 /* nl */,
|
||||||
997BF045585AF6DB2EBC5755 /* pl */,
|
997BF045585AF6DB2EBC5755 /* pl */,
|
||||||
A8DF55467ED4CE76B7AE9A33 /* pt */,
|
A8DF55467ED4CE76B7AE9A33 /* pt */,
|
||||||
@ -7900,6 +7904,7 @@
|
|||||||
9B7D8D3638864B7482E148CC /* ru */,
|
9B7D8D3638864B7482E148CC /* ru */,
|
||||||
7D39AF1F659923D77778511E /* sk */,
|
7D39AF1F659923D77778511E /* sk */,
|
||||||
969694F67E844FCA51F7E051 /* sv */,
|
969694F67E844FCA51F7E051 /* sv */,
|
||||||
|
CA46BDF38F87118939BDF659 /* tr */,
|
||||||
D66B5D86A9AB95E0E01BED82 /* uk */,
|
D66B5D86A9AB95E0E01BED82 /* uk */,
|
||||||
FF720BA68256297680980481 /* zh-Hans */,
|
FF720BA68256297680980481 /* zh-Hans */,
|
||||||
0545AC444BEEA89FF8C509FD /* zh-Hant-TW */,
|
0545AC444BEEA89FF8C509FD /* zh-Hant-TW */,
|
||||||
@ -8521,7 +8526,7 @@
|
|||||||
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = 25.02.11;
|
version = 25.02.17;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
||||||
|
@ -149,8 +149,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "cc010fc6971370d1df2c0eb67cc5cfd577465b62",
|
"revision" : "422d7bef3ffd3edcb3e30afb410ee523f5659adc",
|
||||||
"version" : "25.2.11"
|
"version" : "25.2.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,7 @@
|
|||||||
"action_yes" = "Yes";
|
"action_yes" = "Yes";
|
||||||
"action_yes_try_again" = "Yes, try again";
|
"action_yes_try_again" = "Yes, try again";
|
||||||
"banner_migrate_to_native_sliding_sync_action" = "Log Out & Upgrade";
|
"banner_migrate_to_native_sliding_sync_action" = "Log Out & Upgrade";
|
||||||
|
"banner_migrate_to_native_sliding_sync_app_force_logout_title" = "Element X no longer supports the old protocol. Please log out and log back in to continue using the app.";
|
||||||
"banner_migrate_to_native_sliding_sync_description" = "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later.";
|
"banner_migrate_to_native_sliding_sync_description" = "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later.";
|
||||||
"banner_migrate_to_native_sliding_sync_force_logout_title" = "Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app.";
|
"banner_migrate_to_native_sliding_sync_force_logout_title" = "Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app.";
|
||||||
"banner_migrate_to_native_sliding_sync_title" = "Upgrade available";
|
"banner_migrate_to_native_sliding_sync_title" = "Upgrade available";
|
||||||
|
@ -120,6 +120,7 @@
|
|||||||
"action_yes" = "Yes";
|
"action_yes" = "Yes";
|
||||||
"action_yes_try_again" = "Yes, try again";
|
"action_yes_try_again" = "Yes, try again";
|
||||||
"banner_migrate_to_native_sliding_sync_action" = "Log Out & Upgrade";
|
"banner_migrate_to_native_sliding_sync_action" = "Log Out & Upgrade";
|
||||||
|
"banner_migrate_to_native_sliding_sync_app_force_logout_title" = "Element X no longer supports the old protocol. Please log out and log back in to continue using the app.";
|
||||||
"banner_migrate_to_native_sliding_sync_description" = "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later.";
|
"banner_migrate_to_native_sliding_sync_description" = "Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later.";
|
||||||
"banner_migrate_to_native_sliding_sync_force_logout_title" = "Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app.";
|
"banner_migrate_to_native_sliding_sync_force_logout_title" = "Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app.";
|
||||||
"banner_migrate_to_native_sliding_sync_title" = "Upgrade available";
|
"banner_migrate_to_native_sliding_sync_title" = "Upgrade available";
|
||||||
|
@ -44,7 +44,6 @@ final class AppSettings {
|
|||||||
case elementCallBaseURLOverride
|
case elementCallBaseURLOverride
|
||||||
|
|
||||||
// Feature flags
|
// Feature flags
|
||||||
case slidingSyncDiscovery
|
|
||||||
case publicSearchEnabled
|
case publicSearchEnabled
|
||||||
case fuzzyRoomListSearchEnabled
|
case fuzzyRoomListSearchEnabled
|
||||||
case enableOnlySignedDeviceIsolationMode
|
case enableOnlySignedDeviceIsolationMode
|
||||||
@ -283,10 +282,6 @@ final class AppSettings {
|
|||||||
@UserPreference(key: UserDefaultsKeys.fuzzyRoomListSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.fuzzyRoomListSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var fuzzyRoomListSearchEnabled
|
var fuzzyRoomListSearchEnabled
|
||||||
|
|
||||||
enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative }
|
|
||||||
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
|
|
||||||
var slidingSyncDiscovery: SlidingSyncDiscovery
|
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var knockingEnabled
|
var knockingEnabled
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func presentDeveloperOptions() {
|
private func presentDeveloperOptions() {
|
||||||
let coordinator = DeveloperOptionsScreenCoordinator(isUsingNativeSlidingSync: parameters.userSession.clientProxy.slidingSyncVersion == .native)
|
let coordinator = DeveloperOptionsScreenCoordinator()
|
||||||
|
|
||||||
coordinator.actions
|
coordinator.actions
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] action in
|
||||||
|
@ -274,6 +274,8 @@ internal enum L10n {
|
|||||||
internal static var actionYesTryAgain: String { return L10n.tr("Localizable", "action_yes_try_again") }
|
internal static var actionYesTryAgain: String { return L10n.tr("Localizable", "action_yes_try_again") }
|
||||||
/// Log Out & Upgrade
|
/// Log Out & Upgrade
|
||||||
internal static var bannerMigrateToNativeSlidingSyncAction: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_action") }
|
internal static var bannerMigrateToNativeSlidingSyncAction: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_action") }
|
||||||
|
/// Element X no longer supports the old protocol. Please log out and log back in to continue using the app.
|
||||||
|
internal static var bannerMigrateToNativeSlidingSyncAppForceLogoutTitle: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_app_force_logout_title") }
|
||||||
/// Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later.
|
/// Your server now supports a new, faster protocol. Log out and log back in to upgrade now. Doing this now will help you avoid a forced logout when the old protocol is removed later.
|
||||||
internal static var bannerMigrateToNativeSlidingSyncDescription: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_description") }
|
internal static var bannerMigrateToNativeSlidingSyncDescription: String { return L10n.tr("Localizable", "banner_migrate_to_native_sliding_sync_description") }
|
||||||
/// Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app.
|
/// Your homeserver no longer supports the old protocol. Please log out and log back in to continue using the app.
|
||||||
|
@ -69,10 +69,8 @@ extension ClientProxyMock {
|
|||||||
ignoreUserReturnValue = .success(())
|
ignoreUserReturnValue = .success(())
|
||||||
unignoreUserReturnValue = .success(())
|
unignoreUserReturnValue = .success(())
|
||||||
|
|
||||||
|
needsSlidingSyncMigration = false
|
||||||
slidingSyncVersion = .native
|
slidingSyncVersion = .native
|
||||||
availableSlidingSyncVersionsClosure = {
|
|
||||||
[]
|
|
||||||
}
|
|
||||||
|
|
||||||
trackRecentlyVisitedRoomReturnValue = .success(())
|
trackRecentlyVisitedRoomReturnValue = .success(())
|
||||||
recentlyVisitedRoomsReturnValue = .success([])
|
recentlyVisitedRoomsReturnValue = .success([])
|
||||||
|
@ -2235,28 +2235,16 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
|||||||
set(value) { underlyingHomeserver = value }
|
set(value) { underlyingHomeserver = value }
|
||||||
}
|
}
|
||||||
var underlyingHomeserver: String!
|
var underlyingHomeserver: String!
|
||||||
|
var needsSlidingSyncMigration: Bool {
|
||||||
|
get { return underlyingNeedsSlidingSyncMigration }
|
||||||
|
set(value) { underlyingNeedsSlidingSyncMigration = value }
|
||||||
|
}
|
||||||
|
var underlyingNeedsSlidingSyncMigration: Bool!
|
||||||
var slidingSyncVersion: SlidingSyncVersion {
|
var slidingSyncVersion: SlidingSyncVersion {
|
||||||
get { return underlyingSlidingSyncVersion }
|
get { return underlyingSlidingSyncVersion }
|
||||||
set(value) { underlyingSlidingSyncVersion = value }
|
set(value) { underlyingSlidingSyncVersion = value }
|
||||||
}
|
}
|
||||||
var underlyingSlidingSyncVersion: SlidingSyncVersion!
|
var underlyingSlidingSyncVersion: SlidingSyncVersion!
|
||||||
var availableSlidingSyncVersionsCallsCount = 0
|
|
||||||
var availableSlidingSyncVersionsCalled: Bool {
|
|
||||||
return availableSlidingSyncVersionsCallsCount > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var availableSlidingSyncVersions: [SlidingSyncVersion] {
|
|
||||||
get async {
|
|
||||||
availableSlidingSyncVersionsCallsCount += 1
|
|
||||||
if let availableSlidingSyncVersionsClosure = availableSlidingSyncVersionsClosure {
|
|
||||||
return await availableSlidingSyncVersionsClosure()
|
|
||||||
} else {
|
|
||||||
return underlyingAvailableSlidingSyncVersions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var underlyingAvailableSlidingSyncVersions: [SlidingSyncVersion]!
|
|
||||||
var availableSlidingSyncVersionsClosure: (() async -> [SlidingSyncVersion])?
|
|
||||||
var canDeactivateAccount: Bool {
|
var canDeactivateAccount: Bool {
|
||||||
get { return underlyingCanDeactivateAccount }
|
get { return underlyingCanDeactivateAccount }
|
||||||
set(value) { underlyingCanDeactivateAccount = value }
|
set(value) { underlyingCanDeactivateAccount = value }
|
||||||
|
@ -27,9 +27,7 @@ extension ClientBuilder {
|
|||||||
|
|
||||||
builder = switch slidingSync {
|
builder = switch slidingSync {
|
||||||
case .restored: builder
|
case .restored: builder
|
||||||
case .discoverProxy: builder.slidingSyncVersionBuilder(versionBuilder: .discoverProxy)
|
case .discover: builder.slidingSyncVersionBuilder(versionBuilder: .discoverNative)
|
||||||
case .discoverNative: builder.slidingSyncVersionBuilder(versionBuilder: .discoverNative)
|
|
||||||
case .forceNative: builder.slidingSyncVersionBuilder(versionBuilder: .native)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if setupEncryption {
|
if setupEncryption {
|
||||||
@ -58,12 +56,8 @@ extension ClientBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ClientBuilderSlidingSync {
|
enum ClientBuilderSlidingSync {
|
||||||
/// The proxy will be supplied when restoring the Session.
|
/// Sliding sync will be configured when restoring the Session.
|
||||||
case restored
|
case restored
|
||||||
/// A proxy must be discovered whilst building the session.
|
/// Sliding sync must be discovered whilst building the session.
|
||||||
case discoverProxy
|
case discover
|
||||||
/// Native sliding sync must be discovered whilst building the session.
|
|
||||||
case discoverNative
|
|
||||||
/// Forces native sliding sync without discovering it.
|
|
||||||
case forceNative
|
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,6 @@ enum HomeScreenViewAction {
|
|||||||
case confirmRecoveryKey
|
case confirmRecoveryKey
|
||||||
case resetEncryption
|
case resetEncryption
|
||||||
case skipRecoveryKeyConfirmation
|
case skipRecoveryKeyConfirmation
|
||||||
case confirmSlidingSyncUpgrade
|
|
||||||
case skipSlidingSyncUpgrade
|
|
||||||
case updateVisibleItemRange(Range<Int>)
|
case updateVisibleItemRange(Range<Int>)
|
||||||
case globalSearch
|
case globalSearch
|
||||||
case markRoomAsUnread(roomIdentifier: String)
|
case markRoomAsUnread(roomIdentifier: String)
|
||||||
@ -86,17 +84,12 @@ enum HomeScreenSecurityBannerMode: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HomeScreenMigrationBannerMode {
|
|
||||||
case none, show, dismissed
|
|
||||||
}
|
|
||||||
|
|
||||||
struct HomeScreenViewState: BindableState {
|
struct HomeScreenViewState: BindableState {
|
||||||
let userID: String
|
let userID: String
|
||||||
var userDisplayName: String?
|
var userDisplayName: String?
|
||||||
var userAvatarURL: URL?
|
var userAvatarURL: URL?
|
||||||
|
|
||||||
var securityBannerMode = HomeScreenSecurityBannerMode.none
|
var securityBannerMode = HomeScreenSecurityBannerMode.none
|
||||||
var slidingSyncMigrationBannerMode = HomeScreenMigrationBannerMode.none
|
|
||||||
|
|
||||||
var requiresExtraAccountSetup = false
|
var requiresExtraAccountSetup = false
|
||||||
|
|
||||||
|
@ -145,11 +145,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
actionsSubject.send(.presentEncryptionResetScreen)
|
actionsSubject.send(.presentEncryptionResetScreen)
|
||||||
case .skipRecoveryKeyConfirmation:
|
case .skipRecoveryKeyConfirmation:
|
||||||
state.securityBannerMode = .dismissed
|
state.securityBannerMode = .dismissed
|
||||||
case .confirmSlidingSyncUpgrade:
|
|
||||||
appSettings.slidingSyncDiscovery = .native
|
|
||||||
actionsSubject.send(.logout)
|
|
||||||
case .skipSlidingSyncUpgrade:
|
|
||||||
state.slidingSyncMigrationBannerMode = .dismissed
|
|
||||||
case .updateVisibleItemRange(let range):
|
case .updateVisibleItemRange(let range):
|
||||||
roomSummaryProvider?.updateVisibleRange(range)
|
roomSummaryProvider?.updateVisibleRange(range)
|
||||||
case .startChat:
|
case .startChat:
|
||||||
@ -307,30 +302,18 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
/// Check whether we can inform the user about potential migrations
|
/// Check whether we can inform the user about potential migrations
|
||||||
/// or have him logout as his proxy is no longer available
|
/// or have him logout as his proxy is no longer available
|
||||||
private func checkSlidingSyncMigration() async {
|
private func checkSlidingSyncMigration() async {
|
||||||
// Not logged in with a proxy, don't need to do anything
|
guard userSession.clientProxy.needsSlidingSyncMigration else {
|
||||||
guard userSession.clientProxy.slidingSyncVersion.isProxy else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let versions = await userSession.clientProxy.availableSlidingSyncVersions
|
// The proxy is no longer supported so a logout is needed.
|
||||||
|
// Delay setting the alert otherwise it automatically gets dismissed. Same as the crashed last run one
|
||||||
// Native not available, nothing we can do
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
guard versions.contains(.native) else {
|
self.state.bindings.alertInfo = AlertInfo(id: UUID(),
|
||||||
return
|
title: L10n.bannerMigrateToNativeSlidingSyncAppForceLogoutTitle,
|
||||||
}
|
primaryButton: .init(title: L10n.bannerMigrateToNativeSlidingSyncAction) { [weak self] in
|
||||||
|
self?.actionsSubject.send(.logoutWithoutConfirmation)
|
||||||
if versions.contains(where: \.isProxy) { // Both available, prompt for migration
|
})
|
||||||
state.slidingSyncMigrationBannerMode = .show
|
|
||||||
} else { // The proxy has been removed and logout is needed
|
|
||||||
// Delay setting the alert otherwise it automatically gets dismissed. Same as the crashed last run one
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
|
||||||
self.state.bindings.alertInfo = AlertInfo(id: UUID(),
|
|
||||||
title: L10n.bannerMigrateToNativeSlidingSyncForceLogoutTitle,
|
|
||||||
primaryButton: .init(title: L10n.bannerMigrateToNativeSlidingSyncAction) { [weak self] in
|
|
||||||
self?.appSettings.slidingSyncDiscovery = .native
|
|
||||||
self?.actionsSubject.send(.logoutWithoutConfirmation)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,14 +443,3 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
message: L10n.errorUnknown)
|
message: L10n.errorUnknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SlidingSyncVersion {
|
|
||||||
var isProxy: Bool {
|
|
||||||
switch self {
|
|
||||||
case .proxy:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -119,17 +119,13 @@ struct HomeScreenContent: View {
|
|||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var topSection: some View {
|
private var topSection: some View {
|
||||||
// An empty VStack causes glitches within the room list
|
// An empty VStack causes glitches within the room list
|
||||||
if context.viewState.shouldShowFilters ||
|
if context.viewState.shouldShowFilters || context.viewState.securityBannerMode.isShown {
|
||||||
context.viewState.securityBannerMode.isShown ||
|
|
||||||
context.viewState.slidingSyncMigrationBannerMode == .show {
|
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
if context.viewState.shouldShowFilters {
|
if context.viewState.shouldShowFilters {
|
||||||
RoomListFiltersView(state: $context.filtersState)
|
RoomListFiltersView(state: $context.filtersState)
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.viewState.slidingSyncMigrationBannerMode == .show {
|
if case let .show(state) = context.viewState.securityBannerMode {
|
||||||
HomeScreenSlidingSyncMigrationBanner(context: context)
|
|
||||||
} else if case let .show(state) = context.viewState.securityBannerMode {
|
|
||||||
HomeScreenRecoveryKeyConfirmationBanner(state: state, context: context)
|
HomeScreenRecoveryKeyConfirmationBanner(state: state, context: context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2024 New Vector Ltd.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
||||||
// Please see LICENSE files in the repository root for full details.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Combine
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct HomeScreenSlidingSyncMigrationBanner: View {
|
|
||||||
var context: HomeScreenViewModel.Context
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
|
||||||
HStack(spacing: 16) {
|
|
||||||
Text(L10n.bannerMigrateToNativeSlidingSyncTitle)
|
|
||||||
.font(.compound.bodyLGSemibold)
|
|
||||||
.foregroundColor(.compound.textPrimary)
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Button {
|
|
||||||
context.send(viewAction: .skipSlidingSyncUpgrade)
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "xmark")
|
|
||||||
.foregroundColor(.compound.iconSecondary)
|
|
||||||
.frame(width: 12, height: 12)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text(L10n.bannerMigrateToNativeSlidingSyncDescription)
|
|
||||||
.font(.compound.bodyMD)
|
|
||||||
.foregroundColor(.compound.textSecondary)
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(L10n.bannerMigrateToNativeSlidingSyncAction) {
|
|
||||||
context.send(viewAction: .confirmSlidingSyncUpgrade)
|
|
||||||
}
|
|
||||||
.frame(maxWidth: .infinity)
|
|
||||||
.buttonStyle(.compound(.primary, size: .medium))
|
|
||||||
}
|
|
||||||
.padding(16)
|
|
||||||
.background(Color.compound.bgSubtleSecondary)
|
|
||||||
.cornerRadius(14)
|
|
||||||
.padding(.horizontal, 16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct HomeScreenSlidingSyncMigrationBanner_Previews: PreviewProvider, TestablePreview {
|
|
||||||
static let viewModel = buildViewModel()
|
|
||||||
|
|
||||||
static var previews: some View {
|
|
||||||
HomeScreenSlidingSyncMigrationBanner(context: viewModel.context)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func buildViewModel() -> HomeScreenViewModel {
|
|
||||||
let clientProxy = ClientProxyMock(.init())
|
|
||||||
|
|
||||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
|
||||||
|
|
||||||
return HomeScreenViewModel(userSession: userSession,
|
|
||||||
analyticsService: ServiceLocator.shared.analytics,
|
|
||||||
appSettings: ServiceLocator.shared.settings,
|
|
||||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,10 +22,9 @@ final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol {
|
|||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(isUsingNativeSlidingSync: Bool) {
|
init() {
|
||||||
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
|
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
|
||||||
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL,
|
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL)
|
||||||
isUsingNativeSlidingSync: isUsingNativeSlidingSync)
|
|
||||||
|
|
||||||
viewModel.actions
|
viewModel.actions
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] action in
|
||||||
|
@ -13,12 +13,7 @@ enum DeveloperOptionsScreenViewModelAction {
|
|||||||
|
|
||||||
struct DeveloperOptionsScreenViewState: BindableState {
|
struct DeveloperOptionsScreenViewState: BindableState {
|
||||||
let elementCallBaseURL: URL
|
let elementCallBaseURL: URL
|
||||||
let isUsingNativeSlidingSync: Bool
|
|
||||||
var bindings: DeveloperOptionsScreenViewStateBindings
|
var bindings: DeveloperOptionsScreenViewStateBindings
|
||||||
|
|
||||||
var slidingSyncFooter: String {
|
|
||||||
"The method used to configure sliding sync when signing in. Changing this setting has no effect until you sign out.\n\nYour current session is using \(isUsingNativeSlidingSync ? "native sliding sync." : "a sliding sync proxy.")"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// periphery: ignore - subscripts are seen as false positive
|
// periphery: ignore - subscripts are seen as false positive
|
||||||
@ -42,7 +37,6 @@ enum DeveloperOptionsScreenViewAction {
|
|||||||
|
|
||||||
protocol DeveloperOptionsProtocol: AnyObject {
|
protocol DeveloperOptionsProtocol: AnyObject {
|
||||||
var logLevel: LogLevel { get set }
|
var logLevel: LogLevel { get set }
|
||||||
var slidingSyncDiscovery: AppSettings.SlidingSyncDiscovery { get set }
|
|
||||||
var publicSearchEnabled: Bool { get set }
|
var publicSearchEnabled: Bool { get set }
|
||||||
var hideUnreadMessagesBadge: Bool { get set }
|
var hideUnreadMessagesBadge: Bool { get set }
|
||||||
var fuzzyRoomListSearchEnabled: Bool { get set }
|
var fuzzyRoomListSearchEnabled: Bool { get set }
|
||||||
|
@ -17,9 +17,9 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve
|
|||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(developerOptions: DeveloperOptionsProtocol, elementCallBaseURL: URL, isUsingNativeSlidingSync: Bool) {
|
init(developerOptions: DeveloperOptionsProtocol, elementCallBaseURL: URL) {
|
||||||
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
||||||
let state = DeveloperOptionsScreenViewState(elementCallBaseURL: elementCallBaseURL, isUsingNativeSlidingSync: isUsingNativeSlidingSync, bindings: bindings)
|
let state = DeveloperOptionsScreenViewState(elementCallBaseURL: elementCallBaseURL, bindings: bindings)
|
||||||
|
|
||||||
super.init(initialViewState: state)
|
super.init(initialViewState: state)
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,6 @@ struct DeveloperOptionsScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section {
|
|
||||||
Picker("Discovery", selection: $context.slidingSyncDiscovery) {
|
|
||||||
Text("Proxy only").tag(AppSettings.SlidingSyncDiscovery.proxy)
|
|
||||||
Text("Automatic").tag(AppSettings.SlidingSyncDiscovery.native)
|
|
||||||
Text("Force Native ⚠️").tag(AppSettings.SlidingSyncDiscovery.forceNative)
|
|
||||||
}
|
|
||||||
} header: {
|
|
||||||
Text("Sliding Sync")
|
|
||||||
} footer: {
|
|
||||||
Text(context.viewState.slidingSyncFooter)
|
|
||||||
}
|
|
||||||
|
|
||||||
Section("Room List") {
|
Section("Room List") {
|
||||||
Toggle(isOn: $context.publicSearchEnabled) {
|
Toggle(isOn: $context.publicSearchEnabled) {
|
||||||
Text("Public search")
|
Text("Public search")
|
||||||
@ -175,8 +163,7 @@ private struct LogLevelConfigurationView: View {
|
|||||||
|
|
||||||
struct DeveloperOptionsScreen_Previews: PreviewProvider {
|
struct DeveloperOptionsScreen_Previews: PreviewProvider {
|
||||||
static let viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
|
static let viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
|
||||||
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL,
|
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL)
|
||||||
isUsingNativeSlidingSync: true)
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
DeveloperOptionsScreen(context: viewModel.context)
|
DeveloperOptionsScreen(context: viewModel.context)
|
||||||
|
@ -27,55 +27,25 @@ struct AuthenticationClientBuilder: AuthenticationClientBuilderProtocol {
|
|||||||
|
|
||||||
/// Builds a Client for login using OIDC or password authentication.
|
/// Builds a Client for login using OIDC or password authentication.
|
||||||
func build(homeserverAddress: String) async throws -> ClientProtocol {
|
func build(homeserverAddress: String) async throws -> ClientProtocol {
|
||||||
if appSettings.slidingSyncDiscovery == .forceNative {
|
try await makeClientBuilder().serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
||||||
return try await makeClientBuilder(slidingSync: .forceNative).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
if appSettings.slidingSyncDiscovery == .native {
|
|
||||||
do {
|
|
||||||
return try await makeClientBuilder(slidingSync: .discoverNative).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
|
||||||
} catch {
|
|
||||||
MXLog.warning("Native sliding sync not available: \(error)")
|
|
||||||
MXLog.info("Falling back to a sliding sync proxy.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return try await makeClientBuilder(slidingSync: .discoverProxy).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a Client, authenticating with the given QR code data.
|
/// Builds a Client, authenticating with the given QR code data.
|
||||||
func buildWithQRCode(qrCodeData: QrCodeData,
|
func buildWithQRCode(qrCodeData: QrCodeData,
|
||||||
oidcConfiguration: OIDCConfigurationProxy,
|
oidcConfiguration: OIDCConfigurationProxy,
|
||||||
progressListener: QrLoginProgressListenerProxy) async throws -> ClientProtocol {
|
progressListener: QrLoginProgressListenerProxy) async throws -> ClientProtocol {
|
||||||
if appSettings.slidingSyncDiscovery == .forceNative {
|
try await makeClientBuilder().buildWithQrCode(qrCodeData: qrCodeData,
|
||||||
return try await makeClientBuilder(slidingSync: .forceNative).buildWithQrCode(qrCodeData: qrCodeData,
|
oidcConfiguration: oidcConfiguration.rustValue,
|
||||||
oidcConfiguration: oidcConfiguration.rustValue,
|
progressListener: progressListener)
|
||||||
progressListener: progressListener)
|
|
||||||
}
|
|
||||||
|
|
||||||
if appSettings.slidingSyncDiscovery == .native {
|
|
||||||
do {
|
|
||||||
return try await makeClientBuilder(slidingSync: .discoverNative).buildWithQrCode(qrCodeData: qrCodeData,
|
|
||||||
oidcConfiguration: oidcConfiguration.rustValue,
|
|
||||||
progressListener: progressListener)
|
|
||||||
} catch HumanQrLoginError.SlidingSyncNotAvailable {
|
|
||||||
MXLog.warning("Native sliding sync not available")
|
|
||||||
MXLog.info("Falling back to a sliding sync proxy.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return try await makeClientBuilder(slidingSync: .discoverProxy).buildWithQrCode(qrCodeData: qrCodeData,
|
|
||||||
oidcConfiguration: oidcConfiguration.rustValue,
|
|
||||||
progressListener: progressListener)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
/// The base builder configuration used for authentication within the app.
|
/// The base builder configuration used for authentication within the app.
|
||||||
private func makeClientBuilder(slidingSync: ClientBuilderSlidingSync) -> ClientBuilder {
|
private func makeClientBuilder() -> ClientBuilder {
|
||||||
ClientBuilder
|
ClientBuilder
|
||||||
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
||||||
slidingSync: slidingSync,
|
slidingSync: .discover,
|
||||||
sessionDelegate: clientSessionDelegate,
|
sessionDelegate: clientSessionDelegate,
|
||||||
appHooks: appHooks,
|
appHooks: appHooks,
|
||||||
enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode,
|
enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode,
|
||||||
|
@ -19,7 +19,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
private let mediaLoader: MediaLoaderProtocol
|
private let mediaLoader: MediaLoaderProtocol
|
||||||
private let clientQueue: DispatchQueue
|
private let clientQueue: DispatchQueue
|
||||||
|
|
||||||
private var roomListService: RoomListService?
|
private var roomListService: RoomListService?
|
||||||
// periphery: ignore - only for retain
|
// periphery: ignore - only for retain
|
||||||
private var roomListStateUpdateTaskHandle: TaskHandle?
|
private var roomListStateUpdateTaskHandle: TaskHandle?
|
||||||
@ -135,6 +135,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
private let sendQueueStatusSubject = CurrentValueSubject<Bool, Never>(false)
|
private let sendQueueStatusSubject = CurrentValueSubject<Bool, Never>(false)
|
||||||
|
|
||||||
init(client: ClientProtocol,
|
init(client: ClientProtocol,
|
||||||
|
needsSlidingSyncMigration: Bool,
|
||||||
networkMonitor: NetworkMonitorProtocol,
|
networkMonitor: NetworkMonitorProtocol,
|
||||||
appSettings: AppSettings) async {
|
appSettings: AppSettings) async {
|
||||||
self.client = client
|
self.client = client
|
||||||
@ -148,6 +149,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings())
|
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings())
|
||||||
|
|
||||||
secureBackupController = SecureBackupController(encryption: client.encryption())
|
secureBackupController = SecureBackupController(encryption: client.encryption())
|
||||||
|
|
||||||
|
self.needsSlidingSyncMigration = needsSlidingSyncMigration
|
||||||
|
|
||||||
delegateHandle = client.setDelegate(delegate: ClientDelegateWrapper { [weak self] isSoftLogout in
|
delegateHandle = client.setDelegate(delegate: ClientDelegateWrapper { [weak self] isSoftLogout in
|
||||||
self?.hasEncounteredAuthError = true
|
self?.hasEncounteredAuthError = true
|
||||||
@ -221,16 +224,11 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
client.homeserver()
|
client.homeserver()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let needsSlidingSyncMigration: Bool
|
||||||
var slidingSyncVersion: SlidingSyncVersion {
|
var slidingSyncVersion: SlidingSyncVersion {
|
||||||
client.slidingSyncVersion()
|
client.slidingSyncVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
var availableSlidingSyncVersions: [SlidingSyncVersion] {
|
|
||||||
get async {
|
|
||||||
await client.availableSlidingSyncVersions()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var canDeactivateAccount: Bool {
|
var canDeactivateAccount: Bool {
|
||||||
client.canDeactivateAccount()
|
client.canDeactivateAccount()
|
||||||
}
|
}
|
||||||
@ -263,6 +261,11 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startSync() {
|
func startSync() {
|
||||||
|
guard !needsSlidingSyncMigration else {
|
||||||
|
MXLog.warning("Ignoring request, this client needs to be migrated to native sliding sync.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard !hasEncounteredAuthError else {
|
guard !hasEncounteredAuthError else {
|
||||||
MXLog.warning("Ignoring request, this client has an unknown token.")
|
MXLog.warning("Ignoring request, this client has an unknown token.")
|
||||||
return
|
return
|
||||||
|
@ -75,9 +75,11 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
|||||||
var deviceID: String? { get }
|
var deviceID: String? { get }
|
||||||
|
|
||||||
var homeserver: String { get }
|
var homeserver: String { get }
|
||||||
|
|
||||||
|
// TODO: This is a temporary value, in the future we should throw a migration error
|
||||||
|
// when decoding a session that contains a sliding sync proxy URL instead of restoring it.
|
||||||
|
var needsSlidingSyncMigration: Bool { get }
|
||||||
var slidingSyncVersion: SlidingSyncVersion { get }
|
var slidingSyncVersion: SlidingSyncVersion { get }
|
||||||
var availableSlidingSyncVersions: [SlidingSyncVersion] { get async }
|
|
||||||
|
|
||||||
var canDeactivateAccount: Bool { get }
|
var canDeactivateAccount: Bool { get }
|
||||||
|
|
||||||
|
@ -112,7 +112,8 @@ class KeychainController: KeychainControllerProtocol {
|
|||||||
let restorationToken = RestorationToken(session: session,
|
let restorationToken = RestorationToken(session: session,
|
||||||
sessionDirectories: oldToken.sessionDirectories,
|
sessionDirectories: oldToken.sessionDirectories,
|
||||||
passphrase: oldToken.passphrase,
|
passphrase: oldToken.passphrase,
|
||||||
pusherNotificationClientIdentifier: oldToken.pusherNotificationClientIdentifier)
|
pusherNotificationClientIdentifier: oldToken.pusherNotificationClientIdentifier,
|
||||||
|
slidingSyncProxyURLString: oldToken.slidingSyncProxyURLString)
|
||||||
setRestorationToken(restorationToken, forUsername: session.userId)
|
setRestorationToken(restorationToken, forUsername: session.userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,13 @@ struct RestorationToken: Equatable {
|
|||||||
let passphrase: String?
|
let passphrase: String?
|
||||||
let pusherNotificationClientIdentifier: String?
|
let pusherNotificationClientIdentifier: String?
|
||||||
|
|
||||||
|
/// The sliding sync proxy URL that was previously encoded in the Session.
|
||||||
|
/// This is temporary to help make a nicer user migration flow. In the future
|
||||||
|
/// we will throw when decoding sessions with a sliding sync proxy URL.
|
||||||
|
let slidingSyncProxyURLString: String?
|
||||||
|
/// Whether the token is for a session that is using the now unsupported sliding sync proxy.
|
||||||
|
var needsSlidingSyncMigration: Bool { slidingSyncProxyURLString != nil }
|
||||||
|
|
||||||
enum CodingKeys: CodingKey {
|
enum CodingKeys: CodingKey {
|
||||||
case session
|
case session
|
||||||
case sessionDirectory
|
case sessionDirectory
|
||||||
@ -27,7 +34,7 @@ extension RestorationToken: Codable {
|
|||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
let session = try container.decode(MatrixRustSDK.Session.self, forKey: .session)
|
let sessionWrapper = try container.decode(SessionWrapper.self, forKey: .session)
|
||||||
let dataDirectory = try container.decodeIfPresent(URL.self, forKey: .sessionDirectory)
|
let dataDirectory = try container.decodeIfPresent(URL.self, forKey: .sessionDirectory)
|
||||||
let cacheDirectory = try container.decodeIfPresent(URL.self, forKey: .cacheDirectory)
|
let cacheDirectory = try container.decodeIfPresent(URL.self, forKey: .cacheDirectory)
|
||||||
|
|
||||||
@ -38,18 +45,19 @@ extension RestorationToken: Codable {
|
|||||||
SessionDirectories(dataDirectory: dataDirectory)
|
SessionDirectories(dataDirectory: dataDirectory)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SessionDirectories(userID: session.userId)
|
SessionDirectories(userID: sessionWrapper.session.userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
self = try .init(session: session,
|
self = try .init(session: sessionWrapper.session,
|
||||||
sessionDirectories: sessionDirectories,
|
sessionDirectories: sessionDirectories,
|
||||||
passphrase: container.decodeIfPresent(String.self, forKey: .passphrase),
|
passphrase: container.decodeIfPresent(String.self, forKey: .passphrase),
|
||||||
pusherNotificationClientIdentifier: container.decodeIfPresent(String.self, forKey: .pusherNotificationClientIdentifier))
|
pusherNotificationClientIdentifier: container.decodeIfPresent(String.self, forKey: .pusherNotificationClientIdentifier),
|
||||||
|
slidingSyncProxyURLString: sessionWrapper.slidingSyncProxyURLString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func encode(to encoder: any Encoder) throws {
|
func encode(to encoder: any Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(session, forKey: .session)
|
try container.encode(SessionWrapper(session: session, slidingSyncProxyURLString: slidingSyncProxyURLString), forKey: .session)
|
||||||
try container.encode(sessionDirectories.dataDirectory, forKey: .sessionDirectory)
|
try container.encode(sessionDirectories.dataDirectory, forKey: .sessionDirectory)
|
||||||
try container.encode(sessionDirectories.cacheDirectory, forKey: .cacheDirectory)
|
try container.encode(sessionDirectories.cacheDirectory, forKey: .cacheDirectory)
|
||||||
try container.encode(passphrase, forKey: .passphrase)
|
try container.encode(passphrase, forKey: .passphrase)
|
||||||
@ -57,17 +65,40 @@ extension RestorationToken: Codable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Temporary struct to smooth the forced migration by keeping a user session.
|
||||||
|
/// In the future we can remove this and throw a migration error when the URL
|
||||||
|
/// is decoded to a non-nil value.
|
||||||
|
private struct SessionWrapper {
|
||||||
|
let session: MatrixRustSDK.Session
|
||||||
|
let slidingSyncProxyURLString: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SessionWrapper: Codable {
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: MatrixRustSDK.Session.CodingKeys.self)
|
||||||
|
session = try Session(from: decoder)
|
||||||
|
|
||||||
|
// TODO: In the future we should decode this in the Session and throw a migration error if it contains a value.
|
||||||
|
slidingSyncProxyURLString = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: MatrixRustSDK.Session.CodingKeys.self)
|
||||||
|
try session.encode(to: encoder)
|
||||||
|
try container.encode(slidingSyncProxyURLString, forKey: .slidingSyncProxy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension MatrixRustSDK.Session: Codable {
|
extension MatrixRustSDK.Session: Codable {
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
let slidingSyncProxy = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)
|
|
||||||
self = try .init(accessToken: container.decode(String.self, forKey: .accessToken),
|
self = try .init(accessToken: container.decode(String.self, forKey: .accessToken),
|
||||||
refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken),
|
refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken),
|
||||||
userId: container.decode(String.self, forKey: .userId),
|
userId: container.decode(String.self, forKey: .userId),
|
||||||
deviceId: container.decode(String.self, forKey: .deviceId),
|
deviceId: container.decode(String.self, forKey: .deviceId),
|
||||||
homeserverUrl: container.decode(String.self, forKey: .homeserverUrl),
|
homeserverUrl: container.decode(String.self, forKey: .homeserverUrl),
|
||||||
oidcData: container.decodeIfPresent(String.self, forKey: .oidcData),
|
oidcData: container.decodeIfPresent(String.self, forKey: .oidcData),
|
||||||
slidingSyncVersion: slidingSyncProxy.map { .proxy(url: $0) } ?? .native)
|
slidingSyncVersion: .native)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -78,17 +109,9 @@ extension MatrixRustSDK.Session: Codable {
|
|||||||
try container.encode(deviceId, forKey: .deviceId)
|
try container.encode(deviceId, forKey: .deviceId)
|
||||||
try container.encode(homeserverUrl, forKey: .homeserverUrl)
|
try container.encode(homeserverUrl, forKey: .homeserverUrl)
|
||||||
try container.encode(oidcData, forKey: .oidcData)
|
try container.encode(oidcData, forKey: .oidcData)
|
||||||
try container.encode(slidingSyncVersion.proxyURL, forKey: .slidingSyncProxy)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case accessToken, refreshToken, userId, deviceId, homeserverUrl, oidcData, slidingSyncProxy
|
case accessToken, refreshToken, userId, deviceId, homeserverUrl, oidcData, slidingSyncProxy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension SlidingSyncVersion {
|
|
||||||
var proxyURL: String? {
|
|
||||||
guard case let .proxy(url) = self else { return nil }
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -64,12 +64,13 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
do {
|
do {
|
||||||
let session = try client.session()
|
let session = try client.session()
|
||||||
let userID = try client.userId()
|
let userID = try client.userId()
|
||||||
let clientProxy = await setupProxyForClient(client)
|
let clientProxy = await setupProxyForClient(client, needsSlidingSyncMigration: false)
|
||||||
|
|
||||||
keychainController.setRestorationToken(RestorationToken(session: session,
|
keychainController.setRestorationToken(RestorationToken(session: session,
|
||||||
sessionDirectories: sessionDirectories,
|
sessionDirectories: sessionDirectories,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
pusherNotificationClientIdentifier: clientProxy.pusherNotificationClientIdentifier),
|
pusherNotificationClientIdentifier: clientProxy.pusherNotificationClientIdentifier,
|
||||||
|
slidingSyncProxyURLString: nil),
|
||||||
forUsername: userID)
|
forUsername: userID)
|
||||||
|
|
||||||
MXLog.info("Set up session for user \(userID) at: \(sessionDirectories)")
|
MXLog.info("Set up session for user \(userID) at: \(sessionDirectories)")
|
||||||
@ -145,15 +146,16 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
|
|
||||||
MXLog.info("Set up session for user \(credentials.userID) at: \(credentials.restorationToken.sessionDirectories)")
|
MXLog.info("Set up session for user \(credentials.userID) at: \(credentials.restorationToken.sessionDirectories)")
|
||||||
|
|
||||||
return await .success(setupProxyForClient(client))
|
return await .success(setupProxyForClient(client, needsSlidingSyncMigration: credentials.restorationToken.needsSlidingSyncMigration))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed restoring login with error: \(error)")
|
MXLog.error("Failed restoring login with error: \(error)")
|
||||||
return .failure(.failedRestoringLogin)
|
return .failure(.failedRestoringLogin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupProxyForClient(_ client: ClientProtocol) async -> ClientProxyProtocol {
|
private func setupProxyForClient(_ client: ClientProtocol, needsSlidingSyncMigration: Bool) async -> ClientProxyProtocol {
|
||||||
await ClientProxy(client: client,
|
await ClientProxy(client: client,
|
||||||
|
needsSlidingSyncMigration: needsSlidingSyncMigration,
|
||||||
networkMonitor: networkMonitor,
|
networkMonitor: networkMonitor,
|
||||||
appSettings: appSettings)
|
appSettings: appSettings)
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/jpsim/Yams",
|
"location" : "https://github.com/jpsim/Yams",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "db9ff235cf800bc657c3ed0961078fc231d0f28b",
|
"revision" : "2688707e563b44d7d87c29ba6c5ca04ce86ae58b",
|
||||||
"version" : "5.2.0"
|
"version" : "5.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -275,12 +275,6 @@ extension PreviewTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_homeScreenSlidingSyncMigrationBanner() async throws {
|
|
||||||
for preview in HomeScreenSlidingSyncMigrationBanner_Previews._allPreviews {
|
|
||||||
try await assertSnapshots(matching: preview)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_homeScreen() async throws {
|
func test_homeScreen() async throws {
|
||||||
for preview in HomeScreen_Previews._allPreviews {
|
for preview in HomeScreen_Previews._allPreviews {
|
||||||
try await assertSnapshots(matching: preview)
|
try await assertSnapshots(matching: preview)
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -30,10 +30,11 @@ class KeychainControllerTests: XCTestCase {
|
|||||||
deviceId: "deviceId",
|
deviceId: "deviceId",
|
||||||
homeserverUrl: "homeserverUrl",
|
homeserverUrl: "homeserverUrl",
|
||||||
oidcData: "oidcData",
|
oidcData: "oidcData",
|
||||||
slidingSyncVersion: .proxy(url: "https://my.sync.proxy")),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectories: .init(),
|
sessionDirectories: .init(),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusherClientID")
|
pusherNotificationClientIdentifier: "pusherClientID",
|
||||||
|
slidingSyncProxyURLString: "https://my.sync.proxy")
|
||||||
keychain.setRestorationToken(restorationToken, forUsername: username)
|
keychain.setRestorationToken(restorationToken, forUsername: username)
|
||||||
|
|
||||||
// Then the restoration token should be stored in the keychain.
|
// Then the restoration token should be stored in the keychain.
|
||||||
@ -49,10 +50,11 @@ class KeychainControllerTests: XCTestCase {
|
|||||||
deviceId: "deviceId",
|
deviceId: "deviceId",
|
||||||
homeserverUrl: "homeserverUrl",
|
homeserverUrl: "homeserverUrl",
|
||||||
oidcData: "oidcData",
|
oidcData: "oidcData",
|
||||||
slidingSyncVersion: .proxy(url: "https://my.sync.proxy")),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectories: .init(),
|
sessionDirectories: .init(),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusherClientID")
|
pusherNotificationClientIdentifier: "pusherClientID",
|
||||||
|
slidingSyncProxyURLString: "https://my.sync.proxy")
|
||||||
keychain.setRestorationToken(restorationToken, forUsername: username)
|
keychain.setRestorationToken(restorationToken, forUsername: username)
|
||||||
XCTAssertEqual(keychain.restorationTokens().count, 1, "The keychain should have 1 restoration token.")
|
XCTAssertEqual(keychain.restorationTokens().count, 1, "The keychain should have 1 restoration token.")
|
||||||
XCTAssertEqual(keychain.restorationTokenForUsername(username), restorationToken, "The initial restoration token should match the value that was stored.")
|
XCTAssertEqual(keychain.restorationTokenForUsername(username), restorationToken, "The initial restoration token should match the value that was stored.")
|
||||||
@ -74,10 +76,11 @@ class KeychainControllerTests: XCTestCase {
|
|||||||
deviceId: "deviceId",
|
deviceId: "deviceId",
|
||||||
homeserverUrl: "homeserverUrl",
|
homeserverUrl: "homeserverUrl",
|
||||||
oidcData: "oidcData",
|
oidcData: "oidcData",
|
||||||
slidingSyncVersion: .proxy(url: "https://my.sync.proxy")),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectories: .init(),
|
sessionDirectories: .init(),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusherClientID")
|
pusherNotificationClientIdentifier: "pusherClientID",
|
||||||
|
slidingSyncProxyURLString: "https://my.sync.proxy")
|
||||||
keychain.setRestorationToken(restorationToken, forUsername: "@test\(index):example.com")
|
keychain.setRestorationToken(restorationToken, forUsername: "@test\(index):example.com")
|
||||||
}
|
}
|
||||||
XCTAssertEqual(keychain.restorationTokens().count, 5, "The keychain should have 5 restoration tokens.")
|
XCTAssertEqual(keychain.restorationTokens().count, 5, "The keychain should have 5 restoration tokens.")
|
||||||
@ -98,10 +101,11 @@ class KeychainControllerTests: XCTestCase {
|
|||||||
deviceId: "deviceId",
|
deviceId: "deviceId",
|
||||||
homeserverUrl: "homeserverUrl",
|
homeserverUrl: "homeserverUrl",
|
||||||
oidcData: "oidcData",
|
oidcData: "oidcData",
|
||||||
slidingSyncVersion: .proxy(url: "https://my.sync.proxy")),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectories: .init(),
|
sessionDirectories: .init(),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusherClientID")
|
pusherNotificationClientIdentifier: "pusherClientID",
|
||||||
|
slidingSyncProxyURLString: "https://my.sync.proxy")
|
||||||
keychain.setRestorationToken(restorationToken, forUsername: "@test\(index):example.com")
|
keychain.setRestorationToken(restorationToken, forUsername: "@test\(index):example.com")
|
||||||
}
|
}
|
||||||
XCTAssertEqual(keychain.restorationTokens().count, 5, "The keychain should have 5 restoration tokens.")
|
XCTAssertEqual(keychain.restorationTokens().count, 5, "The keychain should have 5 restoration tokens.")
|
||||||
@ -133,7 +137,8 @@ class KeychainControllerTests: XCTestCase {
|
|||||||
slidingSyncVersion: .native),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectories: .init(),
|
sessionDirectories: .init(),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusherClientID")
|
pusherNotificationClientIdentifier: "pusherClientID",
|
||||||
|
slidingSyncProxyURLString: nil)
|
||||||
keychain.setRestorationToken(restorationToken, forUsername: username)
|
keychain.setRestorationToken(restorationToken, forUsername: username)
|
||||||
|
|
||||||
// Then decoding the restoration token from the keychain should still work.
|
// Then decoding the restoration token from the keychain should still work.
|
||||||
|
@ -13,38 +13,42 @@ import MatrixRustSDK
|
|||||||
class RestorationTokenTests: XCTestCase {
|
class RestorationTokenTests: XCTestCase {
|
||||||
func testDecodeFromTokenV1() throws {
|
func testDecodeFromTokenV1() throws {
|
||||||
// Given an encoded restoration token in the original format that only contains a Session from the SDK.
|
// Given an encoded restoration token in the original format that only contains a Session from the SDK.
|
||||||
let originalToken = RestorationTokenV1(session: Session(accessToken: "1234",
|
let originalToken = RestorationTokenV1(session: SessionV1(accessToken: "1234",
|
||||||
refreshToken: nil,
|
refreshToken: nil,
|
||||||
userId: "@user:example.com",
|
userId: "@user:example.com",
|
||||||
deviceId: "D3V1C3",
|
deviceId: "D3V1C3",
|
||||||
homeserverUrl: "https://matrix.example.com",
|
homeserverUrl: "https://matrix.example.com",
|
||||||
oidcData: nil,
|
oidcData: nil,
|
||||||
slidingSyncVersion: .proxy(url: "https://sync.example.com")))
|
slidingSyncVersion: .proxy(url: "https://sync.example.com")))
|
||||||
let data = try JSONEncoder().encode(originalToken)
|
let data = try JSONEncoder().encode(originalToken)
|
||||||
|
|
||||||
// When decoding the data to the current restoration token format.
|
// When decoding the data to the current restoration token format.
|
||||||
let decodedToken = try JSONDecoder().decode(RestorationToken.self, from: data)
|
let decodedToken = try JSONDecoder().decode(RestorationToken.self, from: data)
|
||||||
|
|
||||||
// Then the output should be a valid token with the expected store directories.
|
// Then the output should be a valid token with the expected store directories.
|
||||||
XCTAssertEqual(decodedToken.session, originalToken.session, "The session should not be changed.")
|
assertEqual(session: decodedToken.session, originalSession: originalToken.session)
|
||||||
XCTAssertNil(decodedToken.passphrase, "There should not be a passphrase.")
|
XCTAssertNil(decodedToken.passphrase, "There should not be a passphrase.")
|
||||||
XCTAssertNil(decodedToken.pusherNotificationClientIdentifier, "There should not be a push notification client ID.")
|
XCTAssertNil(decodedToken.pusherNotificationClientIdentifier, "There should not be a push notification client ID.")
|
||||||
XCTAssertEqual(decodedToken.sessionDirectories.dataDirectory, .sessionsBaseDirectory.appending(component: "@user_example.com"),
|
XCTAssertEqual(decodedToken.sessionDirectories.dataDirectory, .sessionsBaseDirectory.appending(component: "@user_example.com"),
|
||||||
"The session directory should match the original location set by the Rust SDK from our base directory.")
|
"The session directory should match the original location set by the Rust SDK from our base directory.")
|
||||||
XCTAssertEqual(decodedToken.sessionDirectories.cacheDirectory, .sessionCachesBaseDirectory.appending(component: "@user_example.com"),
|
XCTAssertEqual(decodedToken.sessionDirectories.cacheDirectory, .sessionCachesBaseDirectory.appending(component: "@user_example.com"),
|
||||||
"The cache directory should be derived from the session directory but in the caches directory.")
|
"The cache directory should be derived from the session directory but in the caches directory.")
|
||||||
|
|
||||||
|
XCTAssertEqual(decodedToken.slidingSyncProxyURLString, "https://sync.example.com",
|
||||||
|
"The original sliding sync URL should be preserved in order to trigger the migration prompt.")
|
||||||
|
XCTAssertTrue(decodedToken.needsSlidingSyncMigration, "The migration flag should be set to true.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDecodeFromTokenV4() throws {
|
func testDecodeFromTokenV4() throws {
|
||||||
// Given an encoded restoration token in the 4th format that contains a stored session directory.
|
// Given an encoded restoration token in the 4th format that contains a stored session directory.
|
||||||
let sessionDirectoryName = UUID().uuidString
|
let sessionDirectoryName = UUID().uuidString
|
||||||
let originalToken = RestorationTokenV4(session: Session(accessToken: "1234",
|
let originalToken = RestorationTokenV4(session: SessionV1(accessToken: "1234",
|
||||||
refreshToken: "5678",
|
refreshToken: "5678",
|
||||||
userId: "@user:example.com",
|
userId: "@user:example.com",
|
||||||
deviceId: "D3V1C3",
|
deviceId: "D3V1C3",
|
||||||
homeserverUrl: "https://matrix.example.com",
|
homeserverUrl: "https://matrix.example.com",
|
||||||
oidcData: "data-from-mas",
|
oidcData: "data-from-mas",
|
||||||
slidingSyncVersion: .proxy(url: "https://sync.example.com")),
|
slidingSyncVersion: .proxy(url: "https://sync.example.com")),
|
||||||
sessionDirectory: .sessionsBaseDirectory.appending(component: sessionDirectoryName),
|
sessionDirectory: .sessionsBaseDirectory.appending(component: sessionDirectoryName),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusher-identifier")
|
pusherNotificationClientIdentifier: "pusher-identifier")
|
||||||
@ -54,7 +58,7 @@ class RestorationTokenTests: XCTestCase {
|
|||||||
let decodedToken = try JSONDecoder().decode(RestorationToken.self, from: data)
|
let decodedToken = try JSONDecoder().decode(RestorationToken.self, from: data)
|
||||||
|
|
||||||
// Then the output should be a valid token with the expected store directories.
|
// Then the output should be a valid token with the expected store directories.
|
||||||
XCTAssertEqual(decodedToken.session, originalToken.session, "The session should not be changed.")
|
assertEqual(session: decodedToken.session, originalSession: originalToken.session)
|
||||||
XCTAssertEqual(decodedToken.passphrase, originalToken.passphrase, "The passphrase should not be changed.")
|
XCTAssertEqual(decodedToken.passphrase, originalToken.passphrase, "The passphrase should not be changed.")
|
||||||
XCTAssertEqual(decodedToken.pusherNotificationClientIdentifier, originalToken.pusherNotificationClientIdentifier,
|
XCTAssertEqual(decodedToken.pusherNotificationClientIdentifier, originalToken.pusherNotificationClientIdentifier,
|
||||||
"The push notification client identifier should not be changed.")
|
"The push notification client identifier should not be changed.")
|
||||||
@ -62,18 +66,22 @@ class RestorationTokenTests: XCTestCase {
|
|||||||
"The session directory should not be changed.")
|
"The session directory should not be changed.")
|
||||||
XCTAssertEqual(decodedToken.sessionDirectories.cacheDirectory, .sessionCachesBaseDirectory.appending(component: sessionDirectoryName),
|
XCTAssertEqual(decodedToken.sessionDirectories.cacheDirectory, .sessionCachesBaseDirectory.appending(component: sessionDirectoryName),
|
||||||
"The cache directory should be derived from the session directory but in the caches directory.")
|
"The cache directory should be derived from the session directory but in the caches directory.")
|
||||||
|
|
||||||
|
XCTAssertEqual(decodedToken.slidingSyncProxyURLString, "https://sync.example.com",
|
||||||
|
"The original sliding sync URL should be preserved in order to trigger the migration prompt.")
|
||||||
|
XCTAssertTrue(decodedToken.needsSlidingSyncMigration, "The migration flag should be set to true.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDecodeFromTokenV5() throws {
|
func testDecodeFromTokenV5() throws {
|
||||||
// Given an encoded restoration token in the 5th format that contains separate directories for session data and caches.
|
// Given an encoded restoration token in the 5th format that contains separate directories for session data and caches.
|
||||||
let sessionDirectoryName = UUID().uuidString
|
let sessionDirectoryName = UUID().uuidString
|
||||||
let originalToken = RestorationTokenV5(session: Session(accessToken: "1234",
|
let originalToken = RestorationTokenV5(session: SessionV1(accessToken: "1234",
|
||||||
refreshToken: "5678",
|
refreshToken: "5678",
|
||||||
userId: "@user:example.com",
|
userId: "@user:example.com",
|
||||||
deviceId: "D3V1C3",
|
deviceId: "D3V1C3",
|
||||||
homeserverUrl: "https://matrix.example.com",
|
homeserverUrl: "https://matrix.example.com",
|
||||||
oidcData: "data-from-mas",
|
oidcData: "data-from-mas",
|
||||||
slidingSyncVersion: .native),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectory: .sessionsBaseDirectory.appending(component: sessionDirectoryName),
|
sessionDirectory: .sessionsBaseDirectory.appending(component: sessionDirectoryName),
|
||||||
cacheDirectory: .sessionCachesBaseDirectory.appending(component: sessionDirectoryName),
|
cacheDirectory: .sessionCachesBaseDirectory.appending(component: sessionDirectoryName),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
@ -84,7 +92,7 @@ class RestorationTokenTests: XCTestCase {
|
|||||||
let decodedToken = try JSONDecoder().decode(RestorationToken.self, from: data)
|
let decodedToken = try JSONDecoder().decode(RestorationToken.self, from: data)
|
||||||
|
|
||||||
// Then the output should be a valid token.
|
// Then the output should be a valid token.
|
||||||
XCTAssertEqual(decodedToken.session, originalToken.session, "The session should not be changed.")
|
assertEqual(session: decodedToken.session, originalSession: originalToken.session)
|
||||||
XCTAssertEqual(decodedToken.passphrase, originalToken.passphrase, "The passphrase should not be changed.")
|
XCTAssertEqual(decodedToken.passphrase, originalToken.passphrase, "The passphrase should not be changed.")
|
||||||
XCTAssertEqual(decodedToken.pusherNotificationClientIdentifier, originalToken.pusherNotificationClientIdentifier,
|
XCTAssertEqual(decodedToken.pusherNotificationClientIdentifier, originalToken.pusherNotificationClientIdentifier,
|
||||||
"The push notification client identifier should not be changed.")
|
"The push notification client identifier should not be changed.")
|
||||||
@ -92,6 +100,9 @@ class RestorationTokenTests: XCTestCase {
|
|||||||
"The session directory should not be changed.")
|
"The session directory should not be changed.")
|
||||||
XCTAssertEqual(decodedToken.sessionDirectories.cacheDirectory, originalToken.cacheDirectory,
|
XCTAssertEqual(decodedToken.sessionDirectories.cacheDirectory, originalToken.cacheDirectory,
|
||||||
"The cache directory should not be changed.")
|
"The cache directory should not be changed.")
|
||||||
|
|
||||||
|
XCTAssertNil(decodedToken.slidingSyncProxyURLString, "No sliding sync proxy URL should be decoded for native sliding sync.")
|
||||||
|
XCTAssertFalse(decodedToken.needsSlidingSyncMigration, "The migration flag should not be set.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDecodeFromCurrentToken() throws {
|
func testDecodeFromCurrentToken() throws {
|
||||||
@ -105,7 +116,8 @@ class RestorationTokenTests: XCTestCase {
|
|||||||
slidingSyncVersion: .native),
|
slidingSyncVersion: .native),
|
||||||
sessionDirectories: .init(),
|
sessionDirectories: .init(),
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
pusherNotificationClientIdentifier: "pusher-identifier")
|
pusherNotificationClientIdentifier: "pusher-identifier",
|
||||||
|
slidingSyncProxyURLString: nil)
|
||||||
let data = try JSONEncoder().encode(originalToken)
|
let data = try JSONEncoder().encode(originalToken)
|
||||||
|
|
||||||
// When decoding the data.
|
// When decoding the data.
|
||||||
@ -114,23 +126,86 @@ class RestorationTokenTests: XCTestCase {
|
|||||||
// Then the output should be a valid token.
|
// Then the output should be a valid token.
|
||||||
XCTAssertEqual(decodedToken, originalToken, "The token should remain identical.")
|
XCTAssertEqual(decodedToken, originalToken, "The token should remain identical.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertEqual(session: Session, originalSession: SessionV1) {
|
||||||
|
XCTAssertEqual(session.accessToken, originalSession.accessToken, "The access token should not be changed.")
|
||||||
|
XCTAssertEqual(session.refreshToken, originalSession.refreshToken, "The refresh token should not be changed.")
|
||||||
|
XCTAssertEqual(session.userId, originalSession.userId, "The user ID should not be changed.")
|
||||||
|
XCTAssertEqual(session.deviceId, originalSession.deviceId, "The device ID should not be changed.")
|
||||||
|
XCTAssertEqual(session.homeserverUrl, originalSession.homeserverUrl, "The homeserver URL should not be changed.")
|
||||||
|
XCTAssertEqual(session.oidcData, originalSession.oidcData, "The OIDC data should not be changed.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Token formats
|
||||||
|
|
||||||
struct RestorationTokenV1: Equatable, Codable {
|
struct RestorationTokenV1: Equatable, Codable {
|
||||||
let session: MatrixRustSDK.Session
|
let session: SessionV1
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RestorationTokenV4: Equatable, Codable {
|
struct RestorationTokenV4: Equatable, Codable {
|
||||||
let session: MatrixRustSDK.Session
|
let session: SessionV1
|
||||||
let sessionDirectory: URL
|
let sessionDirectory: URL
|
||||||
let passphrase: String?
|
let passphrase: String?
|
||||||
let pusherNotificationClientIdentifier: String?
|
let pusherNotificationClientIdentifier: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RestorationTokenV5: Equatable, Codable {
|
struct RestorationTokenV5: Equatable, Codable {
|
||||||
let session: MatrixRustSDK.Session
|
let session: SessionV1
|
||||||
let sessionDirectory: URL
|
let sessionDirectory: URL
|
||||||
let cacheDirectory: URL
|
let cacheDirectory: URL
|
||||||
let passphrase: String?
|
let passphrase: String?
|
||||||
let pusherNotificationClientIdentifier: String?
|
let pusherNotificationClientIdentifier: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Session formats
|
||||||
|
|
||||||
|
struct SessionV1: Equatable {
|
||||||
|
var accessToken: String
|
||||||
|
var refreshToken: String?
|
||||||
|
var userId: String
|
||||||
|
var deviceId: String
|
||||||
|
var homeserverUrl: String
|
||||||
|
var oidcData: String?
|
||||||
|
var slidingSyncVersion: SlidingSyncVersionV1
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SlidingSyncVersionV1: Equatable {
|
||||||
|
case none
|
||||||
|
case proxy(url: String)
|
||||||
|
case native
|
||||||
|
|
||||||
|
var proxyURL: String? {
|
||||||
|
guard case let .proxy(url) = self else { return nil }
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SessionV1: Codable {
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
let slidingSyncProxy = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)
|
||||||
|
self = try .init(accessToken: container.decode(String.self, forKey: .accessToken),
|
||||||
|
refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken),
|
||||||
|
userId: container.decode(String.self, forKey: .userId),
|
||||||
|
deviceId: container.decode(String.self, forKey: .deviceId),
|
||||||
|
homeserverUrl: container.decode(String.self, forKey: .homeserverUrl),
|
||||||
|
oidcData: container.decodeIfPresent(String.self, forKey: .oidcData),
|
||||||
|
slidingSyncVersion: slidingSyncProxy.map { .proxy(url: $0) } ?? .native)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(accessToken, forKey: .accessToken)
|
||||||
|
try container.encode(refreshToken, forKey: .refreshToken)
|
||||||
|
try container.encode(userId, forKey: .userId)
|
||||||
|
try container.encode(deviceId, forKey: .deviceId)
|
||||||
|
try container.encode(homeserverUrl, forKey: .homeserverUrl)
|
||||||
|
try container.encode(oidcData, forKey: .oidcData)
|
||||||
|
try container.encode(slidingSyncVersion.proxyURL, forKey: .slidingSyncProxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case accessToken, refreshToken, userId, deviceId, homeserverUrl, oidcData, slidingSyncProxy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -61,7 +61,7 @@ packages:
|
|||||||
# Element/Matrix dependencies
|
# Element/Matrix dependencies
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/element-hq/matrix-rust-components-swift
|
url: https://github.com/element-hq/matrix-rust-components-swift
|
||||||
exactVersion: 25.02.11
|
exactVersion: 25.02.17
|
||||||
# path: ../matrix-rust-sdk
|
# path: ../matrix-rust-sdk
|
||||||
Compound:
|
Compound:
|
||||||
url: https://github.com/element-hq/compound-ios
|
url: https://github.com/element-hq/compound-ios
|
||||||
|
Loading…
x
Reference in New Issue
Block a user