From c87f4e97928c5eb1284cb187959a89f102ee7775 Mon Sep 17 00:00:00 2001 From: Danny Moesch Date: Sun, 5 Jul 2020 00:16:22 +0200 Subject: [PATCH] Enable SwiftLint rule 'multiline_arguments_brackets' and fix all violations --- .swiftlint.yml | 2 +- pass/AppDelegate.swift | 4 +- .../AdvancedSettingsTableViewController.swift | 39 ++++--- ...epositorySettingsTableViewController.swift | 104 +++++++++++------- ...nSourceComponentsTableViewController.swift | 18 +-- .../PasswordDetailTableViewController.swift | 22 ++-- .../PasswordEditorTableViewController.swift | 30 +++-- .../Controllers/PasswordsViewController.swift | 8 +- pass/Controllers/QRScannerController.swift | 20 ++-- .../SSHKeyUrlImportTableViewController.swift | 8 +- .../SettingsTableViewController.swift | 68 +++++++----- pass/Helpers/GitCredentialPassword.swift | 20 ++-- pass/Helpers/SecurePasteboard.swift | 4 +- .../Controllers/ExtensionViewController.swift | 15 +-- .../PasscodeLockViewController.swift | 102 ++++++++--------- passKit/Helpers/FileManagerExtension.swift | 10 +- passKit/Helpers/Utils.swift | 10 +- passKit/Models/PasswordStore.swift | 22 ++-- 18 files changed, 286 insertions(+), 220 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 885f798..7668393 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -97,7 +97,7 @@ whitelist_rules: # - missing_docs - modifier_order - multiline_arguments -# - multiline_arguments_brackets + - multiline_arguments_brackets # - multiline_function_chains # - multiline_literal_brackets # - multiline_parameters diff --git a/pass/AppDelegate.swift b/pass/AppDelegate.swift index 7b8d466..e1e1daa 100644 --- a/pass/AppDelegate.swift +++ b/pass/AppDelegate.swift @@ -123,7 +123,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { try! FileManager.default.createDirectory(atPath: Globals.documentPath, withIntermediateDirectories: true, attributes: nil) } container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: URL(fileURLWithPath: Globals.dbPath))] - container.loadPersistentStores(completionHandler: { _, error in + container.loadPersistentStores { _, error in if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. @@ -138,7 +138,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { */ fatalError("UnresolvedError".localize("\(error), \(error.userInfo)")) } - }) + } return container }() diff --git a/pass/Controllers/AdvancedSettingsTableViewController.swift b/pass/Controllers/AdvancedSettingsTableViewController.swift index 4716f01..4806d36 100644 --- a/pass/Controllers/AdvancedSettingsTableViewController.swift +++ b/pass/Controllers/AdvancedSettingsTableViewController.swift @@ -48,29 +48,32 @@ class AdvancedSettingsTableViewController: UITableViewController { tableView.deselectRow(at: indexPath, animated: true) if tableView.cellForRow(at: indexPath) == eraseDataTableViewCell { let alert = UIAlertController(title: "ErasePasswordStoreData?".localize(), message: "EraseExplanation.".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "ErasePasswordStoreData".localize(), style: UIAlertAction.Style.destructive, handler: { [unowned self] (_) -> Void in - SVProgressHUD.show(withStatus: "Erasing...".localize()) - self.passwordStore.erase() - self.navigationController!.popViewController(animated: true) - SVProgressHUD.showSuccess(withStatus: "Done".localize()) - SVProgressHUD.dismiss(withDelay: 1) - })) + alert.addAction( + UIAlertAction(title: "ErasePasswordStoreData".localize(), style: UIAlertAction.Style.destructive) { [unowned self] (_) -> Void in + SVProgressHUD.show(withStatus: "Erasing...".localize()) + self.passwordStore.erase() + self.navigationController!.popViewController(animated: true) + SVProgressHUD.showSuccess(withStatus: "Done".localize()) + SVProgressHUD.dismiss(withDelay: 1) + } + ) alert.addAction(UIAlertAction.dismiss()) present(alert, animated: true, completion: nil) } else if tableView.cellForRow(at: indexPath) == discardChangesTableViewCell { let alert = UIAlertController(title: "DiscardAllLocalChanges?".localize(), message: "DiscardExplanation.".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "DiscardAllLocalChanges".localize(), style: UIAlertAction.Style.destructive, handler: { [unowned self] (_) -> Void in - SVProgressHUD.show(withStatus: "Resetting...".localize()) - do { - let numberDiscarded = try self.passwordStore.reset() - self.navigationController!.popViewController(animated: true) - SVProgressHUD.showSuccess(withStatus: "DiscardedCommits(%d)".localize(numberDiscarded)) - SVProgressHUD.dismiss(withDelay: 1) - } catch { - Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil) + alert.addAction( + UIAlertAction(title: "DiscardAllLocalChanges".localize(), style: UIAlertAction.Style.destructive) { [unowned self] (_) -> Void in + SVProgressHUD.show(withStatus: "Resetting...".localize()) + do { + let numberDiscarded = try self.passwordStore.reset() + self.navigationController!.popViewController(animated: true) + SVProgressHUD.showSuccess(withStatus: "DiscardedCommits(%d)".localize(numberDiscarded)) + SVProgressHUD.dismiss(withDelay: 1) + } catch { + Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil) + } } - - })) + ) alert.addAction(UIAlertAction.dismiss()) present(alert, animated: true, completion: nil) } diff --git a/pass/Controllers/GitRepositorySettingsTableViewController.swift b/pass/Controllers/GitRepositorySettingsTableViewController.swift index b8232a9..77780f9 100644 --- a/pass/Controllers/GitRepositorySettingsTableViewController.swift +++ b/pass/Controllers/GitRepositorySettingsTableViewController.swift @@ -146,9 +146,11 @@ class GitRepositorySettingsTableViewController: UITableViewController { if passwordStore.repositoryExists() { let overwriteAlert: UIAlertController = { let alert = UIAlertController(title: "Overwrite?".localize(), message: "OperationWillOverwriteData.".localize(), preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Overwrite".localize(), style: .destructive) { _ in - self.cloneAndSegueIfSuccess() - }) + alert.addAction( + UIAlertAction(title: "Overwrite".localize(), style: .destructive) { _ in + self.cloneAndSegueIfSuccess() + } + ) alert.addAction(UIAlertAction.cancel()) return alert }() @@ -174,26 +176,32 @@ class GitRepositorySettingsTableViewController: UITableViewController { SVProgressHUD.showProgress(progress, status: "CheckingOutBranch".localize(self.gitBranchName)) } - try self.passwordStore.cloneRepository(remoteRepoURL: self.gitUrl, - credential: self.gitCredential, - branchName: self.gitBranchName, - requestCredentialPassword: self.requestCredentialPassword, - transferProgressBlock: transferProgressBlock, - checkoutProgressBlock: checkoutProgressBlock) + try self.passwordStore.cloneRepository( + remoteRepoURL: self.gitUrl, + credential: self.gitCredential, + branchName: self.gitBranchName, + requestCredentialPassword: self.requestCredentialPassword, + transferProgressBlock: transferProgressBlock, + checkoutProgressBlock: checkoutProgressBlock + ) SVProgressHUD.dismiss { let savePassphraseAlert: UIAlertController = { let alert = UIAlertController(title: "Done".localize(), message: "WantToSaveGitCredential?".localize(), preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "No".localize(), style: .default) { _ in - Defaults.isRememberGitCredentialPassphraseOn = false - self.passwordStore.gitPassword = nil - self.passwordStore.gitSSHPrivateKeyPassphrase = nil - self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) - }) - alert.addAction(UIAlertAction(title: "Yes".localize(), style: .destructive) { _ in - Defaults.isRememberGitCredentialPassphraseOn = true - self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) - }) + alert.addAction( + UIAlertAction(title: "No".localize(), style: .default) { _ in + Defaults.isRememberGitCredentialPassphraseOn = false + self.passwordStore.gitPassword = nil + self.passwordStore.gitSSHPrivateKeyPassphrase = nil + self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) + } + ) + alert.addAction( + UIAlertAction(title: "Yes".localize(), style: .destructive) { _ in + Defaults.isRememberGitCredentialPassphraseOn = true + self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) + } + ) return alert }() DispatchQueue.main.async { @@ -244,35 +252,47 @@ class GitRepositorySettingsTableViewController: UITableViewController { private func showSSHKeyActionSheet() { let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - optionMenu.addAction(UIAlertAction(title: SSHKeyUrlImportTableViewController.menuLabel, style: .default) { _ in - self.performSegue(withIdentifier: "setGitSSHKeyByURLSegue", sender: self) - }) - optionMenu.addAction(UIAlertAction(title: SSHKeyArmorImportTableViewController.menuLabel, style: .default) { _ in - self.performSegue(withIdentifier: "setGitSSHKeyByArmorSegue", sender: self) - }) - optionMenu.addAction(UIAlertAction(title: SSHKeyFileImportTableViewController.menuLabel, style: .default) { _ in - self.performSegue(withIdentifier: "setGitSSHKeyByFileSegue", sender: self) - }) + optionMenu.addAction( + UIAlertAction(title: SSHKeyUrlImportTableViewController.menuLabel, style: .default) { _ in + self.performSegue(withIdentifier: "setGitSSHKeyByURLSegue", sender: self) + } + ) + optionMenu.addAction( + UIAlertAction(title: SSHKeyArmorImportTableViewController.menuLabel, style: .default) { _ in + self.performSegue(withIdentifier: "setGitSSHKeyByArmorSegue", sender: self) + } + ) + optionMenu.addAction( + UIAlertAction(title: SSHKeyFileImportTableViewController.menuLabel, style: .default) { _ in + self.performSegue(withIdentifier: "setGitSSHKeyByFileSegue", sender: self) + } + ) if isReadyToUse() { - optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in - self.importSSHKey(using: self) - }) + optionMenu.addAction( + UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in + self.importSSHKey(using: self) + } + ) } else { - optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Tips".localize()))", style: .default) { _ in - let title = "Tips".localize() - let message = "SshCopyPrivateKeyToPass.".localize() - Utils.alert(title: title, message: message, controller: self) - }) + optionMenu.addAction( + UIAlertAction(title: "\(Self.menuLabel) (\("Tips".localize()))", style: .default) { _ in + let title = "Tips".localize() + let message = "SshCopyPrivateKeyToPass.".localize() + Utils.alert(title: title, message: message, controller: self) + } + ) } if Defaults.gitSSHKeySource != nil { - optionMenu.addAction(UIAlertAction(title: "RemoveSShKeys".localize(), style: .destructive) { _ in - self.passwordStore.removeGitSSHKeys() - Defaults.gitSSHKeySource = nil - self.sshLabel?.isEnabled = false - self.gitAuthenticationMethod = .password - }) + optionMenu.addAction( + UIAlertAction(title: "RemoveSShKeys".localize(), style: .destructive) { _ in + self.passwordStore.removeGitSSHKeys() + Defaults.gitSSHKeySource = nil + self.sshLabel?.isEnabled = false + self.gitAuthenticationMethod = .password + } + ) } optionMenu.addAction(UIAlertAction.cancel()) optionMenu.popoverPresentationController?.sourceView = authSSHKeyCell diff --git a/pass/Controllers/OpenSourceComponentsTableViewController.swift b/pass/Controllers/OpenSourceComponentsTableViewController.swift index 5f2bbde..7ab43f3 100644 --- a/pass/Controllers/OpenSourceComponentsTableViewController.swift +++ b/pass/Controllers/OpenSourceComponentsTableViewController.swift @@ -41,14 +41,16 @@ class OpenSourceComponentsTableViewController: BasicStaticTableViewController { super.viewDidLoad() tableData.append([]) for item in Self.openSourceComponents { - tableData[0].append([ - .title: item[0], - .action: "link", - .link: item[1], - .accessoryType: UITableViewCell.AccessoryType.detailDisclosureButton, - .detailDisclosureAction: #selector(actOnDetailDisclosureButton(_:)), - .detailDisclosureData: item[2], - ]) + tableData[0].append( + [ + .title: item[0], + .action: "link", + .link: item[1], + .accessoryType: UITableViewCell.AccessoryType.detailDisclosureButton, + .detailDisclosureAction: #selector(actOnDetailDisclosureButton(_:)), + .detailDisclosureData: item[2], + ] + ) } } diff --git a/pass/Controllers/PasswordDetailTableViewController.swift b/pass/Controllers/PasswordDetailTableViewController.swift index 8860390..1cad212 100644 --- a/pass/Controllers/PasswordDetailTableViewController.swift +++ b/pass/Controllers/PasswordDetailTableViewController.swift @@ -88,9 +88,9 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni @objc private func decryptThenShowPassword(keyID: String? = nil) { guard let passwordEntity = passwordEntity else { - Utils.alert(title: "CannotShowPassword".localize(), message: "PasswordDoesNotExist".localize(), controller: self, handler: { (_) -> Void in + Utils.alert(title: "CannotShowPassword".localize(), message: "PasswordDoesNotExist".localize(), controller: self) { self.navigationController!.popViewController(animated: true) - }) + } return } DispatchQueue.global(qos: .userInitiated).async { @@ -116,9 +116,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni // alert: cancel or try again let alert = UIAlertController(title: "CannotShowPassword".localize(), message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction.cancelAndPopView(controller: self)) - alert.addAction(UIAlertAction(title: "TryAgain".localize(), style: .default) { _ in - self.decryptThenShowPassword() - }) + alert.addAction( + UIAlertAction(title: "TryAgain".localize(), style: .default) { _ in + self.decryptThenShowPassword() + } + ) self.present(alert, animated: true, completion: nil) } } @@ -288,10 +290,12 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni var newUrlString = urlString if urlString.lowercased().hasPrefix("http://") { // try to replace http url to https url - newUrlString = urlString.replacingOccurrences(of: "http://", - with: "https://", - options: .caseInsensitive, - range: urlString.range(of: "http://")) + newUrlString = urlString.replacingOccurrences( + of: "http://", + with: "https://", + options: .caseInsensitive, + range: urlString.range(of: "http://") + ) } else if urlString.lowercased().hasPrefix("https://") { // do nothing here } else { diff --git a/pass/Controllers/PasswordEditorTableViewController.swift b/pass/Controllers/PasswordEditorTableViewController.swift index d0aad9d..97a72d0 100644 --- a/pass/Controllers/PasswordEditorTableViewController.swift +++ b/pass/Controllers/PasswordEditorTableViewController.swift @@ -246,9 +246,11 @@ class PasswordEditorTableViewController: UITableViewController { if selectedCell == deletePasswordCell { let alert = UIAlertController(title: "DeletePassword?".localize(), message: nil, preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "Delete".localize(), style: UIAlertAction.Style.destructive, handler: { [unowned self] (_) -> Void in - self.performSegue(withIdentifier: "deletePasswordSegue", sender: self) - })) + alert.addAction( + UIAlertAction(title: "Delete".localize(), style: UIAlertAction.Style.destructive) { [unowned self] (_) -> Void in + self.performSegue(withIdentifier: "deletePasswordSegue", sender: self) + } + ) alert.addAction(UIAlertAction.cancel()) present(alert, animated: true, completion: nil) } else if selectedCell == scanQRCodeCell { @@ -388,9 +390,11 @@ extension PasswordEditorTableViewController: FillPasswordTableViewCellDelegate { func generateAndCopyPassword() { if let currentPassword = fillPasswordCell?.getContent(), Constants.isOtpRelated(line: currentPassword) { let alert = UIAlertController(title: "Overwrite?".localize(), message: "OverwriteOtpConfiguration?".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertAction.Style.destructive, handler: { _ in - self.generateAndCopyPasswordNoOtpCheck() - })) + alert.addAction( + UIAlertAction(title: "Yes".localize(), style: UIAlertAction.Style.destructive) { _ in + self.generateAndCopyPasswordNoOtpCheck() + } + ) alert.addAction(UIAlertAction.cancel()) present(alert, animated: true, completion: nil) } else { @@ -436,12 +440,14 @@ extension PasswordEditorTableViewController: SFSafariViewControllerDelegate { let message = NSMutableAttributedString(string: "\("SeemsLikeYouHaveCopiedSomething.".localize()) \("FirstStringIs:".localize())\n") message.append(Utils.attributedPassword(plainPassword: generatedPassword)) alert.setValue(message, forKey: "attributedMessage") - alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: { [unowned self] (_) -> Void in - // update tableData so to make sure reloadData() works correctly - self.tableData[self.passwordSection][0][PasswordEditorCellKey.content] = generatedPassword - // update cell manually, no need to call reloadData() - self.fillPasswordCell?.setContent(content: generatedPassword) - })) + alert.addAction( + UIAlertAction(title: "Yes", style: UIAlertAction.Style.default) { [unowned self] (_) -> Void in + // update tableData so to make sure reloadData() works correctly + self.tableData[self.passwordSection][0][PasswordEditorCellKey.content] = generatedPassword + // update cell manually, no need to call reloadData() + self.fillPasswordCell?.setContent(content: generatedPassword) + } + ) alert.addAction(UIAlertAction.cancel()) present(alert, animated: true, completion: nil) } diff --git a/pass/Controllers/PasswordsViewController.swift b/pass/Controllers/PasswordsViewController.swift index 3249f28..3bb67f5 100644 --- a/pass/Controllers/PasswordsViewController.swift +++ b/pass/Controllers/PasswordsViewController.swift @@ -192,17 +192,17 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try self.passwordStore.pullRepository(credential: self.gitCredential, requestCredentialPassword: self.requestCredentialPassword, progressBlock: { git_transfer_progress, _ in + try self.passwordStore.pullRepository(credential: self.gitCredential, requestCredentialPassword: self.requestCredentialPassword) { git_transfer_progress, _ in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects) / Float(git_transfer_progress.pointee.total_objects), status: "PullingFromRemoteRepository".localize()) } - }) + } if self.passwordStore.numberOfLocalCommits > 0 { - try self.passwordStore.pushRepository(credential: self.gitCredential, requestCredentialPassword: self.requestCredentialPassword, transferProgressBlock: { current, total, _, _ in + try self.passwordStore.pushRepository(credential: self.gitCredential, requestCredentialPassword: self.requestCredentialPassword) { current, total, _, _ in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(current) / Float(total), status: "PushingToRemoteRepository".localize()) } - }) + } } DispatchQueue.main.async { self.reloadTableView(parent: nil) diff --git a/pass/Controllers/QRScannerController.swift b/pass/Controllers/QRScannerController.swift index 5ce782d..9cc9d30 100644 --- a/pass/Controllers/QRScannerController.swift +++ b/pass/Controllers/QRScannerController.swift @@ -129,17 +129,19 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg } func presentCameraSettings() { - let alertController = UIAlertController(title: "Error".localize(), - message: "CameraAccessDenied.".localize() | "WarningToggleCameraPermissionsResetsApp.".localize(), - preferredStyle: .alert) + let alertController = UIAlertController( + title: "Error".localize(), + message: "CameraAccessDenied.".localize() | "WarningToggleCameraPermissionsResetsApp.".localize(), + preferredStyle: .alert + ) alertController.addAction(UIAlertAction(title: "Cancel".localize(), style: .default)) - alertController.addAction(UIAlertAction(title: "Settings".localize(), style: .cancel) { _ in - if let url = URL(string: UIApplication.openSettingsURLString) { - UIApplication.shared.open(url, options: [:], completionHandler: { _ in - // Handle - }) + alertController.addAction( + UIAlertAction(title: "Settings".localize(), style: .cancel) { _ in + if let url = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(url, options: [:]) { _ in } + } } - }) + ) present(alertController, animated: true) } diff --git a/pass/Controllers/SSHKeyUrlImportTableViewController.swift b/pass/Controllers/SSHKeyUrlImportTableViewController.swift index 2fb83b6..fa2f729 100644 --- a/pass/Controllers/SSHKeyUrlImportTableViewController.swift +++ b/pass/Controllers/SSHKeyUrlImportTableViewController.swift @@ -30,9 +30,11 @@ class SSHKeyUrlImportTableViewController: AutoCellHeightUITableViewController { if privateKeyURL.scheme?.lowercased() == "http" { let savePassphraseAlert = UIAlertController(title: "HttpNotSecure".localize(), message: "ReallyUseHttp?".localize(), preferredStyle: .alert) savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: .default) { _ in }) - savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: .destructive) { _ in - self.performSegue(withIdentifier: "importSSHKeySegue", sender: self) - }) + savePassphraseAlert.addAction( + UIAlertAction(title: "Yes".localize(), style: .destructive) { _ in + self.performSegue(withIdentifier: "importSSHKeySegue", sender: self) + } + ) return present(savePassphraseAlert, animated: true) } sshPrivateKeyURL = privateKeyURL diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index f98be35..d756934 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -142,36 +142,48 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele func showPGPKeyActionSheet() { let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - optionMenu.addAction(UIAlertAction(title: PGPKeyUrlImportTableViewController.menuLabel, style: .default) { _ in - self.performSegue(withIdentifier: "setPGPKeyByURLSegue", sender: self) - }) - optionMenu.addAction(UIAlertAction(title: PGPKeyArmorImportTableViewController.menuLabel, style: .default) { _ in - self.performSegue(withIdentifier: "setPGPKeyByASCIISegue", sender: self) - }) - optionMenu.addAction(UIAlertAction(title: PGPKeyFileImportTableViewController.menuLabel, style: .default) { _ in - self.performSegue(withIdentifier: "setPGPKeyByFileSegue", sender: self) - }) + optionMenu.addAction( + UIAlertAction(title: PGPKeyUrlImportTableViewController.menuLabel, style: .default) { _ in + self.performSegue(withIdentifier: "setPGPKeyByURLSegue", sender: self) + } + ) + optionMenu.addAction( + UIAlertAction(title: PGPKeyArmorImportTableViewController.menuLabel, style: .default) { _ in + self.performSegue(withIdentifier: "setPGPKeyByASCIISegue", sender: self) + } + ) + optionMenu.addAction( + UIAlertAction(title: PGPKeyFileImportTableViewController.menuLabel, style: .default) { _ in + self.performSegue(withIdentifier: "setPGPKeyByFileSegue", sender: self) + } + ) if isReadyToUse() { - optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in - self.saveImportedKeys() - }) + optionMenu.addAction( + UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in + self.saveImportedKeys() + } + ) } else { - optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Tips".localize()))", style: .default) { _ in - let title = "Tips".localize() - let message = "PgpCopyPublicAndPrivateKeyToPass.".localize() - Utils.alert(title: title, message: message, controller: self) - }) + optionMenu.addAction( + UIAlertAction(title: "\(Self.menuLabel) (\("Tips".localize()))", style: .default) { _ in + let title = "Tips".localize() + let message = "PgpCopyPublicAndPrivateKeyToPass.".localize() + Utils.alert(title: title, message: message, controller: self) + } + ) } if Defaults.pgpKeySource != nil { - optionMenu.addAction(UIAlertAction(title: "RemovePgpKeys".localize(), style: .destructive) { _ in - self.keychain.removeContent(for: PgpKey.PUBLIC.getKeychainKey()) - self.keychain.removeContent(for: PgpKey.PRIVATE.getKeychainKey()) - PGPAgent.shared.uninitKeys() - self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize() - Defaults.pgpKeySource = nil - }) + optionMenu.addAction( + UIAlertAction(title: "RemovePgpKeys".localize(), style: .destructive) { _ in + self.keychain.removeContent(for: PgpKey.PUBLIC.getKeychainKey()) + self.keychain.removeContent(for: PgpKey.PRIVATE.getKeychainKey()) + PGPAgent.shared.uninitKeys() + self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize() + Defaults.pgpKeySource = nil + } + ) } optionMenu.addAction(UIAlertAction.cancel()) optionMenu.popoverPresentationController?.sourceView = pgpKeyTableViewCell @@ -221,16 +233,16 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele func setPasscodeLock() { // prepare the alert for setting the passcode setPasscodeLockAlert = UIAlertController(title: "SetPasscode".localize(), message: "FillInAppPasscode.".localize(), preferredStyle: .alert) - setPasscodeLockAlert?.addTextField(configurationHandler: { (_ textField: UITextField) -> Void in + setPasscodeLockAlert?.addTextField { textField -> Void in textField.placeholder = "Passcode".localize() textField.isSecureTextEntry = true textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged) - }) - setPasscodeLockAlert?.addTextField(configurationHandler: { (_ textField: UITextField) -> Void in + } + setPasscodeLockAlert?.addTextField { textField -> Void in textField.placeholder = "PasswordConfirmation".localize() textField.isSecureTextEntry = true textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged) - }) + } // save action let saveAction = UIAlertAction(title: "Save".localize(), style: .default) { (_: UIAlertAction) -> Void in diff --git a/pass/Helpers/GitCredentialPassword.swift b/pass/Helpers/GitCredentialPassword.swift index 5ba21f3..96a05f1 100644 --- a/pass/Helpers/GitCredentialPassword.swift +++ b/pass/Helpers/GitCredentialPassword.swift @@ -31,14 +31,18 @@ public func requestGitCredentialPassword(credential: GitCredential.Credential, $0.text = lastPassword ?? "" $0.isSecureTextEntry = true } - alert.addAction(UIAlertAction.ok { _ in - password = alert.textFields?.first?.text - sem.signal() - }) - alert.addAction(UIAlertAction.cancel { _ in - password = nil - sem.signal() - }) + alert.addAction( + UIAlertAction.ok { _ in + password = alert.textFields?.first?.text + sem.signal() + } + ) + alert.addAction( + UIAlertAction.cancel { _ in + password = nil + sem.signal() + } + ) controller.present(alert, animated: true) } diff --git a/pass/Helpers/SecurePasteboard.swift b/pass/Helpers/SecurePasteboard.swift index 8b9b309..f2669bc 100644 --- a/pass/Helpers/SecurePasteboard.swift +++ b/pass/Helpers/SecurePasteboard.swift @@ -29,11 +29,11 @@ public class SecurePasteboard { backgroundTaskID = UIBackgroundTaskIdentifier.invalid } - backgroundTaskID = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in + backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in UIPasteboard.general.string = "" UIApplication.shared.endBackgroundTask(UIBackgroundTaskIdentifier.invalid) self?.backgroundTaskID = UIBackgroundTaskIdentifier.invalid - }) + } DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + expirationTime) { [weak self] in UIPasteboard.general.string = "" diff --git a/passExtension/Controllers/ExtensionViewController.swift b/passExtension/Controllers/ExtensionViewController.swift index 1aff5fa..aa02b24 100644 --- a/passExtension/Controllers/ExtensionViewController.swift +++ b/passExtension/Controllers/ExtensionViewController.swift @@ -67,7 +67,7 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV for provider in itemProviders { // search using the extensionContext inputs if provider.hasItemConformingToTypeIdentifier(OnePasswordExtensionActions.findLogin) { - provider.loadItem(forTypeIdentifier: OnePasswordExtensionActions.findLogin, options: nil, completionHandler: { (item, _) -> Void in + provider.loadItem(forTypeIdentifier: OnePasswordExtensionActions.findLogin, options: nil) { (item, _) -> Void in let dictionary = item as! NSDictionary var url: String? if var urlString = dictionary[OnePasswordExtensionKey.URLStringKey] as? String { @@ -83,9 +83,9 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV self?.searchBar.becomeFirstResponder() self?.searchBarSearchButtonClicked((self?.searchBar)!) } - }) + } } else if provider.hasItemConformingToTypeIdentifier(kUTTypePropertyList as String) { - provider.loadItem(forTypeIdentifier: kUTTypePropertyList as String, options: nil, completionHandler: { (item, _) -> Void in + provider.loadItem(forTypeIdentifier: kUTTypePropertyList as String, options: nil) { (item, _) -> Void in var url: String? if let dictionary = item as? NSDictionary, let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as? NSDictionary, @@ -102,9 +102,9 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV self?.searchBar.becomeFirstResponder() self?.searchBarSearchButtonClicked((self?.searchBar)!) } - }) + } } else if provider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) { - provider.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil, completionHandler: { (item, _) -> Void in + provider.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil) { (item, _) -> Void in let url = (item as? NSURL)!.host DispatchQueue.main.async { [weak self] in self?.extensionAction = .fillBrowser @@ -113,7 +113,7 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV self?.searchBar.becomeFirstResponder() self?.searchBarSearchButtonClicked((self?.searchBar)!) } - }) + } } } } @@ -157,7 +157,8 @@ class ExtensionViewController: UIViewController, UITableViewDataSource, UITableV let username = decryptedPassword.getUsernameForCompletion() let password = decryptedPassword.password - DispatchQueue.main.async { // prepare a dictionary to return + DispatchQueue.main.async { + // prepare a dictionary to return switch self.extensionAction { case .findLogin: let extensionItem = NSExtensionItem() diff --git a/passKit/Controllers/PasscodeLockViewController.swift b/passKit/Controllers/PasscodeLockViewController.swift index 68b5118..4b5b0fc 100644 --- a/passKit/Controllers/PasscodeLockViewController.swift +++ b/passKit/Controllers/PasscodeLockViewController.swift @@ -95,32 +95,34 @@ open class PasscodeLockViewController: UIViewController, UITextFieldDelegate { appIconView.layer.masksToBounds = true view?.addSubview(appIconView) - NSLayoutConstraint.activate([ - passcodeTextField.widthAnchor.constraint(equalToConstant: 250), - passcodeTextField.heightAnchor.constraint(equalToConstant: 40), - passcodeTextField.centerXAnchor.constraint(equalTo: view.centerXAnchor), - passcodeTextField.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -20), - // above passocde - appIconView.widthAnchor.constraint(equalToConstant: appIconSize), - appIconView.heightAnchor.constraint(equalToConstant: appIconSize), - appIconView.centerXAnchor.constraint(equalTo: view.centerXAnchor), - appIconView.bottomAnchor.constraint(equalTo: passcodeTextField.topAnchor, constant: -appIconSize), - // below passcode - biometryAuthButton.widthAnchor.constraint(equalToConstant: 250), - biometryAuthButton.heightAnchor.constraint(equalToConstant: 40), - biometryAuthButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), - biometryAuthButton.topAnchor.constraint(equalTo: passcodeTextField.bottomAnchor), - // cancel (top-left of the screen) - cancelButton.widthAnchor.constraint(equalToConstant: 150), - cancelButton.heightAnchor.constraint(equalToConstant: 40), - cancelButton.topAnchor.constraint(equalTo: view.safeTopAnchor), - cancelButton.leftAnchor.constraint(equalTo: view.safeLeftAnchor, constant: 20), - // bottom of the screen - forgotPasscodeButton.widthAnchor.constraint(equalToConstant: 250), - forgotPasscodeButton.heightAnchor.constraint(equalToConstant: 40), - forgotPasscodeButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), - forgotPasscodeButton.bottomAnchor.constraint(equalTo: view.safeBottomAnchor, constant: -40), - ]) + NSLayoutConstraint.activate( + [ + passcodeTextField.widthAnchor.constraint(equalToConstant: 250), + passcodeTextField.heightAnchor.constraint(equalToConstant: 40), + passcodeTextField.centerXAnchor.constraint(equalTo: view.centerXAnchor), + passcodeTextField.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -20), + // above passocde + appIconView.widthAnchor.constraint(equalToConstant: appIconSize), + appIconView.heightAnchor.constraint(equalToConstant: appIconSize), + appIconView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + appIconView.bottomAnchor.constraint(equalTo: passcodeTextField.topAnchor, constant: -appIconSize), + // below passcode + biometryAuthButton.widthAnchor.constraint(equalToConstant: 250), + biometryAuthButton.heightAnchor.constraint(equalToConstant: 40), + biometryAuthButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + biometryAuthButton.topAnchor.constraint(equalTo: passcodeTextField.bottomAnchor), + // cancel (top-left of the screen) + cancelButton.widthAnchor.constraint(equalToConstant: 150), + cancelButton.heightAnchor.constraint(equalToConstant: 40), + cancelButton.topAnchor.constraint(equalTo: view.safeTopAnchor), + cancelButton.leftAnchor.constraint(equalTo: view.safeLeftAnchor, constant: 20), + // bottom of the screen + forgotPasscodeButton.widthAnchor.constraint(equalToConstant: 250), + forgotPasscodeButton.heightAnchor.constraint(equalToConstant: 40), + forgotPasscodeButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + forgotPasscodeButton.bottomAnchor.constraint(equalTo: view.safeBottomAnchor, constant: -40), + ] + ) // dismiss keyboard when tapping anywhere let tap = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing)) @@ -147,10 +149,10 @@ open class PasscodeLockViewController: UIViewController, UITextFieldDelegate { // pop if presentingViewController?.presentedViewController == self { // if presented as modal - dismiss(animated: true, completion: { [weak self] in + dismiss(animated: true) { [weak self] in self?.dismissCompletionCallback?() completionHandler?() - }) + } } else { // if pushed in a navigation controller _ = navigationController?.popViewController(animated: true) @@ -190,30 +192,32 @@ open class PasscodeLockViewController: UIViewController, UITextFieldDelegate { @objc func forgotPasscodeButtonPressedAction(_: UIButton) { let alert = UIAlertController(title: "ResetPass".localize(), message: "ResetPassExplanation.".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "ErasePasswordStoreData".localize(), style: UIAlertAction.Style.destructive, handler: { [unowned self] (_) -> Void in - let myContext = LAContext() - var error: NSError? - // If the device passcode is not set, reset the app. - guard myContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else { - self.passwordStore.erase() - self.passcodeLockDidSucceed() - return - } - // If the device passcode is set, authentication is required. - myContext.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "ErasePasswordStoreData".localize()) { success, error in - if success { - DispatchQueue.main.async { - // User authenticated successfully, take appropriate action - self.passwordStore.erase() - self.passcodeLockDidSucceed() - } - } else { - DispatchQueue.main.async { - Utils.alert(title: "Error".localize(), message: error?.localizedDescription ?? "", controller: self, completion: nil) + alert.addAction( + UIAlertAction(title: "ErasePasswordStoreData".localize(), style: UIAlertAction.Style.destructive) { [unowned self] (_) -> Void in + let myContext = LAContext() + var error: NSError? + // If the device passcode is not set, reset the app. + guard myContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else { + self.passwordStore.erase() + self.passcodeLockDidSucceed() + return + } + // If the device passcode is set, authentication is required. + myContext.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "ErasePasswordStoreData".localize()) { success, error in + if success { + DispatchQueue.main.async { + // User authenticated successfully, take appropriate action + self.passwordStore.erase() + self.passcodeLockDidSucceed() + } + } else { + DispatchQueue.main.async { + Utils.alert(title: "Error".localize(), message: error?.localizedDescription ?? "", controller: self, completion: nil) + } } } } - })) + ) alert.addAction(UIAlertAction.dismiss()) present(alert, animated: true, completion: nil) } diff --git a/passKit/Helpers/FileManagerExtension.swift b/passKit/Helpers/FileManagerExtension.swift index a1aec6f..320658b 100644 --- a/passKit/Helpers/FileManagerExtension.swift +++ b/passKit/Helpers/FileManagerExtension.swift @@ -37,10 +37,12 @@ public extension FileManager { } // We have to enumerate all directory contents, including subdirectories. - let enumerator = self.enumerator(at: directoryURL, - includingPropertiesForKeys: prefetchedProperties, - options: FileManager.DirectoryEnumerationOptions(), - errorHandler: errorHandler) + let enumerator = self.enumerator( + at: directoryURL, + includingPropertiesForKeys: prefetchedProperties, + options: FileManager.DirectoryEnumerationOptions(), + errorHandler: errorHandler + ) precondition(enumerator != nil) // Start the traversal: diff --git a/passKit/Helpers/Utils.swift b/passKit/Helpers/Utils.swift index 18faeca..7b1d5d5 100644 --- a/passKit/Helpers/Utils.swift +++ b/passKit/Helpers/Utils.swift @@ -46,10 +46,12 @@ public enum Utils { let title = "Passphrase".localize() + " (\(keyID.suffix(8)))" let message = "FillInPgpPassphrase.".localize() let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction.ok { _ in - passphrase = alert.textFields?.first?.text ?? "" - sem.signal() - }) + alert.addAction( + UIAlertAction.ok { _ in + passphrase = alert.textFields?.first?.text ?? "" + sem.signal() + } + ) alert.addTextField { textField in textField.text = AppKeychain.shared.get(for: AppKeychain.getPGPKeyPassphraseKey(keyID: keyID)) ?? "" textField.isSecureTextEntry = true diff --git a/passKit/Models/PasswordStore.swift b/passKit/Models/PasswordStore.swift index 09e4629..adb27a3 100644 --- a/passKit/Models/PasswordStore.swift +++ b/passKit/Models/PasswordStore.swift @@ -62,7 +62,7 @@ public class PasswordStore { try! FileManager.default.createDirectory(atPath: Globals.documentPath, withIntermediateDirectories: true, attributes: nil) } container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: URL(fileURLWithPath: Globals.dbPath))] - container.loadPersistentStores(completionHandler: { _, error in + container.loadPersistentStores { _, error in if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. @@ -77,7 +77,7 @@ public class PasswordStore { */ fatalError("UnresolvedError".localize("\(error.localizedDescription), \(error.userInfo)")) } - }) + } return container.viewContext }() @@ -198,10 +198,12 @@ public class PasswordStore { gitPassword = nil gitSSHPrivateKeyPassphrase = nil do { - storeRepository = try GTRepository.clone(from: remoteRepoURL, - toWorkingDirectory: tempStoreURL, - options: options, - transferProgressBlock: transferProgressBlock) + storeRepository = try GTRepository.clone( + from: remoteRepoURL, + toWorkingDirectory: tempStoreURL, + options: options, + transferProgressBlock: transferProgressBlock + ) try fm.moveItem(at: tempStoreURL, to: storeURL) storeRepository = try GTRepository(url: storeURL) if (try storeRepository?.currentBranch().name) != branchName { @@ -375,10 +377,10 @@ public class PasswordStore { guard let storeRepository = storeRepository else { return "Unknown".localize() } - guard let blameHunks = try? storeRepository.blame(withFile: filename, options: nil).hunks, - let latestCommitTime = blameHunks.map({ - $0.finalSignature?.time?.timeIntervalSince1970 ?? 0 - }).max() else { + guard let blameHunks = try? storeRepository.blame(withFile: filename, options: nil).hunks else { + return "Unknown".localize() + } + guard let latestCommitTime = blameHunks.map({ $0.finalSignature?.time?.timeIntervalSince1970 ?? 0 }).max() else { return "Unknown".localize() } let lastCommitDate = Date(timeIntervalSince1970: latestCommitTime)