Add ability to hide password images
This disables loading of favicon images associated with password entries and hides any images that are already loaded, using the generic icon instead. The key benefit to this option is to prevent passforios revealing that a given device has a password in its store, which could be gleaned from the fact that favicons are being loaded in this manner.
This commit is contained in:
parent
8351c16d75
commit
f98d56753b
4 changed files with 46 additions and 4 deletions
|
|
@ -55,6 +55,15 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
return uiSwitch
|
||||
}()
|
||||
|
||||
let hidePasswordImagesSwitch: UISwitch = {
|
||||
let uiSwitch = UISwitch()
|
||||
uiSwitch.onTintColor = Globals.blue
|
||||
uiSwitch.sizeToFit()
|
||||
uiSwitch.addTarget(self, action: #selector(hidePasswordImagesSwitchAction(_:)), for: UIControlEvents.valueChanged)
|
||||
uiSwitch.isOn = SharedDefaults[.isHidePasswordImagesOn]
|
||||
return uiSwitch
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
tableData = [
|
||||
// section 0
|
||||
|
|
@ -72,6 +81,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
],
|
||||
[
|
||||
[.title: "ShowFolders".localize(), .action: "none",],
|
||||
[.title: "HidePasswordImages".localize(), .action: "none",],
|
||||
[.title: "HideUnknownFields".localize(), .action: "none",],
|
||||
[.title: "HideOtpFields".localize(), .action: "none",],
|
||||
],
|
||||
|
|
@ -120,6 +130,18 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
cell.accessoryType = .none
|
||||
cell.selectionStyle = .none
|
||||
cell.accessoryView = showFolderSwitch
|
||||
case "HidePasswordImages".localize():
|
||||
cell.accessoryType = .none
|
||||
let detailButton = UIButton(type: .detailDisclosure)
|
||||
hidePasswordImagesSwitch.frame = CGRect(x: detailButton.bounds.width+10, y: 0, width: hidePasswordImagesSwitch.bounds.width, height: hidePasswordImagesSwitch.bounds.height)
|
||||
detailButton.frame = CGRect(x: 0, y: 5, width: detailButton.bounds.width, height: detailButton.bounds.height)
|
||||
detailButton.addTarget(self, action: #selector(GeneralSettingsTableViewController.tapHidePasswordImagesSwitchDetailButton(_:)), for: UIControlEvents.touchDown)
|
||||
let accessoryView = UIView(frame: CGRect(x: 0, y: 0, width: detailButton.bounds.width + hidePasswordImagesSwitch.bounds.width+10, height: hidePasswordImagesSwitch.bounds.height))
|
||||
accessoryView.addSubview(detailButton)
|
||||
accessoryView.addSubview(hidePasswordImagesSwitch)
|
||||
cell.accessoryView = accessoryView
|
||||
cell.selectionStyle = .none
|
||||
hidePasswordImagesSwitch.isOn = SharedDefaults[.isHidePasswordImagesOn]
|
||||
case "PasswordGeneratorFlavor".localize():
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.detailTextLabel?.text = PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]).name
|
||||
|
|
@ -180,6 +202,12 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
}
|
||||
|
||||
@objc func tapHidePasswordImagesSwitchDetailButton(_ sender: Any?) {
|
||||
let alertMessage = "HidePasswordImagesExplanation.".localize()
|
||||
let alertTitle = "HidePasswordImages".localize()
|
||||
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)
|
||||
|
|
@ -210,4 +238,9 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
NotificationCenter.default.post(name: .passwordDisplaySettingChanged, object: nil)
|
||||
}
|
||||
|
||||
@objc func hidePasswordImagesSwitchAction(_ sender: Any?) {
|
||||
SharedDefaults[.isHidePasswordImagesOn] = hidePasswordImagesSwitch.isOn
|
||||
NotificationCenter.default.post(name: .passwordDetailDisplaySettingChanged, object: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
self?.setTableData()
|
||||
self?.tableView.reloadData()
|
||||
self?.editUIBarButtonItem.isEnabled = true
|
||||
if !SharedDefaults[.isHidePasswordImagesOn] {
|
||||
if let urlString = self?.password?.urlString {
|
||||
if self?.passwordEntity?.getImage() == nil {
|
||||
self?.updatePasswordImage(urlString: urlString)
|
||||
|
|
@ -155,6 +156,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setupOneTimePasswordAutoRefresh() {
|
||||
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
|
||||
|
|
@ -395,7 +397,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
switch(tableData[sectionIndex].type) {
|
||||
case .name:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordDetailTitleTableViewCell", for: indexPath) as! PasswordDetailTitleTableViewCell
|
||||
if !SharedDefaults[.isHidePasswordImagesOn] {
|
||||
cell.passwordImageImageView.image = passwordImage ?? #imageLiteral(resourceName: "PasswordImagePlaceHolder")
|
||||
} else {
|
||||
cell.passwordImageImageView.image = #imageLiteral(resourceName: "PasswordImagePlaceHolder")
|
||||
}
|
||||
let passwordName = passwordEntity!.getName()
|
||||
if passwordEntity!.synced == false {
|
||||
cell.nameLabel.text = "\(passwordName) ↻"
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
"RememberPgpKeyPassphrase" = "Remember PGP Key Passphrase";
|
||||
"RememberGitCredentialPassphrase" = "Remember Git Credential Passphrase";
|
||||
"ShowFolders" = "Show Folders";
|
||||
"HidePasswordImages" = "Hide Password Images";
|
||||
"HidePasswordImagesExplanation." = "Associated favicon images are loaded and shown based upon the URL associated with an entry. Enable this option to hide these images and prevent them from being loaded.";
|
||||
"HideUnknownFields" = "Hide Unknown Fields";
|
||||
"HideUnknownFieldsExplanation." = "Only \"key: value\" format in additional fields is supported. Unsupported fields will be given \"unknown\" keys. Turn on this switch to hide unsupported fields.";
|
||||
"HideOtpFields" = "Hide OTP Fields";
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public extension DefaultsKeys {
|
|||
static let isRememberPGPPassphraseOn = DefaultsKey<Bool>("isRememberPGPPassphraseOn")
|
||||
static let isRememberGitCredentialPassphraseOn = DefaultsKey<Bool>("isRememberGitCredentialPassphraseOn")
|
||||
static let isShowFolderOn = DefaultsKey<Bool>("isShowFolderOn")
|
||||
static let isHidePasswordImagesOn = DefaultsKey<Bool>("isHidePasswordImagesOn")
|
||||
static let isSearchDefaultAll = DefaultsKey<Bool>("isSearchDefaultAll")
|
||||
static let passwordGeneratorFlavor = DefaultsKey<String>("passwordGeneratorFlavor")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue