lint: delete trailing whitespaces

This commit is contained in:
Mingshen Sun 2018-12-09 16:59:07 -08:00
parent 2ba6917710
commit ed387069a4
No known key found for this signature in database
GPG key ID: 1F86BA2052FED3B4
59 changed files with 624 additions and 623 deletions

View file

@ -10,7 +10,7 @@ import UIKit
import passKit
class AboutRepositoryTableViewController: BasicStaticTableViewController {
private var needRefresh = false
private var indicator: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
@ -23,13 +23,13 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
indicator.center = CGPoint(x: view.bounds.midX, y: view.bounds.height * 0.382)
tableView.addSubview(indicator)
setTableData()
// all password store updates (including erase, discard) will trigger the refresh
NotificationCenter.default.addObserver(self, selector: #selector(setNeedRefresh), name: .passwordStoreUpdated, object: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if needRefresh {
@ -37,14 +37,14 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
needRefresh = false
}
}
private func setTableData() {
// clear current contents (if any)
self.tableData.removeAll(keepingCapacity: true)
self.tableView.reloadData()
indicator.startAnimating()
// reload the table
DispatchQueue.global(qos: .userInitiated).async {
let passwords = self.numberOfPasswordsString()
@ -52,7 +52,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
let localCommits = self.numberOfLocalCommitsString()
let lastSynced = self.lastSyncedTimeString()
let commits = self.numberOfPasswordsString()
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else {
return
@ -97,7 +97,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
formatter.timeStyle = .short
return formatter.string(from: date)
}
@objc func setNeedRefresh() {
needRefresh = true
}

View file

@ -9,21 +9,21 @@
import UIKit
class AboutTableViewController: BasicStaticTableViewController {
override func viewDidLoad() {
tableData = [
// section 0
[[.title: "Website", .action: "link", .link: "https://github.com/mssun/pass-ios.git"],
[.title: "Help", .action: "link", .link: "https://github.com/mssun/passforios/wiki"],
[.title: "Contact Developer", .action: "link", .link: "mailto:developer@passforios.mssun.me?subject=Pass%20for%20iOS"],],
// section 1,
[[.title: "Open Source Components", .action: "segue", .link: "showOpenSourceComponentsSegue"],
[.title: "Special Thanks", .action: "segue", .link: "showSpecialThanksSegue"],],
]
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == tableData.count - 1 {
let view = UIView()
@ -38,7 +38,7 @@ class AboutTableViewController: BasicStaticTableViewController {
}
return nil
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 1 {
return "Acknowledgements".uppercased()

View file

@ -27,7 +27,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
tableData[0][0][PasswordEditorCellKey.content] = defaultDirPrefix
super.viewDidLoad()
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "saveAddPasswordSegue" {
// check PGP key
@ -37,7 +37,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
return false
}
// check name
guard checkName() == true else {
return false
@ -45,7 +45,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
}
return true
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "saveAddPasswordSegue" {

View file

@ -17,7 +17,7 @@ class AdvancedSettingsTableViewController: UITableViewController {
@IBOutlet weak var eraseDataTableViewCell: UITableViewCell!
@IBOutlet weak var discardChangesTableViewCell: UITableViewCell!
let passwordStore = PasswordStore.shared
let encryptInASCIIArmoredSwitch: UISwitch = {
let uiSwitch = UISwitch()
uiSwitch.onTintColor = Globals.blue
@ -33,7 +33,7 @@ class AdvancedSettingsTableViewController: UITableViewController {
encryptInASCIIArmoredTableViewCell.selectionStyle = .none
setGitSignatureText()
}
private func setGitSignatureText() {
let gitSignatureName = passwordStore.gitSignatureForNow.name!
let gitSignatureEmail = passwordStore.gitSignatureForNow.email!
@ -77,17 +77,17 @@ class AdvancedSettingsTableViewController: UITableViewController {
} catch {
Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil)
}
}))
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.cancel, handler:nil))
self.present(alert, animated: true, completion: nil)
}
}
@objc func encryptInASCIIArmoredAction(_ sender: Any?) {
SharedDefaults[.encryptInArmored] = encryptInASCIIArmoredSwitch.isOn
}
@IBAction func saveGitConfigSetting(segue: UIStoryboardSegue) {
if let controller = segue.source as? GitConfigSettingTableViewController {
if let gitSignatureName = controller.nameTextField.text,

View file

@ -27,18 +27,18 @@ enum CellDataKey {
class BasicStaticTableViewController: UITableViewController, MFMailComposeViewControllerDelegate {
var tableData = [[Dictionary<CellDataKey, Any>]]()
var navigationItemTitle: String?
override func viewDidLoad() {
super.viewDidLoad()
if navigationItemTitle != nil {
navigationItem.title = navigationItemTitle
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return tableData.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData[section].count
}
@ -47,13 +47,13 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData = tableData[indexPath.section][indexPath.row]
let cellDataStyle = cellData[CellDataKey.style] as? CellDataStyle
var cell: UITableViewCell?
switch cellDataStyle ?? .defaultStyle {
case .value1:
cell = UITableViewCell(style: .value1, reuseIdentifier: "value1 cell")
@ -61,7 +61,7 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
default:
cell = UITableViewCell(style: .default, reuseIdentifier: "default cell")
}
if let detailText = cellData[CellDataKey.detailText] as? String {
cell?.detailTextLabel?.text = detailText
}
@ -71,17 +71,17 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
cell?.accessoryType = .disclosureIndicator
cell?.selectionStyle = .default
}
cell?.textLabel?.text = cellData[CellDataKey.title] as? String
return cell ?? UITableViewCell()
}
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
let cellData = tableData[indexPath.section][indexPath.row]
let selector = cellData[CellDataKey.detailDisclosureAction] as? Selector
perform(selector, with: cellData[CellDataKey.detailDisclosureData])
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cellData = tableData[indexPath.section][indexPath.row]
@ -116,7 +116,7 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
break
}
}
func sendEmail(toRecipients recipients: [String], subject: String) {
let mailVC = MFMailComposeViewController()
mailVC.mailComposeDelegate = self
@ -125,7 +125,7 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
mailVC.setMessageBody("", isHTML: false)
self.present(mailVC, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true)
}

View file

@ -13,7 +13,7 @@ import passKit
class CommitLogsTableViewController: UITableViewController {
var commits: [GTCommit] = []
let passwordStore = PasswordStore.shared
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(updateCommitLogs), name: .passwordStoreUpdated, object: nil)
@ -25,14 +25,14 @@ class CommitLogsTableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return commits.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "commitLogCell", for: indexPath)
let formatter = DateFormatter()
formatter.dateStyle = DateFormatter.Style.medium
formatter.timeStyle = .medium
let dateString = formatter.string(from: commits[indexPath.row].commitDate)
let author = cell.contentView.viewWithTag(200) as? UILabel
let dateLabel = cell.contentView.viewWithTag(201) as? UILabel
let messageLabel = cell.contentView.viewWithTag(202) as? UILabel
@ -41,12 +41,12 @@ class CommitLogsTableViewController: UITableViewController {
messageLabel?.text = commits[indexPath.row].message?.trimmed
return cell
}
@objc func updateCommitLogs() {
commits = getCommitLogs()
tableView.reloadData()
}
private func getCommitLogs() -> [GTCommit] {
do {
return try passwordStore.getRecentCommits(count: 20)

View file

@ -24,7 +24,7 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
tableData[1].append([.type: PasswordEditorCellType.memorablePasswordGeneratorCell])
super.viewDidLoad()
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "saveEditPasswordSegue" {
// check name
@ -34,7 +34,7 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
}
return true
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "saveEditPasswordSegue" {

View file

@ -19,7 +19,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
uiSwitch.addTarget(self, action: #selector(hideUnknownSwitchAction(_:)), for: UIControlEvents.valueChanged)
return uiSwitch
}()
let hideOTPSwitch: UISwitch = {
let uiSwitch = UISwitch()
uiSwitch.onTintColor = Globals.blue
@ -27,7 +27,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
uiSwitch.addTarget(self, action: #selector(hideOTPSwitchAction(_:)), for: UIControlEvents.valueChanged)
return uiSwitch
}()
let rememberPGPPassphraseSwitch: UISwitch = {
let uiSwitch = UISwitch()
uiSwitch.onTintColor = Globals.blue
@ -36,7 +36,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
uiSwitch.isOn = SharedDefaults[.isRememberPGPPassphraseOn]
return uiSwitch
}()
let rememberGitCredentialPassphraseSwitch: UISwitch = {
let uiSwitch = UISwitch()
uiSwitch.onTintColor = Globals.blue
@ -45,7 +45,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
uiSwitch.isOn = SharedDefaults[.isRememberGitCredentialPassphraseOn]
return uiSwitch
}()
let showFolderSwitch: UISwitch = {
let uiSwitch = UISwitch()
uiSwitch.onTintColor = Globals.blue
@ -59,12 +59,12 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
tableData = [
// section 0
[[.title: "About Repository", .action: "segue", .link: "showAboutRepositorySegue"],],
// section 1
[
[.title: "Password Generator Flavor", .action: "none", .style: CellDataStyle.value1],
],
// section 2
[
[.title: "Remember PGP Key Passphrase", .action: "none",],
@ -78,9 +78,9 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
]
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt: indexPath)
switch cell.textLabel!.text! {
@ -127,7 +127,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
super.tableView(tableView, didSelectRowAt: indexPath)
let cell = tableView.cellForRow(at: indexPath)!
@ -136,7 +136,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
showPasswordGeneratorFlavorActionSheet(sourceCell: cell)
}
}
func showPasswordGeneratorFlavorActionSheet(sourceCell: UITableViewCell) {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
var randomFlavorActionTitle = ""
@ -152,12 +152,12 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
SharedDefaults[.passwordGeneratorFlavor] = "Random"
sourceCell.detailTextLabel?.text = "Random"
}
let appleFlavorAction = UIAlertAction(title: appleFlavorActionTitle, style: .default) { _ in
SharedDefaults[.passwordGeneratorFlavor] = "Apple"
sourceCell.detailTextLabel?.text = "Apple"
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
optionMenu.addAction(randomFlavorAction)
optionMenu.addAction(appleFlavorAction)
@ -166,37 +166,37 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
optionMenu.popoverPresentationController?.sourceRect = sourceCell.bounds
self.present(optionMenu, animated: true, completion: nil)
}
@objc func tapHideUnknownSwitchDetailButton(_ sender: Any?) {
let alertMessage = "Only \"key: value\" format in additional fields is supported. Unsupported fields will be given \"unknown\" keys. Turn on this switch to hide unsupported fields."
let alertTitle = "Hide Unknown Fields"
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
}
@objc func tapHideOTPSwitchDetailButton(_ sender: Any?) {
let keywordsString = Constants.OTP_KEYWORDS.joined(separator: ",")
let alertMessage = "Turn on this switch to hide the fields related to one time passwords (i.e., \(keywordsString))."
let alertTitle = "Hide One Time Password Fields"
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
}
@objc func hideUnknownSwitchAction(_ sender: Any?) {
SharedDefaults[.isHideUnknownOn] = hideUnknownSwitch.isOn
NotificationCenter.default.post(name: .passwordDetailDisplaySettingChanged, object: nil)
}
@objc func hideOTPSwitchAction(_ sender: Any?) {
SharedDefaults[.isHideOTPOn] = hideOTPSwitch.isOn
NotificationCenter.default.post(name: .passwordDetailDisplaySettingChanged, object: nil)
}
@objc func rememberPGPPassphraseSwitchAction(_ sender: Any?) {
SharedDefaults[.isRememberPGPPassphraseOn] = rememberPGPPassphraseSwitch.isOn
if rememberPGPPassphraseSwitch.isOn == false {
passwordStore.pgpKeyPassphrase = nil
}
}
@objc func rememberGitCredentialPassphraseSwitchAction(_ sender: Any?) {
SharedDefaults[.isRememberGitCredentialPassphraseOn] = rememberGitCredentialPassphraseSwitch.isOn
if rememberGitCredentialPassphraseSwitch.isOn == false {
@ -204,10 +204,10 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
passwordStore.gitPassword = nil
}
}
@objc func showFolderSwitchAction(_ sender: Any?) {
SharedDefaults[.isShowFolderOn] = showFolderSwitch.isOn
NotificationCenter.default.post(name: .passwordDisplaySettingChanged, object: nil)
}
}

View file

@ -12,21 +12,21 @@ import passKit
class GitConfigSettingTableViewController: UITableViewController {
let passwordStore = PasswordStore.shared
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var emailTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
let signature = passwordStore.gitSignatureForNow
nameTextField.placeholder = signature.name
emailTextField.placeholder = signature.email
nameTextField.text = SharedDefaults[.gitSignatureName]
emailTextField.text = SharedDefaults[.gitSignatureEmail]
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "saveGitConfigSettingSegue" {
let name = nameTextField.text!.isEmpty ? Globals.gitSignatureDefaultName : nameTextField.text!

View file

@ -12,10 +12,10 @@ import passKit
class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextViewDelegate, QRScannerControllerDelegate {
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
@IBOutlet weak var scanPrivateKeyCell: UITableViewCell!
var gitSSHPrivateKeyPassphrase: String?
let passwordStore = PasswordStore.shared
class ScannedSSHKey {
static let maxNumberOfGif = 100
var numberOfSegments = 0
@ -24,7 +24,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
var message = ""
var hasStarted = false
var isDone = false
func reset() {
numberOfSegments = 0
previousSegment = ""
@ -33,14 +33,14 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
hasStarted = false
isDone = false
}
func addSegment(segment: String) {
// skip duplicated segments
guard segment != previousSegment else {
return
}
previousSegment = segment
// check whether we have found the first block
if hasStarted == false {
hasStarted = segment.contains("-----BEGIN")
@ -48,38 +48,38 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
guard hasStarted == true else {
return
}
// check the number of segments
numberOfSegments = numberOfSegments + 1
guard numberOfSegments <= ScannedSSHKey.maxNumberOfGif else {
key = "Too many QR codes"
return
}
// update full text and check whether we are done
key.append(segment)
if let index1 = key.range(of: "-----END")?.lowerBound,
let _ = key.suffix(from: index1).range(of: "KEY-----")?.lowerBound {
isDone = true
}
// update message
message = "\(numberOfSegments) scanned QR codes."
}
}
var scanned = ScannedSSHKey()
override func viewDidLoad() {
super.viewDidLoad()
armorPrivateKeyTextView.text = SharedDefaults[.gitSSHPrivateKeyArmor]
armorPrivateKeyTextView.delegate = self
scanPrivateKeyCell?.textLabel?.text = "Scan Private Key QR Codes"
scanPrivateKeyCell?.textLabel?.textColor = Globals.blue
scanPrivateKeyCell?.selectionStyle = .default
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
}
@IBAction func doneButtonTapped(_ sender: Any) {
SharedDefaults[.gitSSHPrivateKeyArmor] = armorPrivateKeyTextView.text
do {
@ -90,7 +90,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
SharedDefaults[.gitSSHKeySource] = "armor"
self.navigationController!.popViewController(animated: true)
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == UIPasteboard.general.string {
// user pastes something, do the copy here again and clear the pasteboard in 45s
@ -98,7 +98,7 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
}
return true
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
if selectedCell == scanPrivateKeyCell {
@ -107,8 +107,8 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
}
tableView.deselectRow(at: indexPath, animated: true)
}
// MARK: - QRScannerControllerDelegate Methods
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
scanned.addSegment(segment: line)
@ -118,12 +118,12 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
return (accept: false, message: scanned.message)
}
}
// MARK: - QRScannerControllerDelegate Methods
func handleScannedOutput(line: String) {
armorPrivateKeyTextView.text = scanned.key
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSSHScannerSegue" {
if let navController = segue.destination as? UINavigationController {
@ -135,9 +135,9 @@ class GitSSHKeyArmorSettingTableViewController: UITableViewController, UITextVie
}
}
}
@IBAction private func cancelSSHScanner(segue: UIStoryboardSegue) {
}
}

View file

@ -37,7 +37,7 @@ class GitServerSettingTableViewController: UITableViewController {
sshKeyCheckView.isHidden = true
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Grey out ssh option if ssh_key is not present
@ -55,30 +55,30 @@ class GitServerSettingTableViewController: UITableViewController {
checkAuthenticationMethod(method: authenticationMethod)
authSSHKeyCell.accessoryType = .detailButton
}
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
if cell == authSSHKeyCell {
showSSHKeyActionSheet()
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
view.endEditing(true)
}
private func cloneAndSegueIfSuccess() {
// try to clone
let gitRepostiroyURL = gitURLTextField.text!.trimmed
let username = usernameTextField.text!
let auth = authenticationMethod
SVProgressHUD.setDefaultMaskType(.black)
SVProgressHUD.setDefaultStyle(.light)
SVProgressHUD.show(withStatus: "Prepare Repository")
@ -160,15 +160,15 @@ class GitServerSettingTableViewController: UITableViewController {
checkAuthenticationMethod(method: authenticationMethod)
tableView.deselectRow(at: indexPath, animated: true)
}
@IBAction func save(_ sender: Any) {
// some sanity checks
guard let gitURL = URL(string: gitURLTextField.text!) else {
Utils.alert(title: "Cannot Save", message: "Please set the Git repository URL.", controller: self, completion: nil)
return
}
switch gitURL.scheme {
case let val where val == "https":
break
@ -188,7 +188,7 @@ class GitServerSettingTableViewController: UITableViewController {
Utils.alert(title: "Cannot Save", message: "Please specify the scheme of the Git repository URL (https or ssh).", controller: self, completion: nil)
return
}
if passwordStore.repositoryExisted() {
let alert = UIAlertController(title: "Overwrite?", message: "This operation will overwrite your current password store data (repository). Data on your remote server will not be affected.", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Overwrite", style: UIAlertActionStyle.destructive, handler: { _ in
@ -202,13 +202,13 @@ class GitServerSettingTableViewController: UITableViewController {
cloneAndSegueIfSuccess()
}
}
func showSSHKeyActionSheet() {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
var urlActionTitle = "Download from URL"
var armorActionTitle = "ASCII-Armor Encrypted Key"
var fileActionTitle = "iTunes File Sharing"
if SharedDefaults[.gitSSHKeySource] == "url" {
urlActionTitle = "\(urlActionTitle)"
} else if SharedDefaults[.gitSSHKeySource] == "armor" {
@ -225,7 +225,7 @@ class GitServerSettingTableViewController: UITableViewController {
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
optionMenu.addAction(urlAction)
optionMenu.addAction(armorAction)
if passwordStore.gitSSHKeyExists(inFileSharing: true) {
// might keys updated via iTunes, or downloaded/pasted inside the app
fileActionTitle.append(" (Import)")
@ -249,7 +249,7 @@ class GitServerSettingTableViewController: UITableViewController {
}
optionMenu.addAction(fileAction)
}
if SharedDefaults[.gitSSHKeySource] != nil {
let deleteAction = UIAlertAction(title: "Remove Git SSH Keys", style: .destructive) { _ in
self.passwordStore.removeGitSSHKeys()
@ -266,7 +266,7 @@ class GitServerSettingTableViewController: UITableViewController {
optionMenu.popoverPresentationController?.sourceRect = authSSHKeyCell.bounds
self.present(optionMenu, animated: true, completion: nil)
}
private func requestGitPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? {
let sem = DispatchSemaphore(value: 0)
var password: String?
@ -277,7 +277,7 @@ class GitServerSettingTableViewController: UITableViewController {
case .ssh:
message = "Please fill in the passphrase of your SSH key."
}
DispatchQueue.main.async {
SVProgressHUD.dismiss()
let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert)
@ -295,7 +295,7 @@ class GitServerSettingTableViewController: UITableViewController {
})
self.present(alert, animated: true, completion: nil)
}
let _ = sem.wait(timeout: .distantFuture)
return password
}

View file

@ -33,7 +33,7 @@ class OpenSourceComponentsTableViewController: BasicStaticTableViewController {
"https://github.com/SVProgressHUD/SVProgressHUD",
"https://github.com/SVProgressHUD/SVProgressHUD/blob/master/LICENSE.txt"],
]
override func viewDidLoad() {
tableData.append([])
for item in openSourceComponents {
@ -43,7 +43,7 @@ class OpenSourceComponentsTableViewController: BasicStaticTableViewController {
}
super.viewDidLoad()
}
@objc func actOnDetailDisclosureButton(_ sender: Any?) {
if let link = sender as? String {
let svc = SFSafariViewController(url: URL(string: link)!, entersReaderIfAvailable: false)

View file

@ -14,10 +14,10 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
@IBOutlet weak var armorPrivateKeyTextView: UITextView!
@IBOutlet weak var scanPublicKeyCell: UITableViewCell!
@IBOutlet weak var scanPrivateKeyCell: UITableViewCell!
var pgpPassphrase: String?
let passwordStore = PasswordStore.shared
class ScannedPGPKey {
static let maxNumberOfGif = 100
enum KeyType {
@ -30,7 +30,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
var message = ""
var hasStarted = false
var isDone = false
func reset(keytype: KeyType) {
self.keyType = keytype
numberOfSegments = 0
@ -40,14 +40,14 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
hasStarted = false
isDone = false
}
func addSegment(segment: String) {
// skip duplicated segments
guard segment != previousSegment else {
return
}
previousSegment = segment
// check whether we have found the first block
if hasStarted == false {
let findPublic = segment.contains("-----BEGIN PGP PUBLIC KEY BLOCK-----")
@ -68,32 +68,32 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
guard hasStarted == true else {
return
}
// check the number of segments
numberOfSegments = numberOfSegments + 1
guard numberOfSegments <= ScannedPGPKey.maxNumberOfGif else {
key = "Too many QR codes"
return
}
// update full text and check whether we are done
key.append(segment)
if key.contains("-----END PGP PUBLIC KEY BLOCK-----") || key.contains("-----END PGP PRIVATE KEY BLOCK-----") {
isDone = true
}
// update message
message = "\(numberOfSegments) scanned QR codes."
}
}
var scanned = ScannedPGPKey()
override func viewDidLoad() {
super.viewDidLoad()
armorPublicKeyTextView.text = SharedDefaults[.pgpPublicKeyArmor]
armorPrivateKeyTextView.text = SharedDefaults[.pgpPrivateKeyArmor]
pgpPassphrase = passwordStore.pgpKeyPassphrase
scanPublicKeyCell?.textLabel?.text = "Scan Public Key QR Codes"
scanPublicKeyCell?.textLabel?.textColor = Globals.blue
scanPublicKeyCell?.selectionStyle = .default
@ -104,7 +104,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
scanPrivateKeyCell?.selectionStyle = .default
scanPrivateKeyCell?.accessoryType = .disclosureIndicator
}
@IBAction func save(_ sender: Any) {
guard armorPublicKeyTextView.text.isEmpty == false else {
Utils.alert(title: "Cannot Save", message: "Please set public key first.", controller: self, completion: nil)
@ -138,7 +138,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
})
self.present(savePassphraseAlert, animated: true, completion: nil)
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == UIPasteboard.general.string {
// user pastes something, do the copy here again and clear the pasteboard in 45s
@ -146,7 +146,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
}
return true
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
if selectedCell == scanPublicKeyCell {
@ -158,7 +158,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
}
tableView.deselectRow(at: indexPath, animated: true)
}
// MARK: - QRScannerControllerDelegate Methods
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
scanned.addSegment(segment: line)
@ -168,7 +168,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
return (accept: false, message: scanned.message)
}
}
// MARK: - QRScannerControllerDelegate Methods
func handleScannedOutput(line: String) {
switch scanned.keyType {
@ -178,7 +178,7 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe
armorPrivateKeyTextView.text = scanned.key
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showPGPScannerSegue" {
if let navController = segue.destination as? UINavigationController {

View file

@ -15,7 +15,7 @@ class PGPKeySettingTableViewController: UITableViewController {
@IBOutlet weak var pgpPrivateKeyURLTextField: UITextField!
var pgpPassphrase: String?
let passwordStore = PasswordStore.shared
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
@ -23,7 +23,7 @@ class PGPKeySettingTableViewController: UITableViewController {
pgpPrivateKeyURLTextField.text = SharedDefaults[.pgpPrivateKeyURL]?.absoluteString
pgpPassphrase = passwordStore.pgpKeyPassphrase
}
private func validatePGPKeyURL(input: String?) -> Bool {
guard let path = input, let url = URL(string: path) else {
Utils.alert(title: "Cannot Save PGP Key", message: "Please set PGP Key URL first.", controller: self, completion: nil)
@ -35,7 +35,7 @@ class PGPKeySettingTableViewController: UITableViewController {
}
return true
}
@IBAction func save(_ sender: Any) {
guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true,
validatePGPKeyURL(input: pgpPrivateKeyURLTextField.text) == true else {
@ -65,6 +65,6 @@ class PGPKeySettingTableViewController: UITableViewController {
})
self.present(savePassphraseAlert, animated: true, completion: nil)
}
}

View file

@ -18,7 +18,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
private var oneTimePasswordIndexPath : IndexPath?
private var shouldPopCurrentView = false
private let passwordStore = PasswordStore.shared
private lazy var editUIBarButtonItem: UIBarButtonItem = {
let uiBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit(_:)))
return uiBarButtonItem
@ -31,18 +31,18 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
title = ""
content = ""
}
init(title: String) {
self.title = title
self.content = ""
}
init(title: String, content: String) {
self.title = title
self.content = content
}
}
private struct TableSection {
var type: PasswordDetailTableViewControllerSectionType
var header: String?
@ -52,56 +52,56 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
header = nil
item = [TableCell]()
}
init(type: PasswordDetailTableViewControllerSectionType, header: String) {
self.init(type: type)
self.header = header
}
}
private var tableData = Array<TableSection>()
private enum PasswordDetailTableViewControllerSectionType {
case name, main, addition, misc
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "LabelTableViewCell", bundle: nil), forCellReuseIdentifier: "labelCell")
tableView.register(UINib(nibName: "PasswordDetailTitleTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordDetailTitleTableViewCell")
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(PasswordDetailTableViewController.tapMenu(recognizer:)))
tapGesture.cancelsTouchesInView = false
tableView.addGestureRecognizer(tapGesture)
tapGesture.delegate = self
tableView.contentInset = UIEdgeInsetsMake(-36, 0, 44, 0);
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 52
editUIBarButtonItem.isEnabled = false
navigationItem.rightBarButtonItem = editUIBarButtonItem
if #available(iOS 11.0, *) {
navigationItem.largeTitleDisplayMode = .never
}
if let imageData = passwordEntity?.getImage() {
let image = UIImage(data: imageData as Data)
passwordImage = image
}
self.decryptThenShowPassword()
self.setupOneTimePasswordAutoRefresh()
// pop the current view because this password might be "discarded"
NotificationCenter.default.addObserver(self, selector: #selector(setShouldPopCurrentView), name: .passwordStoreChangeDiscarded, object: nil)
// reset the data table if some password (maybe another one) has been updated
NotificationCenter.default.addObserver(self, selector: #selector(decryptThenShowPassword), name: .passwordStoreUpdated, object: nil)
// reset the data table if the disaply settings have been changed
NotificationCenter.default.addObserver(self, selector: #selector(decryptThenShowPassword), name: .passwordDetailDisplaySettingChanged, object: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if self.shouldPopCurrentView {
@ -112,7 +112,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
self.present(alert, animated: true, completion: nil)
}
}
private func requestPGPKeyPassphrase() -> String {
let sem = DispatchSemaphore(value: 0)
var passphrase = ""
@ -134,7 +134,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
return passphrase
}
@objc private func decryptThenShowPassword() {
guard let passwordEntity = passwordEntity else {
Utils.alert(title: "Cannot Show Password", message: "The password does not exist.", controller: self, handler: {(UIAlertAction) -> Void in
@ -166,7 +166,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
self.showPassword()
}
}
private func showPassword() {
DispatchQueue.main.async { [weak self] in
self?.setTableData()
@ -179,7 +179,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
}
}
private func setupOneTimePasswordAutoRefresh() {
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
[weak self] timer in
@ -204,19 +204,19 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
}
}
@objc private func pressEdit(_ sender: Any?) {
performSegue(withIdentifier: "editPasswordSegue", sender: self)
}
@objc private func setShouldPopCurrentView() {
self.shouldPopCurrentView = true
}
@IBAction private func cancelEditPassword(segue: UIStoryboardSegue) {
}
@IBAction private func saveEditPassword(segue: UIStoryboardSegue) {
if self.password!.changed != 0 {
SVProgressHUD.show(withStatus: "Saving")
@ -231,7 +231,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
SVProgressHUD.dismiss(withDelay: 1)
}
}
@IBAction private func deletePassword(segue: UIStoryboardSegue) {
do {
try passwordStore.delete(passwordEntity: passwordEntity!)
@ -243,7 +243,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
private func setTableData() {
self.tableData = Array<TableSection>()
// name section
var section = TableSection(type: .name)
section.item.append(TableCell())
@ -261,9 +261,9 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
section.item.append(TableCell(title: "password", content: password.password))
tableData.append(section)
// addition section
// show one time password
if password.otpType != .none {
if let (title, otp) = self.password?.getOtpStrings() {
@ -273,7 +273,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
oneTimePasswordIndexPath = IndexPath(row: 0, section: tableData.count - 1)
}
}
// show additional information
let filteredAdditionKeys = password.getFilteredAdditions()
if filteredAdditionKeys.count > 0 {
@ -283,14 +283,14 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
})
tableData.append(section)
}
// misc section
section = TableSection(type: .misc)
section.item.append(TableCell(title: "Show Raw"))
tableData.append(section)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "editPasswordSegue" {
if let controller = segue.destination as? UINavigationController {
@ -306,7 +306,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
}
}
private func updatePasswordImage(urlString: String) {
var newUrlString = urlString
if urlString.lowercased().hasPrefix("http://") {
@ -321,7 +321,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
// if a url does not start with http or https, try to add https
newUrlString = "https://\(urlString)"
}
try? FavIcon.downloadPreferred(newUrlString) { [weak self] result in
if case let .success(image) = result {
let indexPath = IndexPath(row: 0, section: 0)
@ -334,7 +334,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
}
}
@objc private func tapMenu(recognizer: UITapGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.ended {
let tapLocation = recognizer.location(in: self.tableView)
@ -353,17 +353,17 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if touch.view!.isKind(of: UIButton.classForCoder()) {
return false
}
return true
}
@IBAction func back(segue:UIStoryboardSegue) {
}
func getNextHOTP() {
guard password != nil, passwordEntity != nil, password?.otpType == .hotp else {
DispatchQueue.main.async {
@ -371,12 +371,12 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
return;
}
// copy HOTP to pasteboard (will update counter)
if let plainPassword = password!.getNextHotp() {
SecurePasteboard.shared.copy(textToCopy: plainPassword)
}
// commit the change of HOTP counter
if password!.changed != 0 {
do {
@ -465,11 +465,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
detailTextLabel.textColor = .gray
detailTextLabel.text = "\(numberOfHiddenFields) hidden field\(numberOfHiddenFields > 1 ? "s" : "")"
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return tableData[section].header
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == tableData.count - 1 {
let view = UIView()
@ -484,13 +484,13 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
return nil
}
override func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) {
if action == #selector(copy(_:)) {
SecurePasteboard.shared.copy(textToCopy: tableData[indexPath.section].item[indexPath.row].content)
}
}
override func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
let section = tableData[indexPath.section]
switch(section.type) {
@ -500,11 +500,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
return false
}
}
override func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let section = tableData[indexPath.section]
if section.type == .misc {

View file

@ -20,21 +20,21 @@ enum PasswordEditorCellKey {
}
class PasswordEditorTableViewController: UITableViewController, FillPasswordTableViewCellDelegate, PasswordSettingSliderTableViewCellDelegate, QRScannerControllerDelegate, UITextFieldDelegate, UITextViewDelegate, SFSafariViewControllerDelegate {
var tableData = [
[Dictionary<PasswordEditorCellKey, Any>]
]()
var password: Password?
private var navigationItemTitle: String?
private var sectionHeaderTitles = ["name", "password", "additions",""].map {$0.uppercased()}
private var sectionFooterTitles = ["", "", "Use \"key: value\" format for additional fields.", ""]
private let nameSection = 0
private let passwordSection = 1
private let additionsSection = 2
private var hidePasswordSettings = true
var nameCell: TextFieldTableViewCell?
var fillPasswordCell: FillPasswordTableViewCell?
private var passwordLengthCell: SliderTableViewCell?
@ -42,39 +42,39 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
private var deletePasswordCell: UITableViewCell?
private var scanQRCodeCell: UITableViewCell?
private var memorablePasswordGeneratorCell: UITableViewCell?
override func loadView() {
super.loadView()
deletePasswordCell = UITableViewCell(style: .default, reuseIdentifier: "default")
deletePasswordCell!.textLabel?.text = "Delete Password"
deletePasswordCell!.textLabel?.textColor = Globals.red
deletePasswordCell?.selectionStyle = .default
scanQRCodeCell = UITableViewCell(style: .default, reuseIdentifier: "default")
scanQRCodeCell?.textLabel?.text = "Add One-Time Password"
scanQRCodeCell?.textLabel?.textColor = Globals.blue
scanQRCodeCell?.selectionStyle = .default
scanQRCodeCell?.accessoryType = .disclosureIndicator
memorablePasswordGeneratorCell = UITableViewCell(style: .default, reuseIdentifier: "default")
memorablePasswordGeneratorCell?.textLabel?.text = "Get a Memorable One: xkpasswd"
memorablePasswordGeneratorCell?.textLabel?.textColor = Globals.blue
memorablePasswordGeneratorCell?.selectionStyle = .default
memorablePasswordGeneratorCell?.accessoryType = .disclosureIndicator
}
override func viewDidLoad() {
super.viewDidLoad()
if navigationItemTitle != nil {
navigationItem.title = navigationItemTitle
}
tableView.register(UINib(nibName: "TextFieldTableViewCell", bundle: nil), forCellReuseIdentifier: "textFieldCell")
tableView.register(UINib(nibName: "TextViewTableViewCell", bundle: nil), forCellReuseIdentifier: "textViewCell")
tableView.register(UINib(nibName: "FillPasswordTableViewCell", bundle: nil), forCellReuseIdentifier: "fillPasswordCell")
tableView.register(UINib(nibName: "SliderTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordLengthCell")
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 48
self.tableView.sectionFooterHeight = UITableViewAutomaticDimension;
@ -83,10 +83,10 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
override func viewDidLayoutSubviews() {
additionsCell?.contentTextView.setContentOffset(.zero, animated: false)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData = tableData[indexPath.section][indexPath.row]
switch cellData[PasswordEditorCellKey.type] as! PasswordEditorCellType {
case .nameCell:
nameCell = tableView.dequeueReusableCell(withIdentifier: "textFieldCell", for: indexPath) as? TextFieldTableViewCell
@ -132,7 +132,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
return scanQRCodeCell!
}
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44
}
@ -153,11 +153,11 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionHeaderTitles[section]
}
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return sectionFooterTitles[section]
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
if selectedCell == deletePasswordCell {
@ -175,12 +175,12 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
let vc = SFSafariViewController(url: url, entersReaderIfAvailable: false)
vc.delegate = self
present(vc, animated: true)
}
}
tableView.deselectRow(at: indexPath, animated: true)
}
// generate password, copy to pasteboard, and set the cell
// check whether the current password looks like an OTP field
func generateAndCopyPassword() {
@ -195,23 +195,23 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
self.generateAndCopyPasswordNoOtpCheck()
}
}
// generate the password, don't care whether the original line is otp
func generateAndCopyPasswordNoOtpCheck() {
// show password settings (e.g., the length slider)
showPasswordSettings()
let length = passwordLengthCell?.roundedValue ?? 0
let plainPassword = PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]).generatePassword(length: length)
SecurePasteboard.shared.copy(textToCopy: plainPassword)
// update tableData so to make sure reloadData() works correctly
tableData[passwordSection][0][PasswordEditorCellKey.content] = plainPassword
// update cell manually, no need to call reloadData()
fillPasswordCell?.setContent(content: plainPassword)
}
// show password settings (e.g., the length slider)
func showPasswordSettings() {
if hidePasswordSettings == true {
@ -219,13 +219,13 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
tableView.reloadSections([passwordSection], with: .fade)
}
}
// show/hide password settings (e.g., the length slider)
func showHidePasswordSettings() {
hidePasswordSettings = !hidePasswordSettings
tableView.reloadSections([passwordSection], with: .fade)
}
func insertScannedOTPFields(_ otpauth: String) {
// update tableData
var additionsString = ""
@ -235,11 +235,11 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
additionsString = otpauth
}
tableData[additionsSection][0][PasswordEditorCellKey.content] = additionsString
// reload the additions cell
additionsCell?.setContent(content: additionsString)
}
// MARK: - QRScannerControllerDelegate Methods
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
if let url = URL(string: line), let _ = Token(url: url) {
@ -248,12 +248,12 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
return (accept: false, message: "Invalid token URL")
}
}
// MARK: - QRScannerControllerDelegate Methods
func handleScannedOutput(line: String) {
insertScannedOTPFields(line)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showQRScannerSegue" {
if let navController = segue.destination as? UINavigationController {
@ -265,7 +265,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
}
}
}
// update tableData so to make sure reloadData() works correctly
func textFieldDidEndEditing(_ textField: UITextField) {
if textField == nameCell?.contentTextField {
@ -277,48 +277,48 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
}
}
}
// update tableData so to make sure reloadData() works correctly
func textViewDidEndEditing(_ textView: UITextView) {
if textView == additionsCell?.contentTextView {
tableData[additionsSection][0][PasswordEditorCellKey.content] = additionsCell?.getContent()
}
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == fillPasswordCell?.contentTextField {
// show password generation settings automatically
showPasswordSettings()
}
}
func getNameURL() -> (String, URL) {
let encodedName = (nameCell?.getContent()?.stringByAddingPercentEncodingForRFC3986())!
let name = URL(string: encodedName)!.lastPathComponent
let url = URL(string: encodedName)!.appendingPathExtension("gpg")
return (name, url)
}
func checkName() -> Bool {
// the name field should not be empty
guard let name = nameCell?.getContent(), name.isEmpty == false else {
Utils.alert(title: "Cannot Save", message: "Please fill in the name.", controller: self, completion: nil)
return false
}
// the name should not start with /
guard name.hasPrefix("/") == false else {
Utils.alert(title: "Cannot Save", message: "Please remove the prefix \"/\" from your password name.", controller: self, completion: nil)
return false
}
// the name field should be a valid url
guard let path = name.stringByAddingPercentEncodingForRFC3986(),
var passwordURL = URL(string: path) else {
Utils.alert(title: "Cannot Save", message: "Password name is invalid.", controller: self, completion: nil)
return false
}
// check whether we can parse the filename (be consistent with PasswordStore::addPasswordEntities)
var previousPathLength = Int.max
while passwordURL.path != "." {
@ -329,10 +329,10 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
}
previousPathLength = passwordURL.path.count
}
return true
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
let copiedLinesSplit = UIPasteboard.general.string?.components(separatedBy: CharacterSet.whitespacesAndNewlines).filter({ !$0.isEmpty })
if copiedLinesSplit?.count ?? 0 > 0 {
@ -353,5 +353,5 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
self.present(alert, animated: true, completion: nil)
}
}
}

View file

@ -27,13 +27,13 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
private var filteredPasswordsTableEntries: [PasswordsTableEntry] = []
private var parentPasswordEntity: PasswordEntity? = nil
private let passwordStore = PasswordStore.shared
private var tapTabBarTime: TimeInterval = 0
private var sections = [(title: String, entries: [PasswordsTableEntry])]()
private var searchActive : Bool = false
private lazy var searchController: UISearchController = {
let uiSearchController = UISearchController(searchResultsController: nil)
uiSearchController.searchResultsUpdater = self
@ -59,7 +59,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
let backUIBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(self.backAction(_:)))
return backUIBarButtonItem
}()
private lazy var transitionFromRight: CATransition = {
let transition = CATransition()
transition.type = kCATransitionPush
@ -69,7 +69,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
transition.subtype = kCATransitionFromRight
return transition
}()
private lazy var transitionFromLeft: CATransition = {
let transition = CATransition()
transition.type = kCATransitionPush
@ -81,7 +81,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}()
@IBOutlet weak var tableView: UITableView!
private func initPasswordsTableEntries(parent: PasswordEntity?) {
passwordsTableEntries.removeAll()
passwordsTableAllEntries.removeAll()
@ -102,9 +102,9 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
parentPasswordEntity = parent
}
@IBAction func cancelAddPassword(segue: UIStoryboardSegue) {
}
@IBAction func saveAddPassword(segue: UIStoryboardSegue) {
if let controller = segue.source as? AddPasswordTableViewController {
@ -127,7 +127,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
}
private func syncPasswords() {
guard passwordStore.repositoryExisted() else {
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800)) {
@ -190,17 +190,17 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if SharedDefaults[.isShowFolderOn] {
searchController.searchBar.scopeButtonTitles = ["Current", "All"]
} else {
searchController.searchBar.scopeButtonTitles = nil
}
}
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchBar.delegate = self
@ -220,22 +220,22 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
tableView.refreshControl = syncControl
SVProgressHUD.setDefaultMaskType(.black)
tableView.register(UINib(nibName: "PasswordWithFolderTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordWithFolderTableViewCell")
// initialize the password table
reloadTableView(parent: nil)
// reset the data table if some password (maybe another one) has been updated
NotificationCenter.default.addObserver(self, selector: #selector(actOnReloadTableViewRelatedNotification), name: .passwordStoreUpdated, object: nil)
// reset the data table if the disaply settings have been changed
NotificationCenter.default.addObserver(self, selector: #selector(actOnReloadTableViewRelatedNotification), name: .passwordDisplaySettingChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(actOnSearchNotification), name: .passwordSearch, object: nil)
// listen to the swipe back guesture
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeRight.direction = UISwipeGestureRecognizerDirection.right
self.view.addGestureRecognizer(swipeRight)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tabBarController!.delegate = self
@ -243,7 +243,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
tableView.deselectRow(at: path, animated: false)
}
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
guard #available(iOS 11, *) else {
@ -252,21 +252,21 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
return
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].entries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(_:)))
longPressGestureRecognizer.minimumPressDuration = 0.6
if SharedDefaults[.isShowFolderOn] && searchController.searchBar.selectedScopeButtonIndex == 0{
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordTableViewCell", for: indexPath)
let entry = getPasswordEntry(by: indexPath)
if entry.passwordEntity!.synced {
cell.textLabel?.text = entry.title
@ -299,11 +299,11 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
private func getPasswordEntry(by indexPath: IndexPath) -> PasswordsTableEntry {
return sections[indexPath.section].entries[indexPath.row]
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let entry = getPasswordEntry(by: indexPath)
if !entry.isDir {
@ -318,7 +318,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
reloadTableView(parent: entry.passwordEntity, anim: transitionFromRight)
}
}
@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
// swipe right -> swipe back
@ -327,7 +327,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
}
@objc func backAction(_ sender: Any?) {
guard SharedDefaults[.isShowFolderOn] else { return }
var anim: CATransition? = transitionFromLeft
@ -336,7 +336,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
reloadTableView(parent: parentPasswordEntity?.parent, anim: anim)
}
@objc func longPressAction(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began {
let touchPoint = gesture.location(in: tableView)
@ -345,7 +345,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].title
}
@ -357,11 +357,11 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
return index
}
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
decryptThenCopyPassword(from: indexPath)
}
private func requestPGPKeyPassphrase() -> String {
let sem = DispatchSemaphore(value: 0)
var passphrase = ""
@ -389,7 +389,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
return passphrase
}
private func decryptThenCopyPassword(from indexPath: IndexPath) {
guard self.passwordStore.privateKey != nil else {
Utils.alert(title: "Cannot Copy Password", message: "PGP Key is not set. Please set your PGP Key first.", controller: self, completion: nil)
@ -418,39 +418,39 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
}
private func generateSections(item: [PasswordsTableEntry]) {
let collation = UILocalizedIndexedCollation.current()
let sectionTitles = collation.sectionIndexTitles
var newSections = [(title: String, entries: [PasswordsTableEntry])]()
// initialize all sections
for i in 0..<sectionTitles.count {
newSections.append((title: sectionTitles[i], entries: [PasswordsTableEntry]()))
}
// put entries into sections
for entry in item {
let sectionNumber = collation.section(for: entry, collationStringSelector: #selector(getter: PasswordsTableEntry.title))
newSections[sectionNumber].entries.append(entry)
}
// sort each list and set sectionTitles
for i in 0..<sectionTitles.count {
let entriesToSort = newSections[i].entries
let sortedEntries = collation.sortedArray(from: entriesToSort, collationStringSelector: #selector(getter: PasswordsTableEntry.title))
newSections[i].entries = sortedEntries as! [PasswordsTableEntry]
}
// only keep non-empty sections
sections = newSections.filter {$0.entries.count > 0}
}
@objc func actOnSearchNotification() {
searchController.searchBar.becomeFirstResponder()
}
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "showPasswordDetail" {
guard self.passwordStore.privateKey != nil else {
@ -487,7 +487,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
}
}
func filterContentForSearchText(searchText: String, scope: String = "All") {
switch scope {
case "All":
@ -512,10 +512,10 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
default:
break
}
}
private func reloadTableView(data: [PasswordsTableEntry], anim: CAAnimation? = nil) {
// set navigation item
let numberOfLocalCommits = self.passwordStore.numberOfLocalCommits
@ -529,7 +529,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
} else {
navigationItem.leftBarButtonItem = nil
}
// set the password table
generateSections(item: data)
if anim != nil {
@ -537,7 +537,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
tableView.reloadData()
self.tableView.layer.removeAnimation(forKey: "UITableViewReloadDataAnimationKey")
// set the sync control title
let atribbutedTitle = "Last Synced: \(lastSyncedTimeString())"
syncControl.attributedTitle = NSAttributedString(string: atribbutedTitle)
@ -552,12 +552,12 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
formatter.timeStyle = .short
return formatter.string(from: date)
}
private func reloadTableView(parent: PasswordEntity?, anim: CAAnimation? = nil) {
initPasswordsTableEntries(parent: parent)
reloadTableView(data: passwordsTableEntries, anim: anim)
}
@objc func actOnReloadTableViewRelatedNotification() {
DispatchQueue.main.async { [weak weakSelf = self] in
guard let strongSelf = weakSelf else { return }
@ -565,11 +565,11 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
strongSelf.reloadTableView(data: strongSelf.passwordsTableEntries)
}
}
@objc func handleRefresh(_ syncControl: UIRefreshControl) {
syncPasswords()
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if viewController == self.navigationController {
let currentTime = Date().timeIntervalSince1970
@ -586,14 +586,14 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
backAction(self)
}
}
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
// update the default search scope
SharedDefaults[.isSearchDefaultAll] = searchController.searchBar.scopeButtonTitles![selectedScope] == "All"
updateSearchResults(for: searchController)
}
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
// set the default search scope to "all"
if SharedDefaults[.isShowFolderOn] && SharedDefaults[.isSearchDefaultAll] {
@ -603,14 +603,14 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
}
return true
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
// set the default search scope to "current"
searchController.searchBar.selectedScopeButtonIndex = 0
updateSearchResults(for: searchController)
return true
}
private func requestGitPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? {
let sem = DispatchSemaphore(value: 0)
var password: String?
@ -621,7 +621,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
case .ssh:
message = "Please fill in the password of your SSH key."
}
DispatchQueue.main.async {
SVProgressHUD.dismiss()
let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert)
@ -639,7 +639,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
})
self.present(alert, animated: true, completion: nil)
}
let _ = sem.wait(timeout: .distantFuture)
return password
}

View file

@ -17,90 +17,90 @@ protocol QRScannerControllerDelegate {
}
class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet weak var scannerOutput: UILabel!
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var qrCodeFrameView: UIView?
let supportedCodeTypes = [AVMetadataObject.ObjectType.qr]
var delegate: QRScannerControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
if AVCaptureDevice.authorizationStatus(for: .video) == .denied {
presentCameraSettings()
}
// Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter.
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
do {
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
let input = try AVCaptureDeviceInput(device: captureDevice!)
// Initialize the captureSession object.
captureSession = AVCaptureSession()
// Set the input device on the capture session.
captureSession?.addInput(input)
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession?.addOutput(captureMetadataOutput)
// Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = supportedCodeTypes
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoPreviewLayer?.frame = view.layer.bounds
view.layer.addSublayer(videoPreviewLayer!)
// Start video capture.
captureSession?.startRunning()
// Move the message label to the front
scannerOutput.layer.cornerRadius = 10
scannerOutput.text = "No QR code detected"
view.bringSubview(toFront: scannerOutput)
// Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
if let qrCodeFrameView = qrCodeFrameView {
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubview(toFront: qrCodeFrameView)
}
} catch {
scannerOutput.text = error.localizedDescription
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - AVCaptureMetadataOutputObjectsDelegate Methods
func metadataOutput(_ captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if let metadataObj = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
supportedCodeTypes.contains(metadataObj.type),
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) {
// draw a bounds on the found QR code
qrCodeFrameView?.frame = barCodeObject.bounds
// check whether it is a valid result
if let scanned = metadataObj.stringValue {
if let (accept, message) = delegate?.checkScannedOutput(line: scanned) {
@ -121,13 +121,13 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
} else {
scannerOutput.text = "No string value"
}
} else {
qrCodeFrameView?.frame = CGRect.zero
scannerOutput.text = "No QR code detected"
}
}
func presentCameraSettings() {
let alertController = UIAlertController(title: "Error",
message: "Camera access denied.\nWARNING: Toggle the camera permission resets the app! Save your changes.",
@ -140,7 +140,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
})
}
})
present(alertController, animated: true)
}
}

View file

@ -13,7 +13,7 @@ class RawPasswordViewController: UIViewController {
@IBOutlet weak var rawPasswordTextView: UITextView!
var password: Password?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = password?.name

View file

@ -14,21 +14,21 @@ class SSHKeySettingTableViewController: UITableViewController {
@IBOutlet weak var privateKeyURLTextField: UITextField!
let passwordStore = PasswordStore.shared
override func viewDidLoad() {
super.viewDidLoad()
privateKeyURLTextField.text = SharedDefaults[.gitSSHPrivateKeyURL]?.absoluteString
}
@IBAction func doneButtonTapped(_ sender: UIButton) {
guard let privateKeyURL = URL(string: privateKeyURLTextField.text!.trimmed) else {
Utils.alert(title: "Cannot Save", message: "Please set Private Key URL first.", controller: self, completion: nil)
return
}
SharedDefaults[.gitSSHPrivateKeyURL] = privateKeyURL
do {
try Data(contentsOf: privateKeyURL).write(to: URL(fileURLWithPath: Globals.gitSSHPrivateKeyPath), options: .atomic)
} catch {

View file

@ -13,7 +13,7 @@ class SettingsSplitViewController: UISplitViewController, UISplitViewControllerD
self.delegate = self
self.preferredDisplayMode = .allVisible
}
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,

View file

@ -16,14 +16,14 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
@IBOutlet weak var passcodeTableViewCell: UITableViewCell!
@IBOutlet weak var passwordRepositoryTableViewCell: UITableViewCell!
var setPasscodeLockAlert: UIAlertController?
let passwordStore = PasswordStore.shared
var passcodeLock = PasscodeLock.shared
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
navigationController?.popViewController(animated: true)
}
@IBAction func savePGPKey(segue: UIStoryboardSegue) {
if let controller = segue.source as? PGPKeySettingTableViewController {
SharedDefaults[.pgpPrivateKeyURL] = URL(string: controller.pgpPrivateKeyURLTextField.text!.trimmed)
@ -32,7 +32,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
self.passwordStore.pgpKeyPassphrase = controller.pgpPassphrase
}
SharedDefaults[.pgpKeySource] = "url"
SVProgressHUD.setDefaultMaskType(.black)
SVProgressHUD.setDefaultStyle(.light)
SVProgressHUD.show(withStatus: "Fetching PGP Key")
@ -53,7 +53,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
}
}
} else if let controller = segue.source as? PGPKeyArmorSettingTableViewController {
SharedDefaults[.pgpKeySource] = "armor"
if SharedDefaults[.isRememberPGPPassphraseOn] {
@ -62,7 +62,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
SharedDefaults[.pgpPublicKeyArmor] = controller.armorPublicKeyTextView.text!
SharedDefaults[.pgpPrivateKeyArmor] = controller.armorPrivateKeyTextView.text!
SVProgressHUD.setDefaultMaskType(.black)
SVProgressHUD.setDefaultStyle(.light)
SVProgressHUD.show(withStatus: "Fetching PGP Key")
@ -84,7 +84,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
}
}
private func saveImportedPGPKey() {
// load keys
SharedDefaults[.pgpKeySource] = "file"
@ -108,11 +108,11 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
}
}
@IBAction func saveGitServerSetting(segue: UIStoryboardSegue) {
self.passwordRepositoryTableViewCell.detailTextLabel?.text = SharedDefaults[.gitURL]?.host
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return super.tableView(tableView, numberOfRowsInSection: section)
}
@ -125,12 +125,12 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
setPasswordRepositoryTableViewCellDetailText()
setPasscodeLockCell()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
tabBarController!.delegate = self
}
private func setPasscodeLockCell() {
if passcodeLock.hasPasscode {
self.passcodeTableViewCell.detailTextLabel?.text = "On"
@ -138,7 +138,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
self.passcodeTableViewCell.detailTextLabel?.text = "Off"
}
}
private func setPGPKeyTableViewCellDetailText() {
if let pgpKeyID = self.passwordStore.pgpKeyID {
pgpKeyTableViewCell.detailTextLabel?.text = pgpKeyID
@ -146,7 +146,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
pgpKeyTableViewCell.detailTextLabel?.text = "Not Set"
}
}
private func setPasswordRepositoryTableViewCellDetailText() {
if SharedDefaults[.gitURL] == nil {
passwordRepositoryTableViewCell.detailTextLabel?.text = "Not Set"
@ -154,13 +154,13 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
passwordRepositoryTableViewCell.detailTextLabel?.text = SharedDefaults[.gitURL]!.host
}
}
@objc func actOnPasswordStoreErasedNotification() {
setPGPKeyTableViewCellDetailText()
setPasswordRepositoryTableViewCellDetailText()
setPasscodeLockCell()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath) == passcodeTableViewCell {
if SharedDefaults[.passcodeKey] != nil{
@ -173,13 +173,13 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
tableView.deselectRow(at: indexPath, animated: true)
}
func showPGPKeyActionSheet() {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
var urlActionTitle = "Download from URL"
var armorActionTitle = "ASCII-Armor Encrypted Key"
var fileActionTitle = "iTunes File Sharing"
if SharedDefaults[.pgpKeySource] == "url" {
urlActionTitle = "\(urlActionTitle)"
} else if SharedDefaults[.pgpKeySource] == "armor" {
@ -235,8 +235,8 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
optionMenu.addAction(fileAction)
}
if SharedDefaults[.pgpKeySource] != nil {
let deleteAction = UIAlertAction(title: "Remove PGP Keys", style: .destructive) { _ in
self.passwordStore.removePGPKeys()
@ -249,12 +249,12 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
optionMenu.popoverPresentationController?.sourceRect = pgpKeyTableViewCell.bounds
self.present(optionMenu, animated: true, completion: nil)
}
func showPasscodeActionSheet() {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let passcodeRemoveViewController = PasscodeLockViewController()
let removePasscodeAction = UIAlertAction(title: "Remove Passcode", style: .destructive) { [weak self] _ in
passcodeRemoveViewController.successCallback = {
self?.passcodeLock.delete()
@ -262,11 +262,11 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
self?.present(passcodeRemoveViewController, animated: true, completion: nil)
}
let changePasscodeAction = UIAlertAction(title: "Change Passcode", style: .default) { [weak self] _ in
self?.setPasscodeLock()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
optionMenu.addAction(removePasscodeAction)
optionMenu.addAction(changePasscodeAction)
@ -289,7 +289,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
}
}
}
func setPasscodeLock() {
// prepare the alert for setting the passcode
setPasscodeLockAlert = UIAlertController(title: "Set passcode", message: "Fill in your passcode for Pass (at least 4 characters)", preferredStyle: .alert)
@ -303,7 +303,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
textField.isSecureTextEntry = true
textField.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControlEvents.editingChanged)
})
// save action
let saveAction = UIAlertAction(title: "Save", style: .default) { (action:UIAlertAction) -> Void in
let passcode: String = self.setPasscodeLockAlert!.textFields![0].text!
@ -312,10 +312,10 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
self.setPasscodeLockCell()
}
saveAction.isEnabled = false // disable the Save button by default
// cancel action
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
// present
setPasscodeLockAlert?.addAction(saveAction)
setPasscodeLockAlert?.addAction(cancelAction)

View file

@ -19,7 +19,7 @@ class SpecialThanksTableViewController: BasicStaticTableViewController {
["FlatIcon",
"https://www.flaticon.com"],
]
override func viewDidLoad() {
tableData.append([])
for item in openSourceComponents {