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
4 changes: 4 additions & 0 deletions FlowCrypt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
21FEE26626FDD91A00E3783F /* ComposeMessageAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FEE26526FDD91A00E3783F /* ComposeMessageAttachment.swift */; };
2C2A3B4B2719EE6100B7F27B /* KeyServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2A3B4A2719EE6100B7F27B /* KeyServiceTests.swift */; };
2C2A3B4D2719EF7300B7F27B /* PassPhraseServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2A3B4C2719EF7300B7F27B /* PassPhraseServiceMock.swift */; };
2C60AB0C272564D40040D7F2 /* InvalidStorageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C60AB0B272564D40040D7F2 /* InvalidStorageViewController.swift */; };
32DCA00224982EDA88D69C6E /* AppErr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCA4B11D4531B3B04D01D1 /* AppErr.swift */; };
32DCA04CA0DAB79C39514782 /* CoreTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCAC732B988D9704658812 /* CoreTypes.swift */; };
32DCA1414EEA727B86C337D5 /* Core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCA0C3D34A69851A238E87 /* Core.swift */; };
Expand Down Expand Up @@ -442,6 +443,7 @@
21FEE26526FDD91A00E3783F /* ComposeMessageAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeMessageAttachment.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>"; };
2C60AB0B272564D40040D7F2 /* InvalidStorageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvalidStorageViewController.swift; sourceTree = "<group>"; };
32DCA058652FD4616FB04FB6 /* SequenceExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceExtensions.swift; sourceTree = "<group>"; };
32DCA0C3D34A69851A238E87 /* Core.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Core.swift; sourceTree = "<group>"; };
32DCA0E63F2F0473D0A8EDB0 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1912,6 +1914,7 @@
isa = PBXGroup;
children = (
D24F4C2123E2359B00C5EEE4 /* BootstrapViewController.swift */,
2C60AB0B272564D40040D7F2 /* InvalidStorageViewController.swift */,
);
path = Bootstrap;
sourceTree = "<group>";
Expand Down Expand Up @@ -2578,6 +2581,7 @@
32DCA1B95DDC04D671F662F8 /* URLSessionExtension.swift in Sources */,
214A023A26A3029700C24066 /* EmailKeyManagerApi.swift in Sources */,
D2E26F7424F2705B00612AF1 /* ContactDetailDecorator.swift in Sources */,
2C60AB0C272564D40040D7F2 /* InvalidStorageViewController.swift in Sources */,
21C7DF0526697DA500C44800 /* PromiseKitExtension.swift in Sources */,
9F7E8F19269C538E0021C07F /* NavigationChildController.swift in Sources */,
9FB22CD625715CA10026EE64 /* BackupServiceErrorHandler.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// InvalidStorageViewController.swift
// FlowCrypt
//
// Created by  Ivan Ushakov on 24.10.2021
// Copyright © 2017-present FlowCrypt a. s. All rights reserved.
//

import AsyncDisplayKit
import FlowCryptUI

final class InvalidStorageViewController: TableNodeViewController {
private let encryptedStorage: EncryptedStorageType
private let router: GlobalRouterType

init(encryptedStorage: EncryptedStorageType, router: GlobalRouterType) {
self.encryptedStorage = encryptedStorage
self.router = router
super.init(node: TableNode())
}

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

override func viewDidLoad() {
super.viewDidLoad()
title = "invalid_storage_title".localized

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

private func handleTap() {
do {
try encryptedStorage.reset()
router.proceed()
} catch {
showAlert(message: "invalid_storage_reset_error".localized)
}
}
}

extension InvalidStorageViewController: ASTableDelegate, ASTableDataSource {
func tableNode(_: ASTableNode, numberOfRowsInSection _: Int) -> Int {
2
}

func tableNode(_: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
{
if indexPath.row == 0 {
return KeyTextCellNode(
title: "invalid_storage_text".localized.attributed(.regular(12), color: .black),
insets: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
)
}

if indexPath.row == 1 {
let input = ButtonCellNode.Input(
title: "invalid_storage_reset_button".localized.attributed(.bold(16), color: .white),
insets: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16),
color: .red
)
return ButtonCellNode(input: input) { [weak self] in
self?.handleTap()
}
}

return ASCellNode()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ protocol EncryptedStorageType: KeyStorageType {
var activeUser: UserObject? { get }
func doesAnyKeyExist(for email: String) -> Bool

func validate() throws
func reset() throws
func cleanup()
}

Expand Down Expand Up @@ -79,7 +81,6 @@ final class EncryptedStorage: EncryptedStorageType {
let realm = try Realm(configuration: encryptedConfiguration)
return realm
} catch {
// destroyEncryptedStorage() - todo - give user option to wipe, don't do it automatically
fatalError("failed to initiate realm: \(error)")
}
}
Expand Down Expand Up @@ -254,6 +255,16 @@ extension EncryptedStorage {
}

extension EncryptedStorage {
func validate() throws {
Realm.Configuration.defaultConfiguration = encryptedConfiguration
_ = try Realm(configuration: encryptedConfiguration)
}

func reset() throws {
let path = getDocumentDirectory() + "/" + Constants.encryptedDbFilename
try FileManager.default.removeItem(atPath: path)
}

func cleanup() {
do {
try storage.write {
Expand Down
21 changes: 19 additions & 2 deletions FlowCrypt/Functionality/Services/GlobalRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,25 @@ final class GlobalRouter: GlobalRouterType {
extension GlobalRouter {
/// proceed to flow (signing/setup/app) depends on user status (isLoggedIn/isSetupFinished)
func proceed() {
userAccountService.cleanupSessions()
proceed(with: nil)
validateEncryptedStorage {
userAccountService.cleanupSessions()
proceed(with: nil)
}
}

private func validateEncryptedStorage(_ completion: () -> Void) {
let storage = EncryptedStorage()
do {
try storage.validate()
completion()
} catch {
let controller = InvalidStorageViewController(
encryptedStorage: storage,
router: self
)
keyWindow.rootViewController = UINavigationController(rootViewController: controller)
keyWindow.makeKeyAndVisible()
}
Comment on lines +70 to +77
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should actually use the error description that we caught and also render that to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it very long because it contains stack trace.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's already an error screen, more information is better. The worst we can do is be vague when error happens. You can put it below and make it scrollable, or show the first few hundred characters.

}

private func proceed(with session: SessionType?) {
Expand Down
6 changes: 6 additions & 0 deletions FlowCrypt/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,9 @@
"files_picking_photos_error_message" = "Could not add a photo";
"files_picking_size_error_message" = "Total attachments size can not exceed 10 MB";

// Invalid storage view controller
"invalid_storage_title" = "Error";
"invalid_storage_text" = "Your data storage is invalid. You could reset it and start with new one";
"invalid_storage_reset_button" = "Reset";
"invalid_storage_reset_error" = "Couldn't remove storage. Please reinstall application";