From aa8ddaac87a143aca75c7321956fa44efbc3d5eb Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 28 Nov 2024 20:58:43 +0600 Subject: [PATCH 1/4] update to match macOS codebase --- DuckDuckGo.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 2 +- DuckDuckGo/TabViewController.swift | 21 +++++-------- DuckDuckGoTests/SpecialErrorPageTests.swift | 30 ++++++------------- 4 files changed, 19 insertions(+), 36 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 8a641aa491..f734287ddc 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -11054,7 +11054,7 @@ repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { kind = revision; - revision = b2bdcc7fedf176fbf167d17bd76e25e488e71b86; + revision = b65fd02ab1ca29a73286f79f9da4678bc4af1789; }; }; 9F8FE9472BAE50E50071E372 /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e02a1b9a67..6d82ab8375 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,7 +32,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "revision" : "b2bdcc7fedf176fbf167d17bd76e25e488e71b86" + "revision" : "b65fd02ab1ca29a73286f79f9da4678bc4af1789" } }, { diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index f755becbf9..ac1e2196bd 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -1705,20 +1705,15 @@ extension TabViewController: WKNavigationDelegate { private func loadSpecialErrorPageIfNeeded(error: NSError) { guard featureFlagger.isFeatureOn(.sslCertificatesBypass), - error.code == NSURLErrorServerCertificateUntrusted, - let errorCode = error.userInfo["_kCFStreamErrorCodeKey"] as? Int32, - let failedURL = error.failedUrl else { - return - } + error.isServerCertificateUntrusted, + let errorType = error.sslErrorType, + let failedURL = error.failedUrl else { return } + let tld = storageCache.tld - let errorType = SSLErrorType.forErrorCode(Int(errorCode)) self.failedURL = failedURL - errorData = SpecialErrorData(kind: .ssl, - errorType: errorType.rawValue, - domain: failedURL.host, - eTldPlus1: tld.eTLDplus1(failedURL.host)) + errorData = SpecialErrorData.ssl(type: errorType, domain: failedURL.host!, eTldPlus1: tld.eTLDplus1(failedURL.host)) loadSpecialErrorPage(url: failedURL) - Pixel.fire(pixel: .certificateWarningDisplayed(errorType.rawParameter)) + Pixel.fire(pixel: .certificateWarningDisplayed(errorType.pixelParameter)) } private func loadSpecialErrorPage(url: URL) { @@ -3138,7 +3133,7 @@ extension UserContentController { extension TabViewController: SpecialErrorPageUserScriptDelegate { - func leaveSite() { + func leaveSiteAction() { Pixel.fire(pixel: .certificateWarningLeaveClicked) guard webView?.canGoBack == true else { delegate?.tabDidRequestClose(self) @@ -3147,7 +3142,7 @@ extension TabViewController: SpecialErrorPageUserScriptDelegate { _ = webView?.goBack() } - func visitSite() { + func visitSiteAction() { Pixel.fire(pixel: .certificateWarningProceedClicked) isSpecialErrorPageVisible = false shouldBypassSSLError = true diff --git a/DuckDuckGoTests/SpecialErrorPageTests.swift b/DuckDuckGoTests/SpecialErrorPageTests.swift index febab4cf3e..2b6ecbbdb1 100644 --- a/DuckDuckGoTests/SpecialErrorPageTests.swift +++ b/DuckDuckGoTests/SpecialErrorPageTests.swift @@ -68,7 +68,7 @@ final class SpecialErrorPageTests: XCTestCase { func testWhenCertificateExpiredThenExpectedErrorPageIsShown() { // GIVEN - let error = NSError(domain: "test", + let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorServerCertificateUntrusted, userInfo: ["_kCFStreamErrorCodeKey": errSSLCertExpired, NSURLErrorFailingURLErrorKey: URL(string: "https://expired.badssl.com")!]) @@ -89,10 +89,7 @@ final class SpecialErrorPageTests: XCTestCase { // THEN XCTAssertEqual(sut.failedURL, URL(string: "https://expired.badssl.com")!) - XCTAssertEqual(sut.errorData, SpecialErrorData(kind: .ssl, - errorType: "expired", - domain: "expired.badssl.com", - eTldPlus1: "badssl.com")) + XCTAssertEqual(sut.errorData, SpecialErrorData.ssl(type: .expired, domain: "expired.badssl.com", eTldPlus1: "badssl.com")) waitForExpectations(timeout: 1) { error in XCTAssertNil(error, "Expectation was not fulfilled in time") } @@ -100,7 +97,7 @@ final class SpecialErrorPageTests: XCTestCase { func testWhenCertificateWrongHostThenExpectedErrorPageIsShown() { // GIVEN - let error = NSError(domain: "test", + let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorServerCertificateUntrusted, userInfo: ["_kCFStreamErrorCodeKey": errSSLHostNameMismatch, NSURLErrorFailingURLErrorKey: URL(string: "https://wrong.host.badssl.com")!]) @@ -121,10 +118,7 @@ final class SpecialErrorPageTests: XCTestCase { // THEN XCTAssertEqual(sut.failedURL, URL(string: "https://wrong.host.badssl.com")!) - XCTAssertEqual(sut.errorData, SpecialErrorData(kind: .ssl, - errorType: "wrongHost", - domain: "wrong.host.badssl.com", - eTldPlus1: "badssl.com")) + XCTAssertEqual(sut.errorData, SpecialErrorData.ssl(type: .wrongHost, domain: "wrong.host.badssl.com", eTldPlus1: "badssl.com")) waitForExpectations(timeout: 1) { error in XCTAssertNil(error, "Expectation was not fulfilled in time") } @@ -132,7 +126,7 @@ final class SpecialErrorPageTests: XCTestCase { func testWhenCertificateSelfSignedThenExpectedErrorPageIsShown() { // GIVEN - let error = NSError(domain: "test", + let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorServerCertificateUntrusted, userInfo: ["_kCFStreamErrorCodeKey": errSSLXCertChainInvalid, NSURLErrorFailingURLErrorKey: URL(string: "https://self-signed.badssl.com")!]) @@ -153,10 +147,7 @@ final class SpecialErrorPageTests: XCTestCase { // THEN XCTAssertEqual(sut.failedURL, URL(string: "https://self-signed.badssl.com")!) - XCTAssertEqual(sut.errorData, SpecialErrorData(kind: .ssl, - errorType: "selfSigned", - domain: "self-signed.badssl.com", - eTldPlus1: "badssl.com")) + XCTAssertEqual(sut.errorData, SpecialErrorData.ssl(type: .selfSigned, domain: "self-signed.badssl.com", eTldPlus1: "badssl.com")) waitForExpectations(timeout: 1) { error in XCTAssertNil(error, "Expectation was not fulfilled in time") } @@ -164,7 +155,7 @@ final class SpecialErrorPageTests: XCTestCase { func testWhenOtherCertificateIssueThenExpectedErrorPageIsShown() { // GIVEN - let error = NSError(domain: "test", + let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorServerCertificateUntrusted, userInfo: ["_kCFStreamErrorCodeKey": errSSLUnknownRootCert, NSURLErrorFailingURLErrorKey: URL(string: "https://untrusted-root.badssl.com")!]) @@ -185,10 +176,7 @@ final class SpecialErrorPageTests: XCTestCase { // THEN XCTAssertEqual(sut.failedURL, URL(string: "https://untrusted-root.badssl.com")!) - XCTAssertEqual(sut.errorData, SpecialErrorData(kind: .ssl, - errorType: "invalid", - domain: "untrusted-root.badssl.com", - eTldPlus1: "badssl.com")) + XCTAssertEqual(sut.errorData, SpecialErrorData.ssl(type: .invalid, domain: "untrusted-root.badssl.com", eTldPlus1: "badssl.com")) waitForExpectations(timeout: 1) { error in XCTAssertNil(error, "Expectation was not fulfilled in time") } @@ -246,7 +234,7 @@ final class SpecialErrorPageTests: XCTestCase { func testWhenDidReceiveChallengeIfChallengeForCertificateValidationAndUserRequestBypassThenReturnsCredentials() async { let protectionSpace = URLProtectionSpace(host: "", port: 4, protocol: nil, realm: nil, authenticationMethod: NSURLAuthenticationMethodServerTrust) let challenge = URLAuthenticationChallenge(protectionSpace: protectionSpace, proposedCredential: nil, previousFailureCount: 0, failureResponse: nil, error: nil, sender: ChallengeSender()) - await sut.visitSite() + await sut.visitSiteAction() await sut.webView(webView, didReceive: challenge) { _, credential in XCTAssertNotNil(credential) } From ee9348fcbaf59604f426649c434ccea899c9a2a7 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Fri, 29 Nov 2024 14:16:02 +0600 Subject: [PATCH 2/4] fix build --- .../Subscription/Feedback/UnifiedFeedbackFormViewModel.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/DuckDuckGo/Subscription/Feedback/UnifiedFeedbackFormViewModel.swift b/DuckDuckGo/Subscription/Feedback/UnifiedFeedbackFormViewModel.swift index ea36971224..3587586366 100644 --- a/DuckDuckGo/Subscription/Feedback/UnifiedFeedbackFormViewModel.swift +++ b/DuckDuckGo/Subscription/Feedback/UnifiedFeedbackFormViewModel.swift @@ -66,7 +66,6 @@ final class UnifiedFeedbackFormViewModel: ObservableObject { enum Error: String, Swift.Error { case missingAccessToken - case invalidRequest case invalidResponse } @@ -281,9 +280,7 @@ final class UnifiedFeedbackFormViewModel: ObservableObject { problemSubCategory: selectedSubcategory ?? "", customMetadata: metadata?.toString() ?? "") let headers = APIRequestV2.HeadersV2(additionalHeaders: [HTTPHeaderKey.authorization: "Bearer \(accessToken)"]) - guard let request = APIRequestV2(url: Self.feedbackEndpoint, method: .post, headers: headers, body: payload.toData()) else { - throw Error.invalidRequest - } + let request = APIRequestV2(url: Self.feedbackEndpoint, method: .post, headers: headers, body: payload.toData()) let response: Response = try await apiService.fetch(request: request).decodeBody() if let error = response.error, !error.isEmpty { From 2315fc9b8d7356dd93ee79fa4d68708e0853bc2f Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Fri, 29 Nov 2024 14:28:04 +0600 Subject: [PATCH 3/4] remove host force unwrap --- DuckDuckGo/TabViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index ac1e2196bd..cca6e04272 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -1707,11 +1707,12 @@ extension TabViewController: WKNavigationDelegate { guard featureFlagger.isFeatureOn(.sslCertificatesBypass), error.isServerCertificateUntrusted, let errorType = error.sslErrorType, - let failedURL = error.failedUrl else { return } + let failedURL = error.failedUrl, + let host = failedURL.host else { return } let tld = storageCache.tld self.failedURL = failedURL - errorData = SpecialErrorData.ssl(type: errorType, domain: failedURL.host!, eTldPlus1: tld.eTLDplus1(failedURL.host)) + errorData = SpecialErrorData.ssl(type: errorType, domain: host, eTldPlus1: tld.eTLDplus1(host)) loadSpecialErrorPage(url: failedURL) Pixel.fire(pixel: .certificateWarningDisplayed(errorType.pixelParameter)) } From b990664bf2450147f4b54059acc407b73a7c7526 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Fri, 29 Nov 2024 16:41:54 +0600 Subject: [PATCH 4/4] bump BSK --- DuckDuckGo.xcodeproj/project.pbxproj | 2 +- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index b7da8f8f89..b402060764 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -11251,7 +11251,7 @@ repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { kind = revision; - revision = e48c6df21411bb3c42edb6edb44567626065d765; + revision = 22f3d8f4497d33cbb3fb0920f55bc05a8f655671; }; }; 9F8FE9472BAE50E50071E372 /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4bd117879e..ced7307495 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,7 +32,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "revision" : "e48c6df21411bb3c42edb6edb44567626065d765" + "revision" : "22f3d8f4497d33cbb3fb0920f55bc05a8f655671" } }, { @@ -137,7 +137,7 @@ { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser.git", + "location" : "https://github.com/apple/swift-argument-parser", "state" : { "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b", "version" : "1.4.0"