From df8e254c34ca7d254989f5a3ad958782d74171b8 Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Thu, 16 Mar 2017 19:16:32 -0700 Subject: [PATCH 1/7] Use self-maintained ObjectivePGP first to avoid upstream bugs --- Podfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile b/Podfile index afcb71f..0036760 100644 --- a/Podfile +++ b/Podfile @@ -1,3 +1,3 @@ target 'pass' do - pod 'ObjectivePGP' + pod 'ObjectivePGP', :git => 'https://github.com/mssun/ObjectivePGP.git' end From d338e725d5107774165ad71e4c799b809c18c97b Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Thu, 16 Mar 2017 22:06:39 -0700 Subject: [PATCH 2/7] Polish logic on initializing PGP keys. - simplify interfaces - more robust --- .../AddPasswordTableViewController.swift | 2 +- .../Controllers/PasswordsViewController.swift | 4 +- .../SettingsTableViewController.swift | 31 ++--- pass/Helpers/DefaultsKeys.swift | 2 - pass/Helpers/Utils.swift | 1 - pass/Models/PasswordStore.swift | 116 ++++++++++++------ 6 files changed, 93 insertions(+), 63 deletions(-) diff --git a/pass/Controllers/AddPasswordTableViewController.swift b/pass/Controllers/AddPasswordTableViewController.swift index 55119d8..65c8481 100644 --- a/pass/Controllers/AddPasswordTableViewController.swift +++ b/pass/Controllers/AddPasswordTableViewController.swift @@ -27,7 +27,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController { override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "saveAddPasswordSegue" { // check PGP key - if Defaults[.pgpKeyID] == nil { + if PasswordStore.shared.privateKey == nil { let alertTitle = "Cannot Add Password" let alertMessage = "PGP Key is not set. Please set your PGP Key first." Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil) diff --git a/pass/Controllers/PasswordsViewController.swift b/pass/Controllers/PasswordsViewController.swift index 1ef9648..f6c09d0 100644 --- a/pass/Controllers/PasswordsViewController.swift +++ b/pass/Controllers/PasswordsViewController.swift @@ -283,7 +283,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } func copyToPasteboard(from indexPath: IndexPath) { - guard Defaults[.pgpKeyID] != nil else { + guard PasswordStore.shared.privateKey != nil else { Utils.alert(title: "Cannot Copy Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil) return } @@ -387,7 +387,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "showPasswordDetail" { - if Defaults[.pgpKeyID] == nil { + guard PasswordStore.shared.privateKey != nil else { Utils.alert(title: "Cannot Show Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil) if let s = sender as? UITableViewCell { let selectedIndexPath = tableView.indexPath(for: s)! diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index 26bfba9..ddb93c2 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -41,12 +41,10 @@ class SettingsTableViewController: UITableViewController { SVProgressHUD.show(withStatus: "Fetching PGP Key") DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try PasswordStore.shared.initPGP(pgpPublicKeyURL: Defaults[.pgpPublicKeyURL]!, - pgpPublicKeyLocalPath: Globals.pgpPublicKeyPath, - pgpPrivateKeyURL: Defaults[.pgpPrivateKeyURL]!, - pgpPrivateKeyLocalPath: Globals.pgpPrivateKeyPath) + try PasswordStore.shared.initPGPKey(from: Defaults[.pgpPublicKeyURL]!, keyType: .public) + try PasswordStore.shared.initPGPKey(from: Defaults[.pgpPrivateKeyURL]!, keyType: .secret) DispatchQueue.main.async { - self.pgpKeyTableViewCell.detailTextLabel?.text = Defaults[.pgpKeyID] + self.pgpKeyTableViewCell.detailTextLabel?.text = PasswordStore.shared.pgpKeyID SVProgressHUD.showSuccess(withStatus: "Success") SVProgressHUD.dismiss(withDelay: 1) Utils.alert(title: "Rememver to Remove the Key", message: "Remember to remove the key from the server.", controller: self, completion: nil) @@ -54,7 +52,6 @@ class SettingsTableViewController: UITableViewController { } catch { DispatchQueue.main.async { self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" - Defaults[.pgpKeyID] = nil SVProgressHUD.showError(withStatus: error.localizedDescription) SVProgressHUD.dismiss(withDelay: 1) } @@ -76,19 +73,16 @@ class SettingsTableViewController: UITableViewController { SVProgressHUD.show(withStatus: "Fetching PGP Key") DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try PasswordStore.shared.initPGP(pgpPublicKeyArmor: controller.armorPublicKeyTextView.text!, - pgpPublicKeyLocalPath: Globals.pgpPublicKeyPath, - pgpPrivateKeyArmor: controller.armorPrivateKeyTextView.text!, - pgpPrivateKeyLocalPath: Globals.pgpPrivateKeyPath) + try PasswordStore.shared.initPGPKey(with: controller.armorPublicKeyTextView.text, keyType: .public) + try PasswordStore.shared.initPGPKey(with: controller.armorPrivateKeyTextView.text, keyType: .secret) DispatchQueue.main.async { - self.pgpKeyTableViewCell.detailTextLabel?.text = Defaults[.pgpKeyID] + self.pgpKeyTableViewCell.detailTextLabel?.text = PasswordStore.shared.pgpKeyID SVProgressHUD.showSuccess(withStatus: "Success") SVProgressHUD.dismiss(withDelay: 1) } } catch { DispatchQueue.main.async { self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" - Defaults[.pgpKeyID] = nil SVProgressHUD.showError(withStatus: error.localizedDescription) SVProgressHUD.dismiss(withDelay: 1) } @@ -193,10 +187,10 @@ class SettingsTableViewController: UITableViewController { } private func setPGPKeyTableViewCellDetailText() { - if Defaults[.pgpKeyID] == nil { - pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" + if let pgpKeyID = PasswordStore.shared.pgpKeyID { + pgpKeyTableViewCell.detailTextLabel?.text = pgpKeyID } else { - pgpKeyTableViewCell.detailTextLabel?.text = Defaults[.pgpKeyID] + pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" } } @@ -343,10 +337,7 @@ class SettingsTableViewController: UITableViewController { DispatchQueue.main.async { - try? PasswordStore.shared.initPGP( - pgpPublicKeyLocalPath: Globals.pgpPublicKeyPath, - pgpPrivateKeyLocalPath: Globals.pgpPrivateKeyPath - ) + PasswordStore.shared.initPGPKeys() let key: PGPKey = PasswordStore.shared.getPgpPrivateKey() Defaults[.pgpKeySource] = "file" @@ -357,7 +348,7 @@ class SettingsTableViewController: UITableViewController { } SVProgressHUD.dismiss() - self.pgpKeyTableViewCell.detailTextLabel?.text = Defaults[.pgpKeyID] + self.pgpKeyTableViewCell.detailTextLabel?.text = PasswordStore.shared.pgpKeyID } } diff --git a/pass/Helpers/DefaultsKeys.swift b/pass/Helpers/DefaultsKeys.swift index a658818..a97b1a3 100644 --- a/pass/Helpers/DefaultsKeys.swift +++ b/pass/Helpers/DefaultsKeys.swift @@ -17,8 +17,6 @@ extension DefaultsKeys { static let pgpPublicKeyArmor = DefaultsKey("pgpPublicKeyArmor") static let pgpPrivateKeyArmor = DefaultsKey("pgpPrivateKeyArmor") - static let pgpKeyID = DefaultsKey("pgpKeyID") - static let pgpKeyUserID = DefaultsKey("pgpKeyUserID") static let gitRepositoryURL = DefaultsKey("gitRepositoryURL") static let gitRepositoryAuthenticationMethod = DefaultsKey("gitRepositoryAuthenticationMethod") diff --git a/pass/Helpers/Utils.swift b/pass/Helpers/Utils.swift index 76902cc..1278f24 100644 --- a/pass/Helpers/Utils.swift +++ b/pass/Helpers/Utils.swift @@ -79,7 +79,6 @@ class Utils { Defaults.remove(.pgpPrivateKeyArmor) Defaults.remove(.pgpPrivateKeyURL) Defaults.remove(.pgpPublicKeyURL) - Defaults.remove(.pgpKeyID) Utils.removeKeychain(name: ".pgpKeyPassphrase") } diff --git a/pass/Models/PasswordStore.swift b/pass/Models/PasswordStore.swift index ddc2351..1d6bb0b 100644 --- a/pass/Models/PasswordStore.swift +++ b/pass/Models/PasswordStore.swift @@ -93,11 +93,23 @@ struct GitCredential { class PasswordStore { static let shared = PasswordStore() - let storeURL = URL(fileURLWithPath: "\(Globals.repositoryPath)") let tempStoreURL = URL(fileURLWithPath: "\(Globals.repositoryPath)-temp") + var storeRepository: GTRepository? var gitCredential: GitCredential? + var pgpKeyID: String? + var publicKey: PGPKey? { + didSet { + if publicKey != nil { + pgpKeyID = publicKey!.keyID!.shortKeyString + } else { + pgpKeyID = nil + } + } + } + var privateKey: PGPKey? + var gitSignatureForNow: GTSignature { get { return GTSignature(name: Defaults[.gitRepositoryUsername]!, email: Defaults[.gitRepositoryUsername]!+"@passforios", time: Date())! @@ -134,11 +146,7 @@ class PasswordStore { } catch { print(error) } - if Defaults[.pgpKeyID] != nil { - pgp.importKeys(fromFile: Globals.pgpPublicKeyPath, allowDuplicates: false) - pgp.importKeys(fromFile: Globals.pgpPrivateKeyPath, allowDuplicates: false) - - } + initPGPKeys() if Defaults[.gitRepositoryAuthenticationMethod] == "Password" { gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: Defaults[.gitRepositoryUsername]!, password: Utils.getPasswordFromKeychain(name: "gitRepositoryPassword") ?? "")) } else if Defaults[.gitRepositoryAuthenticationMethod] == "SSH Key"{ @@ -157,28 +165,74 @@ class PasswordStore { } - func initPGP(pgpPublicKeyLocalPath: String, pgpPrivateKeyLocalPath: String) throws { - let pgpPublicKeyData = NSData(contentsOfFile: pgpPublicKeyLocalPath)! as Data - if pgpPublicKeyData.count == 0 { - throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import public key."]) + public func initPGPKeys() { + do { + try initPGPKey(.public) + try initPGPKey(.secret) + } catch { + print(error) } - pgp.importKeys(from: pgpPublicKeyData, allowDuplicates: false) - if pgp.getKeysOf(.public).count == 0 { - throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import public key."]) + } + + public func initPGPKey(_ keyType: PGPKeyType) throws { + var keyPath = "" + switch keyType { + case .public: + keyPath = Globals.pgpPublicKeyPath + case .secret: + keyPath = Globals.pgpPrivateKeyPath + default: + throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import key."]) } - let pgpPrivateKeyData = NSData(contentsOfFile: pgpPrivateKeyLocalPath)! as Data - if pgpPrivateKeyData.count == 0 { - throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import public key."]) + + if let key = importKey(from: keyPath) { + switch keyType { + case .public: + self.publicKey = key + case .secret: + self.privateKey = key + default: + throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import key."]) + } + } else { + throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import key."]) } - pgp.importKeys(from: pgpPrivateKeyData, allowDuplicates: false) - if pgp.getKeysOf(.secret).count == 0 { - throw NSError(domain: "me.mssun.pass.error", code: 2, userInfo: [NSLocalizedDescriptionKey: "Cannot import seceret key."]) + } + + public func initPGPKey(from url: URL, keyType: PGPKeyType) throws{ + var pgpKeyLocalPath = "" + if keyType == .public { + pgpKeyLocalPath = Globals.pgpPublicKeyPath + } else { + pgpKeyLocalPath = Globals.pgpPrivateKeyPath } - let key: PGPKey = getPgpPrivateKey() - Defaults[.pgpKeyID] = key.keyID!.shortKeyString - if let gpgUser = key.users[0] as? PGPUser { - Defaults[.pgpKeyUserID] = gpgUser.userID + let pgpKeyData = try Data(contentsOf: url) + try pgpKeyData.write(to: URL(fileURLWithPath: pgpKeyLocalPath), options: .atomic) + try initPGPKey(keyType) + } + + public func initPGPKey(with armorKey: String, keyType: PGPKeyType) throws { + var pgpKeyLocalPath = "" + if keyType == .public { + pgpKeyLocalPath = Globals.pgpPublicKeyPath + } else { + pgpKeyLocalPath = Globals.pgpPrivateKeyPath } + try armorKey.write(toFile: pgpKeyLocalPath, atomically: true, encoding: .ascii) + try initPGPKey(keyType) + } + + + private func importKey(from keyPath: String) -> PGPKey? { + let fm = FileManager.default + if fm.fileExists(atPath: keyPath) { + if let keys = pgp.importKeys(fromFile: keyPath, allowDuplicates: false) as? [PGPKey] { + if keys.count > 0 { + return keys[0] + } + } + } + return nil } func getPgpPrivateKey() -> PGPKey { @@ -207,20 +261,6 @@ class PasswordStore { return true } - func initPGP(pgpPublicKeyURL: URL, pgpPublicKeyLocalPath: String, pgpPrivateKeyURL: URL, pgpPrivateKeyLocalPath: String) throws { - let pgpPublicData = try Data(contentsOf: pgpPublicKeyURL) - try pgpPublicData.write(to: URL(fileURLWithPath: pgpPublicKeyLocalPath), options: .atomic) - let pgpPrivateData = try Data(contentsOf: pgpPrivateKeyURL) - try pgpPrivateData.write(to: URL(fileURLWithPath: pgpPrivateKeyLocalPath), options: .atomic) - try initPGP(pgpPublicKeyLocalPath: pgpPublicKeyLocalPath, pgpPrivateKeyLocalPath: pgpPrivateKeyLocalPath) - } - - func initPGP(pgpPublicKeyArmor: String, pgpPublicKeyLocalPath: String, pgpPrivateKeyArmor: String, pgpPrivateKeyLocalPath: String) throws { - try pgpPublicKeyArmor.write(toFile: pgpPublicKeyLocalPath, atomically: true, encoding: .ascii) - try pgpPrivateKeyArmor.write(toFile: pgpPrivateKeyLocalPath, atomically: true, encoding: .ascii) - try initPGP(pgpPublicKeyLocalPath: pgpPublicKeyLocalPath, pgpPrivateKeyLocalPath: pgpPrivateKeyLocalPath) - } - func cloneRepository(remoteRepoURL: URL, credential: GitCredential, transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void, @@ -564,6 +604,8 @@ class PasswordStore { } func erase() { + publicKey = nil + privateKey = nil Utils.removeFileIfExists(at: storeURL) Utils.removeFileIfExists(at: tempStoreURL) From d2cff20131ec70b63a15f62ca4809cf31ae6d509 Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Thu, 16 Mar 2017 22:39:03 -0700 Subject: [PATCH 3/7] Put PasswordStore as instance in controllers --- .../AboutRepositoryTableViewController.swift | 11 +++--- .../AddPasswordTableViewController.swift | 3 +- .../AdvancedSettingsTableViewController.swift | 7 ++-- .../CommitLogsTableViewController.swift | 3 +- .../GeneralSettingsTableViewController.swift | 5 ++- .../GitServerSettingTableViewController.swift | 3 +- ...GPKeyArmorSettingTableViewController.swift | 3 +- .../PGPKeySettingTableViewController.swift | 3 +- .../PasswordDetailTableViewController.swift | 15 ++++---- .../Controllers/PasswordsViewController.swift | 27 +++++++------- .../SettingsTableViewController.swift | 37 ++++++++++--------- pass/Views/LabelTableViewCell.swift | 5 ++- 12 files changed, 67 insertions(+), 55 deletions(-) diff --git a/pass/Controllers/AboutRepositoryTableViewController.swift b/pass/Controllers/AboutRepositoryTableViewController.swift index 36588ee..2e76612 100644 --- a/pass/Controllers/AboutRepositoryTableViewController.swift +++ b/pass/Controllers/AboutRepositoryTableViewController.swift @@ -13,6 +13,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController { var needRefresh = false var indicatorLabel: UILabel! var indicator: UIActivityIndicatorView! + let passwordStore = PasswordStore.shared override func viewDidLoad() { navigationItemTitle = "About Repository" @@ -57,20 +58,20 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController { numberFormatter.numberStyle = NumberFormatter.Style.decimal let fm = FileManager.default - let passwordEntities = PasswordStore.shared.fetchPasswordEntityCoreData(withDir: false) + let passwordEntities = self.passwordStore.fetchPasswordEntityCoreData(withDir: false) let numberOfPasswords = numberFormatter.string(from: NSNumber(value: passwordEntities.count))! var size = UInt64(0) do { - if fm.fileExists(atPath: PasswordStore.shared.storeURL.path) { - size = try fm.allocatedSizeOfDirectoryAtURL(directoryURL: PasswordStore.shared.storeURL) + if fm.fileExists(atPath: self.passwordStore.storeURL.path) { + size = try fm.allocatedSizeOfDirectoryAtURL(directoryURL: self.passwordStore.storeURL) } } catch { print(error) } let sizeOfRepository = ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: ByteCountFormatter.CountStyle.file) - let numberOfCommits = PasswordStore.shared.storeRepository?.numberOfCommits(inCurrentBranch: NSErrorPointer(nilLiteral: ())) ?? 0 + let numberOfCommits = self.passwordStore.storeRepository?.numberOfCommits(inCurrentBranch: NSErrorPointer(nilLiteral: ())) ?? 0 let numberOfCommitsString = numberFormatter.string(from: NSNumber(value: numberOfCommits))! @@ -79,7 +80,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController { self?.tableData = [ // section 0 [[.style: CellDataStyle.value1, .accessoryType: type, .title: "Passwords", .detailText: numberOfPasswords], - [.style: CellDataStyle.value1, .accessoryType: type, .title: "Size", .detailText: sizeOfRepository], [.style: CellDataStyle.value1, .accessoryType: type, .title: "Unsynced", .detailText: String(PasswordStore.shared.getNumberOfUnsyncedPasswords())], + [.style: CellDataStyle.value1, .accessoryType: type, .title: "Size", .detailText: sizeOfRepository], [.style: CellDataStyle.value1, .accessoryType: type, .title: "Unsynced", .detailText: String(self?.passwordStore.getNumberOfUnsyncedPasswords() ?? 0)], [.style: CellDataStyle.value1, .accessoryType: type, .title: "Last Synced", .detailText: Utils.getLastUpdatedTimeString()], [.style: CellDataStyle.value1, .accessoryType: type, .title: "Commits", .detailText: numberOfCommitsString], [.title: "Commit Logs", .action: "segue", .link: "showCommitLogsSegue"], diff --git a/pass/Controllers/AddPasswordTableViewController.swift b/pass/Controllers/AddPasswordTableViewController.swift index 65c8481..d50afb1 100644 --- a/pass/Controllers/AddPasswordTableViewController.swift +++ b/pass/Controllers/AddPasswordTableViewController.swift @@ -13,6 +13,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController { var password: Password? var tempContent: String = "" + let passwordStore = PasswordStore.shared override func viewDidLoad() { tableData = [ @@ -27,7 +28,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController { override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "saveAddPasswordSegue" { // check PGP key - if PasswordStore.shared.privateKey == nil { + if passwordStore.privateKey == nil { let alertTitle = "Cannot Add Password" let alertMessage = "PGP Key is not set. Please set your PGP Key first." Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil) diff --git a/pass/Controllers/AdvancedSettingsTableViewController.swift b/pass/Controllers/AdvancedSettingsTableViewController.swift index b73305b..2ede296 100644 --- a/pass/Controllers/AdvancedSettingsTableViewController.swift +++ b/pass/Controllers/AdvancedSettingsTableViewController.swift @@ -13,7 +13,8 @@ class AdvancedSettingsTableViewController: UITableViewController { @IBOutlet weak var eraseDataTableViewCell: UITableViewCell! @IBOutlet weak var discardChangesTableViewCell: UITableViewCell! - + let passwordStore = PasswordStore.shared + override func viewDidLoad() { super.viewDidLoad() } @@ -24,7 +25,7 @@ class AdvancedSettingsTableViewController: UITableViewController { let alert = UIAlertController(title: "Erase Password Store Data?", message: "This will delete all local data and settings. Password store data on your remote server will not be affected.", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "Erase Password Data", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in SVProgressHUD.show(withStatus: "Erasing ...") - PasswordStore.shared.erase() + self.passwordStore.erase() NotificationCenter.default.post(Notification(name: Notification.Name("passwordStoreErased"))) self.navigationController!.popViewController(animated: true) SVProgressHUD.showSuccess(withStatus: "Done") @@ -40,7 +41,7 @@ class AdvancedSettingsTableViewController: UITableViewController { SVProgressHUD.show(withStatus: "Resetting ...") DispatchQueue.main.async { do { - let numberDiscarded = try PasswordStore.shared.reset() + let numberDiscarded = try self.passwordStore.reset() if numberDiscarded > 0 { NotificationCenter.default.post(Notification(name: Notification.Name("passwordStoreChangeDiscarded"))) } diff --git a/pass/Controllers/CommitLogsTableViewController.swift b/pass/Controllers/CommitLogsTableViewController.swift index 0c707dd..4a5088d 100644 --- a/pass/Controllers/CommitLogsTableViewController.swift +++ b/pass/Controllers/CommitLogsTableViewController.swift @@ -11,10 +11,11 @@ import ObjectiveGit class CommitLogsTableViewController: UITableViewController { var commits: [GTCommit] = [] + let passwordStore = PasswordStore.shared override func viewDidLoad() { super.viewDidLoad() - commits = PasswordStore.shared.getRecentCommits(count: 20) + commits = passwordStore.getRecentCommits(count: 20) navigationItem.title = "Recent Commit Logs" navigationController!.navigationBar.topItem!.title = "About" } diff --git a/pass/Controllers/GeneralSettingsTableViewController.swift b/pass/Controllers/GeneralSettingsTableViewController.swift index c94f3a0..c0bd539 100644 --- a/pass/Controllers/GeneralSettingsTableViewController.swift +++ b/pass/Controllers/GeneralSettingsTableViewController.swift @@ -10,7 +10,8 @@ import UIKit import SwiftyUserDefaults class GeneralSettingsTableViewController: BasicStaticTableViewController { - + let passwordStore = PasswordStore.shared + let hideUnknownSwitch: UISwitch = { let uiSwitch = UISwitch() uiSwitch.onTintColor = Globals.blue @@ -177,7 +178,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController { func rememberPassphraseSwitchAction(_ sender: Any?) { Defaults[.isRememberPassphraseOn] = rememberPassphraseSwitch.isOn if rememberPassphraseSwitch.isOn == false { - PasswordStore.shared.pgpKeyPassphrase = nil + passwordStore.pgpKeyPassphrase = nil } } diff --git a/pass/Controllers/GitServerSettingTableViewController.swift b/pass/Controllers/GitServerSettingTableViewController.swift index a697bd7..21e29a0 100644 --- a/pass/Controllers/GitServerSettingTableViewController.swift +++ b/pass/Controllers/GitServerSettingTableViewController.swift @@ -15,6 +15,7 @@ class GitServerSettingTableViewController: UITableViewController { @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var authSSHKeyCell: UITableViewCell! @IBOutlet weak var authPasswordCell: UITableViewCell! + let passwordStore = PasswordStore.shared var password: String? var authenticationMethod = Defaults[.gitRepositoryAuthenticationMethod] @@ -41,7 +42,7 @@ class GitServerSettingTableViewController: UITableViewController { gitRepositoryURLTextField.text = url.absoluteString } usernameTextField.text = Defaults[.gitRepositoryUsername] - password = PasswordStore.shared.gitRepositoryPassword + password = passwordStore.gitRepositoryPassword authenticationMethod = Defaults[.gitRepositoryAuthenticationMethod] // Grey out ssh option if ssh_key and ssh_key.pub are not present diff --git a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift index e335755..16ba52b 100644 --- a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift +++ b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift @@ -13,12 +13,13 @@ class PGPKeyArmorSettingTableViewController: UITableViewController { @IBOutlet weak var armorPublicKeyTextView: UITextView! @IBOutlet weak var armorPrivateKeyTextView: UITextView! var pgpPassphrase: String? + let passwordStore = PasswordStore.shared override func viewDidLoad() { super.viewDidLoad() armorPublicKeyTextView.text = Defaults[.pgpPublicKeyArmor] armorPrivateKeyTextView.text = Defaults[.pgpPrivateKeyArmor] - pgpPassphrase = PasswordStore.shared.pgpKeyPassphrase + pgpPassphrase = passwordStore.pgpKeyPassphrase } private func createSavePassphraseAlert() -> UIAlertController { diff --git a/pass/Controllers/PGPKeySettingTableViewController.swift b/pass/Controllers/PGPKeySettingTableViewController.swift index 17d0ea3..f19422b 100644 --- a/pass/Controllers/PGPKeySettingTableViewController.swift +++ b/pass/Controllers/PGPKeySettingTableViewController.swift @@ -14,13 +14,14 @@ class PGPKeySettingTableViewController: UITableViewController { @IBOutlet weak var pgpPublicKeyURLTextField: UITextField! @IBOutlet weak var pgpPrivateKeyURLTextField: UITextField! var pgpPassphrase: String? + let passwordStore = PasswordStore.shared override func viewDidLoad() { super.viewDidLoad() tableView.rowHeight = UITableViewAutomaticDimension pgpPublicKeyURLTextField.text = Defaults[.pgpPublicKeyURL]?.absoluteString pgpPrivateKeyURLTextField.text = Defaults[.pgpPrivateKeyURL]?.absoluteString - pgpPassphrase = PasswordStore.shared.pgpKeyPassphrase + pgpPassphrase = passwordStore.pgpKeyPassphrase } override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { diff --git a/pass/Controllers/PasswordDetailTableViewController.swift b/pass/Controllers/PasswordDetailTableViewController.swift index a032a94..2dff655 100644 --- a/pass/Controllers/PasswordDetailTableViewController.swift +++ b/pass/Controllers/PasswordDetailTableViewController.swift @@ -18,6 +18,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni var passwordImage: UIImage? var oneTimePasswordIndexPath : IndexPath? var shouldPopCurrentView = false + let passwordStore = PasswordStore.shared let indicatorLable: UILabel = { let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 21)) @@ -91,8 +92,8 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni } var passphrase = "" - if Defaults[.isRememberPassphraseOn] && PasswordStore.shared.pgpKeyPassphrase != nil { - passphrase = PasswordStore.shared.pgpKeyPassphrase! + if Defaults[.isRememberPassphraseOn] && self.passwordStore.pgpKeyPassphrase != nil { + passphrase = self.passwordStore.pgpKeyPassphrase! self.decryptThenShowPassword(passphrase: passphrase) } else { let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) @@ -114,7 +115,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni func decryptThenShowPassword(passphrase: String) { if Defaults[.isRememberPassphraseOn] { - PasswordStore.shared.pgpKeyPassphrase = passphrase + self.passwordStore.pgpKeyPassphrase = passphrase } DispatchQueue.global(qos: .userInitiated).async { do { @@ -188,14 +189,14 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni if self.password!.changed { SVProgressHUD.show(withStatus: "Saving") DispatchQueue.global(qos: .userInitiated).async { - PasswordStore.shared.update(passwordEntity: self.passwordEntity!, password: self.password!, progressBlock: { progress in + self.passwordStore.update(passwordEntity: self.passwordEntity!, password: self.password!, progressBlock: { progress in DispatchQueue.main.async { SVProgressHUD.showProgress(progress, status: "Encrypting") } }) DispatchQueue.main.async { self.passwordEntity!.synced = false - PasswordStore.shared.saveUpdated(passwordEntity: self.passwordEntity!) + self.passwordStore.saveUpdated(passwordEntity: self.passwordEntity!) NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) self.setTableData() self.tableView.reloadData() @@ -296,7 +297,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni self?.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic) let imageData = UIImageJPEGRepresentation(image, 1) if let entity = self?.passwordEntity { - PasswordStore.shared.updateImage(passwordEntity: entity, image: imageData) + self?.passwordStore.updateImage(passwordEntity: entity, image: imageData) } case .failure(let error): print(error) @@ -373,7 +374,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni footerLabel.numberOfLines = 0 footerLabel.font = UIFont.preferredFont(forTextStyle: .footnote) footerLabel.textColor = UIColor.gray - let dateString = PasswordStore.shared.getLatestUpdateInfo(filename: (passwordEntity?.path)!) + let dateString = self.passwordStore.getLatestUpdateInfo(filename: (passwordEntity?.path)!) footerLabel.text = "Last Updated: \(dateString)" view.addSubview(footerLabel) return view diff --git a/pass/Controllers/PasswordsViewController.swift b/pass/Controllers/PasswordsViewController.swift index f6c09d0..302e6a0 100644 --- a/pass/Controllers/PasswordsViewController.swift +++ b/pass/Controllers/PasswordsViewController.swift @@ -25,6 +25,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV private var passwordsTableEntries: [PasswordsTableEntry] = [] private var filteredPasswordsTableEntries: [PasswordsTableEntry] = [] private var parentPasswordEntity: PasswordEntity? = nil + let passwordStore = PasswordStore.shared private var tapTabBarTime: TimeInterval = 0 @@ -61,9 +62,9 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV filteredPasswordsTableEntries.removeAll() var passwordEntities = [PasswordEntity]() if Defaults[.isShowFolderOn] { - passwordEntities = PasswordStore.shared.fetchPasswordEntityCoreData(parent: parent) + passwordEntities = self.passwordStore.fetchPasswordEntityCoreData(parent: parent) } else { - passwordEntities = PasswordStore.shared.fetchPasswordEntityCoreData(withDir: false) + passwordEntities = self.passwordStore.fetchPasswordEntityCoreData(withDir: false) } passwordsTableEntries = passwordEntities.map { @@ -82,7 +83,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV SVProgressHUD.show(withStatus: "Saving") DispatchQueue.global(qos: .userInitiated).async { do { - try PasswordStore.shared.add(password: controller.password!, progressBlock: { progress in + try self.passwordStore.add(password: controller.password!, progressBlock: { progress in DispatchQueue.main.async { SVProgressHUD.showProgress(progress, status: "Encrypting") } @@ -107,26 +108,26 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV SVProgressHUD.setDefaultMaskType(.black) SVProgressHUD.setDefaultStyle(.light) SVProgressHUD.show(withStatus: "Sync Password Store") - let numberOfUnsyncedPasswords = PasswordStore.shared.getNumberOfUnsyncedPasswords() + let numberOfUnsyncedPasswords = self.passwordStore.getNumberOfUnsyncedPasswords() DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try PasswordStore.shared.pullRepository(transferProgressBlock: {(git_transfer_progress, stop) in + try self.passwordStore.pullRepository(transferProgressBlock: {(git_transfer_progress, stop) in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects)/Float(git_transfer_progress.pointee.total_objects), status: "Pull Remote Repository") } }) if numberOfUnsyncedPasswords > 0 { - try PasswordStore.shared.pushRepository(transferProgressBlock: {(current, total, bytes, stop) in + try self.passwordStore.pushRepository(transferProgressBlock: {(current, total, bytes, stop) in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(current)/Float(total), status: "Push Remote Repository") } }) } DispatchQueue.main.async { - PasswordStore.shared.updatePasswordEntityCoreData() + self.passwordStore.updatePasswordEntityCoreData() self.initPasswordsTableEntries(parent: nil) self.reloadTableView(data: self.passwordsTableEntries) - PasswordStore.shared.setAllSynced() + self.passwordStore.setAllSynced() self.setNavigationItemTitle() Defaults[.lastUpdatedTime] = Date() Defaults[.gitRepositoryPasswordAttempts] = 0 @@ -283,15 +284,15 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } func copyToPasteboard(from indexPath: IndexPath) { - guard PasswordStore.shared.privateKey != nil else { + guard self.passwordStore.privateKey != nil else { Utils.alert(title: "Cannot Copy Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil) return } let password = getPasswordEntry(by: indexPath).passwordEntity! UIImpactFeedbackGenerator(style: .medium).impactOccurred() var passphrase = "" - if Defaults[.isRememberPassphraseOn] && PasswordStore.shared.pgpKeyPassphrase != nil { - passphrase = PasswordStore.shared.pgpKeyPassphrase! + if Defaults[.isRememberPassphraseOn] && self.passwordStore.pgpKeyPassphrase != nil { + passphrase = self.passwordStore.pgpKeyPassphrase! self.decryptThenCopyPassword(passwordEntity: password, passphrase: passphrase) } else { let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) @@ -366,7 +367,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } else { title = "Password Store" } - let numberOfUnsynced = PasswordStore.shared.getNumberOfUnsyncedPasswords() + let numberOfUnsynced = self.passwordStore.getNumberOfUnsyncedPasswords() if numberOfUnsynced == 0 { navigationItem.title = "\(title)" } else { @@ -387,7 +388,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "showPasswordDetail" { - guard PasswordStore.shared.privateKey != nil else { + guard self.passwordStore.privateKey != nil else { Utils.alert(title: "Cannot Show Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil) if let s = sender as? UITableViewCell { let selectedIndexPath = tableView.indexPath(for: s)! diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index ddb93c2..c05f53e 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -25,7 +25,8 @@ class SettingsTableViewController: UITableViewController { @IBOutlet weak var touchIDTableViewCell: UITableViewCell! @IBOutlet weak var passcodeTableViewCell: UITableViewCell! @IBOutlet weak var passwordRepositoryTableViewCell: UITableViewCell! - + let passwordStore = PasswordStore.shared + @IBAction func cancelPGPKey(segue: UIStoryboardSegue) { } @@ -33,7 +34,7 @@ class SettingsTableViewController: UITableViewController { if let controller = segue.source as? PGPKeySettingTableViewController { Defaults[.pgpPrivateKeyURL] = URL(string: controller.pgpPrivateKeyURLTextField.text!) Defaults[.pgpPublicKeyURL] = URL(string: controller.pgpPublicKeyURLTextField.text!) - PasswordStore.shared.pgpKeyPassphrase = controller.pgpPassphrase + self.passwordStore.pgpKeyPassphrase = controller.pgpPassphrase Defaults[.pgpKeySource] = "url" SVProgressHUD.setDefaultMaskType(.black) @@ -41,10 +42,10 @@ class SettingsTableViewController: UITableViewController { SVProgressHUD.show(withStatus: "Fetching PGP Key") DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try PasswordStore.shared.initPGPKey(from: Defaults[.pgpPublicKeyURL]!, keyType: .public) - try PasswordStore.shared.initPGPKey(from: Defaults[.pgpPrivateKeyURL]!, keyType: .secret) + try self.passwordStore.initPGPKey(from: Defaults[.pgpPublicKeyURL]!, keyType: .public) + try self.passwordStore.initPGPKey(from: Defaults[.pgpPrivateKeyURL]!, keyType: .secret) DispatchQueue.main.async { - self.pgpKeyTableViewCell.detailTextLabel?.text = PasswordStore.shared.pgpKeyID + self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID SVProgressHUD.showSuccess(withStatus: "Success") SVProgressHUD.dismiss(withDelay: 1) Utils.alert(title: "Rememver to Remove the Key", message: "Remember to remove the key from the server.", controller: self, completion: nil) @@ -60,7 +61,7 @@ class SettingsTableViewController: UITableViewController { } else if let controller = segue.source as? PGPKeyArmorSettingTableViewController { Defaults[.pgpKeySource] = "armor" - PasswordStore.shared.pgpKeyPassphrase = controller.pgpPassphrase + self.passwordStore.pgpKeyPassphrase = controller.pgpPassphrase if Defaults[.isRememberPassphraseOn] { Utils.addPasswordToKeychain(name: "pgpKeyPassphrase", password: controller.pgpPassphrase!) } @@ -73,10 +74,10 @@ class SettingsTableViewController: UITableViewController { SVProgressHUD.show(withStatus: "Fetching PGP Key") DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try PasswordStore.shared.initPGPKey(with: controller.armorPublicKeyTextView.text, keyType: .public) - try PasswordStore.shared.initPGPKey(with: controller.armorPrivateKeyTextView.text, keyType: .secret) + try self.passwordStore.initPGPKey(with: controller.armorPublicKeyTextView.text, keyType: .public) + try self.passwordStore.initPGPKey(with: controller.armorPrivateKeyTextView.text, keyType: .secret) DispatchQueue.main.async { - self.pgpKeyTableViewCell.detailTextLabel?.text = PasswordStore.shared.pgpKeyID + self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID SVProgressHUD.showSuccess(withStatus: "Success") SVProgressHUD.dismiss(withDelay: 1) } @@ -105,8 +106,8 @@ class SettingsTableViewController: UITableViewController { Defaults[.gitRepositoryURL]!.absoluteString != gitRepostiroyURL || auth != Defaults[.gitRepositoryAuthenticationMethod] || username != Defaults[.gitRepositoryUsername] || - password != PasswordStore.shared.gitRepositoryPassword || - PasswordStore.shared.repositoryExisted() == false { + password != self.passwordStore.gitRepositoryPassword || + self.passwordStore.repositoryExisted() == false { SVProgressHUD.setDefaultMaskType(.black) SVProgressHUD.setDefaultStyle(.light) @@ -128,7 +129,7 @@ class SettingsTableViewController: UITableViewController { let dispatchQueue = DispatchQueue.global(qos: .userInitiated) dispatchQueue.async { do { - try PasswordStore.shared.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!, + try self.passwordStore.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!, credential: gitCredential, transferProgressBlock:{ (git_transfer_progress, stop) in DispatchQueue.main.async { @@ -141,7 +142,7 @@ class SettingsTableViewController: UITableViewController { } }) DispatchQueue.main.async { - PasswordStore.shared.updatePasswordEntityCoreData() + self.passwordStore.updatePasswordEntityCoreData() Defaults[.lastUpdatedTime] = Date() NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) Defaults[.gitRepositoryURL] = URL(string: gitRepostiroyURL) @@ -187,7 +188,7 @@ class SettingsTableViewController: UITableViewController { } private func setPGPKeyTableViewCellDetailText() { - if let pgpKeyID = PasswordStore.shared.pgpKeyID { + if let pgpKeyID = self.passwordStore.pgpKeyID { pgpKeyTableViewCell.detailTextLabel?.text = pgpKeyID } else { pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" @@ -224,7 +225,7 @@ class SettingsTableViewController: UITableViewController { })) alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = PasswordStore.shared.gitRepositoryPassword + textField.text = self.passwordStore.gitRepositoryPassword textField.isSecureTextEntry = true }) @@ -337,9 +338,9 @@ class SettingsTableViewController: UITableViewController { DispatchQueue.main.async { - PasswordStore.shared.initPGPKeys() + self.passwordStore.initPGPKeys() - let key: PGPKey = PasswordStore.shared.getPgpPrivateKey() + let key: PGPKey = self.passwordStore.getPgpPrivateKey() Defaults[.pgpKeySource] = "file" if (key.isEncrypted) { @@ -348,7 +349,7 @@ class SettingsTableViewController: UITableViewController { } SVProgressHUD.dismiss() - self.pgpKeyTableViewCell.detailTextLabel?.text = PasswordStore.shared.pgpKeyID + self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID } } diff --git a/pass/Views/LabelTableViewCell.swift b/pass/Views/LabelTableViewCell.swift index e01cd18..088d892 100644 --- a/pass/Views/LabelTableViewCell.swift +++ b/pass/Views/LabelTableViewCell.swift @@ -19,6 +19,7 @@ class LabelTableViewCell: UITableViewCell { @IBOutlet weak var contentLabel: UILabel! @IBOutlet weak var titleLabel: UILabel! + let passwordStore = PasswordStore.shared var isPasswordCell = false var isURLCell = false @@ -126,10 +127,10 @@ class LabelTableViewCell: UITableViewCell { // commit if password.changed { DispatchQueue.global(qos: .userInitiated).async { - PasswordStore.shared.update(passwordEntity: passwordEntity, password: password, progressBlock: {_ in }) + self.passwordStore.update(passwordEntity: passwordEntity, password: password, progressBlock: {_ in }) DispatchQueue.main.async { passwordEntity.synced = false - PasswordStore.shared.saveUpdated(passwordEntity: passwordEntity) + self.passwordStore.saveUpdated(passwordEntity: passwordEntity) NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) // reload so that the "unsynced" symbol could be added self.passwordTableView?.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.automatic) From 0ad9713fc0c69b5ab089bec6075494188952a040 Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Thu, 16 Mar 2017 23:12:31 -0700 Subject: [PATCH 4/7] Show error in alert instead of HUD --- .../AdvancedSettingsTableViewController.swift | 3 +-- pass/Controllers/PasswordsViewController.swift | 9 +++------ .../Controllers/SSHKeySettingTableViewController.swift | 4 +--- pass/Controllers/SettingsTableViewController.swift | 10 +++------- pass/Helpers/Utils.swift | 2 ++ 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/pass/Controllers/AdvancedSettingsTableViewController.swift b/pass/Controllers/AdvancedSettingsTableViewController.swift index 2ede296..e805b88 100644 --- a/pass/Controllers/AdvancedSettingsTableViewController.swift +++ b/pass/Controllers/AdvancedSettingsTableViewController.swift @@ -57,8 +57,7 @@ class AdvancedSettingsTableViewController: UITableViewController { SVProgressHUD.dismiss(withDelay: 1) } catch { DispatchQueue.main.async { - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } } diff --git a/pass/Controllers/PasswordsViewController.swift b/pass/Controllers/PasswordsViewController.swift index 302e6a0..65a7939 100644 --- a/pass/Controllers/PasswordsViewController.swift +++ b/pass/Controllers/PasswordsViewController.swift @@ -96,8 +96,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } } catch { DispatchQueue.main.async { - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } } @@ -136,8 +135,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } } catch { DispatchQueue.main.async { - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } } @@ -325,8 +323,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } catch { print(error) DispatchQueue.main.async { - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } } diff --git a/pass/Controllers/SSHKeySettingTableViewController.swift b/pass/Controllers/SSHKeySettingTableViewController.swift index d04fde0..ad14dd0 100644 --- a/pass/Controllers/SSHKeySettingTableViewController.swift +++ b/pass/Controllers/SSHKeySettingTableViewController.swift @@ -49,9 +49,7 @@ class SSHKeySettingTableViewController: UITableViewController { try Data(contentsOf: Defaults[.gitRepositorySSHPublicKeyURL]!).write(to: Globals.sshPublicKeyURL, options: .atomic) try Data(contentsOf: Defaults[.gitRepositorySSHPrivateKeyURL]!).write(to: Globals.sshPrivateKeyURL, options: .atomic) } catch { - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) - print(error) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } navigationController!.popViewController(animated: true) diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index c05f53e..754b404 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -53,8 +53,7 @@ class SettingsTableViewController: UITableViewController { } catch { DispatchQueue.main.async { self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } } @@ -84,8 +83,7 @@ class SettingsTableViewController: UITableViewController { } catch { DispatchQueue.main.async { self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } } @@ -155,9 +153,7 @@ class SettingsTableViewController: UITableViewController { } } catch { DispatchQueue.main.async { - print(error) - SVProgressHUD.showError(withStatus: error.localizedDescription) - SVProgressHUD.dismiss(withDelay: 1) + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) } } diff --git a/pass/Helpers/Utils.swift b/pass/Helpers/Utils.swift index 1278f24..726e107 100644 --- a/pass/Helpers/Utils.swift +++ b/pass/Helpers/Utils.swift @@ -10,6 +10,7 @@ import Foundation import SwiftyUserDefaults import KeychainAccess import UIKit +import SVProgressHUD class Utils { static func removeFileIfExists(atPath path: String) { @@ -65,6 +66,7 @@ class Utils { } static func alert(title: String, message: String, controller: UIViewController, completion: (() -> Void)?) { + SVProgressHUD.dismiss() let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: completion) From 1f829fffccabbd5ceae695b0937f112366867c0d Mon Sep 17 00:00:00 2001 From: Yishi Lin Date: Sat, 18 Mar 2017 00:18:55 +0800 Subject: [PATCH 5/7] Polish notification - define notification names - move "post notification" to PasswordStore (todo: move "search" and the one for "show folder switch") - "erase" and "reset" also post the "passwordStoreUpdated" notification --- pass.xcodeproj/project.pbxproj | 4 ++++ pass/AppDelegate.swift | 2 +- .../AboutRepositoryTableViewController.swift | 9 +++------ .../AdvancedSettingsTableViewController.swift | 4 ---- .../GeneralSettingsTableViewController.swift | 2 +- .../PasswordDetailTableViewController.swift | 3 +-- pass/Controllers/PasswordsViewController.swift | 14 +++----------- .../SettingsTableViewController.swift | 3 +-- pass/Helpers/NotificationNames.swift | 16 ++++++++++++++++ pass/Models/PasswordStore.swift | 12 +++++++++++- pass/Views/LabelTableViewCell.swift | 1 - 11 files changed, 41 insertions(+), 29 deletions(-) create mode 100644 pass/Helpers/NotificationNames.swift diff --git a/pass.xcodeproj/project.pbxproj b/pass.xcodeproj/project.pbxproj index 52dbf4a..80aac60 100644 --- a/pass.xcodeproj/project.pbxproj +++ b/pass.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 94BA784B85E071D25EE89B59 /* libPods-pass.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADCE7A5C3CCC67D7D21BB3C4 /* libPods-pass.a */; }; A262A58D1E68749C006B0890 /* Base32.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A262A58C1E68749C006B0890 /* Base32.framework */; }; + A27424D91E7C35960093F436 /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = A27424D81E7C35960093F436 /* NotificationNames.swift */; }; A2802BF91E70813A00879216 /* SliderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2802BF71E70813A00879216 /* SliderTableViewCell.swift */; }; A2802BFA1E70813A00879216 /* SliderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2802BF81E70813A00879216 /* SliderTableViewCell.xib */; }; DC037CA61E4B883900609409 /* OpenSourceComponentsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC037CA51E4B883900609409 /* OpenSourceComponentsTableViewController.swift */; }; @@ -69,6 +70,7 @@ /* Begin PBXFileReference section */ 274CCFCF32444A2FF46BE7F4 /* Pods-pass.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pass.debug.xcconfig"; path = "Pods/Target Support Files/Pods-pass/Pods-pass.debug.xcconfig"; sourceTree = ""; }; A262A58C1E68749C006B0890 /* Base32.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Base32.framework; path = Carthage/Build/iOS/Base32.framework; sourceTree = ""; }; + A27424D81E7C35960093F436 /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = ""; }; A2802BF71E70813A00879216 /* SliderTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderTableViewCell.swift; sourceTree = ""; }; A2802BF81E70813A00879216 /* SliderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SliderTableViewCell.xib; sourceTree = ""; }; ADCE7A5C3CCC67D7D21BB3C4 /* libPods-pass.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-pass.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -204,6 +206,7 @@ DC4A746D1E30FBDE00E8EB18 /* Objective-CBridgingHeader.h */, DCA049971E33586A00522E8F /* DefaultsKeys.swift */, DC19400A1E4B36B60077E0A3 /* Utils.swift */, + A27424D81E7C35960093F436 /* NotificationNames.swift */, ); path = Helpers; sourceTree = ""; @@ -447,6 +450,7 @@ DC7E6EEA1E432E48006C2443 /* Password.swift in Sources */, DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */, DC5F385B1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift in Sources */, + A27424D91E7C35960093F436 /* NotificationNames.swift in Sources */, DCAAF7451E2FA66800AB94BC /* SettingsTableViewController.swift in Sources */, DCE6C2671E71261C003038C6 /* PasswordWithFolderTableViewCell.swift in Sources */, DCFB77A71E502DF9008DE471 /* EditPasswordTableViewController.swift in Sources */, diff --git a/pass/AppDelegate.swift b/pass/AppDelegate.swift index 9b635e7..66ee47f 100644 --- a/pass/AppDelegate.swift +++ b/pass/AppDelegate.swift @@ -38,7 +38,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } func postSearchNotification() { - NotificationCenter.default.post(Notification(name: Notification.Name("search"))) + NotificationCenter.default.post(name: .passwordSearch, object: nil) } func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { diff --git a/pass/Controllers/AboutRepositoryTableViewController.swift b/pass/Controllers/AboutRepositoryTableViewController.swift index 2e76612..f6e7178 100644 --- a/pass/Controllers/AboutRepositoryTableViewController.swift +++ b/pass/Controllers/AboutRepositoryTableViewController.swift @@ -32,7 +32,9 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController { tableView.addSubview(indicatorLabel) setTableData() - addNotificationObservers() + + // all password store updates (including erase, discard) will trigger the refresh + NotificationCenter.default.addObserver(self, selector: #selector(setNeedRefresh), name: .passwordStoreUpdated, object: nil) } override func viewWillAppear(_ animated: Bool) { @@ -92,11 +94,6 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController { } } } - - private func addNotificationObservers() { - NotificationCenter.default.addObserver(self, selector: #selector(setNeedRefresh), name: NSNotification.Name(rawValue: "passwordUpdated"), object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(setNeedRefresh), name: NSNotification.Name(rawValue: "passwordStoreErased"), object: nil) - } func setNeedRefresh() { needRefresh = true diff --git a/pass/Controllers/AdvancedSettingsTableViewController.swift b/pass/Controllers/AdvancedSettingsTableViewController.swift index e805b88..7b22c93 100644 --- a/pass/Controllers/AdvancedSettingsTableViewController.swift +++ b/pass/Controllers/AdvancedSettingsTableViewController.swift @@ -26,7 +26,6 @@ class AdvancedSettingsTableViewController: UITableViewController { alert.addAction(UIAlertAction(title: "Erase Password Data", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in SVProgressHUD.show(withStatus: "Erasing ...") self.passwordStore.erase() - NotificationCenter.default.post(Notification(name: Notification.Name("passwordStoreErased"))) self.navigationController!.popViewController(animated: true) SVProgressHUD.showSuccess(withStatus: "Done") SVProgressHUD.dismiss(withDelay: 1) @@ -42,9 +41,6 @@ class AdvancedSettingsTableViewController: UITableViewController { DispatchQueue.main.async { do { let numberDiscarded = try self.passwordStore.reset() - if numberDiscarded > 0 { - NotificationCenter.default.post(Notification(name: Notification.Name("passwordStoreChangeDiscarded"))) - } self.navigationController!.popViewController(animated: true) switch numberDiscarded { case 0: diff --git a/pass/Controllers/GeneralSettingsTableViewController.swift b/pass/Controllers/GeneralSettingsTableViewController.swift index c0bd539..9d83de8 100644 --- a/pass/Controllers/GeneralSettingsTableViewController.swift +++ b/pass/Controllers/GeneralSettingsTableViewController.swift @@ -184,7 +184,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController { func showFolderSwitchAction(_ sender: Any?) { Defaults[.isShowFolderOn] = showFolderSwitch.isOn - NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) } } diff --git a/pass/Controllers/PasswordDetailTableViewController.swift b/pass/Controllers/PasswordDetailTableViewController.swift index 2dff655..0ba0770 100644 --- a/pass/Controllers/PasswordDetailTableViewController.swift +++ b/pass/Controllers/PasswordDetailTableViewController.swift @@ -197,7 +197,6 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni DispatchQueue.main.async { self.passwordEntity!.synced = false self.passwordStore.saveUpdated(passwordEntity: self.passwordEntity!) - NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) self.setTableData() self.tableView.reloadData() SVProgressHUD.showSuccess(withStatus: "Success") @@ -397,7 +396,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni } private func addNotificationObservers() { - NotificationCenter.default.addObserver(self, selector: #selector(setShouldPopCurrentView), name: NSNotification.Name(rawValue: "passwordStoreChangeDiscarded"), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(setShouldPopCurrentView), name: .passwordStoreChangeDiscarded, object: nil) } func setShouldPopCurrentView() { diff --git a/pass/Controllers/PasswordsViewController.swift b/pass/Controllers/PasswordsViewController.swift index 65a7939..035f889 100644 --- a/pass/Controllers/PasswordsViewController.swift +++ b/pass/Controllers/PasswordsViewController.swift @@ -92,7 +92,6 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV DispatchQueue.main.async { SVProgressHUD.showSuccess(withStatus: "Done") SVProgressHUD.dismiss(withDelay: 1) - NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) } } catch { DispatchQueue.main.async { @@ -142,9 +141,8 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } private func addNotificationObservers() { - NotificationCenter.default.addObserver(self, selector: #selector(PasswordsViewController.actOnPasswordUpdatedNotification), name: NSNotification.Name(rawValue: "passwordUpdated"), object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(PasswordsViewController.actOnPasswordStoreErasedNotification), name: NSNotification.Name(rawValue: "passwordStoreErased"), object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(PasswordsViewController.actOnSearchNotification), name: NSNotification.Name(rawValue: "search"), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(PasswordsViewController.actOnPasswordStoreUpdatedNotification), name: .passwordStoreUpdated, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(PasswordsViewController.actOnSearchNotification), name: .passwordSearch, object: nil) } override func viewDidLoad() { @@ -351,7 +349,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV sections.append(newSection) } - func actOnPasswordUpdatedNotification() { + func actOnPasswordStoreUpdatedNotification() { initPasswordsTableEntries(parent: nil) reloadTableView(data: passwordsTableEntries) setNavigationItemTitle() @@ -372,12 +370,6 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV } } - func actOnPasswordStoreErasedNotification() { - initPasswordsTableEntries(parent: nil) - reloadTableView(data: passwordsTableEntries) - setNavigationItemTitle() - } - func actOnSearchNotification() { searchController.searchBar.becomeFirstResponder() } diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index 754b404..2d26a34 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -142,7 +142,6 @@ class SettingsTableViewController: UITableViewController { DispatchQueue.main.async { self.passwordStore.updatePasswordEntityCoreData() Defaults[.lastUpdatedTime] = Date() - NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) Defaults[.gitRepositoryURL] = URL(string: gitRepostiroyURL) Defaults[.gitRepositoryUsername] = username Defaults[.gitRepositoryAuthenticationMethod] = auth @@ -164,7 +163,7 @@ class SettingsTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() - NotificationCenter.default.addObserver(self, selector: #selector(SettingsTableViewController.actOnPasswordStoreErasedNotification), name: NSNotification.Name(rawValue: "passwordStoreErased"), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(SettingsTableViewController.actOnPasswordStoreErasedNotification), name: .passwordStoreErased, object: nil) self.passwordRepositoryTableViewCell.detailTextLabel?.text = Defaults[.gitRepositoryURL]?.host touchIDTableViewCell.accessoryView = touchIDSwitch setPGPKeyTableViewCellDetailText() diff --git a/pass/Helpers/NotificationNames.swift b/pass/Helpers/NotificationNames.swift new file mode 100644 index 0000000..e4bf3d8 --- /dev/null +++ b/pass/Helpers/NotificationNames.swift @@ -0,0 +1,16 @@ +// +// NotificationNames.swift +// pass +// +// Created by Yishi Lin on 17/3/17. +// Copyright © 2017 Yishi Lin, Bob Sun. All rights reserved. +// + +import Foundation + +extension Notification.Name { + static let passwordStoreUpdated = Notification.Name("passwordStoreUpdated") + static let passwordStoreErased = Notification.Name("passwordStoreErased") + static let passwordStoreChangeDiscarded = Notification.Name("passwordStoreChangeDiscarded") + static let passwordSearch = Notification.Name("passwordSearch") +} diff --git a/pass/Models/PasswordStore.swift b/pass/Models/PasswordStore.swift index 1d6bb0b..be28d0f 100644 --- a/pass/Models/PasswordStore.swift +++ b/pass/Models/PasswordStore.swift @@ -285,6 +285,7 @@ class PasswordStore { } storeRepository = try GTRepository(url: storeURL) gitCredential = credential + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) } func pullRepository(transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void) throws { @@ -297,6 +298,7 @@ class PasswordStore { ] let remote = try GTRemote(name: "origin", in: storeRepository!) try storeRepository?.pull((storeRepository?.currentBranch())!, from: remote, withOptions: options, progress: transferProgressBlock) + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) } @@ -542,18 +544,22 @@ class PasswordStore { print(saveURL.path) let _ = createAddCommitInRepository(message: "Add password for \(passwordEntity.nameWithCategory) to store using Pass for iOS.", fileData: encryptedData, filename: saveURL.lastPathComponent, progressBlock: progressBlock) progressBlock(1.0) + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) } catch { print(error) } } func update(passwordEntity: PasswordEntity, password: Password, progressBlock: (_ progress: Float) -> Void) { + progressBlock(0.0) do { let encryptedData = try passwordEntity.encrypt(password: password) let saveURL = storeURL.appendingPathComponent(passwordEntity.path!) try encryptedData.write(to: saveURL) progressBlock(0.3) let _ = createAddCommitInRepository(message: "Edit password for \(passwordEntity.nameWithCategory) using Pass for iOS.", fileData: encryptedData, filename: saveURL.lastPathComponent, progressBlock: progressBlock) + progressBlock(1.0) + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) } catch { print(error) } @@ -621,6 +627,9 @@ class PasswordStore { Defaults.removeAll() storeRepository = nil + + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) + NotificationCenter.default.post(name: .passwordStoreErased, object: nil) } // return the number of discarded commits @@ -645,7 +654,8 @@ class PasswordStore { } try self.storeRepository?.reset(to: newHead, resetType: GTRepositoryResetType.hard) self.updatePasswordEntityCoreData() - NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) + NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil) + NotificationCenter.default.post(name: .passwordStoreChangeDiscarded, object: nil) self.setAllSynced() return localCommits.count } else { diff --git a/pass/Views/LabelTableViewCell.swift b/pass/Views/LabelTableViewCell.swift index 088d892..242ca3b 100644 --- a/pass/Views/LabelTableViewCell.swift +++ b/pass/Views/LabelTableViewCell.swift @@ -131,7 +131,6 @@ class LabelTableViewCell: UITableViewCell { DispatchQueue.main.async { passwordEntity.synced = false self.passwordStore.saveUpdated(passwordEntity: passwordEntity) - NotificationCenter.default.post(Notification(name: Notification.Name("passwordUpdated"))) // reload so that the "unsynced" symbol could be added self.passwordTableView?.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation.automatic) SVProgressHUD.showSuccess(withStatus: "Password Copied\nCounter Updated") From 035da94ad92ede601d91645e5cd80ed0241800a0 Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Fri, 17 Mar 2017 10:25:10 -0700 Subject: [PATCH 6/7] Remove indicator label during decrypting password since decryption become really fast --- .../PasswordDetailTableViewController.swift | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pass/Controllers/PasswordDetailTableViewController.swift b/pass/Controllers/PasswordDetailTableViewController.swift index 0ba0770..ba3f278 100644 --- a/pass/Controllers/PasswordDetailTableViewController.swift +++ b/pass/Controllers/PasswordDetailTableViewController.swift @@ -20,17 +20,6 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni var shouldPopCurrentView = false let passwordStore = PasswordStore.shared - let indicatorLable: UILabel = { - let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 21)) - label.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height * 0.382 + 22) - label.backgroundColor = UIColor.clear - label.textColor = UIColor.gray - label.text = "decrypting password" - label.textAlignment = .center - label.font = UIFont.preferredFont(forTextStyle: .footnote) - return label - }() - let indicator: UIActivityIndicatorView = { let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) indicator.center = CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height * 0.382) @@ -82,7 +71,6 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni indicator.startAnimating() tableView.addSubview(indicator) - tableView.addSubview(indicatorLable) editUIBarButtonItem.isEnabled = false navigationItem.rightBarButtonItem = editUIBarButtonItem @@ -142,7 +130,6 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni setTableData() self.tableView.reloadData() indicator.stopAnimating() - indicatorLable.isHidden = true editUIBarButtonItem.isEnabled = true if let urlString = password.getURLString() { if self.passwordEntity?.image == nil{ From ffe2eb71ad0ab5ca1b0fea00f3836c5bdb1de611 Mon Sep 17 00:00:00 2001 From: Bob Sun Date: Fri, 17 Mar 2017 10:37:26 -0700 Subject: [PATCH 7/7] Version bump --- pass/Info.plist | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pass/Info.plist b/pass/Info.plist index c59a698..f1ca210 100644 --- a/pass/Info.plist +++ b/pass/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.2 + 0.2.1 CFBundleVersion - 24 + 1 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS @@ -35,6 +35,8 @@ $(PRODUCT_BUNDLE_IDENTIFIER).search + UIFileSharingEnabled + UILaunchStoryboardName Main UIMainStoryboardFile @@ -43,8 +45,6 @@ armv7 - UIFileSharingEnabled - UISupportedInterfaceOrientations UIInterfaceOrientationPortrait