Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breakage report improvements #578

Merged
merged 19 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a856932
Privacy dashboard controller now can open Report Broken site directly
federicocappelli Nov 14, 2023
2eff437
PrivacyDashboardController, didSetHeight is now for iOS and Mac
federicocappelli Nov 15, 2023
1cec675
Comments added
federicocappelli Nov 16, 2023
5f576a4
Merge https://github.com/duckduckgo/BrowserServicesKit into fcappelli…
federicocappelli Nov 16, 2023
473d5ff
fixed typos in comments
federicocappelli Nov 16, 2023
209e701
swiftlint fixes
federicocappelli Nov 16, 2023
f0991ba
privacy-dashboard now pointing to feature branch
federicocappelli Nov 16, 2023
279f27b
swiftlint fixes
federicocappelli Nov 16, 2023
3beb9e4
privacy-dashboard dependency updated to 3.1.0
federicocappelli Nov 17, 2023
60cc52d
Merge branch 'main' of https://github.com/duckduckgo/BrowserServicesK…
federicocappelli Nov 20, 2023
ab4154a
white spaces reverted
federicocappelli Nov 20, 2023
beb710e
white spaces fix
federicocappelli Nov 20, 2023
5912517
indentation fix
federicocappelli Nov 20, 2023
6dc31cc
Merge branch 'main' into fcappelli/breakage_report_improvements
federicocappelli Nov 23, 2023
3d32d29
Merge branch 'main' into fcappelli/breakage_report_improvements
federicocappelli Nov 27, 2023
895b0ad
Merge branch 'main' into fcappelli/breakage_report_improvements
federicocappelli Nov 27, 2023
14a78c7
Merge branch 'main' into fcappelli/breakage_report_improvements
federicocappelli Nov 28, 2023
6278254
Merge branch 'main' into fcappelli/breakage_report_improvements
federicocappelli Dec 6, 2023
3820c6b
API enabled in macos
federicocappelli Dec 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/privacy-dashboard",
"state" : {
"revision" : "daa9708223b4b4318fb6448ca44801dfabcddc6f",
"version" : "3.0.0"
"revision" : "59dedf0f4ff1e9147de0806a54c6043861eb0870",
"version" : "3.1.0"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ let package = Package(
.package(url: "https://github.com/duckduckgo/TrackerRadarKit", exact: "1.2.1"),
.package(url: "https://github.com/duckduckgo/sync_crypto", exact: "0.2.0"),
.package(url: "https://github.com/gumob/PunycodeSwift.git", exact: "2.1.0"),
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "3.1.0" ),
.package(url: "https://github.com/duckduckgo/content-scope-scripts", exact: "4.52.0"),
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "3.0.0"),
.package(url: "https://github.com/httpswift/swifter.git", exact: "1.5.0"),
.package(url: "https://github.com/duckduckgo/bloom_cpp.git", exact: "3.0.0"),
.package(url: "https://github.com/duckduckgo/wireguard-apple", exact: "1.1.1")
Expand Down
2 changes: 1 addition & 1 deletion Sources/PrivacyDashboard/Model/CookieConsentInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public struct CookieConsentInfo: Encodable {
let optoutFailed: Bool?
let selftestFailed: Bool?
let configurable = true

public init(consentManaged: Bool, cosmetic: Bool?, optoutFailed: Bool?, selftestFailed: Bool?) {
self.consentManaged = consentManaged
self.cosmetic = cosmetic
Expand Down
2 changes: 1 addition & 1 deletion Sources/PrivacyDashboard/Model/ProtectionStatus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import Foundation

public struct ProtectionStatus: Encodable {

let unprotectedTemporary: Bool
let enabledFeatures: [String]
let allowlisted: Bool
Expand Down
10 changes: 5 additions & 5 deletions Sources/PrivacyDashboard/Model/TrackerInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ public struct TrackerInfo: Encodable {
case requests
case installedSurrogates
}

public private (set) var trackers = Set<DetectedRequest>()
private(set) var thirdPartyRequests = Set<DetectedRequest>()
public private(set) var installedSurrogates = Set<String>()

public init() { }

// MARK: - Collecting detected elements
Expand All @@ -43,12 +43,12 @@ public struct TrackerInfo: Encodable {
public mutating func add(detectedThirdPartyRequest request: DetectedRequest) {
thirdPartyRequests.insert(request)
}

public mutating func addInstalledSurrogateHost(_ host: String, for tracker: DetectedRequest, onPageWithURL url: URL) {
guard tracker.pageUrl == url.absoluteString else { return }
installedSurrogates.insert(host)
}

// MARK: - Helper accessors

public var trackersBlocked: [DetectedRequest] {
Expand All @@ -67,5 +67,5 @@ public struct TrackerInfo: Encodable {
try container.encode(allRequests, forKey: .requests)
try container.encode(installedSurrogates, forKey: .installedSurrogates)
}

}
126 changes: 76 additions & 50 deletions Sources/PrivacyDashboard/PrivacyDashboardController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,58 +26,77 @@ public enum PrivacyDashboardOpenSettingsTarget: String {
case cookiePopupManagement = "cpm"
}

public protocol PrivacyDashboardControllerDelegate: AnyObject {
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didChangeProtectionSwitch protectionState: ProtectionState)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController, didRequestOpenUrlInNewTab url: URL)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didRequestOpenSettings target: PrivacyDashboardOpenSettingsTarget)

/// Navigation delegate for the pages provided by the PrivacyDashboardController
public protocol PrivacyDashboardNavigationDelegate: AnyObject {
#if os(iOS)
func privacyDashboardControllerDidTapClose(_ privacyDashboardController: PrivacyDashboardController)
func privacyDashboardControllerDidRequestShowReportBrokenSite(_ privacyDashboardController: PrivacyDashboardController)
#endif

#if os(macOS)

func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController, didSetHeight height: Int)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
}

/// `Report broken site` web page delegate
public protocol PrivacyDashboardReportBrokenSiteDelegate: AnyObject {

func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didRequestSubmitBrokenSiteReportWithCategory category: String, description: String)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didSetPermission permissionName: String,
to state: PermissionAuthorizationState)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
setPermission permissionName: String,
paused: Bool)
#endif
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
reportBrokenSiteDidChangeProtectionSwitch protectionState: ProtectionState)
}

/// `Privacy Dasboard` web page delegate
public protocol PrivacyDashboardControllerDelegate: AnyObject {

func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didChangeProtectionSwitch protectionState: ProtectionState)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didRequestOpenUrlInNewTab url: URL)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didRequestOpenSettings target: PrivacyDashboardOpenSettingsTarget)
func privacyDashboardControllerDidRequestShowReportBrokenSite(_ privacyDashboardController: PrivacyDashboardController)

#if os(macOS)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
didSetPermission permissionName: String, to state: PermissionAuthorizationState)
func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController,
setPermission permissionName: String, paused: Bool)
#endif
}

@MainActor
public final class PrivacyDashboardController: NSObject {
/// This controller provides two type of user experiences
/// 1- `Privacy Dashboard` with the possibility to navigate to the `Report broken site` page
/// 2- Direct access to the `Report broken site` page
/// Which flow is used is decided at `setup(...)` time, where if `reportBrokenSiteOnly` is true then the `Report broken site` page is opened directly.
@MainActor public final class PrivacyDashboardController: NSObject {

public weak var delegate: PrivacyDashboardControllerDelegate?
// Delegates
public weak var privacyDashboardDelegate: PrivacyDashboardControllerDelegate?
public weak var privacyDashboardNavigationDelegate: PrivacyDashboardNavigationDelegate?
public weak var privacyDashboardReportBrokenSiteDelegate: PrivacyDashboardReportBrokenSiteDelegate?

@Published public var theme: PrivacyDashboardTheme?
public var preferredLocale: String?
@Published public var allowedPermissions: [AllowedPermission] = []

public private(set) weak var privacyInfo: PrivacyInfo?
private weak var webView: WKWebView?

private weak var webView: WKWebView?
private let privacyDashboardScript = PrivacyDashboardUserScript()
private var cancellables = Set<AnyCancellable>()

public init(privacyInfo: PrivacyInfo?) {
self.privacyInfo = privacyInfo
}

public func setup(for webView: WKWebView) {
/// Configure the webview for showing `Privacy Dasboard` or `Report broken site`
/// - Parameters:
/// - webView: The webview to use
/// - reportBrokenSiteOnly: true = `Report broken site`, false = `Privacy Dasboard`
public func setup(for webView: WKWebView, reportBrokenSiteOnly: Bool) {
self.webView = webView

webView.navigationDelegate = self

setupPrivacyDashboardUserScript()
loadPrivacyDashboardHTML()
loadPrivacyDashboardHTML(reportBrokenSiteOnly: reportBrokenSiteOnly)
}

public func updatePrivacyInfo(_ privacyInfo: PrivacyInfo?) {
Expand Down Expand Up @@ -112,20 +131,25 @@ public final class PrivacyDashboardController: NSObject {
privacyDashboardScript.delegate = self

webView.configuration.userContentController.addUserScript(privacyDashboardScript.makeWKUserScriptSync())

privacyDashboardScript.messageNames.forEach { messageName in
webView.configuration.userContentController.add(privacyDashboardScript, name: messageName)
}
}

private func loadPrivacyDashboardHTML() {
guard let url = Bundle.privacyDashboardURL else { return }
private func loadPrivacyDashboardHTML(reportBrokenSiteOnly: Bool) {
guard var url = Bundle.privacyDashboardURL else { return }

if reportBrokenSiteOnly {
url = url.appendingParameter(name: "screen", value: ProtectionState.EventOriginScreen.breakageForm.rawValue)
}

webView?.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent().deletingLastPathComponent())
}
}

extension PrivacyDashboardController: WKNavigationDelegate {

public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
subscribeToDataModelChanges()

Expand Down Expand Up @@ -155,7 +179,7 @@ extension PrivacyDashboardController: WKNavigationDelegate {
})
.store(in: &cancellables)
}

private func subscribeToTrackerInfo() {
privacyInfo?.$trackerInfo
.receive(on: DispatchQueue.main)
Expand Down Expand Up @@ -234,53 +258,55 @@ extension PrivacyDashboardController: WKNavigationDelegate {
}

extension PrivacyDashboardController: PrivacyDashboardUserScriptDelegate {

func userScript(_ userScript: PrivacyDashboardUserScript, didRequestOpenSettings target: String) {
let settingsTarget = PrivacyDashboardOpenSettingsTarget(rawValue: target) ?? .general
delegate?.privacyDashboardController(self, didRequestOpenSettings: settingsTarget)
privacyDashboardDelegate?.privacyDashboardController(self, didRequestOpenSettings: settingsTarget)
}

func userScript(_ userScript: PrivacyDashboardUserScript, didChangeProtectionState protectionState: ProtectionState) {
delegate?.privacyDashboardController(self, didChangeProtectionSwitch: protectionState)

switch protectionState.eventOrigin.screen {
case .primaryScreen:
privacyDashboardDelegate?.privacyDashboardController(self, didChangeProtectionSwitch: protectionState)
case .breakageForm:
privacyDashboardReportBrokenSiteDelegate?.privacyDashboardController(self, reportBrokenSiteDidChangeProtectionSwitch: protectionState)
}

}

func userScript(_ userScript: PrivacyDashboardUserScript, didRequestOpenUrlInNewTab url: URL) {
delegate?.privacyDashboardController(self, didRequestOpenUrlInNewTab: url)
privacyDashboardDelegate?.privacyDashboardController(self, didRequestOpenUrlInNewTab: url)
}

func userScriptDidRequestClosing(_ userScript: PrivacyDashboardUserScript) {
#if os(iOS)
delegate?.privacyDashboardControllerDidTapClose(self)
privacyDashboardNavigationDelegate?.privacyDashboardControllerDidTapClose(self)
#endif
}

func userScriptDidRequestShowReportBrokenSite(_ userScript: PrivacyDashboardUserScript) {
#if os(iOS)
delegate?.privacyDashboardControllerDidRequestShowReportBrokenSite(self)
#endif
privacyDashboardDelegate?.privacyDashboardControllerDidRequestShowReportBrokenSite(self)
}

func userScript(_ userScript: PrivacyDashboardUserScript, setHeight height: Int) {
#if os(macOS)
delegate?.privacyDashboardController(self, didSetHeight: height)
#endif
privacyDashboardNavigationDelegate?.privacyDashboardController(self, didSetHeight: height)
}

func userScript(_ userScript: PrivacyDashboardUserScript, didRequestSubmitBrokenSiteReportWithCategory category: String, description: String) {
#if os(macOS)
delegate?.privacyDashboardController(self, didRequestSubmitBrokenSiteReportWithCategory: category, description: description)
#endif
privacyDashboardReportBrokenSiteDelegate?.privacyDashboardController(self, didRequestSubmitBrokenSiteReportWithCategory: category,
description: description)
}

func userScript(_ userScript: PrivacyDashboardUserScript, didSetPermission permission: String, to state: PermissionAuthorizationState) {
#if os(macOS)
delegate?.privacyDashboardController(self, didSetPermission: permission, to: state)
privacyDashboardDelegate?.privacyDashboardController(self, didSetPermission: permission, to: state)
#endif
}

func userScript(_ userScript: PrivacyDashboardUserScript, setPermission permission: String, paused: Bool) {
#if os(macOS)
delegate?.privacyDashboardController(self, setPermission: permission, paused: paused)
privacyDashboardDelegate?.privacyDashboardController(self, setPermission: permission, paused: paused)
#endif
}
}
2 changes: 1 addition & 1 deletion Sources/PrivacyDashboard/PrivacyInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public final class PrivacyInfo {
self.url = url
self.parentEntity = parentEntity
self.protectionStatus = protectionStatus

trackerInfo = TrackerInfo()
}

Expand Down
Loading
Loading