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