Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.

Commit 3448518

Browse files
Malicious site protection address bar and privacy dashboard changes (#3718)
Task/Issue URL: https://app.asana.com/0/1206329551987282/1208959082985728/f Tech Design: https://app.asana.com/0/1206329551987282/1207273224076495/f **Description**: This PR addresses the following: 1. Updates the Privacy Icon to use the globe asset when visiting special error pages (SSL error included). 2. Updates the Privacy icon to use the alert asset when the user accepts the risk of visiting a malicious page. 3. Show an updated privacy dashboard for phishing and malware special error pages.
1 parent d8ba501 commit 3448518

17 files changed

+203
-17
lines changed

DuckDuckGo-iOS.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@
823823
9F254B032CF9FB2E0063B308 /* SpecialErrorPageNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254B022CF9FB2E0063B308 /* SpecialErrorPageNavigationDelegate.swift */; };
824824
9F254B052CF9FB890063B308 /* SpecialErrorPageContextHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254B042CF9FB890063B308 /* SpecialErrorPageContextHandling.swift */; };
825825
9F254B082CF9FC270063B308 /* SpecialErrorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F254B072CF9FC270063B308 /* SpecialErrorModel.swift */; };
826+
9F38A28C2D09BDE500EB100E /* SpecialErrorPageThreatProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F38A28B2D09BDE500EB100E /* SpecialErrorPageThreatProvider.swift */; };
826827
9F46BEF82CD8D7490092E0EF /* OnboardingView+AddToDockContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F46BEF72CD8D7490092E0EF /* OnboardingView+AddToDockContent.swift */; };
827828
9F4CC5152C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4CC5142C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift */; };
828829
9F4CC5172C48B8D4006A96EB /* TabViewControllerDaxDialogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4CC5162C48B8D4006A96EB /* TabViewControllerDaxDialogTests.swift */; };
@@ -2743,6 +2744,7 @@
27432744
9F254B022CF9FB2E0063B308 /* SpecialErrorPageNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpecialErrorPageNavigationDelegate.swift; sourceTree = "<group>"; };
27442745
9F254B042CF9FB890063B308 /* SpecialErrorPageContextHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpecialErrorPageContextHandling.swift; sourceTree = "<group>"; };
27452746
9F254B072CF9FC270063B308 /* SpecialErrorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpecialErrorModel.swift; sourceTree = "<group>"; };
2747+
9F38A28B2D09BDE500EB100E /* SpecialErrorPageThreatProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpecialErrorPageThreatProvider.swift; sourceTree = "<group>"; };
27462748
9F46BEF72CD8D7490092E0EF /* OnboardingView+AddToDockContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnboardingView+AddToDockContent.swift"; sourceTree = "<group>"; };
27472749
9F4CC5142C47AD08006A96EB /* ContextualOnboardingPresenterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextualOnboardingPresenterMock.swift; sourceTree = "<group>"; };
27482750
9F4CC5162C48B8D4006A96EB /* TabViewControllerDaxDialogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewControllerDaxDialogTests.swift; sourceTree = "<group>"; };
@@ -5338,6 +5340,7 @@
53385340
9F254B002CF9FA8D0063B308 /* SpecialErrorPageActionHandler.swift */,
53395341
9F254B022CF9FB2E0063B308 /* SpecialErrorPageNavigationDelegate.swift */,
53405342
9F254B042CF9FB890063B308 /* SpecialErrorPageContextHandling.swift */,
5343+
9F38A28B2D09BDE500EB100E /* SpecialErrorPageThreatProvider.swift */,
53415344
);
53425345
path = SpecialErrorPageInterfaces;
53435346
sourceTree = "<group>";
@@ -8423,6 +8426,7 @@
84238426
F42EF9312614BABE00101FB9 /* ActionSheetDaxDialogViewController.swift in Sources */,
84248427
EEC02C142B0519DE0045CE11 /* NetworkProtectionVPNLocationViewModel.swift in Sources */,
84258428
D63FF8962C1B67E9006DE24D /* YoutubeOverlayUserScript.swift in Sources */,
8429+
9F38A28C2D09BDE500EB100E /* SpecialErrorPageThreatProvider.swift in Sources */,
84268430
F13B4BC01F180D8A00814661 /* TabsModel.swift in Sources */,
84278431
8598D2E02CEB98B500C45685 /* Favicons.swift in Sources */,
84288432
8598D2E12CEB98B500C45685 /* NotFoundCachingDownloader.swift in Sources */,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "Alert-Recolorable-24.pdf",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}

DuckDuckGo/Base.lproj/OmniBar.xib

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@
166166
<constraint firstAttribute="width" constant="158" id="yFt-j7-mPi"/>
167167
</constraints>
168168
</view>
169-
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LogoIcon" translatesAutoresizingMaskIntoConstraints="NO" id="eoZ-Ly-QHi">
169+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="eoZ-Ly-QHi">
170170
<rect key="frame" x="0.0" y="2" width="43" height="38"/>
171171
</imageView>
172172
</subviews>
@@ -185,9 +185,9 @@
185185
<constraint firstItem="eoZ-Ly-QHi" firstAttribute="leading" secondItem="99p-YW-bjm" secondAttribute="leading" id="VgX-60-gzX"/>
186186
</constraints>
187187
<connections>
188-
<outlet property="daxLogoImageView" destination="eoZ-Ly-QHi" id="aTN-UG-1Em"/>
189188
<outlet property="shieldAnimationView" destination="dqb-pm-Da8" id="m3S-lp-2hi"/>
190189
<outlet property="shieldDotAnimationView" destination="D46-aN-352" id="yuP-Tc-fZl"/>
190+
<outlet property="staticImageView" destination="eoZ-Ly-QHi" id="DD9-w9-GZy"/>
191191
<outlet property="staticShieldAnimationView" destination="jQy-me-Afa" id="pez-0Q-5Gq"/>
192192
<outlet property="staticShieldDotAnimationView" destination="KE6-Wh-7Yp" id="92x-it-Oyn"/>
193193
<outletCollection property="gestureRecognizers" destination="qXd-RO-1cS" appends="YES" id="3xf-ou-ORG"/>
@@ -458,7 +458,6 @@
458458
<image name="Clear-24" width="24" height="24"/>
459459
<image name="Close-24" width="24" height="24"/>
460460
<image name="Find-Search-20" width="20" height="20"/>
461-
<image name="LogoIcon" width="24" height="24"/>
462461
<image name="Microphone-24" width="24" height="24"/>
463462
<image name="Reload-24" width="24" height="24"/>
464463
<image name="Settings-24" width="24" height="24"/>
@@ -467,7 +466,7 @@
467466
<color red="0.96078431372549022" green="0.96078431372549022" blue="0.96078431372549022" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
468467
</namedColor>
469468
<systemColor name="systemGreenColor">
470-
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
469+
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
471470
</systemColor>
472471
<systemColor name="systemYellowColor">
473472
<color red="1" green="0.80000000000000004" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>

DuckDuckGo/OmniBar.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extension OmniBar: NibLoading {}
2929

3030
public enum OmniBarIcon: String {
3131
case duckPlayer = "DuckPlayerURLIcon"
32+
case specialError = "Globe-24"
3233
}
3334

3435
class OmniBar: UIView {
@@ -300,10 +301,15 @@ class OmniBar: UIView {
300301
showCustomIcon(icon: .duckPlayer)
301302
return
302303
}
303-
304-
privacyInfoContainer.privacyIcon.isHidden = privacyInfo.isSpecialErrorPageVisible
304+
305+
if privacyInfo.isSpecialErrorPageVisible {
306+
showCustomIcon(icon: .specialError)
307+
return
308+
}
309+
305310
let icon = PrivacyIconLogic.privacyIcon(for: privacyInfo)
306311
privacyInfoContainer.privacyIcon.updateIcon(icon)
312+
privacyInfoContainer.privacyIcon.isHidden = false
307313
customIconView.isHidden = true
308314
}
309315

DuckDuckGo/PrivacyIconLogic.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ final class PrivacyIconLogic {
3434
static func privacyIcon(for privacyInfo: PrivacyInfo) -> PrivacyIcon {
3535
if privacyInfo.url.isDuckDuckGoSearch {
3636
return .daxLogo
37+
} else if privacyInfo.malicousSiteThreatKind != .none {
38+
return .alert
3739
} else {
3840
let config = ContentBlocking.shared.privacyConfigurationManager.privacyConfig
3941
let isUserUnprotected = config.isUserUnprotected(domain: privacyInfo.url.host)

DuckDuckGo/PrivacyIconView.swift

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,20 @@ import UIKit
2222
import Lottie
2323

2424
enum PrivacyIcon {
25-
case daxLogo, shield, shieldWithDot
25+
case daxLogo, shield, shieldWithDot, alert
26+
27+
fileprivate var staticImage: UIImage? {
28+
switch self {
29+
case .daxLogo: return UIImage(resource: .logoIcon)
30+
case .alert: return UIImage(resource: .alertColor24)
31+
default: return nil
32+
}
33+
}
2634
}
2735

2836
class PrivacyIconView: UIView {
2937

30-
@IBOutlet var daxLogoImageView: UIImageView!
38+
@IBOutlet var staticImageView: UIImageView!
3139
@IBOutlet var staticShieldAnimationView: LottieAnimationView!
3240
@IBOutlet var staticShieldDotAnimationView: LottieAnimationView!
3341

@@ -91,16 +99,17 @@ class PrivacyIconView: UIView {
9199

92100
private func updateShieldImageView(for icon: PrivacyIcon) {
93101
switch icon {
94-
case .daxLogo:
95-
daxLogoImageView.isHidden = false
102+
case .daxLogo, .alert:
103+
staticImageView.isHidden = false
104+
staticImageView.image = icon.staticImage
96105
staticShieldAnimationView.isHidden = true
97106
staticShieldDotAnimationView.isHidden = true
98107
case .shield:
99-
daxLogoImageView.isHidden = true
108+
staticImageView.isHidden = true
100109
staticShieldAnimationView.isHidden = false
101110
staticShieldDotAnimationView.isHidden = true
102111
case .shieldWithDot:
103-
daxLogoImageView.isHidden = true
112+
staticImageView.isHidden = true
104113
staticShieldAnimationView.isHidden = true
105114
staticShieldDotAnimationView.isHidden = false
106115
}
@@ -116,6 +125,10 @@ class PrivacyIconView: UIView {
116125
accessibilityLabel = UserText.privacyIconShield
117126
accessibilityHint = UserText.privacyIconOpenDashboardHint
118127
accessibilityTraits = .button
128+
case .alert:
129+
accessibilityLabel = UserText.privacyIconShield
130+
accessibilityHint = UserText.privacyIconOpenDashboardHint
131+
accessibilityTraits = .button
119132
}
120133
}
121134

@@ -134,7 +147,7 @@ class PrivacyIconView: UIView {
134147

135148
staticShieldAnimationView.isHidden = true
136149
staticShieldDotAnimationView.isHidden = true
137-
daxLogoImageView.isHidden = true
150+
staticImageView.isHidden = true
138151
}
139152

140153
func shieldAnimationView(for icon: PrivacyIcon) -> LottieAnimationView? {

DuckDuckGo/SpecialErrorPage/SpecialErrorPageInterfaces/SpecialErrorPageContextHandling.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import WebKit
2222
import SpecialErrorPages
2323

2424
/// A type that defines the base functionality for handling navigation related to special error pages.
25-
protocol SpecialErrorPageContextHandling: AnyObject {
25+
protocol SpecialErrorPageContextHandling: SpecialErrorPageThreatProvider {
2626
/// The delegate that handles navigation actions for special error pages.
2727
var delegate: SpecialErrorPageNavigationDelegate? { get set }
2828

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// SpecialErrorPageThreatProvider.swift
3+
// DuckDuckGo
4+
//
5+
// Copyright © 2024 DuckDuckGo. All rights reserved.
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License.
18+
//
19+
20+
import Foundation
21+
import MaliciousSiteProtection
22+
23+
protocol SpecialErrorPageThreatProvider: AnyObject {
24+
/// Provides the current threat kind detected.
25+
///
26+
/// - Returns: An optional `ThreatKind` that indicates the current threat type, or `nil` if no threat is detected.
27+
@MainActor
28+
var currentThreatKind: ThreatKind? { get }
29+
}

DuckDuckGo/SpecialErrorPage/SpecialErrorPageNavigationHandler+MaliciousSite.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ enum MaliciousSiteProtectionNavigationResult: Equatable {
3434
}
3535
}
3636

37-
protocol MaliciousSiteProtectionNavigationHandling: AnyObject {
37+
protocol MaliciousSiteProtectionNavigationHandling: SpecialErrorPageThreatProvider {
3838
/// Creates a task for detecting malicious sites based on the provided navigation action.
3939
///
4040
/// - Parameters:
@@ -78,6 +78,11 @@ final class MaliciousSiteProtectionNavigationHandler {
7878

7979
extension MaliciousSiteProtectionNavigationHandler: MaliciousSiteProtectionNavigationHandling {
8080

81+
@MainActor
82+
var currentThreatKind: ThreatKind? {
83+
bypassedMaliciousSiteThreatKind
84+
}
85+
8186
@MainActor
8287
func makeMaliciousSiteDetectionTask(for navigationAction: WKNavigationAction, webView: WKWebView) {
8388

0 commit comments

Comments
 (0)