mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Merge the AuthenticationService with the QRCodeLoginService. (#4323)
* Merge the AuthenticationServer with the QRCodeLoginService. * Merge AuthenticationClientBuilderFactory and AuthenticationClientBuilder into AuthenticationClientFactory The separation is no longer needed now that password/OIDC login and QR code login have a similar API shape.
This commit is contained in:
@@ -96,7 +96,6 @@
|
|||||||
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
||||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
||||||
0EEC614342F823E5BF966C2C /* AppLockTimerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */; };
|
0EEC614342F823E5BF966C2C /* AppLockTimerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */; };
|
||||||
0F4709282FCCFBEFED427B8A /* AuthenticationClientBuilderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4760CE2128FBC217304272AB /* AuthenticationClientBuilderMock.swift */; };
|
|
||||||
0F6C8033FA60CFD36F7CA205 /* AppLockSetupPINScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */; };
|
0F6C8033FA60CFD36F7CA205 /* AppLockSetupPINScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */; };
|
||||||
0F81DEE3E02A6549B20DF09A /* DeactivateAccountScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633924B26ACCD29C18BEF4E8 /* DeactivateAccountScreenViewModelProtocol.swift */; };
|
0F81DEE3E02A6549B20DF09A /* DeactivateAccountScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633924B26ACCD29C18BEF4E8 /* DeactivateAccountScreenViewModelProtocol.swift */; };
|
||||||
0FA03F5A33C0857231B32B44 /* ReportRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FDB0B87D925AE830E32621 /* ReportRoomScreenViewModel.swift */; };
|
0FA03F5A33C0857231B32B44 /* ReportRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FDB0B87D925AE830E32621 /* ReportRoomScreenViewModel.swift */; };
|
||||||
@@ -184,7 +183,6 @@
|
|||||||
1FEC0A4EC6E6DF693C16B32A /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CEBCB9676FCD1D0F13188DD /* StringTests.swift */; };
|
1FEC0A4EC6E6DF693C16B32A /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CEBCB9676FCD1D0F13188DD /* StringTests.swift */; };
|
||||||
208C19811613F9A10F8A7B75 /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
208C19811613F9A10F8A7B75 /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
||||||
20C16A3F718802B0E4A19C83 /* URLComponentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76310030C831D4610A705603 /* URLComponentsTests.swift */; };
|
20C16A3F718802B0E4A19C83 /* URLComponentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76310030C831D4610A705603 /* URLComponentsTests.swift */; };
|
||||||
210DB40676DF2A23E69C2D06 /* AuthenticationClientBuilderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B655A536341D2695158C6664 /* AuthenticationClientBuilderFactory.swift */; };
|
|
||||||
2118E35D312951B241067BD5 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345172AD4377E83A44BD864F /* MessageComposerTextField.swift */; };
|
2118E35D312951B241067BD5 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345172AD4377E83A44BD864F /* MessageComposerTextField.swift */; };
|
||||||
211B5F524E851178EE549417 /* CurrentValuePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */; };
|
211B5F524E851178EE549417 /* CurrentValuePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */; };
|
||||||
21813AF91CFC6F3E3896DB53 /* AppLockSetupBiometricsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10F130DF775CE6BC51A4E392 /* AppLockSetupBiometricsScreenModels.swift */; };
|
21813AF91CFC6F3E3896DB53 /* AppLockSetupBiometricsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10F130DF775CE6BC51A4E392 /* AppLockSetupBiometricsScreenModels.swift */; };
|
||||||
@@ -727,7 +725,6 @@
|
|||||||
89DF67AECBF9D0EE0DDB7737 /* Tracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B574805B9812C111D6215D /* Tracing.swift */; };
|
89DF67AECBF9D0EE0DDB7737 /* Tracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B574805B9812C111D6215D /* Tracing.swift */; };
|
||||||
8A0BD60CA4A6004DB06B5403 /* MediaUploadingPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */; };
|
8A0BD60CA4A6004DB06B5403 /* MediaUploadingPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */; };
|
||||||
8A5064CAC8E5F3B18645621D /* CallNotificationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6E082B0507FB28F966516A /* CallNotificationRoomTimelineView.swift */; };
|
8A5064CAC8E5F3B18645621D /* CallNotificationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6E082B0507FB28F966516A /* CallNotificationRoomTimelineView.swift */; };
|
||||||
8A6CB15C8FC68F557750BF54 /* AuthenticationClientBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */; };
|
|
||||||
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */; };
|
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */; };
|
||||||
8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645E027C112740573D27765C /* SecureBackupRecoveryKeyScreenModels.swift */; };
|
8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645E027C112740573D27765C /* SecureBackupRecoveryKeyScreenModels.swift */; };
|
||||||
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; };
|
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; };
|
||||||
@@ -913,6 +910,7 @@
|
|||||||
AC90434798E7894370E80E66 /* SecureBackupScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79BB714D28C9F588DD69353 /* SecureBackupScreenViewModelProtocol.swift */; };
|
AC90434798E7894370E80E66 /* SecureBackupScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79BB714D28C9F588DD69353 /* SecureBackupScreenViewModelProtocol.swift */; };
|
||||||
AD2A81B65A9F6163012086F1 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; };
|
AD2A81B65A9F6163012086F1 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; };
|
||||||
AD55E245FE686D7DB4C86406 /* RoomTimelineItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90F2F8998E5632668B0AD848 /* RoomTimelineItemView.swift */; };
|
AD55E245FE686D7DB4C86406 /* RoomTimelineItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90F2F8998E5632668B0AD848 /* RoomTimelineItemView.swift */; };
|
||||||
|
AE066FC93E7B707C826B335A /* AuthenticationClientFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD19057FDB154A44335CE62 /* AuthenticationClientFactory.swift */; };
|
||||||
AE07F215EBC2B9CBF17AA54B /* TimelineItemMenuAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F1C3CBBC62C566DDF5E84C1 /* TimelineItemMenuAction.swift */; };
|
AE07F215EBC2B9CBF17AA54B /* TimelineItemMenuAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F1C3CBBC62C566DDF5E84C1 /* TimelineItemMenuAction.swift */; };
|
||||||
AE1160076F663BF14E0E893A /* EffectsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4548A9BDE5CB3AB864BCA9F /* EffectsView.swift */; };
|
AE1160076F663BF14E0E893A /* EffectsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4548A9BDE5CB3AB864BCA9F /* EffectsView.swift */; };
|
||||||
AE1A73B24D63DA3D63DC4EE3 /* SessionVerificationControllerProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */; };
|
AE1A73B24D63DA3D63DC4EE3 /* SessionVerificationControllerProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */; };
|
||||||
@@ -977,7 +975,6 @@
|
|||||||
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; };
|
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; };
|
||||||
BA48D6AFF6421D199148C0A1 /* KnockRequestsListScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9AC2CC94FA06F728883B694 /* KnockRequestsListScreenViewModelTests.swift */; };
|
BA48D6AFF6421D199148C0A1 /* KnockRequestsListScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9AC2CC94FA06F728883B694 /* KnockRequestsListScreenViewModelTests.swift */; };
|
||||||
BA4C9049BC96DED3A2F3B82E /* RoomNotificationSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03DD998E523D4EC93C7ED703 /* RoomNotificationSettingsScreenViewModelProtocol.swift */; };
|
BA4C9049BC96DED3A2F3B82E /* RoomNotificationSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03DD998E523D4EC93C7ED703 /* RoomNotificationSettingsScreenViewModelProtocol.swift */; };
|
||||||
BB04B1D8E7401C90506D401E /* QRCodeLoginServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536C0E2178949B290776EA4E /* QRCodeLoginServiceProtocol.swift */; };
|
|
||||||
BB6BF528BC7F5B87E08C4F18 /* CameraPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */; };
|
BB6BF528BC7F5B87E08C4F18 /* CameraPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */; };
|
||||||
BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */; };
|
BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */; };
|
||||||
BB9B800C6094E34860E89DC5 /* AppLockSetupBiometricsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CCF9A924521DECA44778C4 /* AppLockSetupBiometricsScreen.swift */; };
|
BB9B800C6094E34860E89DC5 /* AppLockSetupBiometricsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CCF9A924521DECA44778C4 /* AppLockSetupBiometricsScreen.swift */; };
|
||||||
@@ -1041,7 +1038,6 @@
|
|||||||
C85C7A201E4CFDA477ACEBEB /* AppLockSetupSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8610C1D21565C950BCA6A454 /* AppLockSetupSettingsScreenViewModelProtocol.swift */; };
|
C85C7A201E4CFDA477ACEBEB /* AppLockSetupSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8610C1D21565C950BCA6A454 /* AppLockSetupSettingsScreenViewModelProtocol.swift */; };
|
||||||
C8A9C595038AFA2D707AC8C1 /* NotificationPermissionsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20E69F67D2A70ABD08CA6D54 /* NotificationPermissionsScreenViewModelProtocol.swift */; };
|
C8A9C595038AFA2D707AC8C1 /* NotificationPermissionsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20E69F67D2A70ABD08CA6D54 /* NotificationPermissionsScreenViewModelProtocol.swift */; };
|
||||||
C8BD80891BAD688EF2C15CDB /* MediaUploadPreviewScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74DD0855F2F76D47E5555082 /* MediaUploadPreviewScreenCoordinator.swift */; };
|
C8BD80891BAD688EF2C15CDB /* MediaUploadPreviewScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74DD0855F2F76D47E5555082 /* MediaUploadPreviewScreenCoordinator.swift */; };
|
||||||
C8C7AF33AADF88B306CD2695 /* QRCodeLoginService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4427AF4B7FB7EF3E3D424C7 /* QRCodeLoginService.swift */; };
|
|
||||||
C8E0FA0FF2CD6613264FA6B9 /* MessageForwardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFEA446F8618DBA79A9239CC /* MessageForwardingScreen.swift */; };
|
C8E0FA0FF2CD6613264FA6B9 /* MessageForwardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFEA446F8618DBA79A9239CC /* MessageForwardingScreen.swift */; };
|
||||||
C8E1E4E06B7C7A3A8246FC9B /* MediaEventsTimelineScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8512B82404B1751D0BCC82D2 /* MediaEventsTimelineScreenCoordinator.swift */; };
|
C8E1E4E06B7C7A3A8246FC9B /* MediaEventsTimelineScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8512B82404B1751D0BCC82D2 /* MediaEventsTimelineScreenCoordinator.swift */; };
|
||||||
C915347779B3C7FDD073A87A /* AVMetadataMachineReadableCodeObjectExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E1FF0DFBB3768F79FDBF6D /* AVMetadataMachineReadableCodeObjectExtensionsTest.swift */; };
|
C915347779B3C7FDD073A87A /* AVMetadataMachineReadableCodeObjectExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E1FF0DFBB3768F79FDBF6D /* AVMetadataMachineReadableCodeObjectExtensionsTest.swift */; };
|
||||||
@@ -1472,7 +1468,6 @@
|
|||||||
0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitedRoomProxy.swift; sourceTree = "<group>"; };
|
0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitedRoomProxy.swift; sourceTree = "<group>"; };
|
||||||
0EE9EAF0309A2A1D67D8FAF5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = sv.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
0EE9EAF0309A2A1D67D8FAF5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = sv.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPicker.swift; sourceTree = "<group>"; };
|
0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPicker.swift; sourceTree = "<group>"; };
|
||||||
0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilder.swift; sourceTree = "<group>"; };
|
|
||||||
0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenModels.swift; sourceTree = "<group>"; };
|
0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
0F71A54CB96DAA1E72C6541D /* AuthenticationStartScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModel.swift; sourceTree = "<group>"; };
|
0F71A54CB96DAA1E72C6541D /* AuthenticationStartScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentityProxyProtocol.swift; sourceTree = "<group>"; };
|
0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentityProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
@@ -1776,7 +1771,6 @@
|
|||||||
471BB7276C97AF60B3A5463B /* RoomDirectorySearchProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxy.swift; sourceTree = "<group>"; };
|
471BB7276C97AF60B3A5463B /* RoomDirectorySearchProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxy.swift; sourceTree = "<group>"; };
|
||||||
475D47D0BFE961B02BAC5D49 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = id; path = id.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
475D47D0BFE961B02BAC5D49 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = id; path = id.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
475EB595D7527E9A8A14043E /* uz */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uz; path = uz.lproj/Localizable.strings; sourceTree = "<group>"; };
|
475EB595D7527E9A8A14043E /* uz */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uz; path = uz.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
4760CE2128FBC217304272AB /* AuthenticationClientBuilderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilderMock.swift; sourceTree = "<group>"; };
|
|
||||||
47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = "<group>"; };
|
47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = "<group>"; };
|
||||||
47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
||||||
47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = "<group>"; };
|
47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -1828,7 +1822,6 @@
|
|||||||
5327E3B3C58BEB0E65F4CF98 /* Observable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
|
5327E3B3C58BEB0E65F4CF98 /* Observable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observable.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>"; };
|
||||||
5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
536C0E2178949B290776EA4E /* QRCodeLoginServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginServiceProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||||
53F41CEAAE2BB4E74CDC2278 /* TimelineMediaPreviewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewViewModel.swift; sourceTree = "<group>"; };
|
53F41CEAAE2BB4E74CDC2278 /* TimelineMediaPreviewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewViewModel.swift; sourceTree = "<group>"; };
|
||||||
53FD6D3D38F556CEAA280C58 /* test_animated_image.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = test_animated_image.gif; sourceTree = "<group>"; };
|
53FD6D3D38F556CEAA280C58 /* test_animated_image.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = test_animated_image.gif; sourceTree = "<group>"; };
|
||||||
@@ -2301,7 +2294,6 @@
|
|||||||
B40233F2989AD49906BB310D /* RoomPollsHistoryScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenViewModelTests.swift; sourceTree = "<group>"; };
|
B40233F2989AD49906BB310D /* RoomPollsHistoryScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
B410B32B72C90BF94E481F33 /* AppLockSetupPINScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenModels.swift; sourceTree = "<group>"; };
|
B410B32B72C90BF94E481F33 /* AppLockSetupPINScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenModels.swift; sourceTree = "<group>"; };
|
||||||
B43456E73F8A2D52B69B9FB9 /* TemplateScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenViewModel.swift; sourceTree = "<group>"; };
|
B43456E73F8A2D52B69B9FB9 /* TemplateScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
B4427AF4B7FB7EF3E3D424C7 /* QRCodeLoginService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginService.swift; sourceTree = "<group>"; };
|
|
||||||
B4AE42C19EDE64B7CB7BE4D0 /* SecurityAndPrivacyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreen.swift; sourceTree = "<group>"; };
|
B4AE42C19EDE64B7CB7BE4D0 /* SecurityAndPrivacyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreen.swift; sourceTree = "<group>"; };
|
||||||
B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; };
|
B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; };
|
||||||
B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyProtocol.swift; sourceTree = "<group>"; };
|
B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
@@ -2310,7 +2302,6 @@
|
|||||||
B5D829FD8958376614504B18 /* TargetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetConfiguration.swift; sourceTree = "<group>"; };
|
B5D829FD8958376614504B18 /* TargetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetConfiguration.swift; sourceTree = "<group>"; };
|
||||||
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = "<group>"; };
|
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = "<group>"; };
|
||||||
B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetails.swift; sourceTree = "<group>"; };
|
B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetails.swift; sourceTree = "<group>"; };
|
||||||
B655A536341D2695158C6664 /* AuthenticationClientBuilderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilderFactory.swift; sourceTree = "<group>"; };
|
|
||||||
B65DDCF8E41759890355ACBC /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
B65DDCF8E41759890355ACBC /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
B68B31232312AFC844440BFE /* DeclineAndBlockScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeclineAndBlockScreenModels.swift; sourceTree = "<group>"; };
|
B68B31232312AFC844440BFE /* DeclineAndBlockScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeclineAndBlockScreenModels.swift; sourceTree = "<group>"; };
|
||||||
B69AEA8755382DB34892FB7B /* ThreadTimelineScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadTimelineScreenModels.swift; sourceTree = "<group>"; };
|
B69AEA8755382DB34892FB7B /* ThreadTimelineScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadTimelineScreenModels.swift; sourceTree = "<group>"; };
|
||||||
@@ -2575,6 +2566,7 @@
|
|||||||
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = "<group>"; };
|
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = "<group>"; };
|
||||||
EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenModels.swift; sourceTree = "<group>"; };
|
EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenModels.swift; sourceTree = "<group>"; };
|
||||||
EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
|
EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
EBD19057FDB154A44335CE62 /* AuthenticationClientFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientFactory.swift; sourceTree = "<group>"; };
|
||||||
EBD21AF0131AA38FF9534FAD /* EditRoomAddressScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreenModels.swift; sourceTree = "<group>"; };
|
EBD21AF0131AA38FF9534FAD /* EditRoomAddressScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreenModels.swift; sourceTree = "<group>"; };
|
||||||
EBEB8D9F4940E161B18FE4BC /* UITestsNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsNotificationCenter.swift; sourceTree = "<group>"; };
|
EBEB8D9F4940E161B18FE4BC /* UITestsNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsNotificationCenter.swift; sourceTree = "<group>"; };
|
||||||
EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelTests.swift; sourceTree = "<group>"; };
|
EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -2885,7 +2877,6 @@
|
|||||||
6DE13A7AE6587B079F4049D7 /* Notification */,
|
6DE13A7AE6587B079F4049D7 /* Notification */,
|
||||||
114DC16B28140F885FD833E2 /* NotificationSettings */,
|
114DC16B28140F885FD833E2 /* NotificationSettings */,
|
||||||
599DFFE0805B08454E40D64A /* Polls */,
|
599DFFE0805B08454E40D64A /* Polls */,
|
||||||
70CC0CDA4AFDF8299C56ADE7 /* QRCode */,
|
|
||||||
40E6246F03D1FE377BC5D963 /* Room */,
|
40E6246F03D1FE377BC5D963 /* Room */,
|
||||||
4FFDC8D1A752384B4C6EB0EB /* RoomDirectorySearch */,
|
4FFDC8D1A752384B4C6EB0EB /* RoomDirectorySearch */,
|
||||||
BDCEF7C3BF6D09F5611CFC8B /* SecureBackup */,
|
BDCEF7C3BF6D09F5611CFC8B /* SecureBackup */,
|
||||||
@@ -3334,7 +3325,6 @@
|
|||||||
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */,
|
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */,
|
||||||
3BAC027034248429A438886B /* AppMediatorMock.swift */,
|
3BAC027034248429A438886B /* AppMediatorMock.swift */,
|
||||||
0554FEA301486A8CFA475D5A /* AuthenticationClientBuilderFactoryMock.swift */,
|
0554FEA301486A8CFA475D5A /* AuthenticationClientBuilderFactoryMock.swift */,
|
||||||
4760CE2128FBC217304272AB /* AuthenticationClientBuilderMock.swift */,
|
|
||||||
9FD7E851E2BA8C5A8D284B2A /* BannedRoomProxyMock.swift */,
|
9FD7E851E2BA8C5A8D284B2A /* BannedRoomProxyMock.swift */,
|
||||||
8F7FC9580CABF797A2E6213A /* BugReportServiceMock.swift */,
|
8F7FC9580CABF797A2E6213A /* BugReportServiceMock.swift */,
|
||||||
E2F96CCBEAAA7F2185BFA354 /* ClientProxyMock.swift */,
|
E2F96CCBEAAA7F2185BFA354 /* ClientProxyMock.swift */,
|
||||||
@@ -4330,15 +4320,6 @@
|
|||||||
path = Settings;
|
path = Settings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
70CC0CDA4AFDF8299C56ADE7 /* QRCode */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B4427AF4B7FB7EF3E3D424C7 /* QRCodeLoginService.swift */,
|
|
||||||
536C0E2178949B290776EA4E /* QRCodeLoginServiceProtocol.swift */,
|
|
||||||
);
|
|
||||||
path = QRCode;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
70DABA39C844CA931B829395 /* RoomSummary */ = {
|
70DABA39C844CA931B829395 /* RoomSummary */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -5305,8 +5286,7 @@
|
|||||||
AAFDD509929A0CCF8BCE51EB /* Authentication */ = {
|
AAFDD509929A0CCF8BCE51EB /* Authentication */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */,
|
EBD19057FDB154A44335CE62 /* AuthenticationClientFactory.swift */,
|
||||||
B655A536341D2695158C6664 /* AuthenticationClientBuilderFactory.swift */,
|
|
||||||
F3A1AB5A84D843B6AC8D5F1E /* AuthenticationService.swift */,
|
F3A1AB5A84D843B6AC8D5F1E /* AuthenticationService.swift */,
|
||||||
5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */,
|
5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */,
|
||||||
A69869844D2B6F5BD9AABF85 /* OIDCConfigurationProxy.swift */,
|
A69869844D2B6F5BD9AABF85 /* OIDCConfigurationProxy.swift */,
|
||||||
@@ -7222,10 +7202,8 @@
|
|||||||
88F348E2CB14FF71CBBB665D /* AudioRoomTimelineItemContent.swift in Sources */,
|
88F348E2CB14FF71CBBB665D /* AudioRoomTimelineItemContent.swift in Sources */,
|
||||||
7BD2123144A32F082CECC108 /* AudioRoomTimelineView.swift in Sources */,
|
7BD2123144A32F082CECC108 /* AudioRoomTimelineView.swift in Sources */,
|
||||||
9278EC51D24E57445B290521 /* AudioSessionProtocol.swift in Sources */,
|
9278EC51D24E57445B290521 /* AudioSessionProtocol.swift in Sources */,
|
||||||
8A6CB15C8FC68F557750BF54 /* AuthenticationClientBuilder.swift in Sources */,
|
|
||||||
210DB40676DF2A23E69C2D06 /* AuthenticationClientBuilderFactory.swift in Sources */,
|
|
||||||
A51C65E5A3C9F2464A91A380 /* AuthenticationClientBuilderFactoryMock.swift in Sources */,
|
A51C65E5A3C9F2464A91A380 /* AuthenticationClientBuilderFactoryMock.swift in Sources */,
|
||||||
0F4709282FCCFBEFED427B8A /* AuthenticationClientBuilderMock.swift in Sources */,
|
AE066FC93E7B707C826B335A /* AuthenticationClientFactory.swift in Sources */,
|
||||||
67E9926C4572C54F59FCA91A /* AuthenticationFlowCoordinator.swift in Sources */,
|
67E9926C4572C54F59FCA91A /* AuthenticationFlowCoordinator.swift in Sources */,
|
||||||
9847B056C1A216C314D21E68 /* AuthenticationService.swift in Sources */,
|
9847B056C1A216C314D21E68 /* AuthenticationService.swift in Sources */,
|
||||||
56DACDD379A86A1F5DEFE7BE /* AuthenticationServiceProtocol.swift in Sources */,
|
56DACDD379A86A1F5DEFE7BE /* AuthenticationServiceProtocol.swift in Sources */,
|
||||||
@@ -7650,8 +7628,6 @@
|
|||||||
46FCD999E92D9717D24AAB94 /* QRCodeLoginScreenModels.swift in Sources */,
|
46FCD999E92D9717D24AAB94 /* QRCodeLoginScreenModels.swift in Sources */,
|
||||||
30E5628F74AD3C27A061BF25 /* QRCodeLoginScreenViewModel.swift in Sources */,
|
30E5628F74AD3C27A061BF25 /* QRCodeLoginScreenViewModel.swift in Sources */,
|
||||||
E9D2ED1C4186931E3D5FDA4E /* QRCodeLoginScreenViewModelProtocol.swift in Sources */,
|
E9D2ED1C4186931E3D5FDA4E /* QRCodeLoginScreenViewModelProtocol.swift in Sources */,
|
||||||
C8C7AF33AADF88B306CD2695 /* QRCodeLoginService.swift in Sources */,
|
|
||||||
BB04B1D8E7401C90506D401E /* QRCodeLoginServiceProtocol.swift in Sources */,
|
|
||||||
FDD5B4B616D9FF4DE3E9A418 /* QRCodeScannerView.swift in Sources */,
|
FDD5B4B616D9FF4DE3E9A418 /* QRCodeScannerView.swift in Sources */,
|
||||||
C9A631FD968249B4BA0B7B3C /* ReactionsSummaryView.swift in Sources */,
|
C9A631FD968249B4BA0B7B3C /* ReactionsSummaryView.swift in Sources */,
|
||||||
743790BF6A5B0577EA74AF14 /* ReadMarkerRoomTimelineItem.swift in Sources */,
|
743790BF6A5B0577EA74AF14 /* ReadMarkerRoomTimelineItem.swift in Sources */,
|
||||||
|
|||||||
@@ -546,13 +546,8 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
encryptionKeyProvider: encryptionKeyProvider,
|
encryptionKeyProvider: encryptionKeyProvider,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
appHooks: appHooks)
|
appHooks: appHooks)
|
||||||
let qrCodeLoginService = QRCodeLoginService(encryptionKeyProvider: encryptionKeyProvider,
|
|
||||||
userSessionStore: userSessionStore,
|
|
||||||
appSettings: appSettings,
|
|
||||||
appHooks: appHooks)
|
|
||||||
|
|
||||||
let coordinator = AuthenticationFlowCoordinator(authenticationService: authenticationService,
|
let coordinator = AuthenticationFlowCoordinator(authenticationService: authenticationService,
|
||||||
qrCodeLoginService: qrCodeLoginService,
|
|
||||||
bugReportService: ServiceLocator.shared.bugReportService,
|
bugReportService: ServiceLocator.shared.bugReportService,
|
||||||
navigationRootCoordinator: navigationRootCoordinator,
|
navigationRootCoordinator: navigationRootCoordinator,
|
||||||
appMediator: appMediator,
|
appMediator: appMediator,
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let qrCodeLoginService: QRCodeLoginServiceProtocol
|
|
||||||
|
|
||||||
enum State: StateType {
|
enum State: StateType {
|
||||||
/// The state machine hasn't started.
|
/// The state machine hasn't started.
|
||||||
@@ -102,7 +101,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
weak var delegate: AuthenticationFlowCoordinatorDelegate?
|
weak var delegate: AuthenticationFlowCoordinatorDelegate?
|
||||||
|
|
||||||
init(authenticationService: AuthenticationServiceProtocol,
|
init(authenticationService: AuthenticationServiceProtocol,
|
||||||
qrCodeLoginService: QRCodeLoginServiceProtocol,
|
|
||||||
bugReportService: BugReportServiceProtocol,
|
bugReportService: BugReportServiceProtocol,
|
||||||
navigationRootCoordinator: NavigationRootCoordinator,
|
navigationRootCoordinator: NavigationRootCoordinator,
|
||||||
appMediator: AppMediatorProtocol,
|
appMediator: AppMediatorProtocol,
|
||||||
@@ -116,7 +114,6 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.qrCodeLoginService = qrCodeLoginService
|
|
||||||
|
|
||||||
navigationStackCoordinator = NavigationStackCoordinator()
|
navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
|
|
||||||
@@ -300,7 +297,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
// MARK: - QR Code
|
// MARK: - QR Code
|
||||||
|
|
||||||
private func showQRCodeLoginScreen() {
|
private func showQRCodeLoginScreen() {
|
||||||
let coordinator = QRCodeLoginScreenCoordinator(parameters: .init(qrCodeLoginService: qrCodeLoginService,
|
let coordinator = QRCodeLoginScreenCoordinator(parameters: .init(qrCodeLoginService: authenticationService,
|
||||||
canSignInManually: appSettings.allowOtherAccountProviders, // No need to worry about provisioning links as we hide QR login.
|
canSignInManually: appSettings.allowOtherAccountProviders, // No need to worry about provisioning links as we hide QR login.
|
||||||
orientationManager: appMediator.windowManager,
|
orientationManager: appMediator.windowManager,
|
||||||
appMediator: appMediator))
|
appMediator: appMediator))
|
||||||
|
|||||||
@@ -8,15 +8,39 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
extension AuthenticationClientBuilderFactoryMock {
|
extension AuthenticationClientFactoryMock {
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
var builderConfiguration: AuthenticationClientBuilderMock.Configuration = .init()
|
var homeserverClients = [
|
||||||
|
"matrix.org": ClientSDKMock(configuration: .init()),
|
||||||
|
"example.com": ClientSDKMock(configuration: .init(serverAddress: "example.com",
|
||||||
|
homeserverURL: "https://matrix.example.com",
|
||||||
|
slidingSyncVersion: .native,
|
||||||
|
oidcLoginURL: nil,
|
||||||
|
supportsOIDCCreatePrompt: false,
|
||||||
|
supportsPasswordLogin: true)),
|
||||||
|
"company.com": ClientSDKMock(configuration: .init(serverAddress: "company.com",
|
||||||
|
homeserverURL: "https://matrix.company.com",
|
||||||
|
slidingSyncVersion: .native,
|
||||||
|
oidcLoginURL: "https://auth.company.com/oidc",
|
||||||
|
supportsOIDCCreatePrompt: false,
|
||||||
|
supportsPasswordLogin: false)),
|
||||||
|
"server.net": ClientSDKMock(configuration: .init(serverAddress: "server.net",
|
||||||
|
homeserverURL: "https://matrix.example.com",
|
||||||
|
slidingSyncVersion: .native,
|
||||||
|
oidcLoginURL: nil,
|
||||||
|
supportsOIDCCreatePrompt: false,
|
||||||
|
supportsPasswordLogin: false))
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
convenience init(configuration: Configuration) {
|
convenience init(configuration: Configuration) {
|
||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
let clientBuilder = AuthenticationClientBuilderMock(configuration: configuration.builderConfiguration)
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure = { address, _, _, _, _, _ in
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReturnValue = clientBuilder
|
guard let client = configuration.homeserverClients[address] else {
|
||||||
|
throw ClientBuildError.ServerUnreachable(message: "Not a known homeserver.")
|
||||||
|
}
|
||||||
|
return client
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +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 Foundation
|
|
||||||
import MatrixRustSDK
|
|
||||||
|
|
||||||
extension AuthenticationClientBuilderMock {
|
|
||||||
struct Configuration {
|
|
||||||
var homeserverClients = [
|
|
||||||
"matrix.org": ClientSDKMock(configuration: .init()),
|
|
||||||
"example.com": ClientSDKMock(configuration: .init(serverAddress: "example.com",
|
|
||||||
homeserverURL: "https://matrix.example.com",
|
|
||||||
slidingSyncVersion: .native,
|
|
||||||
oidcLoginURL: nil,
|
|
||||||
supportsOIDCCreatePrompt: false,
|
|
||||||
supportsPasswordLogin: true)),
|
|
||||||
"company.com": ClientSDKMock(configuration: .init(serverAddress: "company.com",
|
|
||||||
homeserverURL: "https://matrix.company.com",
|
|
||||||
slidingSyncVersion: .native,
|
|
||||||
oidcLoginURL: "https://auth.company.com/oidc",
|
|
||||||
supportsOIDCCreatePrompt: false,
|
|
||||||
supportsPasswordLogin: false)),
|
|
||||||
"server.net": ClientSDKMock(configuration: .init(serverAddress: "server.net",
|
|
||||||
homeserverURL: "https://matrix.example.com",
|
|
||||||
slidingSyncVersion: .native,
|
|
||||||
oidcLoginURL: nil,
|
|
||||||
supportsOIDCCreatePrompt: false,
|
|
||||||
supportsPasswordLogin: false))
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
convenience init(configuration: Configuration) {
|
|
||||||
self.init()
|
|
||||||
|
|
||||||
buildHomeserverAddressClosure = { address in
|
|
||||||
guard let client = configuration.homeserverClients[address] else {
|
|
||||||
throw ClientBuildError.ServerUnreachable(message: "Not a known homeserver.")
|
|
||||||
}
|
|
||||||
return client
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1823,19 +1823,20 @@ class AudioSessionMock: AudioSessionProtocol, @unchecked Sendable {
|
|||||||
try setActiveOptionsClosure?(active, options)
|
try setActiveOptionsClosure?(active, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class AuthenticationClientBuilderFactoryMock: AuthenticationClientBuilderFactoryProtocol, @unchecked Sendable {
|
class AuthenticationClientFactoryMock: AuthenticationClientFactoryProtocol, @unchecked Sendable {
|
||||||
|
|
||||||
//MARK: - makeBuilder
|
//MARK: - makeClient
|
||||||
|
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount = 0
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksThrowableError: Error?
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount: Int {
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount = 0
|
||||||
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount
|
return makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount
|
returnValue = makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -1843,103 +1844,29 @@ class AuthenticationClientBuilderFactoryMock: AuthenticationClientBuilderFactory
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount = newValue
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount = newValue
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCalled: Bool {
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCalled: Bool {
|
||||||
return makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount > 0
|
return makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount > 0
|
||||||
}
|
}
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments: (sessionDirectories: SessionDirectories, passphrase: String, clientSessionDelegate: ClientSessionDelegate, appSettings: AppSettings, appHooks: AppHooks)?
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments: (homeserverAddress: String, sessionDirectories: SessionDirectories, passphrase: String, clientSessionDelegate: ClientSessionDelegate, appSettings: AppSettings, appHooks: AppHooks)?
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedInvocations: [(sessionDirectories: SessionDirectories, passphrase: String, clientSessionDelegate: ClientSessionDelegate, appSettings: AppSettings, appHooks: AppHooks)] = []
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedInvocations: [(homeserverAddress: String, sessionDirectories: SessionDirectories, passphrase: String, clientSessionDelegate: ClientSessionDelegate, appSettings: AppSettings, appHooks: AppHooks)] = []
|
||||||
|
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue: AuthenticationClientBuilderProtocol!
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue: ClientProtocol!
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReturnValue: AuthenticationClientBuilderProtocol! {
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReturnValue: ClientProtocol! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue
|
return makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue
|
||||||
} else {
|
|
||||||
var returnValue: AuthenticationClientBuilderProtocol? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure: ((SessionDirectories, String, ClientSessionDelegate, AppSettings, AppHooks) -> AuthenticationClientBuilderProtocol)?
|
|
||||||
|
|
||||||
func makeBuilder(sessionDirectories: SessionDirectories, passphrase: String, clientSessionDelegate: ClientSessionDelegate, appSettings: AppSettings, appHooks: AppHooks) -> AuthenticationClientBuilderProtocol {
|
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount += 1
|
|
||||||
makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments = (sessionDirectories: sessionDirectories, passphrase: passphrase, clientSessionDelegate: clientSessionDelegate, appSettings: appSettings, appHooks: appHooks)
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedInvocations.append((sessionDirectories: sessionDirectories, passphrase: passphrase, clientSessionDelegate: clientSessionDelegate, appSettings: appSettings, appHooks: appHooks))
|
|
||||||
}
|
|
||||||
if let makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure = makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure {
|
|
||||||
return makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure(sessionDirectories, passphrase, clientSessionDelegate, appSettings, appHooks)
|
|
||||||
} else {
|
|
||||||
return makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReturnValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class AuthenticationClientBuilderMock: AuthenticationClientBuilderProtocol, @unchecked Sendable {
|
|
||||||
|
|
||||||
//MARK: - build
|
|
||||||
|
|
||||||
var buildHomeserverAddressThrowableError: Error?
|
|
||||||
var buildHomeserverAddressUnderlyingCallsCount = 0
|
|
||||||
var buildHomeserverAddressCallsCount: Int {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return buildHomeserverAddressUnderlyingCallsCount
|
|
||||||
} else {
|
|
||||||
var returnValue: Int? = nil
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
returnValue = buildHomeserverAddressUnderlyingCallsCount
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
buildHomeserverAddressUnderlyingCallsCount = newValue
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
buildHomeserverAddressUnderlyingCallsCount = newValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var buildHomeserverAddressCalled: Bool {
|
|
||||||
return buildHomeserverAddressCallsCount > 0
|
|
||||||
}
|
|
||||||
var buildHomeserverAddressReceivedHomeserverAddress: String?
|
|
||||||
var buildHomeserverAddressReceivedInvocations: [String] = []
|
|
||||||
|
|
||||||
var buildHomeserverAddressUnderlyingReturnValue: ClientProtocol!
|
|
||||||
var buildHomeserverAddressReturnValue: ClientProtocol! {
|
|
||||||
get {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
return buildHomeserverAddressUnderlyingReturnValue
|
|
||||||
} else {
|
} else {
|
||||||
var returnValue: ClientProtocol? = nil
|
var returnValue: ClientProtocol? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = buildHomeserverAddressUnderlyingReturnValue
|
returnValue = makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -1947,29 +1874,29 @@ class AuthenticationClientBuilderMock: AuthenticationClientBuilderProtocol, @unc
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
buildHomeserverAddressUnderlyingReturnValue = newValue
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
buildHomeserverAddressUnderlyingReturnValue = newValue
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksUnderlyingReturnValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var buildHomeserverAddressClosure: ((String) async throws -> ClientProtocol)?
|
var makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure: ((String, SessionDirectories, String, ClientSessionDelegate, AppSettings, AppHooks) async throws -> ClientProtocol)?
|
||||||
|
|
||||||
func build(homeserverAddress: String) async throws -> ClientProtocol {
|
func makeClient(homeserverAddress: String, sessionDirectories: SessionDirectories, passphrase: String, clientSessionDelegate: ClientSessionDelegate, appSettings: AppSettings, appHooks: AppHooks) async throws -> ClientProtocol {
|
||||||
if let error = buildHomeserverAddressThrowableError {
|
if let error = makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
buildHomeserverAddressCallsCount += 1
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount += 1
|
||||||
buildHomeserverAddressReceivedHomeserverAddress = homeserverAddress
|
makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedArguments = (homeserverAddress: homeserverAddress, sessionDirectories: sessionDirectories, passphrase: passphrase, clientSessionDelegate: clientSessionDelegate, appSettings: appSettings, appHooks: appHooks)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.buildHomeserverAddressReceivedInvocations.append(homeserverAddress)
|
self.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReceivedInvocations.append((homeserverAddress: homeserverAddress, sessionDirectories: sessionDirectories, passphrase: passphrase, clientSessionDelegate: clientSessionDelegate, appSettings: appSettings, appHooks: appHooks))
|
||||||
}
|
}
|
||||||
if let buildHomeserverAddressClosure = buildHomeserverAddressClosure {
|
if let makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure = makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure {
|
||||||
return try await buildHomeserverAddressClosure(homeserverAddress)
|
return try await makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksClosure(homeserverAddress, sessionDirectories, passphrase, clientSessionDelegate, appSettings, appHooks)
|
||||||
} else {
|
} else {
|
||||||
return buildHomeserverAddressReturnValue
|
return makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13192,13 +13119,13 @@ class QRCodeLoginServiceMock: QRCodeLoginServiceProtocol, @unchecked Sendable {
|
|||||||
var loginWithQRCodeDataReceivedData: Data?
|
var loginWithQRCodeDataReceivedData: Data?
|
||||||
var loginWithQRCodeDataReceivedInvocations: [Data] = []
|
var loginWithQRCodeDataReceivedInvocations: [Data] = []
|
||||||
|
|
||||||
var loginWithQRCodeDataUnderlyingReturnValue: Result<UserSessionProtocol, QRCodeLoginServiceError>!
|
var loginWithQRCodeDataUnderlyingReturnValue: Result<UserSessionProtocol, AuthenticationServiceError>!
|
||||||
var loginWithQRCodeDataReturnValue: Result<UserSessionProtocol, QRCodeLoginServiceError>! {
|
var loginWithQRCodeDataReturnValue: Result<UserSessionProtocol, AuthenticationServiceError>! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return loginWithQRCodeDataUnderlyingReturnValue
|
return loginWithQRCodeDataUnderlyingReturnValue
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Result<UserSessionProtocol, QRCodeLoginServiceError>? = nil
|
var returnValue: Result<UserSessionProtocol, AuthenticationServiceError>? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = loginWithQRCodeDataUnderlyingReturnValue
|
returnValue = loginWithQRCodeDataUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
@@ -13216,9 +13143,9 @@ class QRCodeLoginServiceMock: QRCodeLoginServiceProtocol, @unchecked Sendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var loginWithQRCodeDataClosure: ((Data) async -> Result<UserSessionProtocol, QRCodeLoginServiceError>)?
|
var loginWithQRCodeDataClosure: ((Data) async -> Result<UserSessionProtocol, AuthenticationServiceError>)?
|
||||||
|
|
||||||
func loginWithQRCode(data: Data) async -> Result<UserSessionProtocol, QRCodeLoginServiceError> {
|
func loginWithQRCode(data: Data) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
|
||||||
loginWithQRCodeDataCallsCount += 1
|
loginWithQRCodeDataCallsCount += 1
|
||||||
loginWithQRCodeDataReceivedData = data
|
loginWithQRCodeDataReceivedData = data
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|||||||
@@ -110,13 +110,15 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
case let .success(session):
|
case let .success(session):
|
||||||
MXLog.info("QR Login completed")
|
MXLog.info("QR Login completed")
|
||||||
actionsSubject.send(.done(userSession: session))
|
actionsSubject.send(.done(userSession: session))
|
||||||
case .failure(let error):
|
case .failure(.qrCodeError(let error)):
|
||||||
handleError(error: error)
|
handleError(error)
|
||||||
|
case .failure:
|
||||||
|
handleError(.unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleError(error: QRCodeLoginServiceError) {
|
private func handleError(_ error: QRCodeLoginError) {
|
||||||
MXLog.error("Failed to scan the QR code: \(error)")
|
MXLog.error("Failed to scan the QR code: \(error)")
|
||||||
switch error {
|
switch error {
|
||||||
case .invalidQRCode:
|
case .invalidQRCode:
|
||||||
@@ -137,7 +139,7 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
state.state = .error(.expired)
|
state.state = .error(.expired)
|
||||||
case .deviceNotSupported:
|
case .deviceNotSupported:
|
||||||
state.state = .error(.deviceNotSupported)
|
state.state = .error(.deviceNotSupported)
|
||||||
case .failedLoggingIn, .unknown:
|
case .unknown:
|
||||||
state.state = .error(.unknown)
|
state.state = .error(.unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +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 Foundation
|
|
||||||
import MatrixRustSDK
|
|
||||||
|
|
||||||
// sourcery: AutoMockable
|
|
||||||
protocol AuthenticationClientBuilderProtocol {
|
|
||||||
func build(homeserverAddress: String) async throws -> ClientProtocol
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wrapper around `ClientBuilder` to share reusable code between Normal and QR logins.
|
|
||||||
struct AuthenticationClientBuilder: AuthenticationClientBuilderProtocol {
|
|
||||||
let sessionDirectories: SessionDirectories
|
|
||||||
let passphrase: String
|
|
||||||
let clientSessionDelegate: ClientSessionDelegate
|
|
||||||
|
|
||||||
let appSettings: AppSettings
|
|
||||||
let appHooks: AppHooks
|
|
||||||
|
|
||||||
/// Builds a Client for login using OIDC or password authentication.
|
|
||||||
func build(homeserverAddress: String) async throws -> ClientProtocol {
|
|
||||||
try await makeClientBuilder().serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Private
|
|
||||||
|
|
||||||
/// The base builder configuration used for authentication within the app.
|
|
||||||
private func makeClientBuilder() -> ClientBuilder {
|
|
||||||
ClientBuilder
|
|
||||||
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
|
||||||
slidingSync: .discover,
|
|
||||||
sessionDelegate: clientSessionDelegate,
|
|
||||||
appHooks: appHooks,
|
|
||||||
enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode,
|
|
||||||
enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite,
|
|
||||||
threadsEnabled: appSettings.threadsEnabled)
|
|
||||||
.sessionPaths(dataPath: sessionDirectories.dataPath,
|
|
||||||
cachePath: sessionDirectories.cachePath)
|
|
||||||
.sessionPassphrase(passphrase: passphrase)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +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 Foundation
|
|
||||||
import MatrixRustSDK
|
|
||||||
|
|
||||||
// sourcery: AutoMockable
|
|
||||||
protocol AuthenticationClientBuilderFactoryProtocol {
|
|
||||||
func makeBuilder(sessionDirectories: SessionDirectories,
|
|
||||||
passphrase: String,
|
|
||||||
clientSessionDelegate: ClientSessionDelegate,
|
|
||||||
appSettings: AppSettings,
|
|
||||||
appHooks: AppHooks) -> AuthenticationClientBuilderProtocol
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wrapper around `ClientBuilder` to share reusable code between Normal and QR logins.
|
|
||||||
struct AuthenticationClientBuilderFactory: AuthenticationClientBuilderFactoryProtocol {
|
|
||||||
func makeBuilder(sessionDirectories: SessionDirectories,
|
|
||||||
passphrase: String,
|
|
||||||
clientSessionDelegate: ClientSessionDelegate,
|
|
||||||
appSettings: AppSettings,
|
|
||||||
appHooks: AppHooks) -> AuthenticationClientBuilderProtocol {
|
|
||||||
AuthenticationClientBuilder(sessionDirectories: sessionDirectories,
|
|
||||||
passphrase: passphrase,
|
|
||||||
clientSessionDelegate: clientSessionDelegate,
|
|
||||||
appSettings: appSettings,
|
|
||||||
appHooks: appHooks)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// 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 Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
|
// sourcery: AutoMockable
|
||||||
|
protocol AuthenticationClientFactoryProtocol {
|
||||||
|
func makeClient(homeserverAddress: String,
|
||||||
|
sessionDirectories: SessionDirectories,
|
||||||
|
passphrase: String,
|
||||||
|
clientSessionDelegate: ClientSessionDelegate,
|
||||||
|
appSettings: AppSettings,
|
||||||
|
appHooks: AppHooks) async throws -> ClientProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A wrapper around `ClientBuilder` to allow for mocked clients to be injected into authentication tests.
|
||||||
|
struct AuthenticationClientFactory: AuthenticationClientFactoryProtocol {
|
||||||
|
func makeClient(homeserverAddress: String,
|
||||||
|
sessionDirectories: SessionDirectories,
|
||||||
|
passphrase: String,
|
||||||
|
clientSessionDelegate: ClientSessionDelegate,
|
||||||
|
appSettings: AppSettings,
|
||||||
|
appHooks: AppHooks) async throws -> ClientProtocol {
|
||||||
|
try await ClientBuilder
|
||||||
|
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
||||||
|
slidingSync: .discover,
|
||||||
|
sessionDelegate: clientSessionDelegate,
|
||||||
|
appHooks: appHooks,
|
||||||
|
enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode,
|
||||||
|
enableKeyShareOnInvite: appSettings.enableKeyShareOnInvite,
|
||||||
|
threadsEnabled: appSettings.threadsEnabled)
|
||||||
|
.sessionPaths(dataPath: sessionDirectories.dataPath,
|
||||||
|
cachePath: sessionDirectories.cachePath)
|
||||||
|
.sessionPassphrase(passphrase: passphrase)
|
||||||
|
.serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
private var sessionDirectories: SessionDirectories
|
private var sessionDirectories: SessionDirectories
|
||||||
private let passphrase: String
|
private let passphrase: String
|
||||||
|
|
||||||
private let clientBuilderFactory: AuthenticationClientBuilderFactoryProtocol
|
private let clientFactory: AuthenticationClientFactoryProtocol
|
||||||
private let userSessionStore: UserSessionStoreProtocol
|
private let userSessionStore: UserSessionStoreProtocol
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let appHooks: AppHooks
|
private let appHooks: AppHooks
|
||||||
@@ -23,14 +23,19 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { homeserverSubject.asCurrentValuePublisher() }
|
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { homeserverSubject.asCurrentValuePublisher() }
|
||||||
private(set) var flow: AuthenticationFlow
|
private(set) var flow: AuthenticationFlow
|
||||||
|
|
||||||
|
private let qrLoginProgressSubject = PassthroughSubject<QrLoginProgress, Never>()
|
||||||
|
var qrLoginProgressPublisher: AnyPublisher<QrLoginProgress, Never> {
|
||||||
|
qrLoginProgressSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(userSessionStore: UserSessionStoreProtocol,
|
init(userSessionStore: UserSessionStoreProtocol,
|
||||||
encryptionKeyProvider: EncryptionKeyProviderProtocol,
|
encryptionKeyProvider: EncryptionKeyProviderProtocol,
|
||||||
clientBuilderFactory: AuthenticationClientBuilderFactoryProtocol = AuthenticationClientBuilderFactory(),
|
clientFactory: AuthenticationClientFactoryProtocol = AuthenticationClientFactory(),
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
appHooks: AppHooks) {
|
appHooks: AppHooks) {
|
||||||
sessionDirectories = .init()
|
sessionDirectories = .init()
|
||||||
passphrase = encryptionKeyProvider.generateKey().base64EncodedString()
|
passphrase = encryptionKeyProvider.generateKey().base64EncodedString()
|
||||||
self.clientBuilderFactory = clientBuilderFactory
|
self.clientFactory = clientFactory
|
||||||
self.userSessionStore = userSessionStore
|
self.userSessionStore = userSessionStore
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.appHooks = appHooks
|
self.appHooks = appHooks
|
||||||
@@ -46,7 +51,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
do {
|
do {
|
||||||
var homeserver = LoginHomeserver(address: homeserverAddress, loginMode: .unknown)
|
var homeserver = LoginHomeserver(address: homeserverAddress, loginMode: .unknown)
|
||||||
|
|
||||||
let client = try await makeClientBuilder().build(homeserverAddress: homeserverAddress)
|
let client = try await makeClient(homeserverAddress: homeserverAddress)
|
||||||
let loginDetails = await client.homeserverLoginDetails()
|
let loginDetails = await client.homeserverLoginDetails()
|
||||||
|
|
||||||
MXLog.info("Sliding sync: \(client.slidingSyncVersion())")
|
MXLog.info("Sliding sync: \(client.slidingSyncVersion())")
|
||||||
@@ -146,6 +151,45 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loginWithQRCode(data: Data) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
|
||||||
|
let qrData: QrCodeData
|
||||||
|
do {
|
||||||
|
qrData = try QrCodeData.fromBytes(bytes: data)
|
||||||
|
} catch {
|
||||||
|
MXLog.error("QRCode decode error: \(error)")
|
||||||
|
return .failure(.qrCodeError(.invalidQRCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let scannedServerName = qrData.serverName() else {
|
||||||
|
MXLog.error("The QR code is from a device that is not yet signed in.")
|
||||||
|
return .failure(.qrCodeError(.deviceNotSignedIn))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !appSettings.allowOtherAccountProviders, !appSettings.accountProviders.contains(scannedServerName) {
|
||||||
|
MXLog.error("The scanned device's server is not allowed: \(scannedServerName)")
|
||||||
|
return .failure(.qrCodeError(.providerNotAllowed(scannedProvider: scannedServerName, allowedProviders: appSettings.accountProviders)))
|
||||||
|
}
|
||||||
|
|
||||||
|
let listener = SDKListener { [weak self] progress in
|
||||||
|
self?.qrLoginProgressSubject.send(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let client = try await makeClient(homeserverAddress: scannedServerName)
|
||||||
|
try await client.loginWithQrCode(qrCodeData: qrData,
|
||||||
|
oidcConfiguration: appSettings.oidcConfiguration.rustValue,
|
||||||
|
progressListener: listener)
|
||||||
|
MXLog.info("Sliding sync: \(client.slidingSyncVersion())")
|
||||||
|
return await userSession(for: client)
|
||||||
|
} catch let error as HumanQrLoginError {
|
||||||
|
MXLog.error("QRCode login error: \(error)")
|
||||||
|
return .failure(error.serviceError)
|
||||||
|
} catch {
|
||||||
|
MXLog.error("QRCode login unknown error: \(error)")
|
||||||
|
return .failure(.qrCodeError(.unknown))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func reset() {
|
func reset() {
|
||||||
homeserverSubject.send(LoginHomeserver(address: appSettings.accountProviders[0], loginMode: .unknown))
|
homeserverSubject.send(LoginHomeserver(address: appSettings.accountProviders[0], loginMode: .unknown))
|
||||||
flow = .login
|
flow = .login
|
||||||
@@ -154,12 +198,13 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func makeClientBuilder() -> AuthenticationClientBuilderProtocol {
|
private func makeClient(homeserverAddress: String) async throws -> ClientProtocol {
|
||||||
// Use a fresh session directory each time the user enters a different server
|
// Use a fresh session directory each time the user enters a different server
|
||||||
// so that caches (e.g. server versions) are always fresh for the new server.
|
// so that caches (e.g. server versions) are always fresh for the new server.
|
||||||
rotateSessionDirectory()
|
rotateSessionDirectory()
|
||||||
|
|
||||||
return clientBuilderFactory.makeBuilder(sessionDirectories: sessionDirectories,
|
return try await clientFactory.makeClient(homeserverAddress: homeserverAddress,
|
||||||
|
sessionDirectories: sessionDirectories,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
clientSessionDelegate: userSessionStore.clientSessionDelegate,
|
clientSessionDelegate: userSessionStore.clientSessionDelegate,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
@@ -181,13 +226,36 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension HumanQrLoginError {
|
||||||
|
var serviceError: AuthenticationServiceError {
|
||||||
|
switch self {
|
||||||
|
case .Cancelled:
|
||||||
|
.qrCodeError(.cancelled)
|
||||||
|
case .ConnectionInsecure:
|
||||||
|
.qrCodeError(.connectionInsecure)
|
||||||
|
case .Declined:
|
||||||
|
.qrCodeError(.declined)
|
||||||
|
case .LinkingNotSupported:
|
||||||
|
.qrCodeError(.linkingNotSupported)
|
||||||
|
case .Expired:
|
||||||
|
.qrCodeError(.expired)
|
||||||
|
case .SlidingSyncNotAvailable:
|
||||||
|
.qrCodeError(.deviceNotSupported)
|
||||||
|
case .OtherDeviceNotSignedIn:
|
||||||
|
.qrCodeError(.deviceNotSignedIn)
|
||||||
|
case .Unknown, .OidcMetadataInvalid:
|
||||||
|
.qrCodeError(.unknown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Mocks
|
// MARK: - Mocks
|
||||||
|
|
||||||
extension AuthenticationService {
|
extension AuthenticationService {
|
||||||
static var mock: AuthenticationService {
|
static var mock: AuthenticationService {
|
||||||
AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
||||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||||
clientBuilderFactory: AuthenticationClientBuilderFactoryMock(configuration: .init()),
|
clientFactory: AuthenticationClientFactoryMock(configuration: .init()),
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
appHooks: AppHooks())
|
appHooks: AppHooks())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
// Please see LICENSE files in the repository root for full details.
|
// Please see LICENSE files in the repository root for full details.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
@@ -19,6 +20,9 @@ enum AuthenticationFlow {
|
|||||||
enum AuthenticationServiceError: Error, Equatable {
|
enum AuthenticationServiceError: Error, Equatable {
|
||||||
/// An error occurred during OIDC authentication.
|
/// An error occurred during OIDC authentication.
|
||||||
case oidcError(OIDCError)
|
case oidcError(OIDCError)
|
||||||
|
/// An error occurred during login with QR Code.
|
||||||
|
case qrCodeError(QRCodeLoginError)
|
||||||
|
|
||||||
case invalidServer
|
case invalidServer
|
||||||
case invalidCredentials
|
case invalidCredentials
|
||||||
case invalidHomeserverAddress
|
case invalidHomeserverAddress
|
||||||
@@ -32,7 +36,7 @@ enum AuthenticationServiceError: Error, Equatable {
|
|||||||
case failedUsingWebCredentials
|
case failedUsingWebCredentials
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol AuthenticationServiceProtocol {
|
protocol AuthenticationServiceProtocol: QRCodeLoginServiceProtocol {
|
||||||
/// The currently configured homeserver.
|
/// The currently configured homeserver.
|
||||||
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { get }
|
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { get }
|
||||||
/// The type of flow the service is currently configured with.
|
/// The type of flow the service is currently configured with.
|
||||||
@@ -86,3 +90,25 @@ extension OAuthAuthorizationData: @retroactive Hashable {
|
|||||||
hasher.combine(loginUrl())
|
hasher.combine(loginUrl())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Login with QR code
|
||||||
|
|
||||||
|
enum QRCodeLoginError: Error, Equatable {
|
||||||
|
case invalidQRCode
|
||||||
|
case providerNotAllowed(scannedProvider: String, allowedProviders: [String])
|
||||||
|
case cancelled
|
||||||
|
case connectionInsecure
|
||||||
|
case declined
|
||||||
|
case linkingNotSupported
|
||||||
|
case expired
|
||||||
|
case deviceNotSupported
|
||||||
|
case deviceNotSignedIn
|
||||||
|
case unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
// sourcery: AutoMockable
|
||||||
|
protocol QRCodeLoginServiceProtocol {
|
||||||
|
var qrLoginProgressPublisher: AnyPublisher<QrLoginProgress, Never> { get }
|
||||||
|
|
||||||
|
func loginWithQRCode(data: Data) async -> Result<UserSessionProtocol, AuthenticationServiceError>
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,127 +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 Foundation
|
|
||||||
|
|
||||||
import MatrixRustSDK
|
|
||||||
|
|
||||||
final class QRCodeLoginService: QRCodeLoginServiceProtocol {
|
|
||||||
private var sessionDirectories: SessionDirectories
|
|
||||||
private let passphrase: String
|
|
||||||
|
|
||||||
private let userSessionStore: UserSessionStoreProtocol
|
|
||||||
private let appSettings: AppSettings
|
|
||||||
private let appHooks: AppHooks
|
|
||||||
|
|
||||||
private let qrLoginProgressSubject = PassthroughSubject<QrLoginProgress, Never>()
|
|
||||||
var qrLoginProgressPublisher: AnyPublisher<QrLoginProgress, Never> {
|
|
||||||
qrLoginProgressSubject.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
init(encryptionKeyProvider: EncryptionKeyProviderProtocol,
|
|
||||||
userSessionStore: UserSessionStoreProtocol,
|
|
||||||
appSettings: AppSettings,
|
|
||||||
appHooks: AppHooks) {
|
|
||||||
sessionDirectories = .init()
|
|
||||||
passphrase = encryptionKeyProvider.generateKey().base64EncodedString()
|
|
||||||
self.userSessionStore = userSessionStore
|
|
||||||
self.appSettings = appSettings
|
|
||||||
self.appHooks = appHooks
|
|
||||||
}
|
|
||||||
|
|
||||||
func loginWithQRCode(data: Data) async -> Result<UserSessionProtocol, QRCodeLoginServiceError> {
|
|
||||||
let qrData: QrCodeData
|
|
||||||
do {
|
|
||||||
qrData = try QrCodeData.fromBytes(bytes: data)
|
|
||||||
} catch {
|
|
||||||
MXLog.error("QRCode decode error: \(error)")
|
|
||||||
return .failure(.invalidQRCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let scannedServerName = qrData.serverName() else {
|
|
||||||
MXLog.error("The QR code is from a device that is not yet signed in.")
|
|
||||||
return .failure(.deviceNotSignedIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !appSettings.allowOtherAccountProviders, !appSettings.accountProviders.contains(scannedServerName) {
|
|
||||||
MXLog.error("The scanned device's server is not allowed: \(scannedServerName)")
|
|
||||||
return .failure(.providerNotAllowed(scannedProvider: scannedServerName, allowedProviders: appSettings.accountProviders))
|
|
||||||
}
|
|
||||||
|
|
||||||
let listener = SDKListener { [weak self] progress in
|
|
||||||
self?.qrLoginProgressSubject.send(progress)
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
let client = try await makeClientBuilder().build(homeserverAddress: scannedServerName)
|
|
||||||
try await client.loginWithQrCode(qrCodeData: qrData,
|
|
||||||
oidcConfiguration: appSettings.oidcConfiguration.rustValue,
|
|
||||||
progressListener: listener)
|
|
||||||
MXLog.info("Sliding sync: \(client.slidingSyncVersion())")
|
|
||||||
return await userSession(for: client)
|
|
||||||
} catch let error as HumanQrLoginError {
|
|
||||||
MXLog.error("QRCode login error: \(error)")
|
|
||||||
return .failure(error.serviceError)
|
|
||||||
} catch {
|
|
||||||
MXLog.error("QRCode login unknown error: \(error)")
|
|
||||||
return .failure(.unknown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Private
|
|
||||||
|
|
||||||
private func makeClientBuilder() -> AuthenticationClientBuilder {
|
|
||||||
// Use a fresh session directory each time the user scans a QR code to ensure caches
|
|
||||||
// (e.g. server versions) are always fresh in case a different server is used.
|
|
||||||
rotateSessionDirectory()
|
|
||||||
|
|
||||||
return AuthenticationClientBuilder(sessionDirectories: sessionDirectories,
|
|
||||||
passphrase: passphrase,
|
|
||||||
clientSessionDelegate: userSessionStore.clientSessionDelegate,
|
|
||||||
appSettings: appSettings,
|
|
||||||
appHooks: appHooks)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func rotateSessionDirectory() {
|
|
||||||
sessionDirectories.delete()
|
|
||||||
sessionDirectories = .init()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func userSession(for client: ClientProtocol) async -> Result<UserSessionProtocol, QRCodeLoginServiceError> {
|
|
||||||
switch await userSessionStore.userSession(for: client, sessionDirectories: sessionDirectories, passphrase: passphrase) {
|
|
||||||
case .success(let session):
|
|
||||||
return .success(session)
|
|
||||||
case .failure(let error):
|
|
||||||
MXLog.error("QRCode login failed error: \(error)")
|
|
||||||
return .failure(.failedLoggingIn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension HumanQrLoginError {
|
|
||||||
var serviceError: QRCodeLoginServiceError {
|
|
||||||
switch self {
|
|
||||||
case .Cancelled:
|
|
||||||
return .cancelled
|
|
||||||
case .ConnectionInsecure:
|
|
||||||
return .connectionInsecure
|
|
||||||
case .Declined:
|
|
||||||
return .declined
|
|
||||||
case .LinkingNotSupported:
|
|
||||||
return .linkingNotSupported
|
|
||||||
case .Expired:
|
|
||||||
return .expired
|
|
||||||
case .SlidingSyncNotAvailable:
|
|
||||||
return .deviceNotSupported
|
|
||||||
case .OtherDeviceNotSignedIn:
|
|
||||||
return .deviceNotSignedIn
|
|
||||||
case .Unknown, .OidcMetadataInvalid:
|
|
||||||
return .unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +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 Foundation
|
|
||||||
|
|
||||||
import MatrixRustSDK
|
|
||||||
|
|
||||||
enum QRCodeLoginServiceError: Error {
|
|
||||||
case failedLoggingIn
|
|
||||||
case invalidQRCode
|
|
||||||
case providerNotAllowed(scannedProvider: String, allowedProviders: [String])
|
|
||||||
case cancelled
|
|
||||||
case connectionInsecure
|
|
||||||
case declined
|
|
||||||
case linkingNotSupported
|
|
||||||
case expired
|
|
||||||
case deviceNotSupported
|
|
||||||
case deviceNotSignedIn
|
|
||||||
case unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
// sourcery: AutoMockable
|
|
||||||
protocol QRCodeLoginServiceProtocol {
|
|
||||||
var qrLoginProgressPublisher: AnyPublisher<QrLoginProgress, Never> { get }
|
|
||||||
|
|
||||||
func loginWithQRCode(data: Data) async -> Result<UserSessionProtocol, QRCodeLoginServiceError>
|
|
||||||
}
|
|
||||||
@@ -146,7 +146,6 @@ class MockScreen: Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let flowCoordinator = AuthenticationFlowCoordinator(authenticationService: AuthenticationService.mock,
|
let flowCoordinator = AuthenticationFlowCoordinator(authenticationService: AuthenticationService.mock,
|
||||||
qrCodeLoginService: QRCodeLoginServiceMock(),
|
|
||||||
bugReportService: BugReportServiceMock(.init()),
|
bugReportService: BugReportServiceMock(.init()),
|
||||||
navigationRootCoordinator: navigationRootCoordinator,
|
navigationRootCoordinator: navigationRootCoordinator,
|
||||||
appMediator: AppMediatorMock.default,
|
appMediator: AppMediatorMock.default,
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ class AuthenticationServiceTests: XCTestCase {
|
|||||||
// MARK: - Helpers
|
// MARK: - Helpers
|
||||||
|
|
||||||
private func setupMocks(serverAddress: String = "matrix.org") {
|
private func setupMocks(serverAddress: String = "matrix.org") {
|
||||||
let configuration: AuthenticationClientBuilderMock.Configuration = .init()
|
let configuration: AuthenticationClientFactoryMock.Configuration = .init()
|
||||||
let clientBuilderFactory = AuthenticationClientBuilderFactoryMock(configuration: .init(builderConfiguration: configuration))
|
let clientFactory = AuthenticationClientFactoryMock(configuration: configuration)
|
||||||
|
|
||||||
client = configuration.homeserverClients[serverAddress]
|
client = configuration.homeserverClients[serverAddress]
|
||||||
userSessionStore = UserSessionStoreMock(configuration: .init())
|
userSessionStore = UserSessionStoreMock(configuration: .init())
|
||||||
@@ -95,7 +95,7 @@ class AuthenticationServiceTests: XCTestCase {
|
|||||||
|
|
||||||
service = AuthenticationService(userSessionStore: userSessionStore,
|
service = AuthenticationService(userSessionStore: userSessionStore,
|
||||||
encryptionKeyProvider: encryptionKeyProvider,
|
encryptionKeyProvider: encryptionKeyProvider,
|
||||||
clientBuilderFactory: clientBuilderFactory,
|
clientFactory: clientFactory,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
appHooks: AppHooks())
|
appHooks: AppHooks())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import XCTest
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class AuthenticationStartScreenViewModelTests: XCTestCase {
|
class AuthenticationStartScreenViewModelTests: XCTestCase {
|
||||||
var clientBuilderFactory: AuthenticationClientBuilderFactoryMock!
|
var clientFactory: AuthenticationClientFactoryMock!
|
||||||
var client: ClientSDKMock!
|
var client: ClientSDKMock!
|
||||||
var appSettings: AppSettings!
|
var appSettings: AppSettings!
|
||||||
var authenticationService: AuthenticationServiceProtocol!
|
var authenticationService: AuthenticationServiceProtocol!
|
||||||
@@ -50,7 +50,7 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the authentication service should not be used yet.
|
// Then the authentication service should not be used yet.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .unknown)
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
|||||||
context.send(viewAction: .login)
|
context.send(viewAction: .login)
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.loginHint, "user@company.com")
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.loginHint, "user@company.com")
|
||||||
@@ -88,7 +88,7 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made.
|
// Then a call to configure service should be made.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .password)
|
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .password)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
|||||||
context.send(viewAction: .login)
|
context.send(viewAction: .login)
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.loginHint, nil)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.loginHint, nil)
|
||||||
@@ -126,7 +126,7 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made.
|
// Then a call to configure service should be made.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .password)
|
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .password)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,12 +137,12 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
|||||||
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.company.com/authorize" : nil,
|
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.company.com/authorize" : nil,
|
||||||
supportsOIDCCreatePrompt: false,
|
supportsOIDCCreatePrompt: false,
|
||||||
supportsPasswordLogin: true))
|
supportsPasswordLogin: true))
|
||||||
let configuration = AuthenticationClientBuilderMock.Configuration(homeserverClients: ["company.com": client])
|
let configuration = AuthenticationClientFactoryMock.Configuration(homeserverClients: ["company.com": client])
|
||||||
|
|
||||||
clientBuilderFactory = AuthenticationClientBuilderFactoryMock(configuration: .init(builderConfiguration: configuration))
|
clientFactory = AuthenticationClientFactoryMock(configuration: configuration)
|
||||||
authenticationService = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
authenticationService = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
||||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||||
clientBuilderFactory: clientBuilderFactory,
|
clientFactory: clientFactory,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
appHooks: AppHooks())
|
appHooks: AppHooks())
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LoginScreenViewModelTests: XCTestCase {
|
|||||||
var viewModel: LoginScreenViewModelProtocol!
|
var viewModel: LoginScreenViewModelProtocol!
|
||||||
var context: LoginScreenViewModelType.Context { viewModel.context }
|
var context: LoginScreenViewModelType.Context { viewModel.context }
|
||||||
|
|
||||||
var clientBuilderFactory: AuthenticationClientBuilderFactoryMock!
|
var clientFactory: AuthenticationClientFactoryMock!
|
||||||
var service: AuthenticationServiceProtocol!
|
var service: AuthenticationServiceProtocol!
|
||||||
|
|
||||||
func testBasicServer() async {
|
func testBasicServer() async {
|
||||||
@@ -157,10 +157,10 @@ class LoginScreenViewModelTests: XCTestCase {
|
|||||||
// MARK: - Helpers
|
// MARK: - Helpers
|
||||||
|
|
||||||
private func setupViewModel(homeserverAddress: String = "example.com", loginHint: String? = nil) async {
|
private func setupViewModel(homeserverAddress: String = "example.com", loginHint: String? = nil) async {
|
||||||
clientBuilderFactory = AuthenticationClientBuilderFactoryMock(configuration: .init())
|
clientFactory = AuthenticationClientFactoryMock(configuration: .init())
|
||||||
service = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
service = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
||||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||||
clientBuilderFactory: clientBuilderFactory,
|
clientFactory: clientFactory,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
appHooks: AppHooks())
|
appHooks: AppHooks())
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import XCTest
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class ServerConfirmationScreenViewModelTests: XCTestCase {
|
class ServerConfirmationScreenViewModelTests: XCTestCase {
|
||||||
var clientBuilderFactory: AuthenticationClientBuilderFactoryMock!
|
var clientFactory: AuthenticationClientFactoryMock!
|
||||||
var client: ClientSDKMock!
|
var client: ClientSDKMock!
|
||||||
var service: AuthenticationServiceProtocol!
|
var service: AuthenticationServiceProtocol!
|
||||||
var appSettings: AppSettings!
|
var appSettings: AppSettings!
|
||||||
@@ -37,7 +37,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
setupViewModel(authenticationFlow: .login)
|
setupViewModel(authenticationFlow: .login)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -46,7 +46,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made.
|
// Then a call to configure service should be made.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
||||||
@@ -61,7 +61,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
||||||
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -70,7 +70,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configured homeserver should be used and no additional client should be built.
|
// Then the configured homeserver should be used and no additional client should be built.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
setupViewModel(authenticationFlow: .register)
|
setupViewModel(authenticationFlow: .register)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -89,7 +89,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made.
|
// Then a call to configure service should be made.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
// The create prompt is broken: https://github.com/element-hq/matrix-authentication-service/issues/3429
|
// The create prompt is broken: https://github.com/element-hq/matrix-authentication-service/issues/3429
|
||||||
// XCTAssertEqual(client.urlForOidcOidcConfigurationPromptReceivedArguments?.prompt, .create)
|
// XCTAssertEqual(client.urlForOidcOidcConfigurationPromptReceivedArguments?.prompt, .create)
|
||||||
@@ -105,7 +105,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
||||||
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -114,7 +114,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configured homeserver should be used and no additional client should be built.
|
// Then the configured homeserver should be used and no additional client should be built.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
// The create prompt is broken: https://github.com/element-hq/matrix-authentication-service/issues/3429
|
// The create prompt is broken: https://github.com/element-hq/matrix-authentication-service/issues/3429
|
||||||
// XCTAssertEqual(client.urlForOidcOidcConfigurationPromptReceivedArguments?.prompt, .create)
|
// XCTAssertEqual(client.urlForOidcOidcConfigurationPromptReceivedArguments?.prompt, .create)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
@@ -125,7 +125,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false)
|
setupViewModel(authenticationFlow: .login, supportsOIDC: false)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -134,7 +134,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made, but not for the OIDC URL.
|
// Then a call to configure service should be made, but not for the OIDC URL.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
||||||
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
XCTAssertEqual(context.viewState.mode, .confirmation(service.homeserver.value.address))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -157,7 +157,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
|
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
// Note: We don't currently take the create prompt into account when determining registration support.
|
// Note: We don't currently take the create prompt into account when determining registration support.
|
||||||
setupViewModel(authenticationFlow: .register, supportsOIDC: false, supportsOIDCCreatePrompt: false)
|
setupViewModel(authenticationFlow: .register, supportsOIDC: false, supportsOIDCCreatePrompt: false)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -175,7 +175,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configuration should fail with an alert about not supporting registration.
|
// Then the configuration should fail with an alert about not supporting registration.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(context.alertInfo?.id, .registration)
|
XCTAssertEqual(context.alertInfo?.id, .registration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
// Given a view model for login using a service that hasn't been configured and the default server doesn't support login.
|
// Given a view model for login using a service that hasn't been configured and the default server doesn't support login.
|
||||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false, supportsOIDCCreatePrompt: false, supportsPasswordLogin: false)
|
setupViewModel(authenticationFlow: .login, supportsOIDC: false, supportsOIDCCreatePrompt: false, supportsPasswordLogin: false)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -192,7 +192,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configuration should fail with an alert about not supporting login.
|
// Then the configuration should fail with an alert about not supporting login.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(context.alertInfo?.id, .login)
|
XCTAssertEqual(context.alertInfo?.id, .login)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
setupViewModel(authenticationFlow: .login, restrictedFlow: true)
|
setupViewModel(authenticationFlow: .login, restrictedFlow: true)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -212,7 +212,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made.
|
// Then a call to configure service should be made.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
||||||
@@ -227,7 +227,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
XCTAssertEqual(service.homeserver.value.loginMode, .oidc(supportsCreatePrompt: true))
|
||||||
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -236,7 +236,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configured homeserver should be used and no additional client should be built.
|
// Then the configured homeserver should be used and no additional client should be built.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdReceivedArguments?.prompt, .consent)
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
setupViewModel(authenticationFlow: .login, supportsOIDC: false, restrictedFlow: true)
|
setupViewModel(authenticationFlow: .login, supportsOIDC: false, restrictedFlow: true)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -255,7 +255,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then a call to configure service should be made, but not for the OIDC URL.
|
// Then a call to configure service should be made, but not for the OIDC URL.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
XCTAssertEqual(service.homeserver.value.loginMode, .password)
|
||||||
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
XCTAssertEqual(context.viewState.mode, .picker(appSettings.accountProviders))
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
|
|
||||||
// When continuing from the confirmation screen.
|
// When continuing from the confirmation screen.
|
||||||
@@ -278,7 +278,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
|
// Then the configured homeserver should be used and no additional client should be built, nor a call to get the OIDC URL.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintDeviceIdCallsCount, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,12 +316,12 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
|
|||||||
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.matrix.org/authorize" : nil,
|
client = ClientSDKMock(configuration: .init(oidcLoginURL: supportsOIDC ? "https://account.matrix.org/authorize" : nil,
|
||||||
supportsOIDCCreatePrompt: supportsOIDCCreatePrompt,
|
supportsOIDCCreatePrompt: supportsOIDCCreatePrompt,
|
||||||
supportsPasswordLogin: supportsPasswordLogin))
|
supportsPasswordLogin: supportsPasswordLogin))
|
||||||
let configuration = AuthenticationClientBuilderMock.Configuration(homeserverClients: ["matrix.org": client])
|
let configuration = AuthenticationClientFactoryMock.Configuration(homeserverClients: ["matrix.org": client])
|
||||||
|
|
||||||
clientBuilderFactory = AuthenticationClientBuilderFactoryMock(configuration: .init(builderConfiguration: configuration))
|
clientFactory = AuthenticationClientFactoryMock(configuration: configuration)
|
||||||
service = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
service = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
||||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||||
clientBuilderFactory: clientBuilderFactory,
|
clientFactory: clientFactory,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
appHooks: AppHooks())
|
appHooks: AppHooks())
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import XCTest
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class ServerSelectionScreenViewModelTests: XCTestCase {
|
class ServerSelectionScreenViewModelTests: XCTestCase {
|
||||||
var clientBuilderFactory: AuthenticationClientBuilderFactoryMock!
|
var clientFactory: AuthenticationClientFactoryMock!
|
||||||
var service: AuthenticationServiceProtocol!
|
var service: AuthenticationServiceProtocol!
|
||||||
|
|
||||||
var viewModel: ServerSelectionScreenViewModelProtocol!
|
var viewModel: ServerSelectionScreenViewModelProtocol!
|
||||||
@@ -21,7 +21,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
// Given a view model for login.
|
// Given a view model for login.
|
||||||
setupViewModel(authenticationFlow: .login)
|
setupViewModel(authenticationFlow: .login)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
|
|
||||||
// When selecting matrix.org.
|
// When selecting matrix.org.
|
||||||
context.homeserverAddress = "matrix.org"
|
context.homeserverAddress = "matrix.org"
|
||||||
@@ -30,7 +30,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then selection should succeed.
|
// Then selection should succeed.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(service.homeserver.value, .mockMatrixDotOrg)
|
XCTAssertEqual(service.homeserver.value, .mockMatrixDotOrg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
// Given a view model for login.
|
// Given a view model for login.
|
||||||
setupViewModel(authenticationFlow: .login)
|
setupViewModel(authenticationFlow: .login)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
|
||||||
// When selecting a server that doesn't support login.
|
// When selecting a server that doesn't support login.
|
||||||
@@ -48,7 +48,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then selection should fail with an alert about not supporting registration.
|
// Then selection should fail with an alert about not supporting registration.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(context.alertInfo?.id, .loginAlert)
|
XCTAssertEqual(context.alertInfo?.id, .loginAlert)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
// Given a view model for registration.
|
// Given a view model for registration.
|
||||||
setupViewModel(authenticationFlow: .register)
|
setupViewModel(authenticationFlow: .register)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
|
|
||||||
// When selecting matrix.org.
|
// When selecting matrix.org.
|
||||||
context.homeserverAddress = "matrix.org"
|
context.homeserverAddress = "matrix.org"
|
||||||
@@ -65,7 +65,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then selection should succeed.
|
// Then selection should succeed.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(service.homeserver.value, .mockMatrixDotOrg)
|
XCTAssertEqual(service.homeserver.value, .mockMatrixDotOrg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
// Given a view model for registration.
|
// Given a view model for registration.
|
||||||
setupViewModel(authenticationFlow: .register)
|
setupViewModel(authenticationFlow: .register)
|
||||||
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
XCTAssertEqual(service.homeserver.value.loginMode, .unknown)
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 0)
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
|
||||||
// When selecting a server that doesn't support registration.
|
// When selecting a server that doesn't support registration.
|
||||||
@@ -83,7 +83,7 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
|
|
||||||
// Then selection should fail with an alert about not supporting registration.
|
// Then selection should fail with an alert about not supporting registration.
|
||||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
XCTAssertEqual(clientFactory.makeClientHomeserverAddressSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||||
XCTAssertEqual(context.alertInfo?.id, .registrationAlert)
|
XCTAssertEqual(context.alertInfo?.id, .registrationAlert)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,10 +122,10 @@ class ServerSelectionScreenViewModelTests: XCTestCase {
|
|||||||
// MARK: - Helpers
|
// MARK: - Helpers
|
||||||
|
|
||||||
private func setupViewModel(authenticationFlow: AuthenticationFlow) {
|
private func setupViewModel(authenticationFlow: AuthenticationFlow) {
|
||||||
clientBuilderFactory = AuthenticationClientBuilderFactoryMock(configuration: .init())
|
clientFactory = AuthenticationClientFactoryMock(configuration: .init())
|
||||||
service = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
service = AuthenticationService(userSessionStore: UserSessionStoreMock(configuration: .init()),
|
||||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||||
clientBuilderFactory: clientBuilderFactory,
|
clientFactory: clientFactory,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
appHooks: AppHooks())
|
appHooks: AppHooks())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user