diff --git a/FlowCrypt/App/AppContext.swift b/FlowCrypt/App/AppContext.swift index 1d8d885d2..33ef97756 100644 --- a/FlowCrypt/App/AppContext.swift +++ b/FlowCrypt/App/AppContext.swift @@ -48,7 +48,7 @@ class AppContext { let keyService = KeyService( storage: encryptedStorage, passPhraseService: passPhraseService, - currentUserEmail: { encryptedStorage.activeUser?.email } + currentUserEmail: { try? encryptedStorage.activeUser?.email } ) let clientConfigurationService = ClientConfigurationService( local: LocalClientConfiguration( @@ -58,10 +58,10 @@ class AppContext { return AppContext( encryptedStorage: encryptedStorage, session: nil, // will be set later. But would be nice to already set here, if available - userAccountService: SessionService( + userAccountService: try SessionService( encryptedStorage: encryptedStorage, googleService: GoogleUserService( - currentUserEmail: encryptedStorage.activeUser?.email, + currentUserEmail: try encryptedStorage.activeUser?.email, appDelegateGoogleSessionContainer: UIApplication.shared.delegate as? AppDelegate ) ), @@ -98,7 +98,7 @@ class AppContext { @MainActor func getOptionalMailProvider() -> MailProvider? { guard - let currentUser = encryptedStorage.activeUser, + let currentUser = try? encryptedStorage.activeUser, let currentAuthType = currentUser.authType else { return nil } diff --git a/FlowCrypt/Controllers/Compose/ComposeViewController.swift b/FlowCrypt/Controllers/Compose/ComposeViewController.swift index 3f164cfef..58113c14a 100644 --- a/FlowCrypt/Controllers/Compose/ComposeViewController.swift +++ b/FlowCrypt/Controllers/Compose/ComposeViewController.swift @@ -96,13 +96,13 @@ final class ComposeViewController: TableNodeViewController { filesManager: FilesManagerType = FilesManager(), photosManager: PhotosManagerType = PhotosManager(), keyMethods: KeyMethodsType = KeyMethods() - ) { + ) throws { self.appContext = appContext self.email = appContext.user.email self.notificationCenter = notificationCenter self.input = input self.decorator = decorator - let clientConfiguration = appContext.clientConfigurationService.getSaved(for: appContext.user.email) + let clientConfiguration = try appContext.clientConfigurationService.getSaved(for: appContext.user.email) self.contactsService = contactsService ?? ContactsService( localContactsProvider: LocalContactsProvider( encryptedStorage: appContext.encryptedStorage @@ -942,10 +942,14 @@ extension ComposeViewController { extension ComposeViewController { private func searchEmail(with query: String) { Task { - let localEmails = contactsService.searchLocalContacts(query: query) - let cloudEmails = try? await service.searchContacts(query: query) - let emails = Set([localEmails, cloudEmails].compactMap { $0 }.flatMap { $0 }) - updateState(with: .searchEmails(Array(emails))) + do { + let localEmails = try contactsService.searchLocalContacts(query: query) + let cloudEmails = try? await service.searchContacts(query: query) + let emails = Set([localEmails, cloudEmails].compactMap { $0 }.flatMap { $0 }) + updateState(with: .searchEmails(Array(emails))) + } catch { + showAlert(message: error.localizedDescription) + } } } diff --git a/FlowCrypt/Controllers/Inbox/InboxViewController.swift b/FlowCrypt/Controllers/Inbox/InboxViewController.swift index 99ca57986..d51616dbe 100644 --- a/FlowCrypt/Controllers/Inbox/InboxViewController.swift +++ b/FlowCrypt/Controllers/Inbox/InboxViewController.swift @@ -331,9 +331,13 @@ extension InboxViewController { } private func btnComposeTap() { - TapTicFeedback.generate(.light) - let composeVc = ComposeViewController(appContext: appContext) - navigationController?.pushViewController(composeVc, animated: true) + do { + TapTicFeedback.generate(.light) + let composeVc = try ComposeViewController(appContext: appContext) + navigationController?.pushViewController(composeVc, animated: true) + } catch { + showAlert(message: error.localizedDescription) + } } } diff --git a/FlowCrypt/Controllers/MessageList Extension/MsgListViewController.swift b/FlowCrypt/Controllers/MessageList Extension/MsgListViewController.swift index 28011a0d4..af3d2e016 100644 --- a/FlowCrypt/Controllers/MessageList Extension/MsgListViewController.swift +++ b/FlowCrypt/Controllers/MessageList Extension/MsgListViewController.swift @@ -31,9 +31,13 @@ extension MsgListViewController where Self: UIViewController { // TODO: uncomment in "sent message from draft" feature private func openDraft(appContext: AppContextWithUser, with message: Message) { - let controller = ComposeViewController(appContext: appContext) - controller.update(with: message) - navigationController?.pushViewController(controller, animated: true) + do { + let controller = try ComposeViewController(appContext: appContext) + controller.update(with: message) + navigationController?.pushViewController(controller, animated: true) + } catch { + showAlert(message: error.localizedDescription) + } } private func openMsg(appContext: AppContextWithUser, with message: Message, path: String) { @@ -47,13 +51,17 @@ extension MsgListViewController where Self: UIViewController { } private func openThread(with thread: MessageThread, appContext: AppContextWithUser) { - let viewController = ThreadDetailsViewController( - appContext: appContext, - thread: thread - ) { [weak self] (action, message) in - self?.handleMessageOperation(with: message, action: action) + do { + let viewController = try ThreadDetailsViewController( + appContext: appContext, + thread: thread + ) { [weak self] (action, message) in + self?.handleMessageOperation(with: message, action: action) + } + navigationController?.pushViewController(viewController, animated: true) + } catch { + showAlert(message: error.localizedDescription) } - navigationController?.pushViewController(viewController, animated: true) } // MARK: Operation diff --git a/FlowCrypt/Controllers/Settings/KeySettings/Key List/KeySettingsViewController.swift b/FlowCrypt/Controllers/Settings/KeySettings/Key List/KeySettingsViewController.swift index 44b51a9b1..c1b3f07f7 100644 --- a/FlowCrypt/Controllers/Settings/KeySettings/Key List/KeySettingsViewController.swift +++ b/FlowCrypt/Controllers/Settings/KeySettings/Key List/KeySettingsViewController.swift @@ -25,10 +25,10 @@ final class KeySettingsViewController: TableNodeViewController { init( appContext: AppContextWithUser, decorator: KeySettingsViewDecorator = KeySettingsViewDecorator() - ) { + ) throws { self.appContext = appContext self.decorator = decorator - self.isUsingKeyManager = appContext.clientConfigurationService.getSaved(for: appContext.user.email).isUsingKeyManager + self.isUsingKeyManager = try appContext.clientConfigurationService.getSaved(for: appContext.user.email).isUsingKeyManager super.init(node: TableNode()) } diff --git a/FlowCrypt/Controllers/Settings/Settings List/SettingsViewController.swift b/FlowCrypt/Controllers/Settings/Settings List/SettingsViewController.swift index 1130dcc11..2977738ad 100644 --- a/FlowCrypt/Controllers/Settings/Settings List/SettingsViewController.swift +++ b/FlowCrypt/Controllers/Settings/Settings List/SettingsViewController.swift @@ -51,10 +51,10 @@ final class SettingsViewController: TableNodeViewController { init( appContext: AppContextWithUser, decorator: SettingsViewDecorator = SettingsViewDecorator() - ) { + ) throws { self.appContext = appContext self.decorator = decorator - self.clientConfiguration = appContext.clientConfigurationService.getSaved(for: appContext.user.email) + self.clientConfiguration = try appContext.clientConfigurationService.getSaved(for: appContext.user.email) self.rows = SettingsMenuItem.filtered(with: clientConfiguration) super.init(node: TableNode()) } @@ -113,7 +113,12 @@ extension SettingsViewController { switch setting { case .keys: - viewController = KeySettingsViewController(appContext: appContext) + do { + viewController = try KeySettingsViewController(appContext: appContext) + } catch { + viewController = nil + showAlert(message: error.localizedDescription) + } case .legal: viewController = LegalViewController() case .contacts: diff --git a/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift b/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift index f9f8c7a61..23e0b43d9 100644 --- a/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift @@ -24,9 +24,9 @@ final class SetupGenerateKeyViewController: SetupCreatePassphraseAbstractViewCon init( appContext: AppContextWithUser, decorator: SetupViewDecorator = SetupViewDecorator() - ) { + ) throws { self.attester = AttesterApi( - clientConfiguration: appContext.clientConfigurationService.getSaved(for: appContext.user.email) + clientConfiguration: try appContext.clientConfigurationService.getSaved(for: appContext.user.email) ) self.service = Service( appContext: appContext, diff --git a/FlowCrypt/Controllers/Setup/SetupInitialViewController.swift b/FlowCrypt/Controllers/Setup/SetupInitialViewController.swift index c1a3f6f49..ff40c8421 100644 --- a/FlowCrypt/Controllers/Setup/SetupInitialViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupInitialViewController.swift @@ -63,11 +63,11 @@ final class SetupInitialViewController: TableNodeViewController { appContext: AppContextWithUser, decorator: SetupViewDecorator = SetupViewDecorator(), emailKeyManagerApi: EmailKeyManagerApiType? = nil - ) { + ) throws { self.appContext = appContext self.service = ServiceActor(backupService: appContext.getBackupService()) self.decorator = decorator - let clientConfiguration = appContext.clientConfigurationService.getSaved(for: appContext.user.email) + let clientConfiguration = try appContext.clientConfigurationService.getSaved(for: appContext.user.email) self.emailKeyManagerApi = emailKeyManagerApi ?? EmailKeyManagerApi(clientConfiguration: clientConfiguration) self.clientConfiguration = clientConfiguration super.init(node: TableNode()) @@ -328,8 +328,12 @@ extension SetupInitialViewController { } private func proceedToCreatingNewKey() { - let viewController = SetupGenerateKeyViewController(appContext: appContext) - navigationController?.pushViewController(viewController, animated: true) + do { + let viewController = try SetupGenerateKeyViewController(appContext: appContext) + navigationController?.pushViewController(viewController, animated: true) + } catch { + showAlert(message: error.localizedDescription) + } } private func proceedToSetupWithEKMKeys(keys: [KeyDetails]) { diff --git a/FlowCrypt/Controllers/SideMenu/Menu/MyMenuViewController.swift b/FlowCrypt/Controllers/SideMenu/Menu/MyMenuViewController.swift index 16bb19df9..4bb268390 100644 --- a/FlowCrypt/Controllers/SideMenu/Menu/MyMenuViewController.swift +++ b/FlowCrypt/Controllers/SideMenu/Menu/MyMenuViewController.swift @@ -50,9 +50,14 @@ final class MyMenuViewController: ViewController { private var folders: [FolderViewModel] = [] private var serviceItems: [FolderViewModel] { FolderViewModel.menuItems } private var accounts: [User] { - appContext.encryptedStorage.getAllUsers() - .filter { $0.email != appContext.user.email } - .filter { appContext.encryptedStorage.doesAnyKeypairExist(for: $0.email) } + do { + return try appContext.encryptedStorage.getAllUsers() + .filter { $0.email != appContext.user.email } + .filter { try appContext.encryptedStorage.doesAnyKeypairExist(for: $0.email) } + } catch { + showAlert(message: error.localizedDescription) + return [] + } } private let tableNode: ASTableNode @@ -294,7 +299,11 @@ extension MyMenuViewController { sideMenuController()?.sideMenu?.hideSideMenu() return } - sideMenuController()?.setContentViewController(SettingsViewController(appContext: appContext)) + do { + sideMenuController()?.setContentViewController(try SettingsViewController(appContext: appContext)) + } catch { + showAlert(message: error.localizedDescription) + } case .logOut: do { try appContext.globalRouter.signOut(appContext: appContext) diff --git a/FlowCrypt/Controllers/Threads/ThreadDetailsViewController.swift b/FlowCrypt/Controllers/Threads/ThreadDetailsViewController.swift index 014b08266..2a638a9b7 100644 --- a/FlowCrypt/Controllers/Threads/ThreadDetailsViewController.swift +++ b/FlowCrypt/Controllers/Threads/ThreadDetailsViewController.swift @@ -50,9 +50,9 @@ final class ThreadDetailsViewController: TableNodeViewController { messageService: MessageService? = nil, thread: MessageThread, completion: @escaping MessageActionCompletion - ) { + ) throws { self.appContext = appContext - let clientConfiguration = appContext.clientConfigurationService.getSaved(for: appContext.user.email) + let clientConfiguration = try appContext.clientConfigurationService.getSaved(for: appContext.user.email) self.messageService = messageService ?? MessageService( contactsService: ContactsService( localContactsProvider: LocalContactsProvider( @@ -259,10 +259,14 @@ extension ThreadDetailsViewController { }() let composeInput = ComposeMessageInput(type: composeType) - navigationController?.pushViewController( - ComposeViewController(appContext: appContext, input: composeInput), - animated: true - ) + do { + navigationController?.pushViewController( + try ComposeViewController(appContext: appContext, input: composeInput), + animated: true + ) + } catch { + showAlert(message: error.localizedDescription) + } } private func markAsRead(at index: Int) { diff --git a/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift b/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift index 9d2bae604..8b44a8cd1 100644 --- a/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift +++ b/FlowCrypt/Functionality/DataManager/Encrypted Storage/EncryptedStorage.swift @@ -11,19 +11,19 @@ import RealmSwift import UIKit protocol EncryptedStorageType { - var storage: Realm { get } + var storage: Realm { get throws } - var activeUser: User? { get } - func getAllUsers() -> [User] + var activeUser: User? { get throws } + func getAllUsers() throws -> [User] func saveActiveUser(with user: User) throws - func doesAnyKeypairExist(for email: String) -> Bool + func doesAnyKeypairExist(for email: String) throws -> Bool func putKeypairs(keyDetails: [KeyDetails], passPhrase: String?, source: KeySource, for email: String) throws - func getKeypairs(by email: String) -> [Keypair] + func getKeypairs(by email: String) throws -> [Keypair] func validate() throws func reset() throws - func cleanup() + func cleanup() throws } final class EncryptedStorage: EncryptedStorageType { @@ -68,13 +68,10 @@ final class EncryptedStorage: EncryptedStorageType { private let storageEncryptionKey: Data var storage: Realm { - do { + get throws { let configuration = try getConfiguration() Realm.Configuration.defaultConfiguration = configuration - let realm = try Realm(configuration: configuration) - return realm - } catch { - fatalError("failed to initiate realm: \(error)") + return try Realm(configuration: configuration) } } @@ -82,9 +79,9 @@ final class EncryptedStorage: EncryptedStorageType { self.storageEncryptionKey = storageEncryptionKey } - private func getDocumentDirectory() -> String { + private func getDocumentDirectory() throws -> String { guard let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { - fatalError("No path direction for .documentDirectory") + throw AppErr.general("No path direction for .documentDirectory") } return documentDirectory } @@ -94,7 +91,7 @@ final class EncryptedStorage: EncryptedStorageType { return Realm.Configuration(inMemoryIdentifier: UUID().uuidString) } - let path = getDocumentDirectory() + "/" + Constants.encryptedDbFilename + let path = try getDocumentDirectory() + "/" + Constants.encryptedDbFilename let latestSchemaVersion = currentSchema.version.dbSchemaVersion return Realm.Configuration( @@ -111,11 +108,13 @@ final class EncryptedStorage: EncryptedStorageType { // MARK: - LogOut extension EncryptedStorage: LogOutHandler { func logOutUser(email: String) throws { + let storage = try storage + let users = storage.objects(UserRealmObject.self) // in case there is only one user - just delete storage if users.count == 1, users.first?.email == email { - destroyEncryptedStorage() + try cleanup() } else { // remove user and keys for this user let userToDelete = users @@ -135,10 +134,6 @@ extension EncryptedStorage: LogOutHandler { } } } - - private func destroyEncryptedStorage() { - cleanup() - } } // MARK: - Schema migration @@ -168,11 +163,12 @@ extension EncryptedStorage { // MARK: - Keys extension EncryptedStorage { func putKeypairs(keyDetails: [KeyDetails], passPhrase: String?, source: KeySource, for email: String) throws { - guard let user = getUserObject(for: email) else { + guard let user = try getUserObject(for: email) else { logger.logError("Can't find user with given email to update keys. User should be already saved") return } + let storage = try storage try storage.write { for key in keyDetails { let object = try KeypairRealmObject(key, passphrase: passPhrase, source: source, user: user) @@ -181,27 +177,27 @@ extension EncryptedStorage { } } - func getKeypairs(by email: String) -> [Keypair] { - return storage.objects(KeypairRealmObject.self).where({ + func getKeypairs(by email: String) throws -> [Keypair] { + return try storage.objects(KeypairRealmObject.self).where({ $0.account == email }).map(Keypair.init) } - func doesAnyKeypairExist(for email: String) -> Bool { - let keys = storage.objects(KeypairRealmObject.self).where { + func doesAnyKeypairExist(for email: String) throws -> Bool { + let keys = try storage.objects(KeypairRealmObject.self).where { $0.account == email } return !keys.isEmpty } - private func getUserObject(for email: String) -> UserRealmObject? { - storage.objects(UserRealmObject.self).where { + private func getUserObject(for email: String) throws -> UserRealmObject? { + try storage.objects(UserRealmObject.self).where { $0.email == email }.first } private func updateKeys(with primaryFingerprint: String, passphrase: String?) throws { - let keys = storage.objects(KeypairRealmObject.self).where { + let keys = try storage.objects(KeypairRealmObject.self).where { $0.primaryFingerprint == primaryFingerprint } @@ -225,8 +221,8 @@ extension EncryptedStorage: PassPhraseStorageType { try updateKeys(with: passPhrase.primaryFingerprintOfAssociatedKey, passphrase: nil) } - func getPassPhrases() -> [PassPhrase] { - return storage.objects(KeypairRealmObject.self) + func getPassPhrases() throws -> [PassPhrase] { + return try storage.objects(KeypairRealmObject.self) .compactMap(PassPhrase.init) } } @@ -234,17 +230,21 @@ extension EncryptedStorage: PassPhraseStorageType { // MARK: - User extension EncryptedStorage { var activeUser: User? { - let users = storage.objects(UserRealmObject.self).where { - $0.isActive == true + get throws { + let users = try storage.objects(UserRealmObject.self).where { + $0.isActive == true + } + return users.first.flatMap(User.init) } - return users.first.flatMap(User.init) } - func getAllUsers() -> [User] { - storage.objects(UserRealmObject.self).map(User.init) + func getAllUsers() throws -> [User] { + try storage.objects(UserRealmObject.self).map(User.init) } func saveActiveUser(with user: User) throws { + let storage = try storage + try storage.write { // Mark all users as inactive storage.objects(UserRealmObject.self).forEach { @@ -266,17 +266,15 @@ extension EncryptedStorage { } func reset() throws { - let path = getDocumentDirectory() + "/" + Constants.encryptedDbFilename + let path = try getDocumentDirectory() + "/" + Constants.encryptedDbFilename try FileManager.default.removeItem(atPath: path) } - func cleanup() { - do { - try storage.write { - storage.deleteAll() - } - } catch { - assertionFailure("Error while deleting the objects from the storage \(error)") + func cleanup() throws { + let storage = try storage + + try storage.write { + storage.deleteAll() } } } diff --git a/FlowCrypt/Functionality/DataManager/SessionService.swift b/FlowCrypt/Functionality/DataManager/SessionService.swift index fd0db82dc..67ad70b9b 100644 --- a/FlowCrypt/Functionality/DataManager/SessionService.swift +++ b/FlowCrypt/Functionality/DataManager/SessionService.swift @@ -28,7 +28,7 @@ protocol SessionServiceType { func switchActiveSessionFor(user: User) throws -> SessionType? func startActiveSessionForNextUser() throws -> SessionType? func logOutUsersThatDontHaveAnyKeysSetUp() throws - func cleanup() + func cleanup() throws } final class SessionService { @@ -45,11 +45,11 @@ final class SessionService { localStorage: LocalStorageType & LogOutHandler = LocalStorage(), imap: Imap? = nil, googleService: GoogleUserService - ) { + ) throws { self.googleService = googleService // todo - the following User.empty may be wrong - unsure, untested // maybe should instead get user - self.imap = imap ?? Imap(user: encryptedStorage.activeUser ?? User.empty) + self.imap = try imap ?? Imap(user: try encryptedStorage.activeUser ?? User.empty) self.encryptedStorage = encryptedStorage self.localStorage = localStorage } @@ -77,12 +77,12 @@ extension SessionService: SessionServiceType { } func startActiveSessionForNextUser() throws -> SessionType? { - guard let currentUser = encryptedStorage.activeUser else { + guard let currentUser = try encryptedStorage.activeUser else { return nil } logOut(user: currentUser) - guard let nextUser = encryptedStorage.getAllUsers().first else { + guard let nextUser = try encryptedStorage.getAllUsers().first else { return nil } @@ -92,7 +92,7 @@ extension SessionService: SessionServiceType { } func switchActiveSessionFor(user: User) throws -> SessionType? { - let currentUser = encryptedStorage + let currentUser = try encryptedStorage .getAllUsers() .first(where: { $0.email == user.email }) @@ -106,14 +106,15 @@ extension SessionService: SessionServiceType { func logOutUsersThatDontHaveAnyKeysSetUp() throws { logger.logInfo("Clean up sessions") - for user in encryptedStorage.getAllUsers() { - if !encryptedStorage.doesAnyKeypairExist(for: user.email) { + for user in try encryptedStorage.getAllUsers() { + if try !encryptedStorage.doesAnyKeypairExist(for: user.email) { logger.logInfo("User session to clean up \(user.email)") logOut(user: user) } } - let users = encryptedStorage.getAllUsers() - if !users.contains(where: { $0.isActive }), let user = users.first(where: { encryptedStorage.doesAnyKeypairExist(for: $0.email) }) { + + let users = try encryptedStorage.getAllUsers() + if !users.contains(where: { $0.isActive }), let user = try users.first(where: { try encryptedStorage.doesAnyKeypairExist(for: $0.email) }) { try switchActiveSession(for: user) } } @@ -158,9 +159,9 @@ extension SessionService: SessionServiceType { } /// cleanup all user sessions - func cleanup() { + func cleanup() throws { logger.logInfo("Clean up storages") - encryptedStorage.cleanup() + try encryptedStorage.cleanup() localStorage.cleanup() } } diff --git a/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift b/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift index 5131730f6..e2c7cab99 100644 --- a/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift +++ b/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift @@ -226,7 +226,7 @@ extension MessageService { private func fetchVerificationPubKeys(for email: String?, onlyLocal: Bool) async throws -> [String] { guard let email = email else { return [] } - let pubKeys = contactsService.retrievePubKeys(for: email) + let pubKeys = try contactsService.retrievePubKeys(for: email) if pubKeys.isNotEmpty || onlyLocal { return pubKeys } guard let contact = try? await contactsService.fetchContact(with: email) diff --git a/FlowCrypt/Functionality/Services/AppStartup.swift b/FlowCrypt/Functionality/Services/AppStartup.swift index 3e33cf2a2..4b570cb64 100644 --- a/FlowCrypt/Functionality/Services/AppStartup.swift +++ b/FlowCrypt/Functionality/Services/AppStartup.swift @@ -34,7 +34,7 @@ struct AppStartup { await setupCore() try await setupSession() try await getUserOrgRulesIfNeeded() - chooseView(for: window) + try chooseView(for: window) } catch { showErrorAlert(of: error, on: window) } @@ -60,8 +60,8 @@ struct AppStartup { } @MainActor - private func chooseView(for window: UIWindow) { - switch entryPointForUser() { + private func chooseView(for window: UIWindow) throws { + switch try entryPointForUser() { case .mainFlow: startWithUserContext(appContext: appContext, window: window) { context in let controller = InboxViewContainerController(appContext: context) @@ -76,21 +76,26 @@ struct AppStartup { ) case .setupFlow: startWithUserContext(appContext: appContext, window: window) { context in - let controller = SetupInitialViewController(appContext: context) - window.rootViewController = MainNavigationController(rootViewController: controller) + do { + let controller = try SetupInitialViewController(appContext: context) + window.rootViewController = MainNavigationController(rootViewController: controller) + } catch { + window.rootViewController?.showAlert(message: error.localizedDescription) + } } } } - private func entryPointForUser() -> EntryPoint { - guard let activeUser = appContext.encryptedStorage.activeUser else { + private func entryPointForUser() throws -> EntryPoint { + guard let activeUser = try appContext.encryptedStorage.activeUser else { logger.logInfo("User is not logged in -> signIn") return .signIn } - if appContext.encryptedStorage.doesAnyKeypairExist(for: activeUser.email) { + + if try appContext.encryptedStorage.doesAnyKeypairExist(for: activeUser.email) { logger.logInfo("Setup finished -> mainFlow") return .mainFlow - } else if let session = appContext.session, let userId = makeUserIdForSetup(session: session) { + } else if let session = appContext.session, let userId = try makeUserIdForSetup(session: session) { logger.logInfo("User with session \(session) -> setupFlow") return .setupFlow(userId) } else { @@ -100,14 +105,14 @@ struct AppStartup { } private func getUserOrgRulesIfNeeded() async throws { - guard let currentUser = appContext.encryptedStorage.activeUser else { + guard let currentUser = try appContext.encryptedStorage.activeUser else { return } _ = try await appContext.clientConfigurationService.fetch(for: currentUser) } - private func makeUserIdForSetup(session: SessionType) -> UserId? { - guard let activeUser = appContext.encryptedStorage.activeUser else { + private func makeUserIdForSetup(session: SessionType) throws -> UserId? { + guard let activeUser = try appContext.encryptedStorage.activeUser else { Logger.logInfo("Can't create user id for setup") return nil } @@ -153,7 +158,7 @@ struct AppStartup { let session = appContext.session guard - let user = appContext.encryptedStorage.activeUser, + let user = try? appContext.encryptedStorage.activeUser, let authType = user.authType else { let message = "Wrong application state. User not found for session \(session?.description ?? "nil")" diff --git a/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift b/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift index 7617bcdcd..05f6e2a8a 100644 --- a/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift +++ b/FlowCrypt/Functionality/Services/Client Configuration Service/ClientConfigurationService.swift @@ -11,7 +11,7 @@ import Foundation protocol ClientConfigurationServiceType { func fetch(for user: User) async throws -> ClientConfiguration - func getSaved(for user: String) -> ClientConfiguration + func getSaved(for user: String) throws -> ClientConfiguration } final class ClientConfigurationService { @@ -38,15 +38,15 @@ extension ClientConfigurationService: ClientConfigurationServiceType { try local.save(for: user, raw: raw, fesUrl: fesUrl) return ClientConfiguration(raw: raw) } catch { - guard let raw = local.load(for: user.email) else { + guard let raw = try local.load(for: user.email) else { throw error } return ClientConfiguration(raw: raw) } } - func getSaved(for userEmail: String) -> ClientConfiguration { - guard let raw = self.local.load(for: userEmail) else { + func getSaved(for userEmail: String) throws -> ClientConfiguration { + guard let raw = try local.load(for: userEmail) else { // todo - throw instead fatalError("There should not be a user without OrganisationalRules") } diff --git a/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift b/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift index 60e885414..7c2a336b8 100644 --- a/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift +++ b/FlowCrypt/Functionality/Services/Client Configuration Service/LocalClientConfiguration.swift @@ -10,7 +10,7 @@ import Foundation import RealmSwift protocol LocalClientConfigurationType { - func load(for user: String) -> RawClientConfiguration? + func load(for user: String) throws -> RawClientConfiguration? func remove(for user: String) throws func save(for user: User, raw: RawClientConfiguration, fesUrl: String?) throws } @@ -19,7 +19,9 @@ final class LocalClientConfiguration { private let encryptedStorage: EncryptedStorageType private var storage: Realm { - encryptedStorage.storage + get throws { + try encryptedStorage.storage + } } init(encryptedStorage: EncryptedStorageType) { @@ -28,13 +30,15 @@ final class LocalClientConfiguration { } extension LocalClientConfiguration: LocalClientConfigurationType { - func load(for userEmail: String) -> RawClientConfiguration? { - return storage.objects(ClientConfigurationRealmObject.self).where { + func load(for userEmail: String) throws -> RawClientConfiguration? { + return try storage.objects(ClientConfigurationRealmObject.self).where { $0.userEmail == userEmail }.first.flatMap(RawClientConfiguration.init) } func remove(for userEmail: String) throws { + let storage = try storage + let objects = storage.objects(ClientConfigurationRealmObject.self).where { $0.userEmail == userEmail } @@ -51,6 +55,7 @@ extension LocalClientConfiguration: LocalClientConfigurationType { fesUrl: fesUrl ) + let storage = try storage try storage.write { storage.add(object, update: .modified) } diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index 2b2141ba7..99d8f7c9c 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -104,7 +104,7 @@ final class ComposeMessageService { let subject = contextToSend.subject ?? "(no subject)" - guard let myPubKey = storage.getKeypairs(by: sender).map(\.public).first else { + guard let myPubKey = try storage.getKeypairs(by: sender).map(\.public).first else { throw MessageValidationError.missingPublicKey } @@ -125,7 +125,7 @@ final class ComposeMessageService { throw MessageValidationError.subjectContainsPassword } - let allAvailablePassPhrases = passPhraseService.getPassPhrases().map(\.value) + let allAvailablePassPhrases = try passPhraseService.getPassPhrases().map(\.value) if allAvailablePassPhrases.contains(password) { throw MessageValidationError.notUniquePassword } @@ -150,7 +150,7 @@ final class ComposeMessageService { private func getRecipientKeys(for recipients: [ComposeMessageRecipient]) async throws -> [RecipientWithSortedPubKeys] { var recipientsWithKeys: [RecipientWithSortedPubKeys] = [] for recipient in recipients { - let armoredPubkeys = contactsService.retrievePubKeys(for: recipient.email).joined(separator: "\n") + let armoredPubkeys = try contactsService.retrievePubKeys(for: recipient.email).joined(separator: "\n") let parsed = try await self.core.parseKeys(armoredOrBinary: armoredPubkeys.data()) recipientsWithKeys.append(RecipientWithSortedPubKeys(email: recipient.email, keyDetails: parsed.keyDetails)) } diff --git a/FlowCrypt/Functionality/Services/Contacts Service/ContactsService.swift b/FlowCrypt/Functionality/Services/Contacts Service/ContactsService.swift index 85f4d26f1..ac090c4e3 100644 --- a/FlowCrypt/Functionality/Services/Contacts Service/ContactsService.swift +++ b/FlowCrypt/Functionality/Services/Contacts Service/ContactsService.swift @@ -18,12 +18,12 @@ protocol ContactsServiceType: PublicKeyProvider, ContactsProviderType { protocol ContactsProviderType { func findLocalContact(with email: String) async throws -> RecipientWithSortedPubKeys? - func searchLocalContacts(query: String) -> [String] + func searchLocalContacts(query: String) throws -> [String] func fetchContact(with email: String) async throws -> RecipientWithSortedPubKeys } protocol PublicKeyProvider { - func retrievePubKeys(for email: String) -> [String] + func retrievePubKeys(for email: String) throws -> [String] func removePubKey(with fingerprint: String, for email: String) throws } @@ -47,8 +47,8 @@ extension ContactsService: ContactsProviderType { return try await localContactsProvider.searchRecipient(with: email) } - func searchLocalContacts(query: String) -> [String] { - localContactsProvider.searchEmails(query: query) + func searchLocalContacts(query: String) throws -> [String] { + try localContactsProvider.searchEmails(query: query) } func fetchContact(with email: String) async throws -> RecipientWithSortedPubKeys { @@ -59,8 +59,8 @@ extension ContactsService: ContactsProviderType { } extension ContactsService: PublicKeyProvider { - func retrievePubKeys(for email: String) -> [String] { - return localContactsProvider.retrievePubKeys(for: email) + func retrievePubKeys(for email: String) throws -> [String] { + try localContactsProvider.retrievePubKeys(for: email) } func removePubKey(with fingerprint: String, for email: String) throws { diff --git a/FlowCrypt/Functionality/Services/Folders Services/FoldersService.swift b/FlowCrypt/Functionality/Services/Folders Services/FoldersService.swift index e8c274a26..f074e9430 100644 --- a/FlowCrypt/Functionality/Services/Folders Services/FoldersService.swift +++ b/FlowCrypt/Functionality/Services/Folders Services/FoldersService.swift @@ -38,7 +38,7 @@ final class FoldersService: FoldersServiceType { if isForceReload { return try await getAndSaveFolders(for: user) } - let localFolders = self.localFoldersProvider.fetchFolders(for: user.email) + let localFolders = try localFoldersProvider.fetchFolders(for: user.email) if localFolders.isEmpty { return try await getAndSaveFolders(for: user) } else { diff --git a/FlowCrypt/Functionality/Services/Folders Services/LocalFoldersProvider.swift b/FlowCrypt/Functionality/Services/Folders Services/LocalFoldersProvider.swift index 5d7f3284d..547023789 100644 --- a/FlowCrypt/Functionality/Services/Folders Services/LocalFoldersProvider.swift +++ b/FlowCrypt/Functionality/Services/Folders Services/LocalFoldersProvider.swift @@ -10,7 +10,7 @@ import Foundation import RealmSwift protocol LocalFoldersProviderType { - func fetchFolders(for userEmail: String) -> [FolderViewModel] + func fetchFolders(for userEmail: String) throws -> [FolderViewModel] func removeFolders(for userEmail: String) throws func save(folders: [Folder], for user: User) throws } @@ -19,7 +19,9 @@ final class LocalFoldersProvider { private let encryptedStorage: EncryptedStorageType private var storage: Realm { - encryptedStorage.storage + get throws { + try encryptedStorage.storage + } } init(encryptedStorage: EncryptedStorageType) { @@ -28,14 +30,15 @@ final class LocalFoldersProvider { } extension LocalFoldersProvider: LocalFoldersProviderType { - func fetchFolders(for userEmail: String) -> [FolderViewModel] { - storage.objects(FolderRealmObject.self).where { + func fetchFolders(for userEmail: String) throws -> [FolderViewModel] { + try storage.objects(FolderRealmObject.self).where { $0.user.email == userEmail }.compactMap(FolderViewModel.init) } func save(folders: [Folder], for user: User) throws { let objects = folders.map { FolderRealmObject(folder: $0, user: user) } + let storage = try storage try storage.write { objects.forEach { storage.add($0, update: .modified) @@ -44,6 +47,8 @@ extension LocalFoldersProvider: LocalFoldersProviderType { } func removeFolders(for userEmail: String) throws { + let storage = try storage + let objects = storage.objects(FolderRealmObject.self).where { $0.user.email == userEmail } diff --git a/FlowCrypt/Functionality/Services/GlobalRouter.swift b/FlowCrypt/Functionality/Services/GlobalRouter.swift index 85efe4631..405c6e625 100644 --- a/FlowCrypt/Functionality/Services/GlobalRouter.swift +++ b/FlowCrypt/Functionality/Services/GlobalRouter.swift @@ -65,7 +65,7 @@ extension GlobalRouter: GlobalRouterType { viewController.showSpinner() let googleService = GoogleUserService( - currentUserEmail: appContext.encryptedStorage.activeUser?.email, + currentUserEmail: try appContext.encryptedStorage.activeUser?.email, appDelegateGoogleSessionContainer: UIApplication.shared.delegate as? AppDelegate ) let session = try await googleService.signIn( @@ -74,10 +74,10 @@ extension GlobalRouter: GlobalRouterType { ) try appContext.userAccountService.startSessionFor(session: session) viewController.hideSpinner() - proceed(with: appContext, session: session) + try proceed(with: appContext, session: session) case .other(let session): try appContext.userAccountService.startSessionFor(session: session) - proceed(with: appContext, session: session) + try proceed(with: appContext, session: session) } } catch { if case .gmailLogin(let viewController) = route { @@ -91,10 +91,10 @@ extension GlobalRouter: GlobalRouterType { func signOut(appContext: AppContext) throws { if let session = try appContext.userAccountService.startActiveSessionForNextUser() { logger.logInfo("Start session for another email user \(session)") - proceed(with: appContext, session: session) + try proceed(with: appContext, session: session) } else { logger.logInfo("Sign out") - appContext.userAccountService.cleanup() + try appContext.userAccountService.cleanup() proceed() } } @@ -130,7 +130,7 @@ extension GlobalRouter: GlobalRouterType { logger.logWarning("Can't switch active user with \(user.email)") return } - proceed(with: appContext, session: session) + try proceed(with: appContext, session: session) } @MainActor @@ -152,10 +152,10 @@ extension GlobalRouter: GlobalRouterType { } @MainActor - private func proceed(with appContext: AppContext, session: SessionType) { + private func proceed(with appContext: AppContext, session: SessionType) throws { logger.logInfo("proceed for session: \(session.description)") guard - let user = appContext.encryptedStorage.activeUser, + let user = try appContext.encryptedStorage.activeUser, let authType = user.authType else { let message = "Wrong application state. User not found for session \(session.description)" diff --git a/FlowCrypt/Functionality/Services/Local Contacts Service/LocalContactsProvider.swift b/FlowCrypt/Functionality/Services/Local Contacts Service/LocalContactsProvider.swift index c32aa0e32..041a34a47 100644 --- a/FlowCrypt/Functionality/Services/Local Contacts Service/LocalContactsProvider.swift +++ b/FlowCrypt/Functionality/Services/Local Contacts Service/LocalContactsProvider.swift @@ -12,7 +12,7 @@ import FlowCryptCommon protocol LocalContactsProviderType: PublicKeyProvider { func searchRecipient(with email: String) async throws -> RecipientWithSortedPubKeys? - func searchEmails(query: String) -> [String] + func searchEmails(query: String) throws -> [String] func save(recipient: RecipientWithSortedPubKeys) throws func remove(recipient: RecipientWithSortedPubKeys) throws func updateKeys(for recipient: RecipientWithSortedPubKeys) throws @@ -26,7 +26,9 @@ final class LocalContactsProvider { private lazy var logger = Logger.nested(Self.self) private var storage: Realm { - encryptedStorage.storage + get throws { + try encryptedStorage.storage + } } init( @@ -39,8 +41,8 @@ final class LocalContactsProvider { } extension LocalContactsProvider: LocalContactsProviderType { - func retrievePubKeys(for email: String) -> [String] { - guard let object = find(with: email) else { return [] } + func retrievePubKeys(for email: String) throws -> [String] { + guard let object = try find(with: email) else { return [] } do { try storage.write { @@ -58,17 +60,18 @@ extension LocalContactsProvider: LocalContactsProviderType { } func remove(recipient: RecipientWithSortedPubKeys) throws { - guard let object = find(with: recipient.email) else { + guard let object = try find(with: recipient.email) else { return } + let storage = try storage try storage.write { storage.delete(object) } } func updateKeys(for recipient: RecipientWithSortedPubKeys) throws { - guard let recipientObject = find(with: recipient.email) else { + guard let recipientObject = try find(with: recipient.email) else { try save(RecipientRealmObject(recipient)) return } @@ -84,18 +87,18 @@ extension LocalContactsProvider: LocalContactsProviderType { } func searchRecipient(with email: String) async throws -> RecipientWithSortedPubKeys? { - guard let recipient = find(with: email).map(Recipient.init) else { return nil } + guard let recipient = try find(with: email).map(Recipient.init) else { return nil } return try await parseRecipient(from: recipient) } - func searchEmails(query: String) -> [String] { - storage.objects(RecipientRealmObject.self) + func searchEmails(query: String) throws -> [String] { + try storage.objects(RecipientRealmObject.self) .filter("email contains[c] %@", query) .map(\.email) } func getAllRecipients() async throws -> [RecipientWithSortedPubKeys] { - let objects: [Recipient] = storage.objects(RecipientRealmObject.self) + let objects: [Recipient] = try storage.objects(RecipientRealmObject.self) .map(Recipient.init) var recipients: [RecipientWithSortedPubKeys] = [] for object in objects { @@ -105,6 +108,8 @@ extension LocalContactsProvider: LocalContactsProviderType { } func removePubKey(with fingerprint: String, for email: String) throws { + let storage = try storage + try find(with: email)? .pubKeys .filter { $0.primaryFingerprint == fingerprint } @@ -117,11 +122,12 @@ extension LocalContactsProvider: LocalContactsProviderType { } extension LocalContactsProvider { - private func find(with email: String) -> RecipientRealmObject? { - storage.object(ofType: RecipientRealmObject.self, forPrimaryKey: email) + private func find(with email: String) throws -> RecipientRealmObject? { + try storage.object(ofType: RecipientRealmObject.self, forPrimaryKey: email) } private func save(_ object: RecipientRealmObject) throws { + let storage = try storage try storage.write { storage.add(object, update: .modified) } diff --git a/FlowCrypt/Functionality/Services/Local Private Key Services/KeyService.swift b/FlowCrypt/Functionality/Services/Local Private Key Services/KeyService.swift index 851eb8fbe..a96021764 100644 --- a/FlowCrypt/Functionality/Services/Local Private Key Services/KeyService.swift +++ b/FlowCrypt/Functionality/Services/Local Private Key Services/KeyService.swift @@ -43,7 +43,7 @@ final class KeyService: KeyServiceType { guard let email = currentUserEmail() else { throw KeyServiceError.missingCurrentUserEmail } - let privateKeys = storage.getKeypairs(by: email).map(\.private) + let privateKeys = try storage.getKeypairs(by: email).map(\.private) let parsed = try await coreService.parseKeys( armoredOrBinary: privateKeys.joined(separator: "\n").data() ) @@ -59,8 +59,8 @@ final class KeyService: KeyServiceType { throw KeyServiceError.missingCurrentUserEmail } - let storedPassPhrases = passPhraseService.getPassPhrases() - let privateKeys = storage.getKeypairs(by: email) + let storedPassPhrases = try passPhraseService.getPassPhrases() + let privateKeys = try storage.getKeypairs(by: email) .map { keypair -> PrvKeyInfo in let passphrase = storedPassPhrases .filter(\.value.isNotEmpty) @@ -77,12 +77,12 @@ final class KeyService: KeyServiceType { throw AppErr.noCurrentUser } - let keysInfo = storage.getKeypairs(by: email) + let keysInfo = try storage.getKeypairs(by: email) guard let foundKey = try await findKeyByUserEmail(keysInfo: keysInfo, email: email) else { return nil } - let storedPassPhrases = passPhraseService.getPassPhrases() + let storedPassPhrases = try passPhraseService.getPassPhrases() let passphrase = storedPassPhrases .filter { $0.value.isNotEmpty } .first(where: { $0.primaryFingerprintOfAssociatedKey == foundKey.primaryFingerprint })? diff --git a/FlowCrypt/Functionality/Services/Local Private Key Services/PassPhraseService.swift b/FlowCrypt/Functionality/Services/Local Private Key Services/PassPhraseService.swift index 185e828e7..36e1df885 100644 --- a/FlowCrypt/Functionality/Services/Local Private Key Services/PassPhraseService.swift +++ b/FlowCrypt/Functionality/Services/Local Private Key Services/PassPhraseService.swift @@ -58,12 +58,12 @@ protocol PassPhraseStorageType { func update(passPhrase: PassPhrase) throws func remove(passPhrase: PassPhrase) throws - func getPassPhrases() -> [PassPhrase] + func getPassPhrases() throws -> [PassPhrase] } // MARK: - PassPhraseService protocol PassPhraseServiceType { - func getPassPhrases() -> [PassPhrase] + func getPassPhrases() throws -> [PassPhrase] func savePassPhrase(with passPhrase: PassPhrase, storageMethod: StorageMethod) throws func updatePassPhrase(with passPhrase: PassPhrase, storageMethod: StorageMethod) throws func savePassPhrasesInMemory(_ passPhrase: String, for privateKeys: [PrvKeyInfo]) throws @@ -89,7 +89,7 @@ final class PassPhraseService: PassPhraseServiceType { case .persistent: try encryptedStorage.save(passPhrase: passPhrase) case .memory: - let storedPassPhrases = encryptedStorage.getPassPhrases() + let storedPassPhrases = try encryptedStorage.getPassPhrases() let fingerprint = passPhrase.primaryFingerprintOfAssociatedKey if storedPassPhrases.contains(where: { $0.primaryFingerprintOfAssociatedKey == fingerprint }) { logger.logInfo("\(StorageMethod.persistent): removing pass phrase for key \(fingerprint)") @@ -109,8 +109,8 @@ final class PassPhraseService: PassPhraseServiceType { } } - func getPassPhrases() -> [PassPhrase] { - encryptedStorage.getPassPhrases() + inMemoryStorage.getPassPhrases() + func getPassPhrases() throws -> [PassPhrase] { + try encryptedStorage.getPassPhrases() + inMemoryStorage.getPassPhrases() } func savePassPhrasesInMemory(_ passPhrase: String, for privateKeys: [PrvKeyInfo]) throws { diff --git a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationServiceTests.swift b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationServiceTests.swift index 63eeee103..af9fceb8a 100644 --- a/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationServiceTests.swift +++ b/FlowCryptAppTests/Functionality/Services/Client Configuration Service/ClientConfigurationServiceTests.swift @@ -29,13 +29,13 @@ final class ClientConfigurationServiceTests: XCTestCase { ) } - func testGetSavedOrganisationalRulesForCurrentUser() { + func testGetSavedOrganisationalRulesForCurrentUser() throws { let expectedConfiguration = RawClientConfiguration(keyManagerUrl: "https://ekm.example.com") localClientConfigurationProvider.fetchCall = { expectedConfiguration } - let clientConfiguration = sut.getSaved(for: user.email) + let clientConfiguration = try sut.getSaved(for: user.email) XCTAssert(localClientConfigurationProvider.fetchCount == 1) XCTAssert(localClientConfigurationProvider.fetchInvoked == true) XCTAssert(clientConfiguration.raw == expectedConfiguration) diff --git a/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift b/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift index 436dce6d4..5b1586d0f 100644 --- a/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift +++ b/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift @@ -25,18 +25,18 @@ class PassPhraseStorageTests: XCTestCase { ) } - func testGetPassPhrasesWhenEmpty() { + func testGetPassPhrasesWhenEmpty() throws { // no pass phrases in storage encryptedStorage.getPassPhrasesResult = { [] } // no pass phrases in localStorage inMemoryStorage.getPassPhrasesResult = { [] } - let result = sut.getPassPhrases() + let result = try sut.getPassPhrases() XCTAssertTrue(result.isEmpty) } - func testGetValidPassPhraseFromStorage() { + func testGetValidPassPhraseFromStorage() throws { let passPhrase1 = PassPhrase( value: "some", fingerprintsOfAssociatedKey: ["11","12"] @@ -50,7 +50,7 @@ class PassPhraseStorageTests: XCTestCase { // no pass phrases in localStorage inMemoryStorage.getPassPhrasesResult = { [] } - var result = sut.getPassPhrases() + var result = try sut.getPassPhrases() XCTAssertTrue(result.count == 1) @@ -58,12 +58,12 @@ class PassPhraseStorageTests: XCTestCase { [passPhrase1, passPhrase2] } - result = sut.getPassPhrases() + result = try sut.getPassPhrases() XCTAssertTrue(result.count == 2) } - func testGetValidPassPhraseInLocalStorage() { + func testGetValidPassPhraseInLocalStorage() throws { encryptedStorage.getPassPhrasesResult = { [] } let savedDate = Date() @@ -77,11 +77,11 @@ class PassPhraseStorageTests: XCTestCase { // current timeout = 2 sleep(1) - let result = sut.getPassPhrases() + let result = try sut.getPassPhrases() XCTAssertTrue(result.isNotEmpty) } - func testBothStorageContainsValidPassPhrase() { + func testBothStorageContainsValidPassPhrase() throws { let passPhrase1 = PassPhrase( value: "some", fingerprintsOfAssociatedKey: ["A123"] @@ -103,7 +103,7 @@ class PassPhraseStorageTests: XCTestCase { inMemoryStorage.getPassPhrasesResult = { [localPassPhrase] } - let result = sut.getPassPhrases() + let result = try sut.getPassPhrases() XCTAssertTrue(result.count == 3) } diff --git a/FlowCryptAppTests/LocalStorageTests.swift b/FlowCryptAppTests/LocalStorageTests.swift index 59e95cb7c..cebf72e13 100644 --- a/FlowCryptAppTests/LocalStorageTests.swift +++ b/FlowCryptAppTests/LocalStorageTests.swift @@ -31,12 +31,12 @@ class LocalStorageTests: XCTestCase { } func testLogOutForUser() throws { - XCTAssertFalse(sut.passPhraseStorage.getPassPhrases().isEmpty) + XCTAssertFalse(try sut.passPhraseStorage.getPassPhrases().isEmpty) let user = "anton@gmail.com" try sut.logOutUser(email: user) XCTAssertNil(UserDefaults.standard.string(forKey: trashKey)) - XCTAssertTrue(sut.passPhraseStorage.getPassPhrases().isEmpty) + XCTAssertTrue(try sut.passPhraseStorage.getPassPhrases().isEmpty) } }