diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index ef590ff8b..616856b66 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -30,6 +30,10 @@ blocks: - cache restore && make dependencies && cache store - mv ~/appium-env ~/git/flowcrypt-ios/appium/.env - sem-version node 16 && cache restore appium-npm && cd ./appium && npm i && cd .. && cache store appium-npm appium/node_modules + # temporary disabled because of https://github.com/ios-control/simctl/issues/30 + # - brew install ideviceinstaller + # - npm install ios-deploy -g --unsafe-perm=true --allow-root + # - npm install ios-sim -g --unsafe-perm=true --allow-root jobs: - name: Appium UI tests commands: diff --git a/FlowCrypt/Controllers/Compose/ComposeViewController.swift b/FlowCrypt/Controllers/Compose/ComposeViewController.swift index 946636902..b025ee8bf 100644 --- a/FlowCrypt/Controllers/Compose/ComposeViewController.swift +++ b/FlowCrypt/Controllers/Compose/ComposeViewController.swift @@ -64,9 +64,7 @@ final class ComposeViewController: TableNodeViewController { private let email: String private var isMessagePasswordSupported: Bool { - guard let domain = email.emailParts?.domain else { return false } - let senderDomainsWithMessagePasswordSupport = ["flowcrypt.com"] - return senderDomainsWithMessagePasswordSupport.contains(domain) + return clientConfiguration.isUsingFes } private let search = PassthroughSubject() diff --git a/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift b/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift index bff3279a5..9d2bae604 100644 --- a/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift +++ b/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift @@ -39,6 +39,7 @@ final class EncryptedStorage: EncryptedStorageType { case initial case version5 case version6 + case version7 var version: SchemaVersion { switch self { @@ -48,6 +49,8 @@ final class EncryptedStorage: EncryptedStorageType { return SchemaVersion(appVersion: "0.2.0", dbSchemaVersion: 5) case .version6: return SchemaVersion(appVersion: "0.2.0", dbSchemaVersion: 6) + case .version7: + return SchemaVersion(appVersion: "0.2.0", dbSchemaVersion: 7) } } } @@ -59,7 +62,7 @@ final class EncryptedStorage: EncryptedStorageType { private lazy var migrationLogger = Logger.nested(in: Self.self, with: .migration) private lazy var logger = Logger.nested(Self.self) - private let currentSchema: EncryptedStorageSchema = .version6 + private let currentSchema: EncryptedStorageSchema = .version7 private let supportedSchemas = EncryptedStorageSchema.allCases private let storageEncryptionKey: Data diff --git a/FlowCrypt/Functionality/Services/AppStartup.swift b/FlowCrypt/Functionality/Services/AppStartup.swift index 7b0ea9d97..a7f354f68 100644 --- a/FlowCrypt/Functionality/Services/AppStartup.swift +++ b/FlowCrypt/Functionality/Services/AppStartup.swift @@ -91,7 +91,7 @@ struct AppStartup { logger.logInfo("User with session \(session) -> setupFlow") return .setupFlow(userId) } else { - logger.logInfo("User us not signed in -> mainFlow") + logger.logInfo("User is not signed in -> mainFlow") return .signIn } } diff --git a/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfiguration.swift b/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfiguration.swift index 251e25f7c..6daa55225 100644 --- a/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfiguration.swift +++ b/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfiguration.swift @@ -53,6 +53,10 @@ class ClientConfiguration { return URL(string: urlString) != nil } + var isUsingFes: Bool { + raw.fesUrl != nil + } + /// Enforce a key algo for keygen, eg rsa2048,rsa4096,curve25519 var enforcedKeygenAlgo: String? { raw.enforceKeygenAlgo diff --git a/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift b/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift index d411577f2..7617bcdcd 100644 --- a/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift +++ b/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift @@ -34,7 +34,8 @@ extension ClientConfigurationService: ClientConfigurationServiceType { func fetch(for user: User) async throws -> ClientConfiguration { do { let raw = try await server.getClientConfiguration(for: user.email) - try local.save(for: user, raw: raw) + let fesUrl = try await server.getActiveFesUrl(for: user.email) + try local.save(for: user, raw: raw, fesUrl: fesUrl) return ClientConfiguration(raw: raw) } catch { guard let raw = local.load(for: user.email) else { diff --git a/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift b/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift index 2e8e6a66b..60e885414 100644 --- a/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift +++ b/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift @@ -12,7 +12,7 @@ import RealmSwift protocol LocalClientConfigurationType { func load(for user: String) -> RawClientConfiguration? func remove(for user: String) throws - func save(for user: User, raw: RawClientConfiguration) throws + func save(for user: User, raw: RawClientConfiguration, fesUrl: String?) throws } final class LocalClientConfiguration { @@ -44,8 +44,13 @@ extension LocalClientConfiguration: LocalClientConfigurationType { } } - func save(for user: User, raw: RawClientConfiguration) throws { - let object = ClientConfigurationRealmObject(configuration: raw, user: user) + func save(for user: User, raw: RawClientConfiguration, fesUrl: String?) throws { + let object = ClientConfigurationRealmObject( + configuration: raw, + user: user, + fesUrl: fesUrl + ) + try storage.write { storage.add(object, update: .modified) } diff --git a/FlowCrypt/Models/Common/RawClientConfiguration.swift b/FlowCrypt/Models/Common/RawClientConfiguration.swift index 582ed6788..cf1a12eb1 100644 --- a/FlowCrypt/Models/Common/RawClientConfiguration.swift +++ b/FlowCrypt/Models/Common/RawClientConfiguration.swift @@ -34,6 +34,7 @@ struct RawClientConfiguration: Codable, Equatable { let flags: [ClientConfigurationFlag]? let customKeyserverUrl: String? let keyManagerUrl: String? + let fesUrl: String? let disallowAttesterSearchForDomains: [String]? let enforceKeygenAlgo: String? let enforceKeygenExpireMonths: Int? @@ -42,6 +43,7 @@ struct RawClientConfiguration: Codable, Equatable { flags: [ClientConfigurationFlag]? = nil, customKeyserverUrl: String? = nil, keyManagerUrl: String? = nil, + fesUrl: String? = nil, disallowAttesterSearchForDomains: [String]? = nil, enforceKeygenAlgo: String? = nil, enforceKeygenExpireMonths: Int? = nil @@ -49,6 +51,7 @@ struct RawClientConfiguration: Codable, Equatable { self.flags = flags self.customKeyserverUrl = customKeyserverUrl self.keyManagerUrl = keyManagerUrl + self.fesUrl = fesUrl self.disallowAttesterSearchForDomains = disallowAttesterSearchForDomains self.enforceKeygenAlgo = enforceKeygenAlgo self.enforceKeygenExpireMonths = enforceKeygenExpireMonths @@ -58,14 +61,7 @@ struct RawClientConfiguration: Codable, Equatable { // MARK: - Empty model extension RawClientConfiguration { static var empty: RawClientConfiguration { - return RawClientConfiguration( - flags: [], - customKeyserverUrl: nil, - keyManagerUrl: nil, - disallowAttesterSearchForDomains: nil, - enforceKeygenAlgo: nil, - enforceKeygenExpireMonths: nil - ) + return RawClientConfiguration() } } @@ -91,6 +87,7 @@ extension RawClientConfiguration { flags: decodedFlags?.compactMap(ClientConfigurationFlag.init), customKeyserverUrl: unwrappedObject.customKeyserverUrl, keyManagerUrl: unwrappedObject.keyManagerUrl, + fesUrl: unwrappedObject.fesUrl, disallowAttesterSearchForDomains: decodedDisallowAttesterSearchForDomains, enforceKeygenAlgo: unwrappedObject.enforceKeygenAlgo, enforceKeygenExpireMonths: unwrappedObject.enforceKeygenExpireMonths diff --git a/FlowCrypt/Models/Realm Models/ClientConfigurationRealmObject.swift b/FlowCrypt/Models/Realm Models/ClientConfigurationRealmObject.swift index 1b4b23c48..ab2850c2b 100644 --- a/FlowCrypt/Models/Realm Models/ClientConfigurationRealmObject.swift +++ b/FlowCrypt/Models/Realm Models/ClientConfigurationRealmObject.swift @@ -14,6 +14,7 @@ final class ClientConfigurationRealmObject: Object { @Persisted var flags: Data? @Persisted var customKeyserverUrl: String? @Persisted var keyManagerUrl: String? + @Persisted var fesUrl: String? @Persisted var disallowAttesterSearchForDomains: Data? @Persisted var enforceKeygenAlgo: String? @Persisted var enforceKeygenExpireMonths: Int @@ -23,6 +24,7 @@ final class ClientConfigurationRealmObject: Object { flags: [String]?, customKeyserverUrl: String?, keyManagerUrl: String?, + fesUrl: String?, disallowAttesterSearchForDomains: [String]?, enforceKeygenAlgo: String?, enforceKeygenExpireMonths: Int?, @@ -34,6 +36,7 @@ final class ClientConfigurationRealmObject: Object { } self.customKeyserverUrl = customKeyserverUrl self.keyManagerUrl = keyManagerUrl + self.fesUrl = fesUrl if let disallowAttesterSearchForDomains = disallowAttesterSearchForDomains { self.disallowAttesterSearchForDomains = try? JSONEncoder().encode(disallowAttesterSearchForDomains) } @@ -45,11 +48,12 @@ final class ClientConfigurationRealmObject: Object { } extension ClientConfigurationRealmObject { - convenience init(configuration: RawClientConfiguration, user: User) { + convenience init(configuration: RawClientConfiguration, user: User, fesUrl: String?) { self.init( flags: configuration.flags?.map(\.rawValue), customKeyserverUrl: configuration.customKeyserverUrl, keyManagerUrl: configuration.keyManagerUrl, + fesUrl: fesUrl, disallowAttesterSearchForDomains: configuration.disallowAttesterSearchForDomains, enforceKeygenAlgo: configuration.enforceKeygenAlgo, enforceKeygenExpireMonths: configuration.enforceKeygenExpireMonths, diff --git a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationTests.swift b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationTests.swift index 2761fb8fd..94adea6e0 100644 --- a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationTests.swift +++ b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationTests.swift @@ -25,6 +25,10 @@ class ClientConfigurationTests: XCTestCase { XCTAssertFalse(ClientConfiguration(raw: RawClientConfiguration(keyManagerUrl: "not a url string")).isKeyManagerUrlValid) } + func testIsUsingFes() { + XCTAssertTrue(ClientConfiguration(raw: RawClientConfiguration(fesUrl: "https://fes.flowcrypt.com") ).isUsingFes) + } + func testMustAutoImportOrAutogenPrvWithKeyManager() { XCTAssertTrue(ClientConfiguration(raw: RawClientConfiguration( flags: [.privateKeyAutoimportOrAutogen], diff --git a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/ClientConfigurationProviderMock.swift b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/ClientConfigurationProviderMock.swift index 6234f866c..cb9471ff1 100644 --- a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/ClientConfigurationProviderMock.swift +++ b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/ClientConfigurationProviderMock.swift @@ -33,7 +33,7 @@ class LocalClientConfigurationMock: LocalClientConfigurationType { var saveCount = 0 var saveCall: (RawClientConfiguration) -> Void = { clientConfiguration in } - func save(for user: User, raw: RawClientConfiguration) { + func save(for user: User, raw: RawClientConfiguration, fesUrl: String?) { saveInvoked = true saveCount += 1 saveCall(raw) diff --git a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/EnterpriseServerApiMock.swift b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/EnterpriseServerApiMock.swift index dc5f50f05..47c935568 100644 --- a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/EnterpriseServerApiMock.swift +++ b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/Mocks/EnterpriseServerApiMock.swift @@ -12,8 +12,8 @@ import Foundation final class EnterpriseServerApiMock: EnterpriseServerApiType { var getActiveFesUrlInvoked = false var getActiveFesUrlInvokedCount = 0 - var getActiveFesUrlCall: (String) throws -> String? = { _ in - throw OrganisationalRulesServiceError.getActiveFesUrlCall + var getActiveFesUrlCall: (String) -> String? = { _ in + return nil } func getActiveFesUrl(for email: String) async throws -> String? { getActiveFesUrlInvoked = true