Skip to content

Commit

Permalink
Merge branch 'main' into sam/remove-wireguard-dependency
Browse files Browse the repository at this point in the history
* main:
  Unified feedback form for Privacy Pro (#922)
  bump privacy-dashboard to 5.1.1 (#955)
  Bump Tests/BrowserServicesKitTests/Resources/privacy-reference-tests from `afb4f61` to `6133e7d` (#962)
  Freemium PIR - Add Desktop RMF Attribute (#960)
  Fix address bar queries when doing math expressions (#952)
  • Loading branch information
samsymons committed Aug 28, 2024
2 parents df1597b + 606ccf9 commit 4fd509b
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 5 deletions.
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/privacy-dashboard",
"state" : {
"revision" : "36dc07cba4bc1e7e0c1d1fb679c3cd077694a072",
"version" : "5.0.0"
"revision" : "665b23dc656c9f787494620494f8e56098a900b2",
"version" : "5.1.1"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ let package = Package(
.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/content-scope-scripts", exact: "6.7.0"),
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "5.0.0"),
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "5.1.1"),
.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/1024jp/GzipSwift.git", exact: "6.0.1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public enum PrivacyProSubfeature: String, Equatable, PrivacySubfeature {
case allowPurchaseStripe
case isLaunchedOverride
case isLaunchedOverrideStripe
case useUnifiedFeedback
}

public enum sslCertificatesSubfeature: String, PrivacySubfeature {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Subscription
public protocol SubscriptionFeatureAvailability {
var isFeatureAvailable: Bool { get }
var isSubscriptionPurchaseAllowed: Bool { get }
var usesUnifiedFeedbackForm: Bool { get }
}

public final class DefaultSubscriptionFeatureAvailability: SubscriptionFeatureAvailability {
Expand Down Expand Up @@ -52,6 +53,10 @@ public final class DefaultSubscriptionFeatureAvailability: SubscriptionFeatureAv
return isPurchaseAllowed || isInternalUser
}

public var usesUnifiedFeedbackForm: Bool {
privacyConfigurationManager.privacyConfig.isSubfeatureEnabled(PrivacyProSubfeature.useUnifiedFeedback)
}

// MARK: - Conditions

private var isInternalUser: Bool {
Expand Down
8 changes: 7 additions & 1 deletion Sources/Common/Extensions/StringExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ extension RegEx {
static let hostName = regex("^(((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)*[A-Za-z0-9-]{2,63})$", .caseInsensitive)

static let email = regex(#"[^\s]+@[^\s]+\.[^\s]+"#)

static let mathExpression = regex(#"^[\s$]*([\d]+(\.[\d]+)?|\\.[\d]+)([\s]*[+\-*/][\s]*([\d]+(\.[\d]+)?|\\.[\d]+))*[\s$]*$"#)
}

// Use this instead of NSLocalizedString for strings that are not supposed to be translated
Expand Down Expand Up @@ -362,7 +364,11 @@ public extension String {
// MARK: Host name validation

var isValidHost: Bool {
return isValidHostname || isValidIpHost
return (isValidHostname || isValidIpHost) && !isMathFormula
}

private var isMathFormula: Bool {
return matches(.mathExpression)
}

var isValidHostname: Bool {
Expand Down
8 changes: 8 additions & 0 deletions Sources/PixelKit/PixelKit+Parameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ public extension PixelKit {
public static let reason = "reason"

public static let vpnCohort = "cohort"

// Unified Feedback Form
public static let pproIssueDescription = "description"
public static let pproIssueSource = "source"
public static let pproIssueReportType = "reportType"
public static let pproIssueCategory = "category"
public static let pproIssueSubcategory = "subcategory"
public static let pproIssueMetadata = "customMetadata"
}

enum Values {
Expand Down
5 changes: 5 additions & 0 deletions Sources/RemoteMessaging/Matchers/UserAttributeMatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public struct MobileUserAttributeMatcher: AttributeMatching {
public struct DesktopUserAttributeMatcher: AttributeMatching {
private let pinnedTabsCount: Int
private let hasCustomHomePage: Bool
private let isCurrentFreemiumPIRUser: Bool
private let dismissedDeprecatedMacRemoteMessageIds: [String]

private let commonUserAttributeMatcher: CommonUserAttributeMatcher
Expand All @@ -123,10 +124,12 @@ public struct DesktopUserAttributeMatcher: AttributeMatching {
hasCustomHomePage: Bool,
isDuckPlayerOnboarded: Bool,
isDuckPlayerEnabled: Bool,
isCurrentFreemiumPIRUser: Bool,
dismissedDeprecatedMacRemoteMessageIds: [String]
) {
self.pinnedTabsCount = pinnedTabsCount
self.hasCustomHomePage = hasCustomHomePage
self.isCurrentFreemiumPIRUser = isCurrentFreemiumPIRUser
self.dismissedDeprecatedMacRemoteMessageIds = dismissedDeprecatedMacRemoteMessageIds

commonUserAttributeMatcher = .init(
Expand Down Expand Up @@ -158,6 +161,8 @@ public struct DesktopUserAttributeMatcher: AttributeMatching {
return matchingAttribute.evaluate(for: pinnedTabsCount)
case let matchingAttribute as CustomHomePageMatchingAttribute:
return matchingAttribute.evaluate(for: hasCustomHomePage)
case let matchingAttribute as FreemiumPIRCurrentUserMatchingAttribute:
return matchingAttribute.evaluate(for: isCurrentFreemiumPIRUser)
case let matchingAttribute as InteractedWithDeprecatedMacRemoteMessageMatchingAttribute:
if dismissedDeprecatedMacRemoteMessageIds.contains(where: { messageId in
StringArrayMatchingAttribute(matchingAttribute.value).matches(value: messageId) == .match
Expand Down
5 changes: 5 additions & 0 deletions Sources/RemoteMessaging/Model/MatchingAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ struct DuckPlayerEnabledMatchingAttribute: SingleValueMatching {
var fallback: Bool?
}

struct FreemiumPIRCurrentUserMatchingAttribute: SingleValueMatching {
var value: Bool?
var fallback: Bool?
}

struct MessageShownMatchingAttribute: SingleValueMatching {
var value: [String]? = []
var fallback: Bool?
Expand Down
34 changes: 34 additions & 0 deletions Tests/CommonTests/Extensions/StringExtensionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,38 @@ final class StringExtensionTests: XCTestCase {

}

func testWhenStringIsValidHost_thenValidHostIsTrue() {
let validHostnames = [
"example.com",
"subdomain.example.com",
"my-host123",
"localhost",
"192.168.1.1", // Valid IP address
"2001:0db8:85a3:0000:0000:8a2e:0370:7334" // Valid IPv6 address
]

for hostname in validHostnames {
XCTAssertTrue(hostname.isValidHost, "\(hostname) should be a valid host")
}
}

func testWhenStringIsInvalidHost_thenValidHostIsFalse() {
let invalidHostnames = [
"invalid_hostname", // Invalid character
"-example.com", // Starts with a hyphen
"example-.com", // Ends with a hyphen
"example..com", // Consecutive dots
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.com", // Too long
"example.com.", // Ends with a dot
"3 + 5 * (2 - 1)", // Mathematical expression
"16385-12228.72", // Other mathetmatical expression
"[email protected]", // Invalid character
"2001:0db8:85a3:0000:0000:8a2e:0370:7334:1234" // Invalid IPv6 address
]

for hostname in invalidHostnames {
XCTAssertFalse(hostname.isValidHost, "\(hostname) should NOT be a valid host")
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ class DesktopUserAttributeMatcherTests: XCTestCase {
.fail)
}

// MARK: - FreemiumPIRCurrentUser

func testWhenIsCurrentFreemiumPIRUserEnabledMatchesThenReturnMatch() throws {
XCTAssertEqual(matcher.evaluate(matchingAttribute: FreemiumPIRCurrentUserMatchingAttribute(value: false, fallback: nil)),
.match)
}

func testWhenIsCurrentFreemiumPIRUserDoesNotMatchThenReturnFail() throws {
XCTAssertEqual(matcher.evaluate(matchingAttribute: FreemiumPIRCurrentUserMatchingAttribute(value: true, fallback: nil)),
.fail)
}

// MARK: - DeprecatedMacRemoteMessage

func testWhenNoDismissedMessageIdsAreProvidedThenReturnFail() throws {
Expand Down Expand Up @@ -186,6 +198,7 @@ class DesktopUserAttributeMatcherTests: XCTestCase {
hasCustomHomePage: true,
isDuckPlayerOnboarded: true,
isDuckPlayerEnabled: false,
isCurrentFreemiumPIRUser: false,
dismissedDeprecatedMacRemoteMessageIds: dismissedDeprecatedMacRemoteMessageIds
)
}
Expand Down

0 comments on commit 4fd509b

Please sign in to comment.