mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-16 06:28:27 +02:00
Merged element 1.11.3 into bum
This commit is contained in:
@@ -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
|
||||
|
||||
20
CHANGES.md
20
CHANGES.md
@@ -1,3 +1,23 @@
|
||||
## 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
|
||||
|
||||
- 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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
52
Config/MDMSettings.swift
Normal file
52
Config/MDMSettings.swift
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// 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 {
|
||||
print("MDM configuration missing")
|
||||
return nil
|
||||
}
|
||||
|
||||
print("Retrieved MDM configuration: \(managedConfiguration)")
|
||||
|
||||
return managedConfiguration[key.rawValue]
|
||||
}
|
||||
}
|
||||
19
INSTALL.md
19
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 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.
|
||||
|
||||
2
Podfile
2
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' } }
|
||||
|
||||
77
Podfile.lock
77
Podfile.lock
@@ -20,31 +20,13 @@ PODS:
|
||||
- Down (0.11.0)
|
||||
- DSBottomSheet (0.3.0)
|
||||
- DSWaveformImage (6.1.1)
|
||||
- DTCoreText (1.6.26):
|
||||
- DTCoreText/Core (= 1.6.26)
|
||||
- DTFoundation/Core (~> 1.7.5)
|
||||
- DTFoundation/DTAnimatedGIF (~> 1.7.5)
|
||||
- DTFoundation/DTHTMLParser (~> 1.7.5)
|
||||
- DTFoundation/UIKit (~> 1.7.5)
|
||||
- DTCoreText/Core (1.6.26):
|
||||
- DTFoundation/Core (~> 1.7.5)
|
||||
- DTFoundation/DTAnimatedGIF (~> 1.7.5)
|
||||
- DTFoundation/DTHTMLParser (~> 1.7.5)
|
||||
- DTFoundation/UIKit (~> 1.7.5)
|
||||
- DTFoundation/Core (1.7.18)
|
||||
- DTFoundation/DTAnimatedGIF (1.7.18)
|
||||
- DTFoundation/DTHTMLParser (1.7.18):
|
||||
- DTFoundation/Core
|
||||
- DTFoundation/UIKit (1.7.18):
|
||||
- DTFoundation/Core
|
||||
- DTTJailbreakDetection (0.4.0)
|
||||
- FLEX (4.5.0)
|
||||
- FlowCommoniOS (1.12.2)
|
||||
- GBDeviceInfo (7.1.0):
|
||||
- GBDeviceInfo/Core (= 7.1.0)
|
||||
- GBDeviceInfo/Core (7.1.0)
|
||||
- GZIP (1.3.0)
|
||||
- Introspect (0.12.0)
|
||||
- Introspect (0.11.0)
|
||||
- JitsiMeetSDKLite (8.1.2-lite):
|
||||
- JitsiWebRTC (~> 111.0)
|
||||
- JitsiWebRTC (111.0.2)
|
||||
@@ -57,12 +39,9 @@ PODS:
|
||||
- LoggerAPI (1.9.200):
|
||||
- Logging (~> 1.1)
|
||||
- Logging (1.4.0)
|
||||
- MatomoTracker (7.5.2):
|
||||
- MatomoTracker/Core (= 7.5.2)
|
||||
- MatomoTracker/Core (7.5.2)
|
||||
- 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)
|
||||
@@ -70,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)
|
||||
@@ -79,7 +58,7 @@ PODS:
|
||||
- OLMKit/olmcpp (= 3.2.12)
|
||||
- OLMKit/olmc (3.2.12)
|
||||
- OLMKit/olmcpp (3.2.12)
|
||||
- PostHog (2.0.2)
|
||||
- PostHog (2.0.0)
|
||||
- ReadMoreTextView (3.0.1)
|
||||
- Realm (10.27.0):
|
||||
- Realm/Headers (= 10.27.0)
|
||||
@@ -94,7 +73,7 @@ PODS:
|
||||
- Sentry/Core (7.15.0)
|
||||
- SideMenu (6.5.0)
|
||||
- SwiftBase32 (0.9.0)
|
||||
- SwiftFormat/CLI (0.52.3)
|
||||
- SwiftFormat/CLI (0.50.2)
|
||||
- SwiftGen (6.6.2)
|
||||
- SwiftJWT (3.6.200):
|
||||
- BlueCryptor (~> 1.0)
|
||||
@@ -102,7 +81,7 @@ PODS:
|
||||
- BlueRSA (~> 1.0)
|
||||
- KituraContracts (~> 1.2)
|
||||
- LoggerAPI (~> 1.7)
|
||||
- SwiftLint (0.52.4)
|
||||
- SwiftLint (0.49.1)
|
||||
- SwiftyBeaver (1.9.5)
|
||||
- UICollectionViewLeftAlignedLayout (1.0.2)
|
||||
- UICollectionViewRightAlignedLayout (0.0.3)
|
||||
@@ -116,8 +95,6 @@ DEPENDENCIES:
|
||||
- Down (~> 0.11.0)
|
||||
- DSBottomSheet (~> 0.3)
|
||||
- DSWaveformImage (~> 6.1.1)
|
||||
- DTCoreText (= 1.6.26)
|
||||
- DTTJailbreakDetection (~> 0.4.0)
|
||||
- FLEX (~> 4.5.0)
|
||||
- FlowCommoniOS (~> 1.12.0)
|
||||
- GBDeviceInfo (~> 7.1.0)
|
||||
@@ -125,9 +102,8 @@ DEPENDENCIES:
|
||||
- KeychainAccess (~> 4.2.2)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatomoTracker (~> 7.5.2)
|
||||
- MatrixSDK (from `https://dl-gitlab.example.com/bwmessenger/bundesmessenger/bundesmessenger-ios-sdk`, tag `v2.10.0_rc2`)
|
||||
- MatrixSDK/JingleCallStack (from `https://dl-gitlab.example.com/bwmessenger/bundesmessenger/bundesmessenger-ios-sdk`, tag `v2.10.0_rc2`)
|
||||
- MatrixSDK (= 0.27.2)
|
||||
- MatrixSDK/JingleCallStack (= 0.27.2)
|
||||
- OLMKit
|
||||
- PostHog (~> 2.0.0)
|
||||
- ReadMoreTextView (~> 3.0.1)
|
||||
@@ -146,7 +122,7 @@ DEPENDENCIES:
|
||||
- ZXingObjC (~> 3.6.5)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/CocoaPods/Specs.git:
|
||||
trunk:
|
||||
- AFNetworking
|
||||
- BlueCryptor
|
||||
- BlueECC
|
||||
@@ -154,9 +130,6 @@ SPEC REPOS:
|
||||
- Down
|
||||
- DSBottomSheet
|
||||
- DSWaveformImage
|
||||
- DTCoreText
|
||||
- DTFoundation
|
||||
- DTTJailbreakDetection
|
||||
- FLEX
|
||||
- FlowCommoniOS
|
||||
- GBDeviceInfo
|
||||
@@ -171,7 +144,7 @@ SPEC REPOS:
|
||||
- libPhoneNumber-iOS
|
||||
- LoggerAPI
|
||||
- Logging
|
||||
- MatomoTracker
|
||||
- MatrixSDK
|
||||
- MatrixSDKCrypto
|
||||
- OLMKit
|
||||
- PostHog
|
||||
@@ -192,16 +165,6 @@ SPEC REPOS:
|
||||
- zxcvbn-ios
|
||||
- ZXingObjC
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
MatrixSDK:
|
||||
:git: https://dl-gitlab.example.com/bwmessenger/bundesmessenger/bundesmessenger-ios-sdk
|
||||
:tag: v2.10.0_rc2
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
MatrixSDK:
|
||||
:git: https://dl-gitlab.example.com/bwmessenger/bundesmessenger/bundesmessenger-ios-sdk
|
||||
:tag: v2.10.0_rc2
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58
|
||||
BlueCryptor: b0aee3d9b8f367b49b30de11cda90e1735571c24
|
||||
@@ -210,14 +173,11 @@ SPEC CHECKSUMS:
|
||||
Down: b6ba1bc985c9d2f4e15e3b293d2207766fa12612
|
||||
DSBottomSheet: ca0ac37eb5af2dd54663f86b84382ed90a59be2a
|
||||
DSWaveformImage: 3c718a0cf99291887ee70d1d0c18d80101d3d9ce
|
||||
DTCoreText: ec749e013f2e1f76de5e7c7634642e600a7467ce
|
||||
DTFoundation: a53f8cda2489208cbc71c648be177f902ee17536
|
||||
DTTJailbreakDetection: 5e356c5badc17995f65a83ed9483f787a0057b71
|
||||
FLEX: e51461dd6f0bfb00643c262acdfea5d5d12c596b
|
||||
FlowCommoniOS: ca92071ab526dc89905495a37844fd7e78d1a7f2
|
||||
GBDeviceInfo: 5d62fa85bdcce3ed288d83c28789adf1173e4376
|
||||
GZIP: 416858efbe66b41b206895ac6dfd5493200d95b3
|
||||
Introspect: b66b675de8a85d9ef832f3a710d8e3c7db186884
|
||||
Introspect: 4cc1e4c34dd016540c8d86a591c231c09dafbee3
|
||||
JitsiMeetSDKLite: 895213158cf62342069a10634a41d2f1c00057f7
|
||||
JitsiWebRTC: 80f62908fcf2a1160e0d14b584323fb6e6be630b
|
||||
KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51
|
||||
@@ -227,21 +187,20 @@ SPEC CHECKSUMS:
|
||||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatomoTracker: 1d98ddc58322fd9d65e1a6886b8e41363047bd13
|
||||
MatrixSDK: f6c197ca06aab29ff69d1105965a57d277dfcd9d
|
||||
MatrixSDK: a39e229a03a00394e055ffa7490e9602d45f8a44
|
||||
MatrixSDKCrypto: 25929a40733b4ab54f659aaf6a730552a0a06504
|
||||
OLMKit: da115f16582e47626616874e20f7bb92222c7a51
|
||||
PostHog: f9e5c13ceea86bb5314218c85d16125b797eb332
|
||||
PostHog: 660ec6c9d80cec17b685e148f17f6785a88b597d
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
Realm: 9ca328bd7e700cc19703799785e37f77d1a130f2
|
||||
Reusable: 6bae6a5e8aa793c9c441db0213c863a64bce9136
|
||||
Sentry: 63ca44f5e0c8cea0ee5a07686b02e56104f41ef7
|
||||
SideMenu: f583187d21c5b1dd04c72002be544b555a2627a2
|
||||
SwiftBase32: 9399c25a80666dc66b51e10076bf591e3bbb8f17
|
||||
SwiftFormat: 5de81c42f043741a16e17ae2da012bbddc7c0b58
|
||||
SwiftFormat: 710117321c55c82675c0dc03055128efbb13c38f
|
||||
SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c
|
||||
SwiftJWT: 88c412708f58c169d431d344c87bc79a87c830ae
|
||||
SwiftLint: 1cc5cd61ba9bacb2194e340aeb47a2a37fda00b3
|
||||
SwiftLint: 32ee33ded0636d0905ef6911b2b67bbaeeedafa5
|
||||
SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82
|
||||
UICollectionViewLeftAlignedLayout: 830bf6fa5bab9f9b464f62e3384f9d2e00b3c0f6
|
||||
UICollectionViewRightAlignedLayout: 823eef8c567eba4a44c21bc2ffcb0d0d5f361e2d
|
||||
@@ -249,6 +208,6 @@ SPEC CHECKSUMS:
|
||||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: e7f4847564a30ed02659a311fe204021498f30e8
|
||||
PODFILE CHECKSUM: b926e281576aabcdbc2bdcb40ef3ad3e0991abe8
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
48
Riot/Modules/Authentication/SSO/SSOAccountService.swift
Normal file
48
Riot/Modules/Authentication/SSO/SSOAccountService.swift
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4634,7 +4634,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) {
|
||||
|
||||
@@ -46,7 +46,7 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
@interface ManageSessionViewController () <UserVerificationCoordinatorBridgePresenterDelegate>
|
||||
@interface ManageSessionViewController () <UserVerificationCoordinatorBridgePresenterDelegate, SSOAuthenticationPresenterDelegate>
|
||||
{
|
||||
// The device to display
|
||||
MXDevice *device;
|
||||
@@ -65,6 +65,8 @@ enum {
|
||||
|
||||
@property (nonatomic, strong) ReauthenticationCoordinatorBridgePresenter *reauthenticationCoordinatorBridgePresenter;
|
||||
|
||||
@property (nonatomic, strong) SSOAuthenticationPresenter *ssoAuthenticationPresenter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ManageSessionViewController
|
||||
@@ -701,17 +703,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];
|
||||
}
|
||||
@@ -777,4 +781,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
|
||||
|
||||
@@ -272,7 +272,8 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate,
|
||||
ServiceTermsModalCoordinatorBridgePresenterDelegate,
|
||||
TableViewSectionsDelegate,
|
||||
ThreadsBetaCoordinatorBridgePresenterDelegate,
|
||||
ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
ChangePasswordCoordinatorBridgePresenterDelegate,
|
||||
SSOAuthenticationPresenterDelegate>
|
||||
{
|
||||
// Current alert (if any).
|
||||
__weak UIAlertController *currentAlert;
|
||||
@@ -373,6 +374,8 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
@property (nonatomic) BOOL isPreparingIdentityService;
|
||||
@property (nonatomic, strong) ServiceTermsModalCoordinatorBridgePresenter *serviceTermsModalCoordinatorBridgePresenter;
|
||||
|
||||
@property (nonatomic, strong) SSOAuthenticationPresenter *ssoAuthenticationPresenter;
|
||||
|
||||
@property (nonatomic) AnalyticsScreenTracker *screenTracker;
|
||||
|
||||
@end
|
||||
@@ -473,24 +476,29 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
[sectionUserSettings addRowWithTag: USER_SETTINGS_PHONENUMBERS_OFFSET + index];
|
||||
}
|
||||
}
|
||||
if (BWIBuildSettings.shared.settingsScreenAllowAddingEmailThreepids &&
|
||||
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 (BWIBuildSettings.shared.settingsScreenAllowAddingPhoneThreepids)
|
||||
{
|
||||
[sectionUserSettings addRowWithTag:USER_SETTINGS_ADD_PHONENUMBER_INDEX];
|
||||
}
|
||||
if (BWIBuildSettings.shared.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 (BWIBuildSettings.shared.settingsScreenAllowAddingEmailThreepids &&
|
||||
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 (BWIBuildSettings.shared.settingsScreenAllowAddingPhoneThreepids)
|
||||
{
|
||||
[sectionUserSettings addRowWithTag:USER_SETTINGS_ADD_PHONENUMBER_INDEX];
|
||||
}
|
||||
if (BWIBuildSettings.shared.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];
|
||||
@@ -4498,7 +4506,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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5510,4 +5523,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
|
||||
|
||||
@@ -60,6 +60,7 @@ targets:
|
||||
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
|
||||
- path: ../bwi/UserAgent/UserAgentService.swift
|
||||
- path: ../bwi/LoginProtection/LoginProtectionService.swift
|
||||
- path: ../Config/MDMSettings.swift
|
||||
- path: ../Riot/Utils/DataProtectionHelper.swift
|
||||
- path: ../Config/CommonConfiguration.swift
|
||||
- path: ../Riot/Experiments/
|
||||
|
||||
@@ -53,10 +53,11 @@ class ForwardingShareItemSender: NSObject, ShareItemSenderProtocol {
|
||||
var localEcho: MXEvent?
|
||||
room.sendMessage(withContent: event.content, threadId: nil, localEcho: &localEcho) { result in
|
||||
switch result {
|
||||
case .success(_):
|
||||
self.trackForwardMessage(room: room)
|
||||
case .failure(let innerError):
|
||||
errors.append(innerError)
|
||||
default:
|
||||
room.summary.resetLastMessage(nil, failure: nil, commit: false)
|
||||
break
|
||||
}
|
||||
|
||||
dispatchGroup.leave()
|
||||
@@ -72,12 +73,4 @@ class ForwardingShareItemSender: NSObject, ShareItemSenderProtocol {
|
||||
success()
|
||||
}
|
||||
}
|
||||
|
||||
func trackForwardMessage(room: MXRoom) {
|
||||
BWIAnalyticsHelper.getRoomDeviceCount(room: room) { deviceCount in
|
||||
let deviceCountString = BWIAnalyticsHelper.dimensionForDeviceCount(deviceCount)
|
||||
let messageType = BWIAnalyticsHelper.getForwardingType(event: self.event)
|
||||
BWIAnalytics.sharedTracker.trackEventWithDimension(category: "Feature", action: "ForwardMessage", dimension: deviceCountString, value: nil, name: messageType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@ typedef NS_ENUM(NSUInteger, ShareManagerResult) {
|
||||
@property (nonatomic, copy) void (^completionCallback)(ShareManagerResult);
|
||||
|
||||
- (instancetype)initWithShareItemSender:(id<ShareItemSenderProtocol>)itemSender
|
||||
type:(ShareManagerType)type;
|
||||
type:(ShareManagerType)type
|
||||
session:(nullable MXSession*)session;
|
||||
|
||||
|
||||
- (UIViewController *)mainViewController;
|
||||
|
||||
|
||||
@@ -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<ShareItemSenderProtocol>)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<NSError *> *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<NSString *> *)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<NSError *> *errors) {
|
||||
self.selectedRooms = nil;
|
||||
[self showFailureAlert:[VectorL10n roomEventFailedToSend]];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)showFailureAlert:(NSString *)title
|
||||
{
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
@@ -54,6 +54,7 @@ targets:
|
||||
- path: ../Config/BWIBuildSettings.swift
|
||||
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
|
||||
- path: ../bwi/UserAgent/UserAgentService.swift
|
||||
- path: ../Config/MDMSettings.swift
|
||||
- path: ../Riot/Categories/Character.swift
|
||||
- path: ../Riot/Categories/MXKImageView.swift
|
||||
- path: ../Riot/Categories/MXRoom+Riot.m
|
||||
|
||||
@@ -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?
|
||||
@@ -188,21 +189,25 @@ 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)
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -547,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.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ struct UserOtherSessionsViewState: BindableState, Equatable {
|
||||
var allItemsSelected: Bool
|
||||
var enableSignOutButton: Bool
|
||||
var showLocationInfo: Bool
|
||||
var showDeviceLogout: Bool
|
||||
}
|
||||
|
||||
struct UserOtherSessionsBindings: Equatable {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) })
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -87,12 +88,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)
|
||||
|
||||
if BWIBuildSettings.shared.deviceManagerShowIPAddress {
|
||||
Button {
|
||||
@@ -102,7 +105,7 @@ struct UserOtherSessionsToolbar: ToolbarContent {
|
||||
}
|
||||
}
|
||||
|
||||
if sessionCount > 0 {
|
||||
if sessionCount > 0, showDeviceLogout {
|
||||
DestructiveButton {
|
||||
onSignOut()
|
||||
} label: {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -51,6 +51,7 @@ struct UserSessionsOverviewViewState: BindableState {
|
||||
var showLoadingIndicator = false
|
||||
var linkDeviceButtonVisible = false
|
||||
var showLocationInfo: Bool
|
||||
var showDeviceLogout: Bool
|
||||
}
|
||||
|
||||
enum UserSessionsOverviewViewAction {
|
||||
|
||||
@@ -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
|
||||
let showLocationInfo = BWIBuildSettings.shared.deviceManagerShowIPAddress && settingsService.showIPAddressesInSessionsManager
|
||||
super.init(initialViewState: .init(showLocationInfo: showLocationInfo))
|
||||
super.init(initialViewState: .init(showLocationInfo: showLocationInfo, showDeviceLogout: showDeviceLogout))
|
||||
|
||||
userSessionsOverviewService.overviewDataPublisher.sink { [weak self] overviewData in
|
||||
self?.updateViewState(with: overviewData)
|
||||
|
||||
@@ -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: {
|
||||
@@ -141,19 +141,20 @@ struct UserSessionsOverview: View {
|
||||
|
||||
private var otherSessionsMenu: some View {
|
||||
Menu {
|
||||
if BWIBuildSettings.shared.deviceManagerShowIPAddress {
|
||||
Button {
|
||||
withAnimation {
|
||||
viewModel.send(viewAction: .showLocationInfo)
|
||||
}
|
||||
} label: {
|
||||
Label(showLocationInfo: viewModel.viewState.showLocationInfo)
|
||||
Button {
|
||||
withAnimation {
|
||||
viewModel.send(viewAction: .showLocationInfo)
|
||||
}
|
||||
}
|
||||
DestructiveButton {
|
||||
viewModel.send(viewAction: .logoutOtherSessions)
|
||||
} label: {
|
||||
Label(VectorL10n.userOtherSessionMenuSignOutSessions(String(viewModel.viewState.otherSessionsViewData.count)), systemImage: "rectangle.portrait.and.arrow.forward.fill")
|
||||
Label(showLocationInfo: viewModel.viewState.showLocationInfo)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -55,6 +55,7 @@ targets:
|
||||
- path: ../Config/BuildSettings.swift
|
||||
- path: ../Config/BWIBuildSettings.swift
|
||||
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
|
||||
- path: ../Config/MDMSettings.swift
|
||||
- path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift
|
||||
- path: ../Riot/Categories/String.swift
|
||||
- path: ../Riot/Categories/Character.swift
|
||||
|
||||
@@ -64,6 +64,7 @@ targets:
|
||||
- path: ../Config/BuildSettings.swift
|
||||
- path: ../Config/BWIBuildSettings.swift
|
||||
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
|
||||
- path: ../Config/MDMSettings.swift
|
||||
- path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift
|
||||
- path: ../Riot/Categories/String.swift
|
||||
- path: ../Riot/Categories/Character.swift
|
||||
|
||||
@@ -65,6 +65,7 @@ targets:
|
||||
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
|
||||
- path: ../Config/AppConfiguration.swift
|
||||
- path: ../Config/CommonConfiguration.swift
|
||||
- path: ../Config/MDMSettings.swift
|
||||
- path: ../Riot/Categories/Bundle.swift
|
||||
- path: ../Riot/Managers/AppInfo/AppInfo.swift
|
||||
- path: ../Riot/Managers/AppInfo/AppVersion.swift
|
||||
|
||||
@@ -50,6 +50,7 @@ targets:
|
||||
- path: ../Config/BuildSettings.swift
|
||||
- path: ../Config/BWIBuildSettings.swift
|
||||
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
|
||||
- path: ../Config/MDMSettings.swift
|
||||
- path: ../Config/Configurable.swift
|
||||
- path: ../Riot/Managers/Settings/RiotSettings.swift
|
||||
- path: ../Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift
|
||||
|
||||
Reference in New Issue
Block a user