From b07845c77868112da249c07e2f9e98bee9156257 Mon Sep 17 00:00:00 2001 From: Sabrina Tardio Date: Fri, 12 Apr 2024 15:17:29 +0200 Subject: [PATCH] give priority to externalAppSchemeHandler --- DuckDuckGo.xcodeproj/project.pbxproj | 16 +++++++-------- DuckDuckGo/Tab/Model/Tab.swift | 10 ++++++++-- ...n.swift => SSLErrorPageTabExtension.swift} | 15 +++++++------- .../Tab/TabExtensions/TabExtensions.swift | 2 +- .../ErrorPageTabExtensionTest.swift | 20 ++----------------- 5 files changed, 26 insertions(+), 37 deletions(-) rename DuckDuckGo/Tab/TabExtensions/{ErrorPageTabExtension.swift => SSLErrorPageTabExtension.swift} (93%) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 843159de47..f1b2e26a6f 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -2197,9 +2197,9 @@ 569277C529DEE09D00B633EF /* ContinueSetUpModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569277C329DEE09D00B633EF /* ContinueSetUpModelTests.swift */; }; 56B234BF2A84EFD200F2A1CC /* NavigationBarUrlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B234BE2A84EFD200F2A1CC /* NavigationBarUrlExtensionsTests.swift */; }; 56B234C02A84EFD800F2A1CC /* NavigationBarUrlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B234BE2A84EFD200F2A1CC /* NavigationBarUrlExtensionsTests.swift */; }; - 56BA1E752BAAF70F001CF69F /* ErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* ErrorPageTabExtension.swift */; }; - 56BA1E762BAAF70F001CF69F /* ErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* ErrorPageTabExtension.swift */; }; - 56BA1E772BAAF70F001CF69F /* ErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* ErrorPageTabExtension.swift */; }; + 56BA1E752BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */; }; + 56BA1E762BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */; }; + 56BA1E772BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */; }; 56BA1E7F2BAB2D29001CF69F /* ErrorPageTabExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E7C2BAB290E001CF69F /* ErrorPageTabExtensionTest.swift */; }; 56BA1E802BAB2E43001CF69F /* ErrorPageTabExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E7C2BAB290E001CF69F /* ErrorPageTabExtensionTest.swift */; }; 56BA1E822BAC506F001CF69F /* SSLErrorPageUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E812BAC506F001CF69F /* SSLErrorPageUserScript.swift */; }; @@ -4079,7 +4079,7 @@ 569277C029DDCBB500B633EF /* HomePageContinueSetUpModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePageContinueSetUpModel.swift; sourceTree = ""; }; 569277C329DEE09D00B633EF /* ContinueSetUpModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContinueSetUpModelTests.swift; sourceTree = ""; }; 56B234BE2A84EFD200F2A1CC /* NavigationBarUrlExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarUrlExtensionsTests.swift; sourceTree = ""; }; - 56BA1E742BAAF70F001CF69F /* ErrorPageTabExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPageTabExtension.swift; sourceTree = ""; }; + 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLErrorPageTabExtension.swift; sourceTree = ""; }; 56BA1E7C2BAB290E001CF69F /* ErrorPageTabExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPageTabExtensionTest.swift; sourceTree = ""; }; 56BA1E812BAC506F001CF69F /* SSLErrorPageUserScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLErrorPageUserScript.swift; sourceTree = ""; }; 56BA1E862BAC8239001CF69F /* SSLErrorPageUserScriptTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLErrorPageUserScriptTests.swift; sourceTree = ""; }; @@ -8436,7 +8436,7 @@ B66260E529ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift */, B66260DC29AC5D4300E9E3EE /* NavigationProtectionTabExtension.swift */, B626A76C29928B1600053070 /* TestsClosureNavigationResponder.swift */, - 56BA1E742BAAF70F001CF69F /* ErrorPageTabExtension.swift */, + 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */, ); path = TabExtensions; sourceTree = ""; @@ -10558,7 +10558,7 @@ 3706FB35293F65D500E42796 /* FlatButton.swift in Sources */, 3706FB36293F65D500E42796 /* PinnedTabView.swift in Sources */, 3706FB37293F65D500E42796 /* DataEncryption.swift in Sources */, - 56BA1E762BAAF70F001CF69F /* ErrorPageTabExtension.swift in Sources */, + 56BA1E762BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */, 4B9DB0362A983B24000927DB /* WaitlistTermsAndConditionsView.swift in Sources */, 37197EA82942443D00394917 /* BrowserTabViewController.swift in Sources */, 3706FB39293F65D500E42796 /* PrivacyDashboardPopover.swift in Sources */, @@ -11829,7 +11829,7 @@ 4B957A272AC7AE700062CA31 /* PrivacyDashboardPopover.swift in Sources */, 4B957A282AC7AE700062CA31 /* TestsClosureNavigationResponder.swift in Sources */, 4B957A292AC7AE700062CA31 /* RootView.swift in Sources */, - 56BA1E772BAAF70F001CF69F /* ErrorPageTabExtension.swift in Sources */, + 56BA1E772BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */, 4B37EE7C2B4CFF8000A89A61 /* HomePageRemoteMessagingRequest.swift in Sources */, 4B957A2A2AC7AE700062CA31 /* AddressBarTextField.swift in Sources */, 4B957A2B2AC7AE700062CA31 /* FocusRingView.swift in Sources */, @@ -12832,7 +12832,7 @@ 4B723E1226B0006E00E14D75 /* DataImport.swift in Sources */, 7BE146072A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift in Sources */, B6085D092743AAB600A9C456 /* FireproofDomains.xcdatamodeld in Sources */, - 56BA1E752BAAF70F001CF69F /* ErrorPageTabExtension.swift in Sources */, + 56BA1E752BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */, 85589E8227BBB8630038AD11 /* HomePageView.swift in Sources */, B6BF5D932947199A006742B1 /* SerpHeadersNavigationResponder.swift in Sources */, 569277C129DDCBB500B633EF /* HomePageContinueSetUpModel.swift in Sources */, diff --git a/DuckDuckGo/Tab/Model/Tab.swift b/DuckDuckGo/Tab/Model/Tab.swift index b717be9746..a1e4228051 100644 --- a/DuckDuckGo/Tab/Model/Tab.swift +++ b/DuckDuckGo/Tab/Model/Tab.swift @@ -1490,9 +1490,15 @@ extension Tab/*: NavigationResponder*/ { // to be moved to Tab+Navigation.swift invalidateInteractionStateData() - if !error.isFrameLoadInterrupted, !error.isNavigationCancelled, - self.content.urlForWebView == url { + if !error.isFrameLoadInterrupted, !error.isNavigationCancelled, error.errorCode != NSURLErrorServerCertificateUntrusted, + // don‘t show an error page if the error was already handled + // (by SearchNonexistentDomainNavigationResponder) or another navigation was triggered by `setContent` + self.content.urlForWebView == url { + self.error = error + // when already displaying the error page and reload navigation fails again: don‘t navigate, just update page HTML + let shouldPerformAlternateNavigation = navigation.url != webView.url || navigation.navigationAction.targetFrame?.url != .error + loadErrorHTML(error, header: UserText.errorPageHeader, forUnreachableURL: url, alternate: shouldPerformAlternateNavigation) } } diff --git a/DuckDuckGo/Tab/TabExtensions/ErrorPageTabExtension.swift b/DuckDuckGo/Tab/TabExtensions/SSLErrorPageTabExtension.swift similarity index 93% rename from DuckDuckGo/Tab/TabExtensions/ErrorPageTabExtension.swift rename to DuckDuckGo/Tab/TabExtensions/SSLErrorPageTabExtension.swift index 20284e3679..aac116210a 100644 --- a/DuckDuckGo/Tab/TabExtensions/ErrorPageTabExtension.swift +++ b/DuckDuckGo/Tab/TabExtensions/SSLErrorPageTabExtension.swift @@ -1,5 +1,5 @@ // -// ErrorPageTabExtension.swift +// SSLErrorPageTabExtension.swift // // Copyright © 2024 DuckDuckGo. All rights reserved. // @@ -29,7 +29,7 @@ protocol SSLErrorPageScriptProvider { extension UserScripts: SSLErrorPageScriptProvider {} -final class ErrorPageTabExtension { +final class SSLErrorPageTabExtension { weak var webView: ErrorPageTabExtensionNavigationDelegate? private weak var sslErrorPageUserScript: SSLErrorPageUserScript? private var shouldBypassSSLError = false @@ -79,11 +79,12 @@ final class ErrorPageTabExtension { } -extension ErrorPageTabExtension: NavigationResponder { +extension SSLErrorPageTabExtension: NavigationResponder { @MainActor func navigation(_ navigation: Navigation, didFailWith error: WKError) { let url = error.failingUrl ?? navigation.url guard navigation.isCurrent else { return } + guard error.errorCode != NSURLErrorCannotFindHost else { return } if !error.isFrameLoadInterrupted, !error.isNavigationCancelled { // when already displaying the error page and reload navigation fails again: don‘t navigate, just update page HTML @@ -94,8 +95,6 @@ extension ErrorPageTabExtension: NavigationResponder { let errorCode = error.userInfo["_kCFStreamErrorCodeKey"] as? Int { sslErrorPageUserScript?.failingURL = url loadSSLErrorHTML(url: url, alternate: shouldPerformAlternateNavigation, errorCode: errorCode) - } else { - loadErrorHTML(error, header: UserText.errorPageHeader, forUnreachableURL: url, alternate: shouldPerformAlternateNavigation) } } } @@ -117,7 +116,7 @@ extension ErrorPageTabExtension: NavigationResponder { } } -extension ErrorPageTabExtension: SSLErrorPageUserScriptDelegate { +extension SSLErrorPageTabExtension: SSLErrorPageUserScriptDelegate { func leaveSite() { guard webView?.canGoBack == true else { webView?.close() @@ -134,14 +133,14 @@ extension ErrorPageTabExtension: SSLErrorPageUserScriptDelegate { protocol ErrorPageTabExtensionProtocol: AnyObject, NavigationResponder {} -extension ErrorPageTabExtension: TabExtension, ErrorPageTabExtensionProtocol { +extension SSLErrorPageTabExtension: TabExtension, ErrorPageTabExtensionProtocol { typealias PublicProtocol = ErrorPageTabExtensionProtocol func getPublicProtocol() -> PublicProtocol { self } } extension TabExtensions { var errorPage: ErrorPageTabExtensionProtocol? { - resolve(ErrorPageTabExtension.self) + resolve(SSLErrorPageTabExtension.self) } } diff --git a/DuckDuckGo/Tab/TabExtensions/TabExtensions.swift b/DuckDuckGo/Tab/TabExtensions/TabExtensions.swift index 0cb7e77d48..b56da3410d 100644 --- a/DuckDuckGo/Tab/TabExtensions/TabExtensions.swift +++ b/DuckDuckGo/Tab/TabExtensions/TabExtensions.swift @@ -187,7 +187,7 @@ extension TabExtensionsBuilder { } add { - ErrorPageTabExtension(webViewPublisher: args.webViewFuture, + SSLErrorPageTabExtension(webViewPublisher: args.webViewFuture, scriptsPublisher: userScripts.compactMap { $0 }) } } diff --git a/UnitTests/TabExtensionsTests/ErrorPageTabExtensionTest.swift b/UnitTests/TabExtensionsTests/ErrorPageTabExtensionTest.swift index f825e858a8..51cfbfff44 100644 --- a/UnitTests/TabExtensionsTests/ErrorPageTabExtensionTest.swift +++ b/UnitTests/TabExtensionsTests/ErrorPageTabExtensionTest.swift @@ -29,7 +29,7 @@ final class ErrorPageTabExtensionTest: XCTestCase { var mockWebViewPublisher: PassthroughSubject! var scriptPublisher: PassthroughSubject! - var errorPageExtention: ErrorPageTabExtension! + var errorPageExtention: SSLErrorPageTabExtension! var credentialCreator: MockCredentialCreator! let errorURLString = "com.example.error" @@ -38,7 +38,7 @@ final class ErrorPageTabExtensionTest: XCTestCase { scriptPublisher = PassthroughSubject() credentialCreator = MockCredentialCreator() let featureFlagger = MockFeatureFlagger() - errorPageExtention = ErrorPageTabExtension(webViewPublisher: mockWebViewPublisher, scriptsPublisher: scriptPublisher, urlCredentialCreator: credentialCreator, featureFlagger: featureFlagger) + errorPageExtention = SSLErrorPageTabExtension(webViewPublisher: mockWebViewPublisher, scriptsPublisher: scriptPublisher, urlCredentialCreator: credentialCreator, featureFlagger: featureFlagger) } override func tearDownWithError() throws { @@ -108,22 +108,6 @@ final class ErrorPageTabExtensionTest: XCTestCase { } - @MainActor func testWhenGenericError_ThenExpectedErrorPageIsShown() { - // GIVEN - let mockWebView = MockWKWebView(url: URL(string: errorURLString)!) - errorPageExtention.webView = mockWebView - let errorDescription = "some error" - let error = WKError(_nsError: NSError(domain: "com.example.error", code: NSURLErrorUnknown, userInfo: ["_kCFStreamErrorCodeKey": -9843, "NSErrorFailingURLKey": URL(string: errorURLString)!, NSLocalizedDescriptionKey: errorDescription])) - let navigation = Navigation(identity: .init(nil), responders: .init(), state: .started, redirectHistory: [], isCurrent: true, isCommitted: true) - - // WHEN - errorPageExtention.navigation(navigation, didFailWith: error) - - // THEN - XCTAssertTrue(mockWebView.capturedHTML.contains("DuckDuckGo can’t load this page.")) - XCTAssertTrue(mockWebView.capturedHTML.contains(errorDescription)) - } - @MainActor func test_WhenUserScriptsPublisherPublishSSLErrorPageScript_ThenErrorPageExtensionIsSetAsUserScriptDelegate() { // GIVEN let aSSLErrorUserScript = SSLErrorPageUserScript()