Skip to content

Commit

Permalink
Merge branch 'main' into sam/add-netp-subscription-auth-support
Browse files Browse the repository at this point in the history
# By Dominik Kapusta (5) and others
# Via GitHub
* main: (31 commits)
  cache the calculated temporary unprotected domains property (#574)
  Merge 83.0.0-3 hotfix (#573)
  Revert "Breakage report improvements (#566)" (#572)
  Breakage report improvements (#566)
  Updating C-S-S to 4.52.0 for DBP (#568)
  Fix NetP connectivity issues. (#567)
  Autofill "Never Save for this Site"  (#555)
  Removing an exception that I think was merged by mistake (#563)
  BSK changes for NetP iOS Geoswitching (#557)
  Fix timing issues with tracker surrogate injection (#558)
  Bump Tests/BrowserServicesKitTests/Resources/privacy-reference-tests (#559)
  Sync form factor specific favorites (#511)
  Add selected environment preference (#544)
  Bump Tests/BrowserServicesKitTests/Resources/privacy-reference-tests from `2e73221` to `7519c3d` (#556)
  Add DBP feature (#551)
  Add a check for the DAU pixel when the bandwidth analyzer runs a test. (#553)
  Fix syncing empty favorites folders (#546)
  Alert user about abnormal app conditions (#539)
  Bump Tests/BrowserServicesKitTests/Resources/privacy-reference-tests (#543)
  NetP iOS notifications settings (#541)
  ...

# Conflicts:
#	Sources/NetworkProtection/Networking/NetworkProtectionClient.swift
#	Sources/NetworkProtectionTestUtils/Networking/MockNetworkProtectionClient.swift
#	Tests/NetworkProtectionTests/NetworkProtectionDeviceManagerTests.swift
  • Loading branch information
samsymons committed Nov 26, 2023
2 parents a6d78a3 + 88935a6 commit 38e19dc
Show file tree
Hide file tree
Showing 116 changed files with 4,107 additions and 685 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
${{ runner.os }}-spm-
- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_14.3.app/Contents/Developer
run: sudo xcode-select -s /Applications/Xcode_15.0.app/Contents/Developer

- name: Install xcbeautify
continue-on-error: true
Expand Down
12 changes: 6 additions & 6 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/content-scope-scripts",
"state" : {
"revision" : "74b6142c016be354144f28551de41b50c4864b1f",
"version" : "4.37.0"
"revision" : "b7ad9843e70cede0c2ca9c4260d970f62cb28156",
"version" : "4.52.0"
}
},
{
"identity" : "duckduckgo-autofill",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/duckduckgo-autofill.git",
"state" : {
"revision" : "55466f10a339843cb79a27af62d5d61c030740b2",
"version" : "8.4.1"
"revision" : "93677cc02cfe650ce7f417246afd0e8e972cd83e",
"version" : "10.0.0"
}
},
{
Expand All @@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/privacy-dashboard",
"state" : {
"revision" : "51e2b46f413bf3ef18afefad631ca70f2c25ef70",
"version" : "1.4.0"
"revision" : "b4ac92a444e79d5651930482623b9f6dc9265667",
"version" : "2.0.0"
}
},
{
Expand Down
22 changes: 16 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ let package = Package(
.library(name: "DDGSync", targets: ["DDGSync"]),
.library(name: "Persistence", targets: ["Persistence"]),
.library(name: "Bookmarks", targets: ["Bookmarks"]),
.library(name: "BloomFilterWrapper", targets: ["BloomFilterWrapper"]),
.library(name: "UserScript", targets: ["UserScript"]),
.library(name: "Crashes", targets: ["Crashes"]),
.library(name: "ContentBlocking", targets: ["ContentBlocking"]),
Expand All @@ -31,13 +32,13 @@ let package = Package(
.library(name: "SecureStorage", targets: ["SecureStorage"])
],
dependencies: [
.package(url: "https://github.com/duckduckgo/duckduckgo-autofill.git", exact: "8.4.1"),
.package(url: "https://github.com/duckduckgo/duckduckgo-autofill.git", exact: "10.0.0"),
.package(url: "https://github.com/duckduckgo/GRDB.swift.git", exact: "2.2.0"),
.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/content-scope-scripts", exact: "4.37.0"),
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "1.4.0"),
.package(url: "https://github.com/duckduckgo/content-scope-scripts", exact: "4.52.0"),
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "2.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 Expand Up @@ -87,11 +88,16 @@ let package = Package(
"Bookmarks"
]
),
.target(
name: "BloomFilterWrapper",
.target(
name: "BloomFilterObjC",
dependencies: [
.product(name: "BloomFilter", package: "bloom_cpp")
]),
.target(
name: "BloomFilterWrapper",
dependencies: [
"BloomFilterObjC"
]),
.target(
name: "Crashes"
),
Expand Down Expand Up @@ -196,6 +202,9 @@ let package = Package(
.target(name: "WireGuardC"),
.product(name: "WireGuard", package: "wireguard-apple"),
"Common"
],
swiftSettings: [
.define("DEBUG", .when(configuration: .debug))
]),
.target(
name: "SecureStorage",
Expand Down Expand Up @@ -310,7 +319,8 @@ let package = Package(
],
resources: [
.copy("Resources/servers-original-endpoint.json"),
.copy("Resources/servers-updated-endpoint.json")
.copy("Resources/servers-updated-endpoint.json"),
.copy("Resources/locations-endpoint.json")
]
),
.testTarget(
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# BrowserServicesKit

## We are hiring!

DuckDuckGo is growing fast and we continue to expand our fully distributed team. We embrace diverse perspectives, and seek out passionate, self-motivated people, committed to our shared vision of raising the standard of trust online. If you are a senior software engineer capable in either iOS or Android, visit our [careers](https://duckduckgo.com/hiring/#open) page to find out more about our openings!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
// limitations under the License.
//

#import "BloomFilterWrapper.h"
#import "BloomFilterObjC.h"
#import "BloomFilter.hpp"

@interface BloomFilterWrapper() {
@interface BloomFilterObjC() {
BloomFilter *filter;
}
@end

@implementation BloomFilterWrapper
@implementation BloomFilterObjC

- (instancetype)initFromPath:(NSString*)path withBitCount:(int)bitCount andTotalItems:(int)totalItems {
self = [super init];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//
#import <Foundation/Foundation.h>

@interface BloomFilterWrapper : NSObject
@interface BloomFilterObjC: NSObject
- (instancetype)initFromPath:(NSString*)path withBitCount:(int)bitCount andTotalItems:(int)totalItems;
- (instancetype)initWithTotalItems:(int)count errorRate:(double)errorRate;
- (void)dealloc;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module BloomFilterWrapper {
header "BloomFilterWrapper.h"
header "BloomFilterObjC.h"
export *
}
40 changes: 40 additions & 0 deletions Sources/BloomFilterWrapper/BloomFilterWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// BloomFilterWrapper.swift
//
// Copyright © 2023 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation
@_implementationOnly import BloomFilterObjC

public final class BloomFilterWrapper {
private let bloomFilter: BloomFilterObjC

public init(fromPath path: String, withBitCount bitCount: Int32, andTotalItems totalItems: Int32) {
bloomFilter = BloomFilterObjC(fromPath: path, withBitCount: bitCount, andTotalItems: totalItems)
}

public init(totalItems count: Int32, errorRate: Double) {
bloomFilter = BloomFilterObjC(totalItems: count, errorRate: errorRate)
}

public func add(_ entry: String) {
bloomFilter.add(entry)
}

public func contains(_ entry: String) -> Bool {
bloomFilter.contains(entry)
}
}
18 changes: 13 additions & 5 deletions Sources/Bookmarks/BookmarkEditorViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ public class BookmarkEditorViewModel: ObservableObject {
}

let context: NSManagedObjectContext
public let favoritesDisplayMode: FavoritesDisplayMode

@Published public var bookmark: BookmarkEntity
@Published public var locations = [Location]()

lazy var favoritesFolder: BookmarkEntity! = BookmarkUtils.fetchFavoritesFolder(context)
lazy var favoritesFolder: BookmarkEntity! = BookmarkUtils.fetchFavoritesFolder(
withUUID: favoritesDisplayMode.displayedFolder.rawValue,
in: context
)

private var observer: NSObjectProtocol?
private let subject = PassthroughSubject<Void, Never>()
Expand All @@ -59,11 +63,13 @@ public class BookmarkEditorViewModel: ObservableObject {

public init(editingEntityID: NSManagedObjectID,
bookmarksDatabase: CoreDataDatabase,
favoritesDisplayMode: FavoritesDisplayMode,
errorEvents: EventMapping<BookmarksModelError>?) {

externalUpdates = subject.eraseToAnyPublisher()
self.errorEvents = errorEvents
self.context = bookmarksDatabase.makeContext(concurrencyType: .mainQueueConcurrencyType)
self.favoritesDisplayMode = favoritesDisplayMode

guard let entity = context.object(with: editingEntityID) as? BookmarkEntity else {
// For sync, this is valid scenario in case of a timing issue
Expand All @@ -84,11 +90,13 @@ public class BookmarkEditorViewModel: ObservableObject {

public init(creatingFolderWithParentID parentFolderID: NSManagedObjectID?,
bookmarksDatabase: CoreDataDatabase,
favoritesDisplayMode: FavoritesDisplayMode,
errorEvents: EventMapping<BookmarksModelError>?) {

externalUpdates = subject.eraseToAnyPublisher()
self.errorEvents = errorEvents
self.context = bookmarksDatabase.makeContext(concurrencyType: .mainQueueConcurrencyType)
self.favoritesDisplayMode = favoritesDisplayMode

let parent: BookmarkEntity?
if let parentFolderID = parentFolderID {
Expand Down Expand Up @@ -173,13 +181,13 @@ public class BookmarkEditorViewModel: ObservableObject {
}

public func removeFromFavorites() {
assert(bookmark.isFavorite)
bookmark.removeFromFavorites()
assert(bookmark.isFavorite(on: favoritesDisplayMode.displayedFolder))
bookmark.removeFromFavorites(with: favoritesDisplayMode)
}

public func addToFavorites() {
assert(!bookmark.isFavorite)
bookmark.addToFavorites(favoritesRoot: favoritesFolder)
assert(!bookmark.isFavorite(on: favoritesDisplayMode.displayedFolder))
bookmark.addToFavorites(with: favoritesDisplayMode, in: context)
}

public func setParentWithID(_ parentID: NSManagedObjectID) {
Expand Down
81 changes: 63 additions & 18 deletions Sources/Bookmarks/BookmarkEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,28 @@
import Foundation
import CoreData

/**
* This enum defines available favorites folders with their UUIDs as raw value.
*/
public enum FavoritesFolderID: String, CaseIterable {
/// Mobile form factor favorites folder
case mobile = "mobile_favorites_root"
/// Desktop form factor favorites folder
case desktop = "desktop_favorites_root"
/// Unified (mobile + desktop) favorites folder
case unified = "favorites_root"
}

@objc(BookmarkEntity)
public class BookmarkEntity: NSManagedObject {

public enum Constants {
public static let rootFolderID = "bookmarks_root"
public static let favoritesFolderID = "favorites_root"
public static let favoriteFoldersIDs: Set<String> = Set(FavoritesFolderID.allCases.map(\.rawValue))
}

public static func isValidFavoritesFolderID(_ value: String) -> Bool {
FavoritesFolderID.allCases.contains { $0.rawValue == value }
}

public enum Error: Swift.Error {
Expand All @@ -49,7 +65,7 @@ public class BookmarkEntity: NSManagedObject {
@NSManaged public var url: String?
@NSManaged public var uuid: String?
@NSManaged public var children: NSOrderedSet?
@NSManaged fileprivate(set) public var favoriteFolder: BookmarkEntity?
@NSManaged public fileprivate(set) var favoriteFolders: NSSet?
@NSManaged public fileprivate(set) var favorites: NSOrderedSet?
@NSManaged public var parent: BookmarkEntity?

Expand All @@ -58,8 +74,12 @@ public class BookmarkEntity: NSManagedObject {
/// In-memory flag. When set to `false`, disables adjusting `modifiedAt` on `willSave()`. It's reset to `true` on `didSave()`.
public var shouldManageModifiedAt: Bool = true

public var isFavorite: Bool {
favoriteFolder != nil
public func isFavorite(on platform: FavoritesFolderID) -> Bool {
favoriteFoldersSet.contains { $0.uuid == platform.rawValue }
}

public var favoritedOn: [FavoritesFolderID] {
favoriteFoldersSet.compactMap(\.uuid).compactMap(FavoritesFolderID.init)
}

public convenience init(context moc: NSManagedObjectContext) {
Expand All @@ -81,7 +101,7 @@ public class BookmarkEntity: NSManagedObject {
guard !changedKeys.isEmpty, !changedKeys.contains(NSStringFromSelector(#selector(getter: modifiedAt))) else {
return
}
if isInserted && (uuid == Constants.rootFolderID || uuid == Constants.favoritesFolderID) {
if isInserted, let uuid, uuid == Constants.rootFolderID || Self.isValidFavoritesFolderID(uuid) {
return
}
modifiedAt = Date()
Expand Down Expand Up @@ -123,6 +143,10 @@ public class BookmarkEntity: NSManagedObject {
return children.filter { $0.isPendingDeletion == false }
}

public var favoriteFoldersSet: Set<BookmarkEntity> {
return favoriteFolders.flatMap(Set<BookmarkEntity>.init) ?? []
}

public static func makeFolder(title: String,
parent: BookmarkEntity,
insertAtBeginning: Bool = false,
Expand Down Expand Up @@ -168,9 +192,21 @@ public class BookmarkEntity: NSManagedObject {
root.addToFavorites(self)
}
}

public func removeFromFavorites() {
favoriteFolder = nil

public func addToFavorites(folders: [BookmarkEntity]) {
for root in folders {
root.addToFavorites(self)
}
}

public func removeFromFavorites(folders: [BookmarkEntity]) {
for root in folders {
root.removeFromFavorites(self)
}
}

public func removeFromFavorites(favoritesRoot: BookmarkEntity) {
favoritesRoot.removeFromFavorites(self)
}

public func markPendingDeletion() {
Expand Down Expand Up @@ -200,20 +236,12 @@ extension BookmarkEntity {
func validate() throws {
try validateThatFoldersDoNotHaveURLs()
try validateThatFolderHierarchyHasNoCycles()
try validateFavoritesStatus()
try validateFavoritesFolder()
}

func validateFavoritesStatus() throws {
let isInFavoriteCollection = favoriteFolder != nil
if isFavorite != isInFavoriteCollection {
throw Error.invalidFavoritesStatus
}
}

func validateFavoritesFolder() throws {
if let favoritesFolderID = favoriteFolder?.uuid,
favoritesFolderID != Constants.favoritesFolderID {
let uuids = Set(favoriteFoldersSet.compactMap(\.uuid))
guard uuids.isSubset(of: Constants.favoriteFoldersIDs) else {
throw Error.invalidFavoritesFolder
}
}
Expand Down Expand Up @@ -296,6 +324,23 @@ extension BookmarkEntity {

}

// MARK: Generated accessors for favoriteFolders
extension BookmarkEntity {

@objc(addFavoriteFoldersObject:)
@NSManaged private func addToFavoriteFolders(_ value: BookmarkEntity)

@objc(removeFavoriteFoldersObject:)
@NSManaged private func removeFromFavoriteFolders(_ value: BookmarkEntity)

@objc(addFavoriteFolders:)
@NSManaged private func addToFavoriteFolders(_ values: NSSet)

@objc(removeFavoriteFolders:)
@NSManaged private func removeFromFavoriteFolders(_ values: NSSet)

}

extension BookmarkEntity: Identifiable {

}
Loading

0 comments on commit 38e19dc

Please sign in to comment.