Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions FlowCrypt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
2C141B2F274578C20038A3F8 /* KeyInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C141B2E274578C20038A3F8 /* KeyInfo.swift */; };
2C2A3B4B2719EE6100B7F27B /* KeyServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2A3B4A2719EE6100B7F27B /* KeyServiceTests.swift */; };
2C2A3B4D2719EF7300B7F27B /* PassPhraseServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2A3B4C2719EF7300B7F27B /* PassPhraseServiceMock.swift */; };
2C339B07275CB136005DEA79 /* FatalErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C339B06275CB136005DEA79 /* FatalErrorViewController.swift */; };
2C4E60F72757D91A00DE5770 /* EncryptedStorageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C4E60F62757D91A00DE5770 /* EncryptedStorageMock.swift */; };
2C60AB0C272564D40040D7F2 /* InvalidStorageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C60AB0B272564D40040D7F2 /* InvalidStorageViewController.swift */; };
2CAF25322756C37E005C7C7C /* AppContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CAF25312756C37E005C7C7C /* AppContext.swift */; };
Expand Down Expand Up @@ -301,7 +302,6 @@
D2717752242567EB00BDA9A9 /* KeyTextCellNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADEDCC123A43C6800EC495E /* KeyTextCellNode.swift */; };
D2717753242568A600BDA9A9 /* NavigationBarItemsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD22A19230FD781005067A6 /* NavigationBarItemsView.swift */; };
D2717754242568A600BDA9A9 /* NavigationBarActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD22A1E230FEFC6005067A6 /* NavigationBarActionButton.swift */; };
D274724124F97C5C006BA6EF /* EncryptedCacheService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274724024F97C5C006BA6EF /* EncryptedCacheService.swift */; };
D274724424FD1932006BA6EF /* FolderRealmObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274724324FD1932006BA6EF /* FolderRealmObject.swift */; };
D27B911924EFE79F002DF0A1 /* LocalContactsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27B911824EFE79F002DF0A1 /* LocalContactsProvider.swift */; };
D27B911D24EFE806002DF0A1 /* RecipientRealmObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27B911C24EFE806002DF0A1 /* RecipientRealmObject.swift */; };
Expand Down Expand Up @@ -451,6 +451,7 @@
2C141B2E274578C20038A3F8 /* KeyInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyInfo.swift; sourceTree = "<group>"; };
2C2A3B4A2719EE6100B7F27B /* KeyServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyServiceTests.swift; sourceTree = "<group>"; };
2C2A3B4C2719EF7300B7F27B /* PassPhraseServiceMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassPhraseServiceMock.swift; sourceTree = "<group>"; };
2C339B06275CB136005DEA79 /* FatalErrorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FatalErrorViewController.swift; sourceTree = "<group>"; };
2C4E60F62757D91A00DE5770 /* EncryptedStorageMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedStorageMock.swift; sourceTree = "<group>"; };
2C60AB0B272564D40040D7F2 /* InvalidStorageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvalidStorageViewController.swift; sourceTree = "<group>"; };
2CAF25312756C37E005C7C7C /* AppContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppContext.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -732,7 +733,6 @@
D26F132624509EB6009175BA /* RecipientEmailsCellNodeInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipientEmailsCellNodeInput.swift; sourceTree = "<group>"; };
D27177482424D73000BDA9A9 /* InboxViewDecorator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InboxViewDecorator.swift; sourceTree = "<group>"; };
D271774D24255F1100BDA9A9 /* UIColorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = "<group>"; };
D274724024F97C5C006BA6EF /* EncryptedCacheService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedCacheService.swift; sourceTree = "<group>"; };
D274724324FD1932006BA6EF /* FolderRealmObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderRealmObject.swift; sourceTree = "<group>"; };
D27B911824EFE79F002DF0A1 /* LocalContactsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalContactsProvider.swift; sourceTree = "<group>"; };
D27B911C24EFE806002DF0A1 /* RecipientRealmObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipientRealmObject.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1127,7 +1127,6 @@
9F41FA1C25372C2D003B970D /* Backup Services */,
21489B81267CC3BC00BDE4AC /* Client Configuration Service */,
9F6F3BEB26ADF5DE005BD9C6 /* Compose Message Service */,
D274724024F97C5C006BA6EF /* EncryptedCacheService.swift */,
D227C0E4250538190070F805 /* Folders Services */,
C132B9CA1EC2DE6400763715 /* GeneralConstants.swift */,
9F31AB9F232C071700CF87EA /* GlobalRouter.swift */,
Expand Down Expand Up @@ -1959,6 +1958,7 @@
isa = PBXGroup;
children = (
D24F4C2123E2359B00C5EEE4 /* BootstrapViewController.swift */,
2C339B06275CB136005DEA79 /* FatalErrorViewController.swift */,
2C60AB0B272564D40040D7F2 /* InvalidStorageViewController.swift */,
);
path = Bootstrap;
Expand Down Expand Up @@ -2537,7 +2537,6 @@
9F5F504326FA6C7500294FA2 /* EnterpriseServerApiMock.swift in Sources */,
51DA5BDA2722C82E001C4359 /* RecipientTests.swift in Sources */,
9FC41171268118A7004C0A69 /* PassPhraseStorageTests.swift in Sources */,
9F6F3C7626ADFC37005BD9C6 /* KeyStorageMock.swift in Sources */,
51DA5BDA2722C82E001C4359 /* RecipientTests.swift in Sources */,
9FC41171268118A7004C0A69 /* PassPhraseStorageTests.swift in Sources */,
);
Expand All @@ -2551,6 +2550,7 @@
D2A9CA3D242619EC00E1D898 /* SignInViewDecorator.swift in Sources */,
9F4300CC2571045B00791CFB /* InboxViewControllerContainerDecorator.swift in Sources */,
9F4163E6266520B600106194 /* CommonNodesInputs.swift in Sources */,
2C339B07275CB136005DEA79 /* FatalErrorViewController.swift in Sources */,
9F883912271F242900669B56 /* ThreadDetailsDecorator.swift in Sources */,
04B472951ECE29F600B8266F /* MyMenuViewController.swift in Sources */,
51B4AE5327144E590001F33B /* PubKey.swift in Sources */,
Expand Down Expand Up @@ -2667,7 +2667,6 @@
9FC4112E2595EA8B001180A8 /* Gmail+Search.swift in Sources */,
5A948DC5239EF2F4006284D7 /* LegalViewController.swift in Sources */,
5133B6722716321F00C95463 /* ContactKeyDetailDecorator.swift in Sources */,
D274724124F97C5C006BA6EF /* EncryptedCacheService.swift in Sources */,
A3B7C31923F576BA0022D628 /* AppStartup.swift in Sources */,
9F31AB8E23298BCF00CF87EA /* Imap+folders.swift in Sources */,
D2891AC224C59EFA008918E3 /* KeyService.swift in Sources */,
Expand Down
96 changes: 96 additions & 0 deletions FlowCrypt/Controllers/Bootstrap/FatalErrorViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// FatalErrorViewController.swift
// FlowCrypt
//
// Created by  Ivan Ushakov on 05.12.2021
// Copyright © 2017-present FlowCrypt a. s. All rights reserved.
//

import FlowCryptUI
import AsyncDisplayKit

final class FatalErrorViewController: TableNodeViewController {
private enum Parts: Int, CaseIterable {
case screenTitle
case title
case description
}

private let error: Error

init(error: Error) {
self.error = error
super.init(node: TableNode())
}

@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .backgroundColor

node.delegate = self
node.dataSource = self
node.bounces = false
node.reloadData()
}
}

extension FatalErrorViewController: ASTableDelegate, ASTableDataSource {
func tableNode(_: ASTableNode, numberOfRowsInSection _: Int) -> Int {
Parts.allCases.count
}

func tableNode(_ node: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
return { [weak self] in
guard let self = self, let part = Parts(rawValue: indexPath.row) else {
return ASCellNode()
}

let insets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
switch part {
case .screenTitle:
return SetupTitleNode(
SetupTitleNode.Input(
title: "fatal_error_screen_title".localized
.attributed(
.bold(18),
color: .mainTextColor,
alignment: .center
),
insets: insets,
backgroundColor: .backgroundColor
)
)
case .title:
return SetupTitleNode(
SetupTitleNode.Input(
title: "fatal_error_screen_text".localized
.attributed(
.regular(16),
color: .mainTextColor,
alignment: .center
),
insets: insets,
backgroundColor: .backgroundColor
)
)
case .description:
return SetupTitleNode(
SetupTitleNode.Input(
title: self.error.localizedDescription.attributed(
.regular(16),
color: .mainTextColor,
alignment: .center
),
insets: insets,
backgroundColor: .backgroundColor
)
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ extension CheckMailAuthViewController {
case 2:
return ButtonCellNode(input: .signInAgain) { [weak self] in
guard let self = self else { return }
self.appContext.globalRouter.signIn(appContext: self.appContext, route: .gmailLogin(self))
Task {
await self.appContext.globalRouter.signIn(
appContext: self.appContext,
route: .gmailLogin(self)
)
}
}
default:
return ASCellNode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ extension ComposeViewController {
}
let matchingKeys = try await self.keyMethods.filterByPassPhraseMatch(keys: allKeys, passPhrase: passPhrase)
// save passphrase for all matching keys
appContext.passPhraseService.savePassPhrasesInMemory(passPhrase, for: matchingKeys)
try appContext.passPhraseService.savePassPhrasesInMemory(passPhrase, for: matchingKeys)
// now figure out if the pass phrase also matched the signing prv itself
let matched = matchingKeys.first(where: { $0.fingerprints.first == signingKey.fingerprints.first })
return matched != nil// true if the pass phrase matched signing key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ extension ContactDetailViewController {

recipient.remove(pubKey: keyToRemove)
if let fingerprint = keyToRemove.fingerprint, fingerprint.isNotEmpty {
contactsProvider.removePubKey(with: fingerprint, for: recipient.email)
do {
try contactsProvider.removePubKey(with: fingerprint, for: recipient.email)
} catch {
showToast("contact_detail_remove_public_key_error".localizeWithArguments(error.localizedDescription))
}
}
node.deleteRows(at: [indexPathToRemove], with: .left)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ extension ContactsListViewController {
self.recipients = try await localContactsProvider.getAllRecipients()
await self.node.reloadData()
} catch {
self.showToast("Failed to load recipients: \(error.localizedDescription)")
self.showToast("contacts_screen_load_error".localizeWithArguments(error.localizedDescription))
}
}

}
}

Expand Down Expand Up @@ -136,8 +135,12 @@ extension ContactsListViewController {
recipientToRemove = recipients[indexPath.row]
}

localContactsProvider.remove(recipient: recipientToRemove)
recipients.remove(at: indexPathToRemove.row)
node.deleteRows(at: [indexPathToRemove], with: .left)
do {
try localContactsProvider.remove(recipient: recipientToRemove)
recipients.remove(at: indexPathToRemove.row)
node.deleteRows(at: [indexPathToRemove], with: .left)
} catch {
showToast("contacts_screen_remove_error".localizeWithArguments(error.localizedDescription))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ extension SetupBackupsViewController {
if storageMethod == .memory {
for backup in matchingKeyBackups {
let pp = PassPhrase(value: passPhrase, fingerprintsOfAssociatedKey: backup.fingerprints)
appContext.passPhraseService.savePassPhrase(with: pp, storageMethod: storageMethod)
try appContext.passPhraseService.savePassPhrase(with: pp, storageMethod: storageMethod)
}
}
appContext.encryptedStorage.putKeypairs(
try appContext.encryptedStorage.putKeypairs(
keyDetails: Array(matchingKeyBackups),
passPhrase: storageMethod == .persistent ? passPhrase : nil,
source: .backup,
Expand Down
4 changes: 2 additions & 2 deletions FlowCrypt/Controllers/Setup/SetupEKMKeyViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ extension SetupEKMKeyViewController {
passphrase: passPhrase
)
let parsedKey = try await self.core.parseKeys(armoredOrBinary: encryptedPrv.encryptedKey.data())
appContext.encryptedStorage.putKeypairs(
try appContext.encryptedStorage.putKeypairs(
keyDetails: parsedKey.keyDetails,
passPhrase: self.storageMethod == .persistent ? passPhrase : nil,
source: .ekm,
Expand All @@ -102,7 +102,7 @@ extension SetupEKMKeyViewController {
}
if self.storageMethod == .memory {
let passPhrase = PassPhrase(value: passPhrase, fingerprintsOfAssociatedKey: allFingerprints.unique())
appContext.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: self.storageMethod)
try appContext.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: self.storageMethod)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private actor Service {
)
try await backupService.backupToInbox(keys: [encryptedPrv.key], for: user)

appContext.encryptedStorage.putKeypairs(
try appContext.encryptedStorage.putKeypairs(
keyDetails: [encryptedPrv.key],
passPhrase: storageMethod == .persistent ? passPhrase: nil,
source: .generated,
Expand All @@ -124,7 +124,7 @@ private actor Service {
value: passPhrase,
fingerprintsOfAssociatedKey: encryptedPrv.key.fingerprints
)
appContext.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: .memory)
try appContext.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: .memory)
}

await submitKeyToAttesterAndShowAlertOnFailure(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,41 +228,41 @@ extension SetupManuallyEnterPassPhraseViewController {
return
}
let keyDetails = try await appContext.keyService.getPrvKeyDetails()
importKeys(with: keyDetails, and: passPhrase)
try importKeys(with: keyDetails, and: passPhrase)
}

private func importKeys(with existedKeys: [KeyDetails], and passPhrase: String) {
private func importKeys(with existedKeys: [KeyDetails], and passPhrase: String) throws {
let keysToUpdate = Array(Set(existedKeys).intersection(fetchedKeys))
let newKeysToAdd = Array(Set(fetchedKeys).subtracting(existedKeys))

appContext.encryptedStorage.putKeypairs(
try appContext.encryptedStorage.putKeypairs(
keyDetails: newKeysToAdd,
passPhrase: passPhrase,
source: .imported,
for: email
)
appContext.encryptedStorage.putKeypairs(
try appContext.encryptedStorage.putKeypairs(
keyDetails: keysToUpdate,
passPhrase: passPhrase,
source: .imported,
for: email
)

if storageMethod == .memory {
keysToUpdate
try keysToUpdate
.map {
PassPhrase(value: passPhrase, fingerprintsOfAssociatedKey: $0.fingerprints)
}
.forEach {
appContext.passPhraseService.updatePassPhrase(with: $0, storageMethod: storageMethod)
try appContext.passPhraseService.updatePassPhrase(with: $0, storageMethod: storageMethod)
}

newKeysToAdd
try newKeysToAdd
.map {
PassPhrase(value: passPhrase, fingerprintsOfAssociatedKey: $0.fingerprints)
}
.forEach {
appContext.passPhraseService.savePassPhrase(with: $0, storageMethod: storageMethod)
try appContext.passPhraseService.savePassPhrase(with: $0, storageMethod: storageMethod)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,9 @@ extension SetupImapViewController {

private func handleSuccessfulConnection() {
hideSpinner()
globalRouter.signIn(appContext: self.appContext, route: .other(.session(user)))
Task {
await globalRouter.signIn(appContext: self.appContext, route: .other(.session(user)))
}
}

private func checkCurrentUser() throws {
Expand Down
4 changes: 3 additions & 1 deletion FlowCrypt/Controllers/SignIn/SignInViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ extension SignInViewController: ASTableDelegate, ASTableDataSource {

extension SignInViewController {
private func signInWithGmail() {
globalRouter.signIn(appContext: appContext, route: .gmailLogin(self))
Task {
await globalRouter.signIn(appContext: appContext, route: .gmailLogin(self))
}
}

private func signInWithOutlook() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ extension ThreadDetailsViewController {
input[index].rawMessage = updatedMessage
node.reloadSections(IndexSet(integer: index), with: .fade)
} catch {
showToast("Could not mark message as read: \(error)")
showToast("message_mark_read_error".localizeWithArguments(error.localizedDescription))
}
}
}
Expand Down
Loading