From 8d0e3894d5d1e78dafa57f43aa1959d6211f47d1 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 16 Oct 2021 20:40:04 +0300 Subject: [PATCH] Further async/await refactoring --- .../SetupGenerateKeyViewController.swift | 94 +++++++++---------- FlowCrypt/Core/Core.swift | 10 +- .../Core/FlowCryptCoreTests.swift | 33 ++++--- 3 files changed, 69 insertions(+), 68 deletions(-) diff --git a/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift b/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift index a895c1f80..60d21902d 100644 --- a/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift @@ -67,71 +67,61 @@ final class SetupGenerateKeyViewController: SetupCreatePassphraseAbstractViewCon } override func setupAccount(with passphrase: String) { - setupAccountWithGeneratedKey(with: passphrase) + showSpinner() + Task { + do { + try await setupAccountWithGeneratedKey(with: passphrase) + hideSpinner() + moveToMainFlow() + } catch { + hideSpinner() + + let isErrorHandled = handleCommon(error: error) + + if !isErrorHandled { + showAlert(error: error, message: "Could not finish setup, please try again") + } + } + } } } // MARK: - Setup extension SetupGenerateKeyViewController { - private func setupAccountWithGeneratedKey(with passPhrase: String) { - Promise { [weak self] in - guard let self = self else { return } - self.showSpinner() + private func setupAccountWithGeneratedKey(with passPhrase: String) async throws { + let userId = try getUserId() - let userId = try self.getUserId() + try awaitPromise(validateAndConfirmNewPassPhraseOrReject(passPhrase: passPhrase)) - try awaitPromise(self.validateAndConfirmNewPassPhraseOrReject(passPhrase: passPhrase)) + let encryptedPrv = try await core.generateKey(passphrase: passPhrase, variant: .curve25519, userIds: [userId]) + try await backupService.backupToInbox(keys: [encryptedPrv.key], for: user) - let encryptedPrv = try self.core.generateKey(passphrase: passPhrase, variant: .curve25519, userIds: [userId]) - - let semaphore = DispatchSemaphore(value: 0) - Task { - try await self.backupService.backupToInbox(keys: [encryptedPrv.key], for: self.user) - semaphore.signal() - } - semaphore.wait() - - self.keyStorage.addKeys(keyDetails: [encryptedPrv.key], - passPhrase: self.storageMethod == .persistent ? passPhrase: nil, - source: .generated, - for: self.user.email) - - if self.storageMethod == .memory { - let passPhrase = PassPhrase(value: passPhrase, fingerprints: encryptedPrv.key.fingerprints) - self.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: .memory) - } + keyStorage.addKeys(keyDetails: [encryptedPrv.key], + passPhrase: storageMethod == .persistent ? passPhrase: nil, + source: .generated, + for: user.email) - let updateKey = self.attester.updateKey( - email: userId.email, - pubkey: encryptedPrv.key.public, - token: self.storage.token - ) - - try awaitPromise(self.alertAndSkipOnRejection( - updateKey, - fail: "Failed to submit Public Key") - ) - let testWelcome = self.attester.testWelcome(email: userId.email, pubkey: encryptedPrv.key.public) - try awaitPromise(self.alertAndSkipOnRejection( - testWelcome, - fail: "Failed to send you welcome email") - ) + if storageMethod == .memory { + let passPhrase = PassPhrase(value: passPhrase, fingerprints: encryptedPrv.key.fingerprints) + passPhraseService.savePassPhrase(with: passPhrase, storageMethod: .memory) } - .then(on: .main) { [weak self] in - self?.hideSpinner() - self?.moveToMainFlow() - } - .catch(on: .main) { [weak self] error in - guard let self = self else { return } - self.hideSpinner() - let isErrorHandled = self.handleCommon(error: error) + let updateKey = attester.updateKey( + email: userId.email, + pubkey: encryptedPrv.key.public, + token: storage.token + ) - if !isErrorHandled { - self.showAlert(error: error, message: "Could not finish setup, please try again") - } - } + try awaitPromise(alertAndSkipOnRejection( + updateKey, + fail: "Failed to submit Public Key") + ) + let testWelcome = attester.testWelcome(email: userId.email, pubkey: encryptedPrv.key.public) + try awaitPromise(alertAndSkipOnRejection( + testWelcome, + fail: "Failed to send you welcome email") + ) } private func getUserId() throws -> UserId { diff --git a/FlowCrypt/Core/Core.swift b/FlowCrypt/Core/Core.swift index 11dd8ae3e..0a9d032b6 100644 --- a/FlowCrypt/Core/Core.swift +++ b/FlowCrypt/Core/Core.swift @@ -87,9 +87,13 @@ final class Core: KeyDecrypter, CoreComposeMessageType { let r = try call("encryptKey", jsonDict: ["armored": armoredPrv, "passphrase": passphrase], data: nil) return try r.json.decodeJson(as: CoreRes.EncryptKey.self) } - - func generateKey(passphrase: String, variant: KeyVariant, userIds: [UserId]) throws -> CoreRes.GenerateKey { - let request: [String: Any] = ["passphrase": passphrase, "variant": String(variant.rawValue), "userIds": try userIds.map { try $0.toJsonEncodedDict() }] + + func generateKey(passphrase: String, variant: KeyVariant, userIds: [UserId]) async throws -> CoreRes.GenerateKey { + let request: [String: Any] = [ + "passphrase": passphrase, + "variant": String(variant.rawValue), + "userIds": try userIds.map { try $0.toJsonEncodedDict() } + ] let r = try call("generateKey", jsonDict: request, data: nil) return try r.json.decodeJson(as: CoreRes.GenerateKey.self) } diff --git a/FlowCryptAppTests/Core/FlowCryptCoreTests.swift b/FlowCryptAppTests/Core/FlowCryptCoreTests.swift index 00051af9c..19de70566 100644 --- a/FlowCryptAppTests/Core/FlowCryptCoreTests.swift +++ b/FlowCryptAppTests/Core/FlowCryptCoreTests.swift @@ -10,9 +10,8 @@ import XCTest import Combine @testable import FlowCrypt -class FlowCryptCoreTests: XCTestCase { +final class FlowCryptCoreTests: XCTestCase { var core: Core! = .shared - private var cancellable = Set() override func setUp() { let expectation = XCTestExpectation() @@ -29,8 +28,12 @@ class FlowCryptCoreTests: XCTestCase { XCTAssertEqual(r.app_version, "iOS 0.2") } - func testGenerateKey() throws { - let r = try core.generateKey(passphrase: "some pass phrase test", variant: KeyVariant.curve25519, userIds: [UserId(email: "first@domain.com", name: "First")]) + func testGenerateKey() async throws { + let r = try await core.generateKey( + passphrase: "some pass phrase test", + variant: KeyVariant.curve25519, + userIds: [UserId(email: "first@domain.com", name: "First")] + ) XCTAssertNotNil(r.key.private) XCTAssertEqual(r.key.isFullyDecrypted, false) XCTAssertEqual(r.key.isFullyEncrypted, true) @@ -165,7 +168,11 @@ class FlowCryptCoreTests: XCTestCase { let passphrase = "some pass phrase test" let email = "e2e@domain.com" let text = "this is the encrypted e2e content" - let generateKeyRes = try core.generateKey(passphrase: passphrase, variant: KeyVariant.curve25519, userIds: [UserId(email: email, name: "End to end")]) + let generateKeyRes = try await core.generateKey( + passphrase: passphrase, + variant: KeyVariant.curve25519, + userIds: [UserId(email: email, name: "End to end")] + ) let k = generateKeyRes.key let msg = SendableMsg( text: text, @@ -209,7 +216,7 @@ class FlowCryptCoreTests: XCTestCase { XCTAssertEqual(e.error.type, MsgBlock.DecryptErr.ErrorType.keyMismatch) } - func testEncryptFile() throws { + func testEncryptFile() async throws { // Given let initialFileName = "data.txt" let urlPath = URL(fileURLWithPath: Bundle(for: type(of: self)) @@ -218,7 +225,7 @@ class FlowCryptCoreTests: XCTestCase { let passphrase = "some pass phrase test" let email = "e2e@domain.com" - let generateKeyRes = try core.generateKey( + let generateKeyRes = try await core.generateKey( passphrase: passphrase, variant: KeyVariant.curve25519, userIds: [UserId(email: email, name: "End to end")] @@ -251,7 +258,7 @@ class FlowCryptCoreTests: XCTestCase { XCTAssertTrue(decrypted.name == initialFileName) } - func testDecryptNotEncryptedFile() throws { + func testDecryptNotEncryptedFile() async throws { // Given let urlPath = URL(fileURLWithPath: Bundle(for: type(of: self)) .path(forResource: "data", ofType: "txt")!) @@ -259,7 +266,7 @@ class FlowCryptCoreTests: XCTestCase { let passphrase = "some pass phrase test" let email = "e2e@domain.com" - let generateKeyRes = try core.generateKey( + let generateKeyRes = try await core.generateKey( passphrase: passphrase, variant: KeyVariant.curve25519, userIds: [UserId(email: email, name: "End to end")] @@ -288,7 +295,7 @@ class FlowCryptCoreTests: XCTestCase { } } - func testDecryptWithNoKeys() throws { + func testDecryptWithNoKeys() async throws { // Given let initialFileName = "data.txt" let urlPath = URL(fileURLWithPath: Bundle(for: type(of: self)) @@ -297,7 +304,7 @@ class FlowCryptCoreTests: XCTestCase { let passphrase = "some pass phrase test" let email = "e2e@domain.com" - let generateKeyRes = try core.generateKey( + let generateKeyRes = try await core.generateKey( passphrase: passphrase, variant: KeyVariant.curve25519, userIds: [UserId(email: email, name: "End to end")] @@ -323,7 +330,7 @@ class FlowCryptCoreTests: XCTestCase { } } - func testDecryptEncryptedFile() throws { + func testDecryptEncryptedFile() async throws { // Given let initialFileName = "data.txt" let urlPath = URL(fileURLWithPath: Bundle(for: type(of: self)) @@ -332,7 +339,7 @@ class FlowCryptCoreTests: XCTestCase { let passphrase = "some pass phrase test" let email = "e2e@domain.com" - let generateKeyRes = try core.generateKey( + let generateKeyRes = try await core.generateKey( passphrase: passphrase, variant: KeyVariant.curve25519, userIds: [UserId(email: email, name: "End to end")]