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:
David Beitey 2019-02-27 21:49:21 +10:00 committed by Mingshen Sun
parent 8351c16d75
commit f98d56753b
4 changed files with 46 additions and 4 deletions

View file

@ -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)
}
}

View file

@ -148,9 +148,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
self?.setTableData()
self?.tableView.reloadData()
self?.editUIBarButtonItem.isEnabled = true
if let urlString = self?.password?.urlString {
if self?.passwordEntity?.getImage() == nil {
self?.updatePasswordImage(urlString: urlString)
if !SharedDefaults[.isHidePasswordImagesOn] {
if let urlString = self?.password?.urlString {
if self?.passwordEntity?.getImage() == nil {
self?.updatePasswordImage(urlString: urlString)
}
}
}
}
@ -395,7 +397,11 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
switch(tableData[sectionIndex].type) {
case .name:
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordDetailTitleTableViewCell", for: indexPath) as! PasswordDetailTitleTableViewCell
cell.passwordImageImageView.image = passwordImage ?? #imageLiteral(resourceName: "PasswordImagePlaceHolder")
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)"