From 1488e78cd0b709c6d84b6f58b18affc996623b4d Mon Sep 17 00:00:00 2001 From: Andreas Lif Date: Thu, 2 Jun 2022 17:55:18 +0200 Subject: [PATCH 1/6] Add option to block adult content and gambling --- ios/MullvadVPN/DNSSettings.swift | 2 + ios/MullvadVPN/PreferencesDataSource.swift | 66 +++++++++++++++++++++- ios/MullvadVPN/PreferencesViewModel.swift | 26 ++++++++- 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/ios/MullvadVPN/DNSSettings.swift b/ios/MullvadVPN/DNSSettings.swift index bee5b1d7f148..f841b6cb1b7f 100644 --- a/ios/MullvadVPN/DNSSettings.swift +++ b/ios/MullvadVPN/DNSSettings.swift @@ -18,6 +18,8 @@ struct DNSBlockingOptions: OptionSet, Codable { static let blockAdvertising = DNSBlockingOptions(rawValue: 1 << 0) static let blockTracking = DNSBlockingOptions(rawValue: 1 << 1) static let blockMalware = DNSBlockingOptions(rawValue: 1 << 2) + static let blockAdultContent = DNSBlockingOptions(rawValue: 1 << 3) + static let blockGambling = DNSBlockingOptions(rawValue: 1 << 4) var serverAddress: IPv4Address? { if isEmpty { diff --git a/ios/MullvadVPN/PreferencesDataSource.swift b/ios/MullvadVPN/PreferencesDataSource.swift index 63482db47f2e..46c0dc54702c 100644 --- a/ios/MullvadVPN/PreferencesDataSource.swift +++ b/ios/MullvadVPN/PreferencesDataSource.swift @@ -49,6 +49,8 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat case blockAdvertising case blockTracking case blockMalware + case blockAdultContent + case blockGambling case useCustomDNS case addDNSServer case dnsServer(_ uniqueID: UUID) @@ -309,7 +311,7 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat private func updateSnapshot() { var newSnapshot = DataSourceSnapshot() newSnapshot.appendSections([.mullvadDNS, .customDNS]) - newSnapshot.appendItems([.blockAdvertising, .blockTracking, .blockMalware], in: .mullvadDNS) + newSnapshot.appendItems([.blockAdvertising, .blockTracking, .blockMalware, .blockAdultContent, .blockGambling], in: .mullvadDNS) newSnapshot.appendItems([.useCustomDNS], in: .customDNS) let dnsServerItems = viewModel.customDNSDomains.map { entry in @@ -377,6 +379,40 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat return cell + case .blockAdultContent: + let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell + + cell.titleLabel.text = NSLocalizedString( + "BLOCK_ADULT_CELL_LABEL", + tableName: "Preferences", + value: "Block adult content", + comment: "" + ) + cell.accessibilityHint = nil + cell.setOn(viewModel.blockAdultContent, animated: false) + cell.action = { [weak self] isOn in + self?.setBlockAdultContent(isOn) + } + + return cell + + case .blockGambling: + let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell + + cell.titleLabel.text = NSLocalizedString( + "BLOCK_GAMBLING_CELL_LABEL", + tableName: "Preferences", + value: "Block gambling", + comment: "" + ) + cell.accessibilityHint = nil + cell.setOn(viewModel.blockGambling, animated: false) + cell.action = { [weak self] isOn in + self?.setBlockGambling(isOn) + } + + return cell + case .useCustomDNS: let cell = tableView.dequeueReusableCell(withIdentifier: CellReuseIdentifiers.settingSwitch.rawValue, for: indexPath) as! SettingsSwitchCell @@ -476,6 +512,34 @@ class PreferencesDataSource: NSObject, UITableViewDataSource, UITableViewDelegat } } + private func setBlockAdultContent(_ isEnabled: Bool) { + let oldViewModel = viewModel + + viewModel.setBlockAdultContent(isEnabled) + + if oldViewModel.customDNSPrecondition != viewModel.customDNSPrecondition { + reloadCustomDNSFooter() + } + + if !isEditing { + delegate?.preferencesDataSource(self, didChangeViewModel: viewModel) + } + } + + private func setBlockGambling(_ isEnabled: Bool) { + let oldViewModel = viewModel + + viewModel.setBlockGambling(isEnabled) + + if oldViewModel.customDNSPrecondition != viewModel.customDNSPrecondition { + reloadCustomDNSFooter() + } + + if !isEditing { + delegate?.preferencesDataSource(self, didChangeViewModel: viewModel) + } + } + private func setEnableCustomDNS(_ isEnabled: Bool) { viewModel.setEnableCustomDNS(isEnabled) diff --git a/ios/MullvadVPN/PreferencesViewModel.swift b/ios/MullvadVPN/PreferencesViewModel.swift index e303e5bae41c..23ee33f57092 100644 --- a/ios/MullvadVPN/PreferencesViewModel.swift +++ b/ios/MullvadVPN/PreferencesViewModel.swift @@ -78,6 +78,8 @@ struct PreferencesViewModel: Equatable { private(set) var blockAdvertising: Bool private(set) var blockTracking: Bool private(set) var blockMalware: Bool + private(set) var blockAdultContent: Bool + private(set) var blockGambling: Bool private(set) var enableCustomDNS: Bool var customDNSDomains: [DNSServerEntry] @@ -96,6 +98,16 @@ struct PreferencesViewModel: Equatable { enableCustomDNS = false } + mutating func setBlockAdultContent(_ newValue: Bool) { + blockAdultContent = newValue + enableCustomDNS = false + } + + mutating func setBlockGambling(_ newValue: Bool) { + blockGambling = newValue + enableCustomDNS = false + } + mutating func setEnableCustomDNS(_ newValue: Bool) { blockTracking = false blockAdvertising = false @@ -104,7 +116,7 @@ struct PreferencesViewModel: Equatable { /// Precondition for enabling Custom DNS. var customDNSPrecondition: CustomDNSPrecondition { - if blockAdvertising || blockTracking || blockMalware { + if blockAdvertising || blockTracking || blockMalware || blockAdultContent || blockGambling { return .conflictsWithOtherSettings } else { let hasValidDNSDomains = customDNSDomains.contains { entry in @@ -128,6 +140,8 @@ struct PreferencesViewModel: Equatable { blockAdvertising = dnsSettings.blockingOptions.contains(.blockAdvertising) blockTracking = dnsSettings.blockingOptions.contains(.blockTracking) blockMalware = dnsSettings.blockingOptions.contains(.blockMalware) + blockAdultContent = dnsSettings.blockingOptions.contains(.blockAdultContent) + blockGambling = dnsSettings.blockingOptions.contains(.blockGambling) enableCustomDNS = dnsSettings.enableCustomDNS customDNSDomains = dnsSettings.customDNSDomains.map { ipAddress in return DNSServerEntry(identifier: UUID(), address: "\(ipAddress)") @@ -141,6 +155,8 @@ struct PreferencesViewModel: Equatable { mergedViewModel.blockAdvertising = other.blockAdvertising mergedViewModel.blockTracking = other.blockTracking mergedViewModel.blockMalware = other.blockMalware + mergedViewModel.blockAdultContent = other.blockAdultContent + mergedViewModel.blockGambling = other.blockGambling mergedViewModel.enableCustomDNS = other.enableCustomDNS var oldDNSDomains = customDNSDomains @@ -218,6 +234,14 @@ struct PreferencesViewModel: Equatable { blockingOptions.insert(.blockMalware) } + if blockAdultContent { + blockingOptions.insert(.blockAdultContent) + } + + if blockGambling { + blockingOptions.insert(.blockGambling) + } + var dnsSettings = DNSSettings() dnsSettings.blockingOptions = blockingOptions dnsSettings.enableCustomDNS = enableCustomDNS From 78fc423267c72fe681472c06647c3284f3a812d0 Mon Sep 17 00:00:00 2001 From: Andreas Lif Date: Thu, 2 Jun 2022 17:55:40 +0200 Subject: [PATCH 2/6] Update changelog --- ios/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index e496d5b23cda..a4376198bade 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -33,6 +33,7 @@ Line wrap the file at 100 chars. Th any inbound traffic received. This should also keep the tunnel in connecting or reconnecting state until the tunnel monitor determined that connection is functional. - Add "FAQ & Guides" link in Settings. +- Add option to block gambling and adult content. ### Changed - Delete leftover settings in Keychain during login. WireGuard keys will be removed from From f126d7e0203b31abc982dcf855ab965209d5f662 Mon Sep 17 00:00:00 2001 From: Andreas Lif Date: Fri, 3 Jun 2022 11:46:38 +0200 Subject: [PATCH 3/6] Change preferences footer text to be more concise --- ios/MullvadVPN/PreferencesViewModel.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ios/MullvadVPN/PreferencesViewModel.swift b/ios/MullvadVPN/PreferencesViewModel.swift index 23ee33f57092..68036b40a1e2 100644 --- a/ios/MullvadVPN/PreferencesViewModel.swift +++ b/ios/MullvadVPN/PreferencesViewModel.swift @@ -57,13 +57,12 @@ enum CustomDNSPrecondition { case .conflictsWithOtherSettings: return NSAttributedString( - markdownString: NSLocalizedString( + string: NSLocalizedString( "CUSTOM_DNS_DISABLE_ADTRACKER_BLOCKING_FOOTNOTE", tableName: "Preferences", - value: "Disable **Block ads**, **Block trackers** and **Block malware** to activate this setting.", + value: "Disable all content blockers (under Preferences) to activate this setting.", comment: "Foot note displayed when custom DNS cannot be enabled, because ad/tracker/malware blockers features should be disabled first." - ), - font: preferredFont + ) ) } } From 30297041c9af475f69df32023af89ebfa4c9d7b2 Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Fri, 3 Jun 2022 11:57:56 +0200 Subject: [PATCH 4/6] Move new changelog entry to unreleased --- ios/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md index a4376198bade..c24541319636 100644 --- a/ios/CHANGELOG.md +++ b/ios/CHANGELOG.md @@ -23,6 +23,9 @@ Line wrap the file at 100 chars. Th ## [Unreleased] +### Added +- Add option to block gambling and adult content. + ### Fixed - Improve random port distribution. Should be less biased towards port 53. @@ -33,7 +36,6 @@ Line wrap the file at 100 chars. Th any inbound traffic received. This should also keep the tunnel in connecting or reconnecting state until the tunnel monitor determined that connection is functional. - Add "FAQ & Guides" link in Settings. -- Add option to block gambling and adult content. ### Changed - Delete leftover settings in Keychain during login. WireGuard keys will be removed from From feb62396e505cadd7888e97bbaedf4e9d494af26 Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Fri, 3 Jun 2022 12:02:02 +0200 Subject: [PATCH 5/6] Specify preferred font --- ios/MullvadVPN/PreferencesViewModel.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ios/MullvadVPN/PreferencesViewModel.swift b/ios/MullvadVPN/PreferencesViewModel.swift index 68036b40a1e2..89222eacfbbf 100644 --- a/ios/MullvadVPN/PreferencesViewModel.swift +++ b/ios/MullvadVPN/PreferencesViewModel.swift @@ -35,13 +35,13 @@ enum CustomDNSPrecondition { case .emptyDNSDomains: if isEditing { return NSAttributedString( - markdownString: NSLocalizedString( + string: NSLocalizedString( "CUSTOM_DNS_NO_DNS_ENTRIES_EDITING_ON_FOOTNOTE", tableName: "Preferences", value: "To enable this setting, add at least one server.", comment: "Foot note displayed if there are no DNS entries and table view is in editing mode." ), - font: preferredFont + attributes: [.font: preferredFont] ) } else { return NSAttributedString( @@ -62,7 +62,8 @@ enum CustomDNSPrecondition { tableName: "Preferences", value: "Disable all content blockers (under Preferences) to activate this setting.", comment: "Foot note displayed when custom DNS cannot be enabled, because ad/tracker/malware blockers features should be disabled first." - ) + ), + attributes: [.font: preferredFont] ) } } From 282da6177382154b30c3ef36279f51c09c7d16e0 Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Fri, 3 Jun 2022 12:03:54 +0200 Subject: [PATCH 6/6] Change foot note when custom DNS conflicts with content blockers --- ios/MullvadVPN/PreferencesViewModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/MullvadVPN/PreferencesViewModel.swift b/ios/MullvadVPN/PreferencesViewModel.swift index 89222eacfbbf..123331f4a86d 100644 --- a/ios/MullvadVPN/PreferencesViewModel.swift +++ b/ios/MullvadVPN/PreferencesViewModel.swift @@ -58,10 +58,10 @@ enum CustomDNSPrecondition { case .conflictsWithOtherSettings: return NSAttributedString( string: NSLocalizedString( - "CUSTOM_DNS_DISABLE_ADTRACKER_BLOCKING_FOOTNOTE", + "CUSTOM_DNS_DISABLE_CONTENT_BLOCKERS_FOOTNOTE", tableName: "Preferences", value: "Disable all content blockers (under Preferences) to activate this setting.", - comment: "Foot note displayed when custom DNS cannot be enabled, because ad/tracker/malware blockers features should be disabled first." + comment: "Foot note displayed when custom DNS cannot be enabled, because content blockers should be disabled first." ), attributes: [.font: preferredFont] )