mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
crypto: Add configuration flag to enable invisible crypto (#3247)
This commit is contained in:
parent
5acfb5dd87
commit
f7d878bac6
@ -473,7 +473,6 @@
|
|||||||
6A54F52443EC52AC5CD772C0 /* JoinRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869A8A4632E511351BFE2EC4 /* JoinRoomScreen.swift */; };
|
6A54F52443EC52AC5CD772C0 /* JoinRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869A8A4632E511351BFE2EC4 /* JoinRoomScreen.swift */; };
|
||||||
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
||||||
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */; };
|
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */; };
|
||||||
6AECC84BE14A13440120FED8 /* NSESettingsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB4F169D653296023ED65E6 /* NSESettingsProtocol.swift */; };
|
|
||||||
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
||||||
6BAD956B909A6E29F6CC6E7C /* ButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC23C63849452BC86EA2852 /* ButtonStyle.swift */; };
|
6BAD956B909A6E29F6CC6E7C /* ButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC23C63849452BC86EA2852 /* ButtonStyle.swift */; };
|
||||||
6BB6944443C421C722ED1E7D /* portrait_test_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */; };
|
6BB6944443C421C722ED1E7D /* portrait_test_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */; };
|
||||||
@ -1874,7 +1873,6 @@
|
|||||||
9F1DF3FFFE5ED2B8133F43A7 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
9F1DF3FFFE5ED2B8133F43A7 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
||||||
9F40FB0A43DAECEC27C73722 /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/SAS.strings; sourceTree = "<group>"; };
|
9F40FB0A43DAECEC27C73722 /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||||
9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
||||||
9FB4F169D653296023ED65E6 /* NSESettingsProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSESettingsProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
A010B8EAD1A9F6B4686DF2F4 /* BlockedUsersScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModel.swift; sourceTree = "<group>"; };
|
A010B8EAD1A9F6B4686DF2F4 /* BlockedUsersScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModel.swift; sourceTree = "<group>"; };
|
A019A12C866D64CF072024B9 /* AppLockSetupPINScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
@ -3467,7 +3465,6 @@
|
|||||||
children = (
|
children = (
|
||||||
4959CECEC984B3995616F427 /* DataProtectionManager.swift */,
|
4959CECEC984B3995616F427 /* DataProtectionManager.swift */,
|
||||||
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */,
|
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */,
|
||||||
9FB4F169D653296023ED65E6 /* NSESettingsProtocol.swift */,
|
|
||||||
EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */,
|
EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */,
|
||||||
49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */,
|
49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */,
|
||||||
);
|
);
|
||||||
@ -6021,7 +6018,6 @@
|
|||||||
E2DB696117BAEABAD5718023 /* MediaSourceProxy.swift in Sources */,
|
E2DB696117BAEABAD5718023 /* MediaSourceProxy.swift in Sources */,
|
||||||
4FC085B1E5D1EB804495E2F4 /* MockMediaProvider.swift in Sources */,
|
4FC085B1E5D1EB804495E2F4 /* MockMediaProvider.swift in Sources */,
|
||||||
5455147CAC63F71E48F7D699 /* NSELogger.swift in Sources */,
|
5455147CAC63F71E48F7D699 /* NSELogger.swift in Sources */,
|
||||||
6AECC84BE14A13440120FED8 /* NSESettingsProtocol.swift in Sources */,
|
|
||||||
30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */,
|
30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */,
|
||||||
1D5DC685CED904386C89B7DA /* NSRegularExpresion.swift in Sources */,
|
1D5DC685CED904386C89B7DA /* NSRegularExpresion.swift in Sources */,
|
||||||
94F0B78928E952689ACDB271 /* NetworkMonitor.swift in Sources */,
|
94F0B78928E952689ACDB271 /* NetworkMonitor.swift in Sources */,
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
// Common settings between app and NSE
|
||||||
|
protocol CommonSettingsProtocol {
|
||||||
|
var logLevel: TracingConfiguration.LogLevel { get }
|
||||||
|
var invisibleCryptoEnabled: Bool { get }
|
||||||
|
}
|
||||||
|
|
||||||
/// Store Element specific app settings.
|
/// Store Element specific app settings.
|
||||||
final class AppSettings {
|
final class AppSettings {
|
||||||
private enum UserDefaultsKeys: String {
|
private enum UserDefaultsKeys: String {
|
||||||
@ -37,6 +43,7 @@ final class AppSettings {
|
|||||||
case publicSearchEnabled
|
case publicSearchEnabled
|
||||||
case fuzzyRoomListSearchEnabled
|
case fuzzyRoomListSearchEnabled
|
||||||
case pinningEnabled
|
case pinningEnabled
|
||||||
|
case invisibleCryptoEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
||||||
@ -270,11 +277,17 @@ final class AppSettings {
|
|||||||
enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative }
|
enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative }
|
||||||
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
|
||||||
var slidingSyncDiscovery: SlidingSyncDiscovery
|
var slidingSyncDiscovery: SlidingSyncDiscovery
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MARK: - Shared
|
// MARK: - Shared
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.logLevel, defaultValue: TracingConfiguration.LogLevel.info, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.logLevel, defaultValue: TracingConfiguration.LogLevel.info, storageType: .userDefaults(store))
|
||||||
var logLevel
|
var logLevel
|
||||||
|
|
||||||
|
/// Configuration to enable invisible crypto. In this mode only devices signed by their owner will be considered in e2ee rooms.
|
||||||
|
@UserPreference(key: UserDefaultsKeys.invisibleCryptoEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
|
var invisibleCryptoEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension AppSettings: CommonSettingsProtocol { }
|
||||||
|
@ -14,12 +14,12 @@ extension ClientBuilder {
|
|||||||
httpProxy: String? = nil,
|
httpProxy: String? = nil,
|
||||||
slidingSync: ClientBuilderSlidingSync,
|
slidingSync: ClientBuilderSlidingSync,
|
||||||
sessionDelegate: ClientSessionDelegate,
|
sessionDelegate: ClientSessionDelegate,
|
||||||
appHooks: AppHooks) -> ClientBuilder {
|
appHooks: AppHooks,
|
||||||
|
invisibleCryptoEnabled: Bool) -> ClientBuilder {
|
||||||
var builder = ClientBuilder()
|
var builder = ClientBuilder()
|
||||||
.enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier, sessionDelegate: sessionDelegate)
|
.enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier, sessionDelegate: sessionDelegate)
|
||||||
.userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent())
|
.userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent())
|
||||||
.requestConfig(config: .init(retryLimit: 0, timeout: 30000, maxConcurrentRequests: nil, retryTimeout: nil))
|
.requestConfig(config: .init(retryLimit: 0, timeout: 30000, maxConcurrentRequests: nil, retryTimeout: nil))
|
||||||
.roomKeyRecipientStrategy(strategy: .deviceBasedStrategy(onlyAllowTrustedDevices: false, errorOnVerifiedUserProblem: true))
|
|
||||||
|
|
||||||
builder = switch slidingSync {
|
builder = switch slidingSync {
|
||||||
case .restored: builder
|
case .restored: builder
|
||||||
@ -33,6 +33,12 @@ extension ClientBuilder {
|
|||||||
.autoEnableCrossSigning(autoEnableCrossSigning: true)
|
.autoEnableCrossSigning(autoEnableCrossSigning: true)
|
||||||
.backupDownloadStrategy(backupDownloadStrategy: .afterDecryptionFailure)
|
.backupDownloadStrategy(backupDownloadStrategy: .afterDecryptionFailure)
|
||||||
.autoEnableBackups(autoEnableBackups: true)
|
.autoEnableBackups(autoEnableBackups: true)
|
||||||
|
|
||||||
|
if invisibleCryptoEnabled {
|
||||||
|
builder = builder.roomKeyRecipientStrategy(strategy: CollectStrategy.identityBasedStrategy)
|
||||||
|
} else {
|
||||||
|
builder = builder.roomKeyRecipientStrategy(strategy: .deviceBasedStrategy(onlyAllowTrustedDevices: false, errorOnVerifiedUserProblem: true))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let httpProxy {
|
if let httpProxy {
|
||||||
|
@ -47,6 +47,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
|||||||
var elementCallBaseURLOverride: URL? { get set }
|
var elementCallBaseURLOverride: URL? { get set }
|
||||||
var fuzzyRoomListSearchEnabled: Bool { get set }
|
var fuzzyRoomListSearchEnabled: Bool { get set }
|
||||||
var pinningEnabled: Bool { get set }
|
var pinningEnabled: Bool { get set }
|
||||||
|
var invisibleCryptoEnabled: Bool { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppSettings: DeveloperOptionsProtocol { }
|
extension AppSettings: DeveloperOptionsProtocol { }
|
||||||
|
@ -52,6 +52,17 @@ struct DeveloperOptionsScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
Toggle(isOn: $context.invisibleCryptoEnabled) {
|
||||||
|
Text("Enabled Invisible Crypto")
|
||||||
|
Text("Requires app reboot")
|
||||||
|
}
|
||||||
|
} header: {
|
||||||
|
Text("Trust and Decoration")
|
||||||
|
} footer: {
|
||||||
|
Text("This setting controls how end-to-end encryption (E2EE) keys are shared. Enabling it will prevent the inclusion of devices that have not been explicitly verified by their owners.")
|
||||||
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
TextField(context.viewState.elementCallBaseURL.absoluteString, text: $elementCallURLOverrideString)
|
TextField(context.viewState.elementCallBaseURL.absoluteString, text: $elementCallURLOverrideString)
|
||||||
.autocorrectionDisabled(true)
|
.autocorrectionDisabled(true)
|
||||||
|
@ -69,7 +69,8 @@ struct AuthenticationClientBuilder {
|
|||||||
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
||||||
slidingSync: slidingSync,
|
slidingSync: slidingSync,
|
||||||
sessionDelegate: clientSessionDelegate,
|
sessionDelegate: clientSessionDelegate,
|
||||||
appHooks: appHooks)
|
appHooks: appHooks,
|
||||||
|
invisibleCryptoEnabled: appSettings.invisibleCryptoEnabled)
|
||||||
.sessionPaths(dataPath: sessionDirectories.dataPath,
|
.sessionPaths(dataPath: sessionDirectories.dataPath,
|
||||||
cachePath: sessionDirectories.cachePath)
|
cachePath: sessionDirectories.cachePath)
|
||||||
.passphrase(passphrase: passphrase)
|
.passphrase(passphrase: passphrase)
|
||||||
|
@ -124,7 +124,8 @@ class UserSessionStore: UserSessionStoreProtocol {
|
|||||||
.baseBuilder(httpProxy: URL(string: homeserverURL)?.globalProxy,
|
.baseBuilder(httpProxy: URL(string: homeserverURL)?.globalProxy,
|
||||||
slidingSync: .restored,
|
slidingSync: .restored,
|
||||||
sessionDelegate: keychainController,
|
sessionDelegate: keychainController,
|
||||||
appHooks: appHooks)
|
appHooks: appHooks,
|
||||||
|
invisibleCryptoEnabled: appSettings.enableNotifications)
|
||||||
.sessionPaths(dataPath: credentials.restorationToken.sessionDirectories.dataPath,
|
.sessionPaths(dataPath: credentials.restorationToken.sessionDirectories.dataPath,
|
||||||
cachePath: credentials.restorationToken.sessionDirectories.cachePath)
|
cachePath: credentials.restorationToken.sessionDirectories.cachePath)
|
||||||
.username(username: credentials.userID)
|
.username(username: credentials.userID)
|
||||||
|
@ -32,7 +32,7 @@ import UserNotifications
|
|||||||
// We keep a global `environment` singleton to ensure that our app context,
|
// We keep a global `environment` singleton to ensure that our app context,
|
||||||
// database, logging, etc. are only ever setup once per *process*
|
// database, logging, etc. are only ever setup once per *process*
|
||||||
|
|
||||||
private let settings: NSESettingsProtocol = AppSettings()
|
private let settings: CommonSettingsProtocol = AppSettings()
|
||||||
private let notificationContentBuilder = NotificationContentBuilder(messageEventStringBuilder: RoomMessageEventStringBuilder(attributedStringBuilder: AttributedStringBuilder(mentionBuilder: PlainMentionBuilder()), prefix: .none))
|
private let notificationContentBuilder = NotificationContentBuilder(messageEventStringBuilder: RoomMessageEventStringBuilder(attributedStringBuilder: AttributedStringBuilder(mentionBuilder: PlainMentionBuilder()), prefix: .none))
|
||||||
private let keychainController = KeychainController(service: .sessions,
|
private let keychainController = KeychainController(service: .sessions,
|
||||||
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
|
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
|
||||||
@ -81,7 +81,8 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
do {
|
do {
|
||||||
Self.userSession = try await NSEUserSession(credentials: credentials,
|
Self.userSession = try await NSEUserSession(credentials: credentials,
|
||||||
clientSessionDelegate: keychainController,
|
clientSessionDelegate: keychainController,
|
||||||
appHooks: appHooks)
|
appHooks: appHooks,
|
||||||
|
appSettings: settings)
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed creating user session with error: \(error)")
|
MXLog.error("Failed creating user session with error: \(error)")
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2023, 2024 New Vector Ltd.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
// Please see LICENSE in the repository root for full details.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
protocol NSESettingsProtocol {
|
|
||||||
var logLevel: TracingConfiguration.LogLevel { get }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension AppSettings: NSESettingsProtocol { }
|
|
@ -19,7 +19,7 @@ final class NSEUserSession {
|
|||||||
networkMonitor: nil)
|
networkMonitor: nil)
|
||||||
private let delegateHandle: TaskHandle?
|
private let delegateHandle: TaskHandle?
|
||||||
|
|
||||||
init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate, appHooks: AppHooks) async throws {
|
init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate, appHooks: AppHooks, appSettings: CommonSettingsProtocol) async throws {
|
||||||
sessionDirectories = credentials.restorationToken.sessionDirectories
|
sessionDirectories = credentials.restorationToken.sessionDirectories
|
||||||
|
|
||||||
userID = credentials.userID
|
userID = credentials.userID
|
||||||
@ -33,7 +33,8 @@ final class NSEUserSession {
|
|||||||
httpProxy: URL(string: homeserverURL)?.globalProxy,
|
httpProxy: URL(string: homeserverURL)?.globalProxy,
|
||||||
slidingSync: .restored,
|
slidingSync: .restored,
|
||||||
sessionDelegate: clientSessionDelegate,
|
sessionDelegate: clientSessionDelegate,
|
||||||
appHooks: appHooks)
|
appHooks: appHooks,
|
||||||
|
invisibleCryptoEnabled: appSettings.invisibleCryptoEnabled)
|
||||||
.sessionPaths(dataPath: credentials.restorationToken.sessionDirectories.dataPath,
|
.sessionPaths(dataPath: credentials.restorationToken.sessionDirectories.dataPath,
|
||||||
cachePath: credentials.restorationToken.sessionDirectories.cachePath)
|
cachePath: credentials.restorationToken.sessionDirectories.cachePath)
|
||||||
.username(username: credentials.userID)
|
.username(username: credentials.userID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user