mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-24 16:36:40 +02:00
Merge branch 'release/1.10.0/master'
This commit is contained in:
+12
@@ -1,3 +1,15 @@
|
||||
## Changes in 1.10.0 (2023-02-02)
|
||||
|
||||
🙌 Improvements
|
||||
|
||||
- CryptoV2: Generate Crypto SDK store key ([#7310](https://github.com/vector-im/element-ios/pull/7310))
|
||||
- Backup: Display backup import progress ([#7319](https://github.com/vector-im/element-ios/pull/7319))
|
||||
- CryptoV2: Reset Crypto SDK on logout ([#7323](https://github.com/vector-im/element-ios/pull/7323))
|
||||
- CryptoV2: Refresh notification service on crypto change ([#7332](https://github.com/vector-im/element-ios/pull/7332))
|
||||
- CryptoV2: Enable Crypto SDK for production ([#7333](https://github.com/vector-im/element-ios/pull/7333))
|
||||
- Upgrade MatrixSDK version ([v0.25.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.25.0)).
|
||||
|
||||
|
||||
## Changes in 1.9.17 (2023-01-26)
|
||||
|
||||
🙌 Improvements
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
//
|
||||
|
||||
// Version
|
||||
MARKETING_VERSION = 1.9.17
|
||||
CURRENT_PROJECT_VERSION = 1.9.17
|
||||
MARKETING_VERSION = 1.10.0
|
||||
CURRENT_PROJECT_VERSION = 1.10.0
|
||||
|
||||
@@ -92,11 +92,14 @@ class CommonConfiguration: NSObject, Configurable {
|
||||
|
||||
sdkOptions.enableNewClientInformationFeature = RiotSettings.shared.enableClientInformationFeature
|
||||
|
||||
#if DEBUG
|
||||
if sdkOptions.isCryptoSDKAvailable {
|
||||
sdkOptions.enableCryptoSDK = RiotSettings.shared.enableCryptoSDK
|
||||
let isEnabled = RiotSettings.shared.enableCryptoSDK
|
||||
MXLog.debug("[CommonConfiguration] Crypto SDK is \(isEnabled ? "enabled" : "disabled")")
|
||||
sdkOptions.enableCryptoSDK = isEnabled
|
||||
sdkOptions.enableStartupProgress = isEnabled
|
||||
} else {
|
||||
MXLog.debug("[CommonConfiguration] Crypto SDK is not available)")
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private func makeASCIIUserAgent() -> String? {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
/// Configuration for enabling / disabling Matrix Crypto SDK
|
||||
@objcMembers class CryptoSDKConfiguration: NSObject {
|
||||
static let shared = CryptoSDKConfiguration()
|
||||
|
||||
func enable() {
|
||||
guard MXSDKOptions.sharedInstance().isCryptoSDKAvailable else {
|
||||
return
|
||||
}
|
||||
|
||||
RiotSettings.shared.enableCryptoSDK = true
|
||||
MXSDKOptions.sharedInstance().enableCryptoSDK = true
|
||||
MXSDKOptions.sharedInstance().enableStartupProgress = true
|
||||
|
||||
MXLog.debug("[CryptoSDKConfiguration] enabling Crypto SDK")
|
||||
}
|
||||
|
||||
func disable() {
|
||||
RiotSettings.shared.enableCryptoSDK = false
|
||||
MXSDKOptions.sharedInstance().enableCryptoSDK = false
|
||||
MXSDKOptions.sharedInstance().enableStartupProgress = false
|
||||
|
||||
MXLog.debug("[CryptoSDKConfiguration] disabling Crypto SDK")
|
||||
}
|
||||
}
|
||||
@@ -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.24.8'
|
||||
$matrixSDKVersion = '= 0.25.0'
|
||||
# $matrixSDKVersion = :local
|
||||
# $matrixSDKVersion = { :branch => 'develop'}
|
||||
# $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } }
|
||||
|
||||
+11
-13
@@ -55,22 +55,20 @@ PODS:
|
||||
- LoggerAPI (1.9.200):
|
||||
- Logging (~> 1.1)
|
||||
- Logging (1.4.0)
|
||||
- MatrixSDK (0.24.8):
|
||||
- MatrixSDK/Core (= 0.24.8)
|
||||
- MatrixSDK/Core (0.24.8):
|
||||
- MatrixSDK (0.25.0):
|
||||
- MatrixSDK/Core (= 0.25.0)
|
||||
- MatrixSDK/Core (0.25.0):
|
||||
- AFNetworking (~> 4.0.0)
|
||||
- GZIP (~> 1.3.0)
|
||||
- libbase58 (~> 0.1.4)
|
||||
- MatrixSDK/CryptoSDK
|
||||
- MatrixSDKCrypto (= 0.2.0)
|
||||
- OLMKit (~> 3.2.5)
|
||||
- Realm (= 10.27.0)
|
||||
- SwiftyBeaver (= 1.9.5)
|
||||
- MatrixSDK/CryptoSDK (0.24.8):
|
||||
- MatrixSDKCrypto (= 0.1.8)
|
||||
- MatrixSDK/JingleCallStack (0.24.8):
|
||||
- MatrixSDK/JingleCallStack (0.25.0):
|
||||
- JitsiMeetSDK (= 5.0.2)
|
||||
- MatrixSDK/Core
|
||||
- MatrixSDKCrypto (0.1.8)
|
||||
- MatrixSDKCrypto (0.2.0)
|
||||
- OLMKit (3.2.12):
|
||||
- OLMKit/olmc (= 3.2.12)
|
||||
- OLMKit/olmcpp (= 3.2.12)
|
||||
@@ -122,8 +120,8 @@ DEPENDENCIES:
|
||||
- KeychainAccess (~> 4.2.2)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.24.8)
|
||||
- MatrixSDK/JingleCallStack (= 0.24.8)
|
||||
- MatrixSDK (= 0.25.0)
|
||||
- MatrixSDK/JingleCallStack (= 0.25.0)
|
||||
- OLMKit
|
||||
- PostHog (~> 1.4.4)
|
||||
- ReadMoreTextView (~> 3.0.1)
|
||||
@@ -220,8 +218,8 @@ SPEC CHECKSUMS:
|
||||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatrixSDK: cf1c1b2a9742f7f4fad21e94bd94cd8f13c47369
|
||||
MatrixSDKCrypto: 862d9b4dbb6861da030943f5a18c39258ed7345b
|
||||
MatrixSDK: a9d05e760434eff941bbb35164cffb01b3f94b63
|
||||
MatrixSDKCrypto: e1ef22aae76b5a6f030ace21a47be83864f4ff44
|
||||
OLMKit: da115f16582e47626616874e20f7bb92222c7a51
|
||||
PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
@@ -241,6 +239,6 @@ SPEC CHECKSUMS:
|
||||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 079b57b800c666ad864e1f059ae69e150a98a4f0
|
||||
PODFILE CHECKSUM: 916221b3e9512715d5e1e1e310a0aa0552e1f0f1
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
@@ -804,9 +804,9 @@ Tap the + to start adding people.";
|
||||
"settings_labs_enable_new_app_layout" = "New Application Layout";
|
||||
"settings_labs_enable_wysiwyg_composer" = "Try out the rich text editor";
|
||||
"settings_labs_enable_voice_broadcast" = "Voice broadcast";
|
||||
"settings_labs_enable_crypto_sdk" = "Enable new rust-based Crypto SDK";
|
||||
"settings_labs_confirm_crypto_sdk" = "This action cannot be undone";
|
||||
"settings_labs_disable_crypto_sdk" = "Crypto SDK is enabled. To disable please reinstall the app";
|
||||
"settings_labs_enable_crypto_sdk" = "Rust end-to-end encryption";
|
||||
"settings_labs_confirm_crypto_sdk" = "Please be advised that as this feature is still in its experimental stage, it may not function as expected and could potentially have unintended consequences. To revert the feature, simply log out and log back in. Use at your own discretion and with caution.";
|
||||
"settings_labs_disable_crypto_sdk" = "Rust end-to-end encryption (log out to disable)";
|
||||
|
||||
"settings_version" = "Version %@";
|
||||
"settings_olm_version" = "Olm Version %@";
|
||||
@@ -1469,6 +1469,7 @@ Tap the + to start adding people.";
|
||||
|
||||
// Recover from private key
|
||||
"key_backup_recover_from_private_key_info" = "Restoring backup…";
|
||||
"key_backup_recover_from_private_key_progress" = "%@%% Complete";
|
||||
|
||||
// Recover from passphrase
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// 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
|
||||
import MatrixSDKCrypto
|
||||
|
||||
extension CryptoStoreError: LocalizedError {
|
||||
public var errorDescription: String? {
|
||||
// We dont really care about the type of error here when showing to the user.
|
||||
// Details about the error are tracked independently
|
||||
return VectorL10n.e2eNeedLogInAgain
|
||||
}
|
||||
}
|
||||
@@ -2755,6 +2755,10 @@ public class VectorL10n: NSObject {
|
||||
public static var keyBackupRecoverFromPrivateKeyInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_private_key_info")
|
||||
}
|
||||
/// %@%% Complete
|
||||
public static func keyBackupRecoverFromPrivateKeyProgress(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_private_key_progress", p1)
|
||||
}
|
||||
/// Use your Security Key to unlock your secure message history
|
||||
public static var keyBackupRecoverFromRecoveryKeyInfo: String {
|
||||
return VectorL10n.tr("Vector", "key_backup_recover_from_recovery_key_info")
|
||||
@@ -7583,7 +7587,7 @@ public class VectorL10n: NSObject {
|
||||
public static var settingsLabs: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs")
|
||||
}
|
||||
/// This action cannot be undone
|
||||
/// Please be advised that as this feature is still in its experimental stage, it may not function as expected and could potentially have unintended consequences. To revert the feature, simply log out and log back in. Use at your own discretion and with caution.
|
||||
public static var settingsLabsConfirmCryptoSdk: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_confirm_crypto_sdk")
|
||||
}
|
||||
@@ -7591,7 +7595,7 @@ public class VectorL10n: NSObject {
|
||||
public static var settingsLabsCreateConferenceWithJitsi: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_create_conference_with_jitsi")
|
||||
}
|
||||
/// Crypto SDK is enabled. To disable please reinstall the app
|
||||
/// Rust end-to-end encryption (log out to disable)
|
||||
public static var settingsLabsDisableCryptoSdk: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_disable_crypto_sdk")
|
||||
}
|
||||
@@ -7607,7 +7611,7 @@ public class VectorL10n: NSObject {
|
||||
public static var settingsLabsEnableAutoReportDecryptionErrors: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_enable_auto_report_decryption_errors")
|
||||
}
|
||||
/// Enable new rust-based Crypto SDK
|
||||
/// Rust end-to-end encryption
|
||||
public static var settingsLabsEnableCryptoSdk: String {
|
||||
return VectorL10n.tr("Vector", "settings_labs_enable_crypto_sdk")
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|
||||
private static let cryptoOlmPickleKey: KeyValueStoreKey = "cryptoOlmPickleKey"
|
||||
private static let roomLastMessageIv: KeyValueStoreKey = "roomLastMessageIv"
|
||||
private static let roomLastMessageAesKey: KeyValueStoreKey = "roomLastMessageAesKey"
|
||||
private static let cryptoSDKStoreKey: KeyValueStoreKey = "cryptoSDKStoreKey"
|
||||
|
||||
private let keychainStore: KeyValueStore = KeychainStore(withKeychain: Keychain(service: keychainService, accessGroup: BuildSettings.keychainAccessGroup))
|
||||
|
||||
@@ -47,6 +48,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|
||||
generateKeyIfNotExists(forKey: EncryptionKeyManager.cryptoOlmPickleKey, size: 32)
|
||||
generateIvIfNotExists(forKey: EncryptionKeyManager.roomLastMessageIv)
|
||||
generateAesKeyIfNotExists(forKey: EncryptionKeyManager.roomLastMessageAesKey)
|
||||
generateKeyIfNotExists(forKey: EncryptionKeyManager.cryptoSDKStoreKey, size: 32)
|
||||
|
||||
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.contactsIv), "[EncryptionKeyManager] initKeys: Failed to generate IV for acount")
|
||||
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.contactsAesKey), "[EncryptionKeyManager] initKeys: Failed to generate AES Key for acount")
|
||||
@@ -55,6 +57,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|
||||
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.cryptoOlmPickleKey), "[EncryptionKeyManager] initKeys: Failed to generate Key for olm pickle key")
|
||||
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageIv), "[EncryptionKeyManager] initKeys: Failed to generate IV for room last message")
|
||||
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageAesKey), "[EncryptionKeyManager] initKeys: Failed to generate AES Key for room last message encryption")
|
||||
assert(keychainStore.containsObject(forKey: EncryptionKeyManager.cryptoSDKStoreKey), "[EncryptionKeyManager] initKeys: Failed to generate Key for crypto sdk store")
|
||||
}
|
||||
|
||||
// MARK: - MXKeyProviderDelegate
|
||||
@@ -64,6 +67,7 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|
||||
|| dataType == MXKAccountManagerDataType
|
||||
|| dataType == MXCryptoOlmPickleKeyDataType
|
||||
|| dataType == MXRoomLastMessageDataType
|
||||
|| dataType == MXCryptoSDKStoreKeyDataType
|
||||
}
|
||||
|
||||
func hasKeyForData(ofType dataType: String) -> Bool {
|
||||
@@ -77,7 +81,10 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|
||||
case MXRoomLastMessageDataType:
|
||||
return keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageIv) &&
|
||||
keychainStore.containsObject(forKey: EncryptionKeyManager.roomLastMessageAesKey)
|
||||
case MXCryptoSDKStoreKeyDataType:
|
||||
return keychainStore.containsObject(forKey: EncryptionKeyManager.cryptoSDKStoreKey)
|
||||
default:
|
||||
MXLog.warning("[EncryptionKeyManager] hasKeyForData: No key for \(dataType)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -103,7 +110,12 @@ class EncryptionKeyManager: NSObject, MXKeyProviderDelegate {
|
||||
let aesKey = try? keychainStore.data(forKey: EncryptionKeyManager.roomLastMessageAesKey) {
|
||||
return MXAesKeyData(iv: ivKey, key: aesKey)
|
||||
}
|
||||
case MXCryptoSDKStoreKeyDataType:
|
||||
if let key = try? keychainStore.data(forKey: EncryptionKeyManager.cryptoSDKStoreKey) {
|
||||
return MXRawDataKey(key: key)
|
||||
}
|
||||
default:
|
||||
MXLog.failure("[EncryptionKeyManager] keyDataForData: Attempting to get data for unknown type", dataType)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -192,11 +192,9 @@ final class RiotSettings: NSObject {
|
||||
@UserDefault(key: "enableVoiceBroadcast", defaultValue: false, storage: defaults)
|
||||
var enableVoiceBroadcast
|
||||
|
||||
#if DEBUG
|
||||
/// Flag indicating if we are using rust-based `MatrixCryptoSDK` instead of `MatrixSDK`'s internal crypto module
|
||||
@UserDefault(key: "enableCryptoSDK", defaultValue: false, storage: defaults)
|
||||
var enableCryptoSDK
|
||||
#endif
|
||||
|
||||
// MARK: Calls
|
||||
|
||||
|
||||
@@ -324,6 +324,11 @@ extension Analytics {
|
||||
viewRoomTrigger = .unknown
|
||||
capture(event: event)
|
||||
}
|
||||
|
||||
func trackCryptoSDKEnabled() {
|
||||
let event = AnalyticsEvent.CryptoSDKEnabled()
|
||||
capture(event: event)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MXAnalyticsDelegate
|
||||
@@ -393,3 +398,14 @@ extension Analytics: MXAnalyticsDelegate {
|
||||
monitoringClient.trackNonFatalIssue(issue, details: details)
|
||||
}
|
||||
}
|
||||
|
||||
/// iOS-specific analytics event triggered when users select the Crypto SDK labs option
|
||||
///
|
||||
/// Due to this event being iOS only, and temporary during gradual rollout of Crypto SDK,
|
||||
/// this event is not added into the shared analytics schema
|
||||
extension AnalyticsEvent {
|
||||
struct CryptoSDKEnabled: AnalyticsEventProtocol {
|
||||
let eventName = "CryptoSDKEnabled"
|
||||
let properties: [String: Any] = [:]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2183,6 +2183,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
// Clear cache
|
||||
[self clearCache];
|
||||
|
||||
// Reset Crypto SDK configuration (labs flag for which crypto module to use)
|
||||
[CryptoSDKConfiguration.shared disable];
|
||||
|
||||
// Reset key backup banner preferences
|
||||
[SecureBackupBannerPreferences.shared reset];
|
||||
|
||||
|
||||
@@ -885,10 +885,12 @@ extension AllChatsViewController: SplitViewMasterViewControllerProtocol {
|
||||
return
|
||||
}
|
||||
|
||||
let devices = mainSession.crypto.devices(forUser: mainSession.myUserId).values
|
||||
let userHasOneUnverifiedDevice = devices.contains(where: {!$0.trustLevel.isCrossSigningVerified})
|
||||
if userHasOneUnverifiedDevice {
|
||||
presentReviewUnverifiedSessionsAlert(with: session)
|
||||
if let userId = mainSession.myUserId, let crypto = mainSession.crypto {
|
||||
let devices = crypto.devices(forUser: userId).values
|
||||
let userHasOneUnverifiedDevice = devices.contains(where: {!$0.trustLevel.isCrossSigningVerified})
|
||||
if userHasOneUnverifiedDevice {
|
||||
presentReviewUnverifiedSessionsAlert(with: session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-9
@@ -1,25 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="cb6-oF-e0m">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="cb6-oF-e0m">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Key Backup Recover Data Loading View Controller-->
|
||||
<!--Key Backup Recover From Private Key View Controller-->
|
||||
<scene sceneID="JIv-4y-eqa">
|
||||
<objects>
|
||||
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="cb6-oF-e0m" customClass="KeyBackupRecoverFromPrivateKeyViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="cb6-oF-e0m" customClass="KeyBackupRecoverFromPrivateKeyViewController" customModule="Element" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="JOd-8G-rga">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cUL-rS-rfi">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a4s-VR-9rG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="239"/>
|
||||
@@ -40,15 +38,24 @@
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0% complete" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bMp-hX-C4X">
|
||||
<rect key="frame" x="20" y="160" width="335" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="c3s-XT-wGy" firstAttribute="top" secondItem="AA6-5y-aKB" secondAttribute="top" constant="35" id="2hk-29-LeR"/>
|
||||
<constraint firstItem="1dN-Ld-mvf" firstAttribute="top" secondItem="c3s-XT-wGy" secondAttribute="bottom" constant="30" id="7oJ-n1-Vec"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bMp-hX-C4X" secondAttribute="trailing" constant="20" id="BLV-CI-4bJ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="1dN-Ld-mvf" secondAttribute="trailing" constant="20" id="RRJ-XS-DKi"/>
|
||||
<constraint firstItem="1dN-Ld-mvf" firstAttribute="leading" secondItem="AA6-5y-aKB" secondAttribute="leading" constant="20" id="bgC-6o-Qd3"/>
|
||||
<constraint firstItem="bMp-hX-C4X" firstAttribute="leading" secondItem="AA6-5y-aKB" secondAttribute="leading" constant="20" id="ePA-YY-3Bd"/>
|
||||
<constraint firstItem="c3s-XT-wGy" firstAttribute="centerX" secondItem="AA6-5y-aKB" secondAttribute="centerX" id="hhx-MR-Ssb"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="500" id="qn9-3x-Vus"/>
|
||||
<constraint firstItem="bMp-hX-C4X" firstAttribute="top" secondItem="1dN-Ld-mvf" secondAttribute="bottom" constant="31" id="zle-dL-YQn"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
@@ -72,6 +79,7 @@
|
||||
</constraints>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="Y3k-2C-Pek"/>
|
||||
<color key="backgroundColor" red="0.94509803920000002" green="0.96078431369999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="cUL-rS-rfi" firstAttribute="leading" secondItem="Y3k-2C-Pek" secondAttribute="leading" id="9ZI-Gm-3DT"/>
|
||||
@@ -79,10 +87,10 @@
|
||||
<constraint firstItem="Y3k-2C-Pek" firstAttribute="top" secondItem="cUL-rS-rfi" secondAttribute="top" id="ffm-HV-RhA"/>
|
||||
<constraint firstAttribute="bottom" secondItem="cUL-rS-rfi" secondAttribute="bottom" id="rib-a1-j68"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="Y3k-2C-Pek"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="informationLabel" destination="1dN-Ld-mvf" id="RAQ-9H-hXQ"/>
|
||||
<outlet property="progressLabel" destination="bMp-hX-C4X" id="Hhf-4p-YYP"/>
|
||||
<outlet property="shieldImageView" destination="c3s-XT-wGy" id="jVg-AC-PGB"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
||||
+7
-3
@@ -29,6 +29,7 @@ final class KeyBackupRecoverFromPrivateKeyViewController: UIViewController {
|
||||
@IBOutlet private weak var shieldImageView: UIImageView!
|
||||
|
||||
@IBOutlet private weak var informationLabel: UILabel!
|
||||
@IBOutlet private weak var progressLabel: UILabel!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@@ -118,8 +119,8 @@ final class KeyBackupRecoverFromPrivateKeyViewController: UIViewController {
|
||||
|
||||
private func render(viewState: KeyBackupRecoverFromPrivateKeyViewState) {
|
||||
switch viewState {
|
||||
case .loading:
|
||||
self.renderLoading()
|
||||
case .loading(let progress):
|
||||
self.renderLoading(progress: progress)
|
||||
case .loaded:
|
||||
self.renderLoaded()
|
||||
case .error(let error):
|
||||
@@ -127,8 +128,11 @@ final class KeyBackupRecoverFromPrivateKeyViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private func renderLoading() {
|
||||
private func renderLoading(progress: Double) {
|
||||
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
|
||||
|
||||
let percent = Int(round(progress * 100))
|
||||
self.progressLabel.text = VectorL10n.keyBackupRecoverFromPrivateKeyProgress("\(percent)")
|
||||
}
|
||||
|
||||
private func renderLoaded() {
|
||||
|
||||
+14
-1
@@ -27,6 +27,7 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
|
||||
private let keyBackup: MXKeyBackup
|
||||
private var currentHTTPOperation: MXHTTPOperation?
|
||||
private let keyBackupVersion: MXKeyBackupVersion
|
||||
private var progressUpdateTimer: Timer?
|
||||
|
||||
// MARK: Public
|
||||
|
||||
@@ -56,7 +57,14 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
|
||||
|
||||
private func recoverWithPrivateKey() {
|
||||
|
||||
self.update(viewState: .loading)
|
||||
self.update(viewState: .loading(0))
|
||||
|
||||
// Update loading progress every second until no longer loading
|
||||
progressUpdateTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
|
||||
if let progress = self?.keyBackup.importProgress {
|
||||
self?.update(viewState: .loading(progress.fractionCompleted))
|
||||
}
|
||||
}
|
||||
|
||||
self.currentHTTPOperation = keyBackup.restore(usingPrivateKeyKeyBackup: keyBackupVersion, room: nil, session: nil, success: { [weak self] (_, _) in
|
||||
guard let self = self else {
|
||||
@@ -91,6 +99,11 @@ final class KeyBackupRecoverFromPrivateKeyViewModel: KeyBackupRecoverFromPrivate
|
||||
}
|
||||
|
||||
private func update(viewState: KeyBackupRecoverFromPrivateKeyViewState) {
|
||||
if case .loading = viewState {} else {
|
||||
progressUpdateTimer?.invalidate()
|
||||
progressUpdateTimer = nil
|
||||
}
|
||||
|
||||
self.viewDelegate?.keyBackupRecoverFromPrivateKeyViewModel(self, didUpdateViewState: viewState)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import Foundation
|
||||
|
||||
/// KeyBackupRecoverFromPrivateKeyViewController view state
|
||||
enum KeyBackupRecoverFromPrivateKeyViewState {
|
||||
case loading
|
||||
case loading(Double)
|
||||
case loaded
|
||||
case error(Error)
|
||||
}
|
||||
|
||||
@@ -588,12 +588,10 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
if (BuildSettings.settingsScreenShowLabSettings)
|
||||
{
|
||||
Section *sectionLabs = [Section sectionWithTag:SECTION_TAG_LABS];
|
||||
#if DEBUG
|
||||
if (MXSDKOptions.sharedInstance.isCryptoSDKAvailable)
|
||||
{
|
||||
[sectionLabs addRowWithTag:LABS_ENABLE_CRYPTO_SDK];
|
||||
}
|
||||
#endif
|
||||
|
||||
[sectionLabs addRowWithTag:LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX];
|
||||
[sectionLabs addRowWithTag:LABS_ENABLE_THREADS_INDEX];
|
||||
@@ -2593,7 +2591,6 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
}
|
||||
else
|
||||
{
|
||||
#if DEBUG
|
||||
if (row == LABS_ENABLE_CRYPTO_SDK)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch *labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
@@ -2602,11 +2599,10 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
labelAndSwitchCell.mxkSwitch.on = isEnabled;
|
||||
[labelAndSwitchCell.mxkSwitch setEnabled:!isEnabled];
|
||||
labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleEnableCryptoSDKFeature:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(enableCryptoSDKFeature:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (section == SECTION_TAG_SECURITY)
|
||||
@@ -3379,17 +3375,14 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
RiotSettings.shared.enableVoiceBroadcast = sender.isOn;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
- (void)toggleEnableCryptoSDKFeature:(UISwitch *)sender
|
||||
- (void)enableCryptoSDKFeature:(UISwitch *)sender
|
||||
{
|
||||
BOOL isEnabled = sender.isOn;
|
||||
MXWeakify(self);
|
||||
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
UIAlertController *confirmationAlert = [UIAlertController alertControllerWithTitle:nil
|
||||
UIAlertController *confirmationAlert = [UIAlertController alertControllerWithTitle:VectorL10n.settingsLabsEnableCryptoSdk
|
||||
message:VectorL10n.settingsLabsConfirmCryptoSdk
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
MXWeakify(self);
|
||||
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
self->currentAlert = nil;
|
||||
@@ -3398,17 +3391,16 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
}]];
|
||||
|
||||
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
RiotSettings.shared.enableCryptoSDK = isEnabled;
|
||||
MXSDKOptions.sharedInstance.enableCryptoSDK = isEnabled;
|
||||
[CryptoSDKConfiguration.shared enable];
|
||||
[Analytics.shared trackCryptoSDKEnabled];
|
||||
|
||||
[[AppDelegate theDelegate] reloadMatrixSessions:YES];
|
||||
}]];
|
||||
|
||||
[self presentViewController:confirmationAlert animated:YES completion:nil];
|
||||
currentAlert = confirmationAlert;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)togglePinRoomsWithMissedNotif:(UISwitch *)sender
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
private var ongoingVoIPPushRequests: [String: Bool] = [:]
|
||||
|
||||
private var userAccount: MXKAccount?
|
||||
private var isCryptoSDKEnabled = false
|
||||
|
||||
/// Best attempt contents. Will be updated incrementally, if something fails during the process, this best attempt content will be showed as notification. Keys are eventId's
|
||||
private var bestAttemptContents: [String: UNMutableNotificationContent] = [:]
|
||||
@@ -195,9 +196,10 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
self.userAccount = MXKAccountManager.shared()?.activeAccounts.first
|
||||
if let userAccount = userAccount {
|
||||
Self.backgroundServiceInitQueue.sync {
|
||||
if NotificationService.backgroundSyncService?.credentials != userAccount.mxCredentials {
|
||||
if hasChangedCryptoSDK() || NotificationService.backgroundSyncService?.credentials != userAccount.mxCredentials {
|
||||
MXLog.debug("[NotificationService] setup: MXBackgroundSyncService init: BEFORE")
|
||||
self.logMemory()
|
||||
|
||||
NotificationService.backgroundSyncService = MXBackgroundSyncService(withCredentials: userAccount.mxCredentials, persistTokenDataHandler: { persistTokenDataHandler in
|
||||
MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler)
|
||||
}, unauthenticatedHandler: { error, softLogout, refreshTokenAuth, completion in
|
||||
@@ -214,6 +216,16 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine whether we have switched from using crypto v1 to v2 or vice versa which will require
|
||||
/// rebuilding `MXBackgroundSyncService`
|
||||
private func hasChangedCryptoSDK() -> Bool {
|
||||
guard isCryptoSDKEnabled != RiotSettings.shared.enableCryptoSDK else {
|
||||
return false
|
||||
}
|
||||
isCryptoSDKEnabled = RiotSettings.shared.enableCryptoSDK
|
||||
return true
|
||||
}
|
||||
|
||||
/// Attempts to preprocess payload and attach room display name to the best attempt content
|
||||
/// - Parameters:
|
||||
/// - eventId: Event identifier to mutate best attempt content
|
||||
|
||||
Reference in New Issue
Block a user