From 87154d19a83eca33dc7ae4e5c4ff4060ff1529d6 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 29 Aug 2023 13:09:59 +0300 Subject: [PATCH 01/16] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 37b603c0b..ad10bbd70 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.1 -CURRENT_PROJECT_VERSION = 1.11.1 +MARKETING_VERSION = 1.11.2 +CURRENT_PROJECT_VERSION = 1.11.2 From 48f8ed85934457ce0ac7214243f11baf6bb89c13 Mon Sep 17 00:00:00 2001 From: Nicolas Mauri Date: Mon, 4 Sep 2023 09:56:29 +0200 Subject: [PATCH 02/16] Fix event forwarding --- Riot/Modules/Room/RoomViewController.m | 3 +- .../Shared/ForwardingShareItemSender.swift | 1 + RiotShareExtension/Shared/ShareManager.h | 4 +- RiotShareExtension/Shared/ShareManager.m | 80 +++++++++++++------ changelog.d/7641.bugfix | 1 + 5 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 changelog.d/7641.bugfix diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index ac1ab9931..71b2e8107 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -4577,7 +4577,8 @@ static CGSize kThreadListBarButtonItemImageSize; { ForwardingShareItemSender *shareItemSender = [[ForwardingShareItemSender alloc] initWithEvent:selectedEvent]; self.shareManager = [[ShareManager alloc] initWithShareItemSender:shareItemSender - type:ShareManagerTypeForward]; + type:ShareManagerTypeForward + session:self.mainSession]; MXWeakify(self); [self.shareManager setCompletionCallback:^(ShareManagerResult result) { diff --git a/RiotShareExtension/Shared/ForwardingShareItemSender.swift b/RiotShareExtension/Shared/ForwardingShareItemSender.swift index 3909812db..e75b6b3fd 100644 --- a/RiotShareExtension/Shared/ForwardingShareItemSender.swift +++ b/RiotShareExtension/Shared/ForwardingShareItemSender.swift @@ -56,6 +56,7 @@ class ForwardingShareItemSender: NSObject, ShareItemSenderProtocol { case .failure(let innerError): errors.append(innerError) default: + room.summary.resetLastMessage(nil, failure: nil, commit: false) break } diff --git a/RiotShareExtension/Shared/ShareManager.h b/RiotShareExtension/Shared/ShareManager.h index c2b110a05..5b7edb90f 100644 --- a/RiotShareExtension/Shared/ShareManager.h +++ b/RiotShareExtension/Shared/ShareManager.h @@ -36,7 +36,9 @@ typedef NS_ENUM(NSUInteger, ShareManagerResult) { @property (nonatomic, copy) void (^completionCallback)(ShareManagerResult); - (instancetype)initWithShareItemSender:(id)itemSender - type:(ShareManagerType)type; + type:(ShareManagerType)type + session:(nullable MXSession*)session; + - (UIViewController *)mainViewController; diff --git a/RiotShareExtension/Shared/ShareManager.m b/RiotShareExtension/Shared/ShareManager.m index 0e1c74cf7..7e2b0172e 100644 --- a/RiotShareExtension/Shared/ShareManager.m +++ b/RiotShareExtension/Shared/ShareManager.m @@ -31,6 +31,8 @@ @property (nonatomic, strong, readonly) ShareViewController *shareViewController; +@property (nonatomic) BOOL useCustomSession; +@property (nonatomic, strong) MXSession* session; @property (nonatomic, strong) MXKAccount *userAccount; @property (nonatomic, strong) MXFileStore *fileStore; @@ -51,11 +53,14 @@ static MXSession *fakeSession; - (instancetype)initWithShareItemSender:(id)itemSender type:(ShareManagerType)type + session:(MXSession*)session { if (self = [super init]) { _shareItemSender = itemSender; _shareItemSender.delegate = self; + _session = session; + _useCustomSession = _session == nil; [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(checkUserAccount) name:kMXKAccountManagerDidRemoveAccountNotification object:nil]; [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(checkUserAccount) name:NSExtensionHostWillEnterForegroundNotification object:nil]; @@ -71,7 +76,20 @@ static MXSession *fakeSession; [NSBundle mxk_setLanguage:language]; [NSBundle mxk_setFallbackLanguage:@"en"]; - [self checkUserAccount]; + if (!_useCustomSession) + { + // If we don't use a custom session, we can initialize the shareViewController with our existing session + self.userAccount = [MXKAccountManager sharedManager].activeAccounts.firstObject; + ShareDataSource *roomDataSource = [[ShareDataSource alloc] initWithFileStore:_session.store + session:_session]; + + [self.shareViewController configureWithState:ShareViewControllerAccountStateConfigured + roomDataSource:roomDataSource]; + } + else + { + [self checkUserAccount]; + } } return self; @@ -95,32 +113,23 @@ static MXSession *fakeSession; MXStrongifyAndReturnIfNil(self); [self.userAccount handleUnauthenticatedWithError:error isSoftLogout:isSoftLogout isRefreshTokenAuth:isRefreshTokenAuth andCompletion:completion]; }]; - MXSession *session = [[MXSession alloc] initWithMatrixRestClient:restClient]; - [MXFileStore setPreloadOptions:0]; - - MXWeakify(session); - [session setStore:self.fileStore success:^{ - MXStrongifyAndReturnIfNil(session); - - self.selectedRooms = [NSMutableArray array]; - for (NSString *roomIdentifier in roomIdentifiers) { - MXRoom *room = [MXRoom loadRoomFromStore:self.fileStore withRoomId:roomIdentifier matrixSession:session]; - if (room) { - [self.selectedRooms addObject:room]; - } - } - - [self.shareItemSender sendItemsToRooms:self.selectedRooms success:^{ - self.selectedRooms = nil; - self.completionCallback(ShareManagerResultFinished); - } failure:^(NSArray *errors) { - self.selectedRooms = nil; - [self showFailureAlert:[VectorL10n roomEventFailedToSend]]; + if (self.useCustomSession || !self.session) + { + MXSession* session = [[MXSession alloc] initWithMatrixRestClient:restClient]; + [MXFileStore setPreloadOptions:0]; + + MXWeakify(session); + [session setStore:self.fileStore success:^{ + MXStrongifyAndReturnIfNil(session); + [self shareForRoomIdentifiers:roomIdentifiers usingSession:session]; + } failure:^(NSError *error) { + MXLogError(@"[ShareManager] Failed preparing matrix session"); }]; - - } failure:^(NSError *error) { - MXLogError(@"[ShareManager] Failed preparing matrix session"); - }]; + } + else + { + [self shareForRoomIdentifiers:roomIdentifiers usingSession:self.session]; + } } - (void)shareViewControllerDidRequestDismissal:(ShareViewController *)shareViewController @@ -142,6 +151,25 @@ static MXSession *fakeSession; #pragma mark - Private +- (void)shareForRoomIdentifiers:(NSSet *)roomIdentifiers usingSession:(MXSession*)session +{ + self.selectedRooms = [NSMutableArray array]; + for (NSString *roomIdentifier in roomIdentifiers) { + MXRoom *room = [MXRoom loadRoomFromStore:session.store withRoomId:roomIdentifier matrixSession:session]; + if (room) { + [self.selectedRooms addObject:room]; + } + } + + [self.shareItemSender sendItemsToRooms:self.selectedRooms success:^{ + self.selectedRooms = nil; + self.completionCallback(ShareManagerResultFinished); + } failure:^(NSArray *errors) { + self.selectedRooms = nil; + [self showFailureAlert:[VectorL10n roomEventFailedToSend]]; + }]; +} + - (void)showFailureAlert:(NSString *)title { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert]; diff --git a/changelog.d/7641.bugfix b/changelog.d/7641.bugfix new file mode 100644 index 000000000..99af6e75a --- /dev/null +++ b/changelog.d/7641.bugfix @@ -0,0 +1 @@ +Fix an issue where rooms were not correctly sorted after forwarding a message. From 0fdaab8b4679c09b1188b2973b1ba1ec7c2508ce Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 7 Sep 2023 17:36:02 +0300 Subject: [PATCH 03/16] Add initial support for configuration through MDM --- BroadcastUploadExtension/target.yml | 1 + Config/BuildSettings.swift | 13 +++++--- Config/MDMSettings.swift | 49 +++++++++++++++++++++++++++++ RiotNSE/target.yml | 1 + RiotShareExtension/target.yml | 1 + RiotSwiftUI/target.yml | 1 + RiotSwiftUI/targetUITests.yml | 1 + RiotTests/target.yml | 1 + SiriIntents/target.yml | 1 + 9 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 Config/MDMSettings.swift diff --git a/BroadcastUploadExtension/target.yml b/BroadcastUploadExtension/target.yml index 1ef21b6b3..b119b433e 100644 --- a/BroadcastUploadExtension/target.yml +++ b/BroadcastUploadExtension/target.yml @@ -38,5 +38,6 @@ targets: sources: - path: . - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Riot/Categories/Bundle.swift - path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index faf730a90..e3e3e55e8 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -102,13 +102,16 @@ final class BuildSettings: NSObject { static let forceHomeserverSelection = false /// Default server proposed on the authentication screen - static let serverConfigDefaultHomeserverUrlString = "https://matrix.org" + static var serverConfigDefaultHomeserverUrlString: String { + MDMSettings.serverConfigDefaultHomeserverUrlString ?? "https://matrix.org" + } /// Default identity server static let serverConfigDefaultIdentityServerUrlString = "https://vector.im" - static let serverConfigSygnalAPIUrlString = "https://matrix.org/_matrix/push/v1/notify" - + static var serverConfigSygnalAPIUrlString: String { + MDMSettings.serverConfigSygnalAPIUrlString ?? "https://matrix.org/_matrix/push/v1/notify" + } // MARK: - Legal URLs @@ -144,7 +147,9 @@ final class BuildSettings: NSObject { // This baseURL is used to generate permalinks within the app (E.g. timeline message permalinks). // Optional String that when set is used as permalink base, when nil matrix.to format is used. // Example value would be "https://www.example.com", note there is no trailing '/'. - static let clientPermalinkBaseUrl: String? = nil + static var clientPermalinkBaseUrl: String? { + MDMSettings.clientPermalinkBaseUrl + } // MARK: - VoIP static var allowVoIPUsage: Bool { diff --git a/Config/MDMSettings.swift b/Config/MDMSettings.swift new file mode 100644 index 000000000..60c18e219 --- /dev/null +++ b/Config/MDMSettings.swift @@ -0,0 +1,49 @@ +// +// Copyright 2023 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +enum MDMSettings { + private static let appleManagedConfigurationKey = "com.apple.configuration.managed" + + private enum Key: String { + case serverConfigDefaultHomeserverUrlString = "im.vector.app.serverConfigDefaultHomeserverUrlString" + case serverConfigSygnalAPIUrlString = "im.vector.app.serverConfigSygnalAPIUrlString" + case clientPermalinkBaseUrl = "im.vector.app.clientPermalinkBaseUrl" + } + + static var serverConfigDefaultHomeserverUrlString: String? { + valueForKey(.serverConfigDefaultHomeserverUrlString) as? String + } + + static var serverConfigSygnalAPIUrlString: String? { + valueForKey(.serverConfigSygnalAPIUrlString) as? String + } + + static var clientPermalinkBaseUrl: String? { + valueForKey(.clientPermalinkBaseUrl) as? String + } + + // MARK: - Private + + static private func valueForKey(_ key: Key) -> Any? { + guard let managedConfiguration = UserDefaults.standard.dictionary(forKey: appleManagedConfigurationKey) else { + return nil + } + + return managedConfiguration[key.rawValue] + } +} diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index 87aedd471..6bc5a474d 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -44,6 +44,7 @@ targets: - path: . - path: ../Riot/Managers/Settings/RiotSettings.swift - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Riot/Utils/DataProtectionHelper.swift - path: ../Config/CommonConfiguration.swift - path: ../Riot/Experiments/ diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index b289f234b..b4803e3ef 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -48,6 +48,7 @@ targets: - path: ../Riot/Managers/Theme/ - path: ../Riot/Utils/AvatarGenerator.m - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Riot/Categories/Character.swift - path: ../Riot/Categories/MXKImageView.swift - path: ../Riot/Categories/MXRoom+Riot.m diff --git a/RiotSwiftUI/target.yml b/RiotSwiftUI/target.yml index c07c15830..bccd8e5bc 100644 --- a/RiotSwiftUI/target.yml +++ b/RiotSwiftUI/target.yml @@ -52,6 +52,7 @@ targets: - path: ../Riot/Managers/Theme/ - path: ../Riot/Managers/Locale/LocaleProviderType.swift - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift - path: ../Riot/Categories/String.swift - path: ../Riot/Categories/Character.swift diff --git a/RiotSwiftUI/targetUITests.yml b/RiotSwiftUI/targetUITests.yml index 85c77f05c..da007464f 100644 --- a/RiotSwiftUI/targetUITests.yml +++ b/RiotSwiftUI/targetUITests.yml @@ -61,6 +61,7 @@ targets: - path: ../Riot/Managers/Theme/ - path: ../Riot/Managers/Locale/LocaleProviderType.swift - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift - path: ../Riot/Categories/String.swift - path: ../Riot/Categories/Character.swift diff --git a/RiotTests/target.yml b/RiotTests/target.yml index 37782a61e..dccdda9c0 100644 --- a/RiotTests/target.yml +++ b/RiotTests/target.yml @@ -61,6 +61,7 @@ targets: - path: . - path: ../Config/Configurable.swift - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Riot/Categories/Bundle.swift - path: ../Riot/Managers/AppInfo/AppInfo.swift - path: ../Riot/Managers/AppInfo/AppVersion.swift diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index 1894d1b9e..f4ecff439 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -48,6 +48,7 @@ targets: - path: ../Config/CommonConfiguration.swift - path: ../Riot/Experiments/ - path: ../Config/BuildSettings.swift + - path: ../Config/MDMSettings.swift - path: ../Config/Configurable.swift - path: ../Riot/Managers/Settings/RiotSettings.swift - path: ../Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift From 8f32547cc4ca168bfc486cd367d9a9e2b39ca033 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 8 Sep 2023 12:09:52 +0200 Subject: [PATCH 04/16] Documentation to run local rust SDK --- INSTALL.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index 792ae4fef..54360664e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -71,6 +71,25 @@ Be sure to use compatible branches for Element iOS and MatrixSDK. For example, i **Important**: By working with [XcodeGen](https://github.com/yonaskolb/XcodeGen) you will need to use the _New Build System_ in Xcode, to have your some of the xcconfig variables taken into account. It should be enabled by default on the latest Xcode versions, but if you need to enable it go to Xcode menu and select `File > Workspace Settings… > Build System` and then choose `New Build System`. +- **Running a local rust MatrixCryptoSDK locally** + +If you want to debug locally or test local changes of the rust `MatrixSDKCrypto` with a local `MatrixSDK`, you must checkout [matrix-rust-sdk](https://github.com/matrix-org/matrix-rust-sdk), and follow the [instructions in the repository](https://github.com/matrix-org/matrix-rust-sdk/tree/main/bindings/apple). + +Once the framework is built using `./build_crypto_xcframework.sh` you will have to move `bindings/apple/MatrixSDKCrypto-Local.podspec` to the root of the `matrix-rust-sdk` folder and rename it to `MatrixSDKCrypto.podspec` then update `s.version` with the current pod version: + +``` + s.version = "0.3.12" +``` + +Then in the element-ios `Podfile`, add the following line under side the existing `pod 'MatrixSDK' [..]`: + +``` +pod 'MatrixSDKCrypto', :path => '../matrix-rust-sdk/MatrixSDKCrypto.podspec' +``` + +Run `pod install` to refresh all. + + ### `$matrixSDKVersion` Modification Every time you change the `$matrixSDKVersion` variable in the `Podfile`, you have to run the `pod install` command again. From f9d04e6c1ec2a68655659a72c12a41895a7aa4ff Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 8 Sep 2023 14:53:28 +0200 Subject: [PATCH 05/16] Update INSTALL.md --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 54360664e..c740b1137 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -81,7 +81,7 @@ Once the framework is built using `./build_crypto_xcframework.sh` you will have s.version = "0.3.12" ``` -Then in the element-ios `Podfile`, add the following line under side the existing `pod 'MatrixSDK' [..]`: +Then in the element-ios `Podfile`, add the following line under the existing `pod 'MatrixSDK' [..]`: ``` pod 'MatrixSDKCrypto', :path => '../matrix-rust-sdk/MatrixSDKCrypto.podspec' From 8c85663c3cc474040c3195f84da41e3cfc5f40b6 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 8 Sep 2023 17:16:58 +0100 Subject: [PATCH 06/16] Hide phone number and explanation if homeserver doesn't have 3pid capability enabled (#7670) --- .../Modules/Settings/SettingsViewController.m | 35 ++++++++++--------- changelog.d/7670.bugfix | 1 + 2 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 changelog.d/7670.bugfix diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 4bc45f827..32871e008 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -371,23 +371,24 @@ ChangePasswordCoordinatorBridgePresenterDelegate> { [sectionUserSettings addRowWithTag: USER_SETTINGS_PHONENUMBERS_OFFSET + index]; } - if (BuildSettings.settingsScreenAllowAddingEmailThreepids && - // If the threePidChanges is nil we assume the capability to be true - (!self.mainSession.homeserverCapabilities.threePidChanges || - self.mainSession.homeserverCapabilities.threePidChanges.enabled)) - { - [sectionUserSettings addRowWithTag:USER_SETTINGS_ADD_EMAIL_INDEX]; - } - if (BuildSettings.settingsScreenAllowAddingPhoneThreepids) - { - [sectionUserSettings addRowWithTag:USER_SETTINGS_ADD_PHONENUMBER_INDEX]; - } - if (BuildSettings.settingsScreenShowThreepidExplanatory) - { - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[VectorL10n settingsThreePidsManagementInformationPart1] attributes:@{}]; - [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[VectorL10n settingsThreePidsManagementInformationPart2] attributes:@{NSForegroundColorAttributeName: ThemeService.shared.theme.tintColor}]]; - [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[VectorL10n settingsThreePidsManagementInformationPart3] attributes:@{}]]; - sectionUserSettings.attributedFooterTitle = attributedString; + // If the threePidChanges is nil we assume the capability to be true + if (!self.mainSession.homeserverCapabilities.threePidChanges || + self.mainSession.homeserverCapabilities.threePidChanges.enabled) { + if (BuildSettings.settingsScreenAllowAddingEmailThreepids) + { + [sectionUserSettings addRowWithTag:USER_SETTINGS_ADD_EMAIL_INDEX]; + } + if (BuildSettings.settingsScreenAllowAddingPhoneThreepids) + { + [sectionUserSettings addRowWithTag:USER_SETTINGS_ADD_PHONENUMBER_INDEX]; + } + if (BuildSettings.settingsScreenShowThreepidExplanatory) + { + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[VectorL10n settingsThreePidsManagementInformationPart1] attributes:@{}]; + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[VectorL10n settingsThreePidsManagementInformationPart2] attributes:@{NSForegroundColorAttributeName: ThemeService.shared.theme.tintColor}]]; + [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[VectorL10n settingsThreePidsManagementInformationPart3] attributes:@{}]]; + sectionUserSettings.attributedFooterTitle = attributedString; + } } sectionUserSettings.headerTitle = [VectorL10n settingsUserSettings]; diff --git a/changelog.d/7670.bugfix b/changelog.d/7670.bugfix new file mode 100644 index 000000000..7f975ec95 --- /dev/null +++ b/changelog.d/7670.bugfix @@ -0,0 +1 @@ +Add phone number UI and explanatory text is hidden if the 3 pid changes capability is disabled. From fbe2a2698e39fcceb11adc377c8cc73e98c17772 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 11 Sep 2023 10:51:27 +0300 Subject: [PATCH 07/16] Added logs --- Config/MDMSettings.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Config/MDMSettings.swift b/Config/MDMSettings.swift index 60c18e219..a6699a617 100644 --- a/Config/MDMSettings.swift +++ b/Config/MDMSettings.swift @@ -41,9 +41,12 @@ enum MDMSettings { static private func valueForKey(_ key: Key) -> Any? { guard let managedConfiguration = UserDefaults.standard.dictionary(forKey: appleManagedConfigurationKey) else { + print("MDM configuration missing") return nil } + print("Retrieved MDM configuration: \(managedConfiguration)") + return managedConfiguration[key.rawValue] } } From 4bb92f9cd192e36073e2f3b9776377e5e1e0b1c8 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 12 Sep 2023 10:07:57 +0300 Subject: [PATCH 08/16] changelog.d: Upgrade MatrixSDK version ([v0.27.2](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.2)). --- Podfile | 2 +- changelog.d/x-nolink-0.change | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/x-nolink-0.change diff --git a/Podfile b/Podfile index 6891bc511..c0d184713 100644 --- a/Podfile +++ b/Podfile @@ -16,7 +16,7 @@ use_frameworks! # - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK repo. Used by Fastfile during CI # # Warning: our internal tooling depends on the name of this variable name, so be sure not to change it -$matrixSDKVersion = '= 0.27.1' +$matrixSDKVersion = '= 0.27.2' # $matrixSDKVersion = :local # $matrixSDKVersion = { :branch => 'develop'} # $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } } diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change new file mode 100644 index 000000000..664d7eaef --- /dev/null +++ b/changelog.d/x-nolink-0.change @@ -0,0 +1 @@ +Upgrade MatrixSDK version ([v0.27.2](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.2)). \ No newline at end of file From d3bf58d4d1c5b6c00fc82b1a38473519a2efc79a Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 12 Sep 2023 10:07:57 +0300 Subject: [PATCH 09/16] version++ --- CHANGES.md | 12 ++++++++++++ changelog.d/7641.bugfix | 1 - changelog.d/7670.bugfix | 1 - changelog.d/x-nolink-0.change | 1 - 4 files changed, 12 insertions(+), 3 deletions(-) delete mode 100644 changelog.d/7641.bugfix delete mode 100644 changelog.d/7670.bugfix delete mode 100644 changelog.d/x-nolink-0.change diff --git a/CHANGES.md b/CHANGES.md index 25f3abef4..3a269699d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,15 @@ +## Changes in 1.11.2 (2023-09-12) + +🙌 Improvements + +- Upgrade MatrixSDK version ([v0.27.2](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.2)). + +🐛 Bugfixes + +- Fix an issue where rooms were not correctly sorted after forwarding a message. ([#7641](https://github.com/vector-im/element-ios/issues/7641)) +- Add phone number UI and explanatory text is hidden if the 3 pid changes capability is disabled. ([#7670](https://github.com/vector-im/element-ios/issues/7670)) + + ## Changes in 1.11.1 (2023-08-29) ✨ Features diff --git a/changelog.d/7641.bugfix b/changelog.d/7641.bugfix deleted file mode 100644 index 99af6e75a..000000000 --- a/changelog.d/7641.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix an issue where rooms were not correctly sorted after forwarding a message. diff --git a/changelog.d/7670.bugfix b/changelog.d/7670.bugfix deleted file mode 100644 index 7f975ec95..000000000 --- a/changelog.d/7670.bugfix +++ /dev/null @@ -1 +0,0 @@ -Add phone number UI and explanatory text is hidden if the 3 pid changes capability is disabled. diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change deleted file mode 100644 index 664d7eaef..000000000 --- a/changelog.d/x-nolink-0.change +++ /dev/null @@ -1 +0,0 @@ -Upgrade MatrixSDK version ([v0.27.2](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.2)). \ No newline at end of file From 72114e89bd6a762aef0f4a25e7a628163e0f62ee Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 12 Sep 2023 10:56:34 +0300 Subject: [PATCH 10/16] finish version++ --- Podfile.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 2a6591aa6..ec974f0f2 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -39,9 +39,9 @@ PODS: - LoggerAPI (1.9.200): - Logging (~> 1.1) - Logging (1.4.0) - - MatrixSDK (0.27.1): - - MatrixSDK/Core (= 0.27.1) - - MatrixSDK/Core (0.27.1): + - MatrixSDK (0.27.2): + - MatrixSDK/Core (= 0.27.2) + - MatrixSDK/Core (0.27.2): - AFNetworking (~> 4.0.0) - GZIP (~> 1.3.0) - libbase58 (~> 0.1.4) @@ -49,7 +49,7 @@ PODS: - OLMKit (~> 3.2.5) - Realm (= 10.27.0) - SwiftyBeaver (= 1.9.5) - - MatrixSDK/JingleCallStack (0.27.1): + - MatrixSDK/JingleCallStack (0.27.2): - JitsiMeetSDKLite (= 8.1.2-lite) - MatrixSDK/Core - MatrixSDKCrypto (0.3.12) @@ -102,8 +102,8 @@ DEPENDENCIES: - KeychainAccess (~> 4.2.2) - KTCenterFlowLayout (~> 1.3.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.27.1) - - MatrixSDK/JingleCallStack (= 0.27.1) + - MatrixSDK (= 0.27.2) + - MatrixSDK/JingleCallStack (= 0.27.2) - OLMKit - PostHog (~> 2.0.0) - ReadMoreTextView (~> 3.0.1) @@ -187,7 +187,7 @@ SPEC CHECKSUMS: libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d Logging: beeb016c9c80cf77042d62e83495816847ef108b - MatrixSDK: f6c197ca06aab29ff69d1105965a57d277dfcd9d + MatrixSDK: a39e229a03a00394e055ffa7490e9602d45f8a44 MatrixSDKCrypto: 25929a40733b4ab54f659aaf6a730552a0a06504 OLMKit: da115f16582e47626616874e20f7bb92222c7a51 PostHog: 660ec6c9d80cec17b685e148f17f6785a88b597d @@ -208,6 +208,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: ce6afe3dea7ea9b073a7ad0406b2cc5615646746 +PODFILE CHECKSUM: b926e281576aabcdbc2bdcb40ef3ad3e0991abe8 COCOAPODS: 1.11.3 From d5fd359f0c24b59721425665f7bd945793fb4218 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 12 Sep 2023 10:56:41 +0300 Subject: [PATCH 11/16] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index ad10bbd70..eabcc9b01 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.2 -CURRENT_PROJECT_VERSION = 1.11.2 +MARKETING_VERSION = 1.11.3 +CURRENT_PROJECT_VERSION = 1.11.3 From a7c8905b10114a346cca60887fc065ebbbcd277f Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Tue, 12 Sep 2023 13:46:36 +0100 Subject: [PATCH 12/16] Hide sign out x/all buttons in the Device Manager when using OIDC. (#7674) --- .../UserSessionsFlowCoordinator.swift | 4 +- .../UserOtherSessionsCoordinator.swift | 2 + .../MockUserOtherSessionsScreenState.swift | 5 +++ .../UserOtherSessionsViewModelTests.swift | 40 +++++++++++++------ .../UserOtherSessionsModels.swift | 1 + .../UserOtherSessionsViewModel.swift | 4 +- .../View/UserOtherSessions.swift | 1 + .../View/UserOtherSessionsToolbar.swift | 3 +- .../UserSessionsOverviewCoordinator.swift | 5 ++- .../MockUserSessionsOverviewScreenState.swift | 2 +- .../UserSessionsOverviewViewModelTests.swift | 16 ++++++-- .../UserSessionsOverviewModels.swift | 1 + .../UserSessionsOverviewViewModel.swift | 4 +- .../View/UserSessionsOverview.swift | 12 +++--- changelog.d/7672.bugfix | 1 + 15 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 changelog.d/7672.bugfix diff --git a/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift b/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift index 041f5a1ae..5225b9fd0 100644 --- a/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift +++ b/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift @@ -188,9 +188,11 @@ final class UserSessionsFlowCoordinator: NSObject, Coordinator, Presentable { private func createOtherSessionsCoordinator(sessionInfos: [UserSessionInfo], filterBy filter: UserOtherSessionsFilter, title: String) -> UserOtherSessionsCoordinator { + let shouldShowDeviceLogout = parameters.session.homeserverWellknown.authentication == nil let parameters = UserOtherSessionsCoordinatorParameters(sessionInfos: sessionInfos, filter: filter, - title: title) + title: title, + showDeviceLogout: shouldShowDeviceLogout) return UserOtherSessionsCoordinator(parameters: parameters) } diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Coordinator/UserOtherSessionsCoordinator.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Coordinator/UserOtherSessionsCoordinator.swift index 8f9dab072..a848a2bf8 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Coordinator/UserOtherSessionsCoordinator.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Coordinator/UserOtherSessionsCoordinator.swift @@ -21,6 +21,7 @@ struct UserOtherSessionsCoordinatorParameters { let sessionInfos: [UserSessionInfo] let filter: UserOtherSessionsFilter let title: String + let showDeviceLogout: Bool } final class UserOtherSessionsCoordinator: Coordinator, Presentable { @@ -40,6 +41,7 @@ final class UserOtherSessionsCoordinator: Coordinator, Presentable { let viewModel = UserOtherSessionsViewModel(sessionInfos: parameters.sessionInfos, filter: parameters.filter, title: parameters.title, + showDeviceLogout: parameters.showDeviceLogout, settingsService: RiotSettings.shared) let view = UserOtherSessions(viewModel: viewModel.context) userOtherSessionsViewModel = viewModel diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/MockUserOtherSessionsScreenState.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/MockUserOtherSessionsScreenState.swift index e81bb7f05..e357e77d0 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/MockUserOtherSessionsScreenState.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/MockUserOtherSessionsScreenState.swift @@ -49,26 +49,31 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable { viewModel = UserOtherSessionsViewModel(sessionInfos: allSessions(), filter: .all, title: VectorL10n.userSessionsOverviewOtherSessionsSectionTitle, + showDeviceLogout: true, settingsService: MockUserSessionSettings()) case .none: viewModel = UserOtherSessionsViewModel(sessionInfos: [], filter: .all, title: VectorL10n.userSessionsOverviewOtherSessionsSectionTitle, + showDeviceLogout: true, settingsService: MockUserSessionSettings()) case .inactiveSessions: viewModel = UserOtherSessionsViewModel(sessionInfos: inactiveSessions(), filter: .inactive, title: VectorL10n.userOtherSessionSecurityRecommendationTitle, + showDeviceLogout: true, settingsService: MockUserSessionSettings()) case .unverifiedSessions: viewModel = UserOtherSessionsViewModel(sessionInfos: unverifiedSessions(), filter: .unverified, title: VectorL10n.userOtherSessionSecurityRecommendationTitle, + showDeviceLogout: true, settingsService: MockUserSessionSettings()) case .verifiedSessions: viewModel = UserOtherSessionsViewModel(sessionInfos: verifiedSessions(), filter: .verified, title: VectorL10n.userOtherSessionSecurityRecommendationTitle, + showDeviceLogout: true, settingsService: MockUserSessionSettings()) } diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/Unit/UserOtherSessionsViewModelTests.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/Unit/UserOtherSessionsViewModelTests.swift index 270891d91..58d8b2dc7 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/Unit/UserOtherSessionsViewModelTests.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/Unit/UserOtherSessionsViewModelTests.swift @@ -63,7 +63,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: VectorL10n.userOtherSessionNoInactiveSessions, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -81,7 +82,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -104,7 +106,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: VectorL10n.userOtherSessionNoUnverifiedSessions, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(expectedItems.count, 2) XCTAssertEqual(sut.state, expectedState) } @@ -123,7 +126,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: VectorL10n.userOtherSessionNoVerifiedSessions, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -139,7 +143,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: VectorL10n.userOtherSessionNoVerifiedSessions, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -155,7 +160,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: VectorL10n.userOtherSessionNoUnverifiedSessions, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -171,7 +177,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: VectorL10n.userOtherSessionNoInactiveSessions, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -192,7 +199,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: true, enableSignOutButton: true, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -213,7 +221,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -233,7 +242,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: false, enableSignOutButton: true, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -253,7 +263,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: true, enableSignOutButton: true, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -273,7 +284,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -296,7 +308,8 @@ class UserOtherSessionsViewModelTests: XCTestCase { emptyItemsTitle: "", allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: false) + showLocationInfo: false, + showDeviceLogout: true) XCTAssertEqual(sut.state, expectedState) } @@ -352,6 +365,7 @@ class UserOtherSessionsViewModelTests: XCTestCase { UserOtherSessionsViewModel(sessionInfos: sessionInfos, filter: filter, title: title, + showDeviceLogout: true, settingsService: MockUserSessionSettings()) } diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsModels.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsModels.swift index deeb5ab95..d486e1cc4 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsModels.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsModels.swift @@ -43,6 +43,7 @@ struct UserOtherSessionsViewState: BindableState, Equatable { var allItemsSelected: Bool var enableSignOutButton: Bool var showLocationInfo: Bool + var showDeviceLogout: Bool } struct UserOtherSessionsBindings: Equatable { diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsViewModel.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsViewModel.swift index 84ea6f9ad..abfb5e99f 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsViewModel.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/UserOtherSessionsViewModel.swift @@ -28,6 +28,7 @@ class UserOtherSessionsViewModel: UserOtherSessionsViewModelType, UserOtherSessi init(sessionInfos: [UserSessionInfo], filter: UserOtherSessionsFilter, title: String, + showDeviceLogout: Bool, settingsService: UserSessionSettingsProtocol) { self.sessionInfos = sessionInfos defaultTitle = title @@ -41,7 +42,8 @@ class UserOtherSessionsViewModel: UserOtherSessionsViewModelType, UserOtherSessi emptyItemsTitle: filter.userOtherSessionsViewEmptyResultsTitle, allItemsSelected: false, enableSignOutButton: false, - showLocationInfo: settingsService.showIPAddressesInSessionsManager)) + showLocationInfo: settingsService.showIPAddressesInSessionsManager, + showDeviceLogout: showDeviceLogout)) } // MARK: - Public diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift index 41d79fe54..92eb505b0 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift @@ -60,6 +60,7 @@ struct UserOtherSessions: View { set: { _ in withAnimation { viewModel.send(viewAction: .showLocationInfo) } }), allItemsSelected: viewModel.viewState.allItemsSelected, sessionCount: viewModel.viewState.sessionItems.count, + showDeviceLogout: viewModel.viewState.showDeviceLogout, onToggleSelection: { viewModel.send(viewAction: .toggleAllSelection) }, onSignOut: { viewModel.send(viewAction: .logoutAllUserSessions) }) } diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift index 331ede0c3..d3c0b3bb0 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift @@ -24,6 +24,7 @@ struct UserOtherSessionsToolbar: ToolbarContent { @Binding var isShowLocationEnabled: Bool let allItemsSelected: Bool let sessionCount: Int + let showDeviceLogout: Bool let onToggleSelection: () -> Void let onSignOut: () -> Void @@ -94,7 +95,7 @@ struct UserOtherSessionsToolbar: ToolbarContent { Label(showLocationInfo: isShowLocationEnabled) } - if sessionCount > 0 { + if sessionCount > 0, showDeviceLogout { DestructiveButton { onSignOut() } label: { diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Coordinator/UserSessionsOverviewCoordinator.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Coordinator/UserSessionsOverviewCoordinator.swift index 7d3d0437c..20a88aaf1 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Coordinator/UserSessionsOverviewCoordinator.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Coordinator/UserSessionsOverviewCoordinator.swift @@ -39,7 +39,10 @@ final class UserSessionsOverviewCoordinator: Coordinator, Presentable { self.parameters = parameters service = parameters.service - viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: parameters.service, settingsService: RiotSettings.shared) + let shouldShowDeviceLogout = parameters.session.homeserverWellknown.authentication == nil + viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: parameters.service, + settingsService: RiotSettings.shared, + showDeviceLogout: shouldShowDeviceLogout) hostingViewController = VectorHostingController(rootView: UserSessionsOverview(viewModel: viewModel.context)) hostingViewController.vc_setLargeTitleDisplayMode(.never) diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/MockUserSessionsOverviewScreenState.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/MockUserSessionsOverviewScreenState.swift index e09586b83..6132febae 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/MockUserSessionsOverviewScreenState.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/MockUserSessionsOverviewScreenState.swift @@ -51,7 +51,7 @@ enum MockUserSessionsOverviewScreenState: MockScreenState, CaseIterable { fatalError() } - let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: service, settingsService: MockUserSessionSettings()) + let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: service, settingsService: MockUserSessionSettings(), showDeviceLogout: true) return ( [service, viewModel], diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Test/Unit/UserSessionsOverviewViewModelTests.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Test/Unit/UserSessionsOverviewViewModelTests.swift index 8ce396a6e..27237983f 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Test/Unit/UserSessionsOverviewViewModelTests.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Test/Unit/UserSessionsOverviewViewModelTests.swift @@ -21,7 +21,9 @@ import XCTest class UserSessionsOverviewViewModelTests: XCTestCase { func testInitialStateEmpty() { - let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: MockUserSessionsOverviewService(), settingsService: MockUserSessionSettings()) + let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: MockUserSessionsOverviewService(), + settingsService: MockUserSessionSettings(), + showDeviceLogout: true) XCTAssertNil(viewModel.state.currentSessionViewData) XCTAssertTrue(viewModel.state.unverifiedSessionsViewData.isEmpty) @@ -31,7 +33,9 @@ class UserSessionsOverviewViewModelTests: XCTestCase { } func testLoadOnDidAppear() { - let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: MockUserSessionsOverviewService(), settingsService: MockUserSessionSettings()) + let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: MockUserSessionsOverviewService(), + settingsService: MockUserSessionSettings(), + showDeviceLogout: true) viewModel.process(viewAction: .viewAppeared) XCTAssertNotNil(viewModel.state.currentSessionViewData) @@ -42,7 +46,9 @@ class UserSessionsOverviewViewModelTests: XCTestCase { } func testSimpleActionProcessing() { - let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: MockUserSessionsOverviewService(), settingsService: MockUserSessionSettings()) + let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: MockUserSessionsOverviewService(), + settingsService: MockUserSessionSettings(), + showDeviceLogout: true) var result: UserSessionsOverviewViewModelResult? viewModel.completion = { action in @@ -69,7 +75,9 @@ class UserSessionsOverviewViewModelTests: XCTestCase { let service = MockUserSessionsOverviewService() service.updateOverviewData { _ in } - let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: service, settingsService: MockUserSessionSettings()) + let viewModel = UserSessionsOverviewViewModel(userSessionsOverviewService: service, + settingsService: MockUserSessionSettings(), + showDeviceLogout: true) var result: UserSessionsOverviewViewModelResult? viewModel.completion = { action in diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewModels.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewModels.swift index a7429f12f..74f35a087 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewModels.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewModels.swift @@ -51,6 +51,7 @@ struct UserSessionsOverviewViewState: BindableState { var showLoadingIndicator = false var linkDeviceButtonVisible = false var showLocationInfo: Bool + var showDeviceLogout: Bool } enum UserSessionsOverviewViewAction { diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewViewModel.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewViewModel.swift index a2d92628a..244126008 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewViewModel.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/UserSessionsOverviewViewModel.swift @@ -24,11 +24,11 @@ class UserSessionsOverviewViewModel: UserSessionsOverviewViewModelType, UserSess var completion: ((UserSessionsOverviewViewModelResult) -> Void)? - init(userSessionsOverviewService: UserSessionsOverviewServiceProtocol, settingsService: UserSessionSettingsProtocol) { + init(userSessionsOverviewService: UserSessionsOverviewServiceProtocol, settingsService: UserSessionSettingsProtocol, showDeviceLogout: Bool) { self.userSessionsOverviewService = userSessionsOverviewService self.settingsService = settingsService - super.init(initialViewState: .init(showLocationInfo: settingsService.showIPAddressesInSessionsManager)) + super.init(initialViewState: .init(showLocationInfo: settingsService.showIPAddressesInSessionsManager, showDeviceLogout: showDeviceLogout)) userSessionsOverviewService.overviewDataPublisher.sink { [weak self] overviewData in self?.updateViewState(with: overviewData) diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/View/UserSessionsOverview.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/View/UserSessionsOverview.swift index 9cfc89ca4..c78718346 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/View/UserSessionsOverview.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/View/UserSessionsOverview.swift @@ -125,7 +125,7 @@ struct UserSessionsOverview: View { Label(VectorL10n.signOut, systemImage: "rectangle.portrait.and.arrow.right.fill") } } - if viewModel.viewState.otherSessionsViewData.count > 0 { + if viewModel.viewState.otherSessionsViewData.count > 0, viewModel.viewState.showDeviceLogout { DestructiveButton { viewModel.send(viewAction: .logoutOtherSessions) } label: { @@ -149,10 +149,12 @@ struct UserSessionsOverview: View { Label(showLocationInfo: viewModel.viewState.showLocationInfo) } - DestructiveButton { - viewModel.send(viewAction: .logoutOtherSessions) - } label: { - Label(VectorL10n.userOtherSessionMenuSignOutSessions(String(viewModel.viewState.otherSessionsViewData.count)), systemImage: "rectangle.portrait.and.arrow.forward.fill") + if viewModel.viewState.showDeviceLogout { + DestructiveButton { + viewModel.send(viewAction: .logoutOtherSessions) + } label: { + Label(VectorL10n.userOtherSessionMenuSignOutSessions(String(viewModel.viewState.otherSessionsViewData.count)), systemImage: "rectangle.portrait.and.arrow.forward.fill") + } } } label: { menuImage diff --git a/changelog.d/7672.bugfix b/changelog.d/7672.bugfix new file mode 100644 index 000000000..d46797f9c --- /dev/null +++ b/changelog.d/7672.bugfix @@ -0,0 +1 @@ +Hide Sign Out X/All Sessions buttons in the Device Manager when using OIDC. \ No newline at end of file From dde602beac902f4b0cd5ec00f0acff1e64fabed3 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 12 Sep 2023 18:05:52 +0100 Subject: [PATCH 13/16] Use ASWebAuthenticationSession to display OIDC account management URL (#7671) Co-authored-by: Doug --- .../SSO/SSOAccountService.swift | 48 +++++++++++++++++++ .../SSO/SSOAuthenticationPresenter.swift | 4 +- .../SSO/SSOAuthenticationService.swift | 10 +++- .../ManageSessionViewController.m | 43 +++++++++++++---- .../Modules/Settings/SettingsViewController.m | 34 ++++++++++++- .../UserSessionsFlowCoordinator.swift | 37 +++++++++++--- changelog.d/7671.bugfix | 1 + 7 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 Riot/Modules/Authentication/SSO/SSOAccountService.swift create mode 100644 changelog.d/7671.bugfix diff --git a/Riot/Modules/Authentication/SSO/SSOAccountService.swift b/Riot/Modules/Authentication/SSO/SSOAccountService.swift new file mode 100644 index 000000000..4623fb84f --- /dev/null +++ b/Riot/Modules/Authentication/SSO/SSOAccountService.swift @@ -0,0 +1,48 @@ +// +// Copyright 2020 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +@objcMembers +/// A service for the SSOAuthenticationPresenter that allows to open an OIDC account management URL. +/// +/// Both `callBackURLScheme` and `loginToken` are unneeded for this use case and return `nil`. +final class SSOAccountService: NSObject, SSOAuthenticationServiceProtocol { + + // MARK: - Properties + + private let accountURL: URL + + let callBackURLScheme: String? = nil + + // MARK: - Setup + + init(accountURL: URL) { + self.accountURL = accountURL + super.init() + } + + // MARK: - Public + + func authenticationURL(for identityProvider: String?, transactionId: String) -> URL? { + accountURL + } + + func loginToken(from url: URL) -> String? { + MXLog.error("The account service shouldn't receive a completion callback.") + return nil + } +} diff --git a/Riot/Modules/Authentication/SSO/SSOAuthenticationPresenter.swift b/Riot/Modules/Authentication/SSO/SSOAuthenticationPresenter.swift index 1145d8651..b45f3a804 100644 --- a/Riot/Modules/Authentication/SSO/SSOAuthenticationPresenter.swift +++ b/Riot/Modules/Authentication/SSO/SSOAuthenticationPresenter.swift @@ -37,7 +37,7 @@ final class SSOAuthenticationPresenter: NSObject { // MARK: - Properties - private let ssoAuthenticationService: SSOAuthenticationService + private let ssoAuthenticationService: SSOAuthenticationServiceProtocol // MARK: Private @@ -53,7 +53,7 @@ final class SSOAuthenticationPresenter: NSObject { // MARK: - Setup - init(ssoAuthenticationService: SSOAuthenticationService) { + init(ssoAuthenticationService: SSOAuthenticationServiceProtocol) { self.ssoAuthenticationService = ssoAuthenticationService super.init() } diff --git a/Riot/Modules/Authentication/SSO/SSOAuthenticationService.swift b/Riot/Modules/Authentication/SSO/SSOAuthenticationService.swift index 706c3782d..cb3d36d07 100644 --- a/Riot/Modules/Authentication/SSO/SSOAuthenticationService.swift +++ b/Riot/Modules/Authentication/SSO/SSOAuthenticationService.swift @@ -22,8 +22,16 @@ enum SSOAuthenticationServiceError: Error { case unknown } +@objc protocol SSOAuthenticationServiceProtocol { + var callBackURLScheme: String? { get } + + func authenticationURL(for identityProvider: String?, transactionId: String) -> URL? + + func loginToken(from url: URL) -> String? +} + @objcMembers -final class SSOAuthenticationService: NSObject { +final class SSOAuthenticationService: NSObject, SSOAuthenticationServiceProtocol { // MARK: - Constants diff --git a/Riot/Modules/Settings/Security/ManageSession/ManageSessionViewController.m b/Riot/Modules/Settings/Security/ManageSession/ManageSessionViewController.m index e1fd5c5e8..665f970ac 100644 --- a/Riot/Modules/Settings/Security/ManageSession/ManageSessionViewController.m +++ b/Riot/Modules/Settings/Security/ManageSession/ManageSessionViewController.m @@ -45,7 +45,7 @@ enum { }; -@interface ManageSessionViewController () +@interface ManageSessionViewController () { // The device to display MXDevice *device; @@ -64,6 +64,8 @@ enum { @property (nonatomic, strong) ReauthenticationCoordinatorBridgePresenter *reauthenticationCoordinatorBridgePresenter; +@property (nonatomic, strong) SSOAuthenticationPresenter *ssoAuthenticationPresenter; + @end @implementation ManageSessionViewController @@ -679,17 +681,19 @@ enum { { UIAlertController *alert = [UIAlertController alertControllerWithTitle: [VectorL10n manageSessionRedirect] message: nil preferredStyle:UIAlertControllerStyleAlert]; - __weak typeof(self) weakSelf = self; + MXWeakify(self); UIAlertAction *action = [UIAlertAction actionWithTitle:[VectorL10n ok] style:UIAlertActionStyleDefault handler: ^(UIAlertAction * action) { - [UIApplication.sharedApplication openURL:url options:@{} completionHandler:^(BOOL success) { - if (success && weakSelf) - { - [weakSelf withdrawViewControllerAnimated:YES completion:nil]; - } - }]; + MXStrongifyAndReturnIfNil(self); + SSOAccountService *service = [[SSOAccountService alloc] initWithAccountURL:url]; + SSOAuthenticationPresenter *presenter = [[SSOAuthenticationPresenter alloc] initWithSsoAuthenticationService:service]; + presenter.delegate = self; + self.ssoAuthenticationPresenter = presenter; + + [presenter presentForIdentityProvider:nil with:@"" from:self animated:YES]; }]; + [alert addAction: action]; [self presentViewController:alert animated:YES completion:nil]; } @@ -755,4 +759,27 @@ enum { [self reloadDeviceWithCompletion:^{}]; } +#pragma mark - SSOAuthenticationPresenterDelegate + +- (void)ssoAuthenticationPresenterDidCancel:(SSOAuthenticationPresenter *)presenter +{ + self.ssoAuthenticationPresenter = nil; + MXLogDebug(@"OIDC account management complete.") + [self withdrawViewControllerAnimated:YES completion:nil]; +} + +- (void)ssoAuthenticationPresenter:(SSOAuthenticationPresenter *)presenter authenticationDidFailWithError:(NSError *)error +{ + self.ssoAuthenticationPresenter = nil; + MXLogError(@"OIDC account management failed.") +} + +- (void)ssoAuthenticationPresenter:(SSOAuthenticationPresenter *)presenter + authenticationSucceededWithToken:(NSString *)token + usingIdentityProvider:(SSOIdentityProvider *)identityProvider +{ + self.ssoAuthenticationPresenter = nil; + MXLogWarning(@"Unexpected callback after OIDC account management.") +} + @end diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 32871e008..6f9c22465 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -204,7 +204,8 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate, ServiceTermsModalCoordinatorBridgePresenterDelegate, TableViewSectionsDelegate, ThreadsBetaCoordinatorBridgePresenterDelegate, -ChangePasswordCoordinatorBridgePresenterDelegate> +ChangePasswordCoordinatorBridgePresenterDelegate, +SSOAuthenticationPresenterDelegate> { // Current alert (if any). __weak UIAlertController *currentAlert; @@ -300,6 +301,8 @@ ChangePasswordCoordinatorBridgePresenterDelegate> @property (nonatomic) BOOL isPreparingIdentityService; @property (nonatomic, strong) ServiceTermsModalCoordinatorBridgePresenter *serviceTermsModalCoordinatorBridgePresenter; +@property (nonatomic, strong) SSOAuthenticationPresenter *ssoAuthenticationPresenter; + @property (nonatomic) AnalyticsScreenTracker *screenTracker; @end @@ -3926,7 +3929,12 @@ ChangePasswordCoordinatorBridgePresenterDelegate> { NSURL *url = [NSURL URLWithString: self.mainSession.homeserverWellknown.authentication.account]; if (url) { - [UIApplication.sharedApplication openURL:url options:@{} completionHandler:nil]; + SSOAccountService *service = [[SSOAccountService alloc] initWithAccountURL:url]; + SSOAuthenticationPresenter *presenter = [[SSOAuthenticationPresenter alloc] initWithSsoAuthenticationService:service]; + presenter.delegate = self; + self.ssoAuthenticationPresenter = presenter; + + [presenter presentForIdentityProvider:nil with:@"" from:self animated:YES]; } } @@ -4602,4 +4610,26 @@ ChangePasswordCoordinatorBridgePresenterDelegate> [self.userSessionsFlowCoordinatorBridgePresenter pushFrom:self.navigationController animated:YES]; } +#pragma mark - SSOAuthenticationPresenterDelegate + +- (void)ssoAuthenticationPresenterDidCancel:(SSOAuthenticationPresenter *)presenter +{ + self.ssoAuthenticationPresenter = nil; + MXLogDebug(@"OIDC account management complete.") +} + +- (void)ssoAuthenticationPresenter:(SSOAuthenticationPresenter *)presenter authenticationDidFailWithError:(NSError *)error +{ + self.ssoAuthenticationPresenter = nil; + MXLogError(@"OIDC account management failed.") +} + +- (void)ssoAuthenticationPresenter:(SSOAuthenticationPresenter *)presenter + authenticationSucceededWithToken:(NSString *)token + usingIdentityProvider:(SSOIdentityProvider *)identityProvider +{ + self.ssoAuthenticationPresenter = nil; + MXLogWarning(@"Unexpected callback after OIDC account management.") +} + @end diff --git a/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift b/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift index 5225b9fd0..ff24b1aa3 100644 --- a/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift +++ b/RiotSwiftUI/Modules/UserSessions/Coordinator/UserSessionsFlowCoordinator.swift @@ -32,6 +32,7 @@ final class UserSessionsFlowCoordinator: NSObject, Coordinator, Presentable { private var errorPresenter: MXKErrorPresentation private var indicatorPresenter: UserIndicatorTypePresenterProtocol private var loadingIndicator: UserIndicator? + private var ssoAuthenticationPresenter: SSOAuthenticationPresenter? /// The root coordinator for user session management. private weak var sessionsOverviewCoordinator: UserSessionsOverviewCoordinator? @@ -199,12 +200,14 @@ final class UserSessionsFlowCoordinator: NSObject, Coordinator, Presentable { private func openDeviceLogoutRedirectURL(_ url: URL) { let alert = UIAlertController(title: VectorL10n.manageSessionRedirect, message: nil, preferredStyle: .alert) alert.addAction(UIAlertAction(title: VectorL10n.ok, style: .default) { [weak self] _ in - UIApplication.shared.open(url) { [weak self] success in - guard success else { - return - } - self?.popToSessionsOverview() - } + guard let self else { return } + + let service = SSOAccountService(accountURL: url) + let presenter = SSOAuthenticationPresenter(ssoAuthenticationService: service) + presenter.delegate = self + self.ssoAuthenticationPresenter = presenter + + presenter.present(forIdentityProvider: nil, with: "", from: self.toPresentable(), animated: true) }) alert.popoverPresentationController?.sourceView = toPresentable().view navigationRouter.present(alert, animated: true) @@ -549,3 +552,25 @@ private extension UserOtherSessionsFilter { } } } + +// MARK: ASWebAuthenticationPresentationContextProviding + +extension UserSessionsFlowCoordinator: SSOAuthenticationPresenterDelegate { + func ssoAuthenticationPresenterDidCancel(_ presenter: SSOAuthenticationPresenter) { + ssoAuthenticationPresenter = nil + MXLog.info("OIDC account management complete.") + popToSessionsOverview() + } + + func ssoAuthenticationPresenter(_ presenter: SSOAuthenticationPresenter, authenticationDidFailWithError error: Error) { + ssoAuthenticationPresenter = nil + MXLog.error("OIDC account management failed.") + } + + func ssoAuthenticationPresenter(_ presenter: SSOAuthenticationPresenter, + authenticationSucceededWithToken token: String, + usingIdentityProvider identityProvider: SSOIdentityProvider?) { + ssoAuthenticationPresenter = nil + MXLog.warning("Unexpected callback after OIDC account management.") + } +} diff --git a/changelog.d/7671.bugfix b/changelog.d/7671.bugfix new file mode 100644 index 000000000..99d153ad4 --- /dev/null +++ b/changelog.d/7671.bugfix @@ -0,0 +1 @@ +Show OIDC account management UI using embedded browser instead of system browser. \ No newline at end of file From 8f0580ca7ec80944eb8c1453619ac33ef1cc9116 Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:07:49 +0100 Subject: [PATCH 14/16] Also hide session selection with OIDC in the device manager. (#7675) --- .../View/UserOtherSessionsToolbar.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift index d3c0b3bb0..ba844904e 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessionsToolbar.swift @@ -82,12 +82,14 @@ struct UserOtherSessionsToolbar: ToolbarContent { private func optionsMenu() -> some View { Button { } label: { Menu { - Button { - isEditModeEnabled = true - } label: { - Label(VectorL10n.userOtherSessionMenuSelectSessions, systemImage: "checkmark.circle") + if showDeviceLogout { // As you can only sign out the selected sessions, we don't allow selection when you're unable to sign out devices. + Button { + isEditModeEnabled = true + } label: { + Label(VectorL10n.userOtherSessionMenuSelectSessions, systemImage: "checkmark.circle") + } + .disabled(sessionCount == 0) } - .disabled(sessionCount == 0) Button { isShowLocationEnabled.toggle() From 638a54ce7c90e11ccdc6b1be4e021af864a3d914 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 13 Sep 2023 15:19:11 +0100 Subject: [PATCH 15/16] version++ --- CHANGES.md | 8 ++++++++ changelog.d/7671.bugfix | 1 - changelog.d/7672.bugfix | 1 - 3 files changed, 8 insertions(+), 2 deletions(-) delete mode 100644 changelog.d/7671.bugfix delete mode 100644 changelog.d/7672.bugfix diff --git a/CHANGES.md b/CHANGES.md index 3a269699d..9aacbd168 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +## Changes in 1.11.3 (2023-09-13) + +🐛 Bugfixes + +- Show OIDC account management UI using embedded browser instead of system browser. ([#7671](https://github.com/vector-im/element-ios/issues/7671)) +- Hide Sign Out X/All Sessions buttons in the Device Manager when using OIDC. ([#7672](https://github.com/vector-im/element-ios/issues/7672)) + + ## Changes in 1.11.2 (2023-09-12) 🙌 Improvements diff --git a/changelog.d/7671.bugfix b/changelog.d/7671.bugfix deleted file mode 100644 index 99d153ad4..000000000 --- a/changelog.d/7671.bugfix +++ /dev/null @@ -1 +0,0 @@ -Show OIDC account management UI using embedded browser instead of system browser. \ No newline at end of file diff --git a/changelog.d/7672.bugfix b/changelog.d/7672.bugfix deleted file mode 100644 index d46797f9c..000000000 --- a/changelog.d/7672.bugfix +++ /dev/null @@ -1 +0,0 @@ -Hide Sign Out X/All Sessions buttons in the Device Manager when using OIDC. \ No newline at end of file From ecb7b39cd5d27f7d5c399c75ff93db5b6def0dd5 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 13 Sep 2023 16:06:20 +0100 Subject: [PATCH 16/16] finish version++