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

Commit 7043bf3

Browse files
Merge remote-tracking branch 'origin/main' into jkt/shared-web-tests
2 parents 3c11508 + 8923a1d commit 7043bf3

File tree

120 files changed

+6008
-328
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+6008
-328
lines changed

.github/workflows/ios-end-to-end.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,4 @@ jobs:
115115
# --header "Accept: application/json" \
116116
# --header "Authorization: Bearer ${{ secrets.ASANA_ACCESS_TOKEN }}" \
117117
# --header "Content-Type: application/json" \
118-
# --data ' { "data": { "name": "GH Workflow Failure - End to end tests", "workspace": "${{ vars.GH_ASANA_WORKSPACE_ID }}", "projects": [ "${{ vars.GH_ASANA_IOS_APP_PROJECT_ID }}" ], "notes" : "The end to end workflow has failed. See https://github.com/duckduckgo/iOS/actions/runs/${{ github.run_id }}. For instructions on how to handle the failure(s), check https://app.asana.com/0/0/1206423571874502/f" } }'
118+
# --data ' { "data": { "name": "GH Workflow Failure - End to end tests", "workspace": "${{ vars.ASANA_WORKSPACE_ID }}", "projects": [ "${{ vars.GH_ASANA_IOS_APP_PROJECT_ID }}" ], "notes" : "The end to end workflow has failed. See https://github.com/duckduckgo/iOS/actions/runs/${{ github.run_id }}. For instructions on how to handle the failure(s), check https://app.asana.com/0/0/1206423571874502/f" } }'

.github/workflows/ios-sync-end-to-end.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,4 @@ jobs:
132132
# --header "Accept: application/json" \
133133
# --header "Authorization: Bearer ${{ secrets.ASANA_ACCESS_TOKEN }}" \
134134
# --header "Content-Type: application/json" \
135-
# --data ' { "data": { "name": "GH Workflow Failure - Sync End to end tests", "workspace": "${{ vars.GH_ASANA_WORKSPACE_ID }}", "projects": [ "${{ vars.GH_ASANA_IOS_APP_PROJECT_ID }}" ], "notes" : "The end to end workflow has failed. See https://github.com/duckduckgo/iOS/actions/runs/${{ github.run_id }}" } }'
135+
# --data ' { "data": { "name": "GH Workflow Failure - Sync End to end tests", "workspace": "${{ vars.ASANA_WORKSPACE_ID }}", "projects": [ "${{ vars.GH_ASANA_IOS_APP_PROJECT_ID }}" ], "notes" : "The end to end workflow has failed. See https://github.com/duckduckgo/iOS/actions/runs/${{ github.run_id }}" } }'
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# state_restoration.yaml
2+
appId: com.duckduckgo.mobile.ios
3+
tags:
4+
- release
5+
6+
---
7+
8+
# Set up
9+
- runFlow:
10+
file: ../shared/setup.yaml
11+
12+
# Load Site
13+
- assertVisible:
14+
id: "searchEntry"
15+
- tapOn:
16+
id: "searchEntry"
17+
- inputText: "https://www.wikipedia.org/"
18+
- pressKey: Enter
19+
20+
# Create navigation stack
21+
- assertVisible: "English"
22+
- tapOn: "English"
23+
- assertVisible: "Welcome to Wikipedia.*"
24+
- tapOn: "Wikipedia"
25+
- assertVisible: "Article"
26+
- scrollUntilVisible:
27+
element: "United States"
28+
# Make sure bottom bar is visible
29+
- tapOn:
30+
point: 80%, 99%
31+
- tapOn: "Browse Back"
32+
- assertVisible: "Welcome to Wikipedia.*"
33+
34+
# Load a new tab
35+
- longPressOn: "Tab Switcher"
36+
- assertVisible:
37+
id: "searchEntry"
38+
- tapOn:
39+
id: "searchEntry"
40+
- inputText: "https://example.com"
41+
- pressKey: Enter
42+
43+
- stopApp
44+
- launchApp
45+
46+
- tapOn: "Tab Switcher"
47+
- tapOn:
48+
point: 20%, 25%
49+
50+
# Check if state from previous session was restored
51+
- assertVisible: "Welcome to Wikipedia.*"
52+
- tapOn: "Browse Forward"
53+
- assertVisible: "United States"

Core/AppURLs.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public extension URL {
3838
static let apps = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/apps?origin=funnel_app_ios"))!
3939
static let searchSettings = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/settings"))!
4040
static let autofillHelpPageLink = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/duckduckgo-help-pages/sync-and-backup/password-manager-security/"))!
41+
static let maliciousSiteProtectionLearnMore = URL(string: AppDeepLinkSchemes.quickLink.appending("\(ddg.host!)/duckduckgo-help-pages/privacy/phishing-and-malware-protection/"))!
4142

4243
static let surrogates = URL(string: "\(staticBase)/surrogates.txt")!
4344

Core/FeatureFlag.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,14 @@ public enum FeatureFlag: String {
7070
/// https://app.asana.com/0/72649045549333/1208944782348823/f
7171
case syncSeamlessAccountSwitching
7272

73+
/// https://app.asana.com/0/1204167627774280/1209205869217377
74+
case aiChatNewTabPage
75+
7376
case testExperiment
77+
78+
/// Feature flag to enable / disable phishing and malware protection
79+
/// https://app.asana.com/0/1206329551987282/1207149365636877/f
80+
case maliciousSiteProtection
7481
}
7582

7683
extension FeatureFlag: FeatureFlagDescribing {
@@ -172,8 +179,12 @@ extension FeatureFlag: FeatureFlagDescribing {
172179
return .remoteReleasable(.feature(.webViewStateRestoration))
173180
case .syncSeamlessAccountSwitching:
174181
return .remoteReleasable(.subfeature(SyncSubfeature.seamlessAccountSwitching))
182+
case .aiChatNewTabPage:
183+
return .internalOnly()
175184
case .testExperiment:
176185
return .remoteReleasable(.subfeature(ExperimentTestSubfeatures.experimentTestAA))
186+
case .maliciousSiteProtection:
187+
return .remoteReleasable(.subfeature(MaliciousSiteProtectionSubfeature.onByDefault))
177188
}
178189
}
179190
}

Core/HistoryManager.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ class NullHistoryCoordinator: HistoryCoordinating {
114114
return nil
115115
}
116116

117+
func addVisit(of url: URL, at date: Date) -> History.Visit? {
118+
return nil
119+
}
120+
117121
func addBlockedTracker(entityName: String, on url: URL) {
118122
}
119123

Core/Pixel.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ public struct PixelParameters {
168168
public static let appEvent = "event"
169169

170170
public static let didCallWillEnterForeground = "didCallWillEnterForeground"
171+
172+
// Background Tasks
173+
public static let backgroundTaskCategory = "category"
171174
}
172175

173176
public struct PixelValues {

Core/PixelEvent.swift

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import BrowserServicesKit
2222
import Bookmarks
2323
import Configuration
2424
import DDGSync
25+
import MaliciousSiteProtection
26+
import PixelKit
2527

2628
extension Pixel {
2729

@@ -979,6 +981,9 @@ extension Pixel {
979981

980982
case tabInteractionStateFailedToRestore
981983
case tabInteractionStateRestorationTime(_ time: BucketAggregation)
984+
985+
// MARK: Malicious Site Protection
986+
case maliciousSiteProtection(event: MaliciousSiteProtectionEvent)
982987
}
983988

984989
}
@@ -1540,7 +1545,7 @@ extension Pixel.Event {
15401545
case .webKitWarmupUnexpectedDidFinish: return "m_d_webkit-warmup-unexpected-did-finish"
15411546
case .webKitWarmupUnexpectedDidTerminate: return "m_d_webkit-warmup-unexpected-did-terminate"
15421547

1543-
case .backgroundTaskSubmissionFailed: return "m_bt_rf"
1548+
case .backgroundTaskSubmissionFailed: return "m_background-task_submission-failed"
15441549

15451550
case .blankOverlayNotDismissed: return "m_d_ovs"
15461551

@@ -1961,6 +1966,9 @@ extension Pixel.Event {
19611966
case .appDidTransitionToUnexpectedState: return "m_debug_app-did-transition-to-unexpected-state-3"
19621967

19631968
case .debugBreakageExperiment: return "m_debug_breakage_experiment_u"
1969+
1970+
// MARK: Malicious Site Protection
1971+
case .maliciousSiteProtection(let event): return "m_\(event.name)"
19641972
}
19651973
}
19661974
}
@@ -2081,3 +2089,67 @@ extension Pixel.Event {
20812089
}
20822090
}
20832091
}
2092+
2093+
// This is a temporary mapper from PixelKit to Pixel events for MaliciousSiteProtection
2094+
// Malicious Site Protection BSK library depends on PixelKit which is not ready yet to be ported to iOS.
2095+
// The below code maps between `PixelKitEvent` to `Pixel.Event` in order to use `Pixel.fire` on the client.
2096+
public extension Pixel.Event {
2097+
2098+
enum MaliciousSiteProtectionEvent: Equatable {
2099+
case errorPageShown(category: ThreatKind, clientSideHit: Bool?)
2100+
case visitSite(category: ThreatKind)
2101+
case iframeLoaded(category: ThreatKind)
2102+
case settingToggled(to: Bool)
2103+
case matchesApiTimeout
2104+
case failedToDownloadInitialDataSets(category: ThreatKind, type: DataManager.StoredDataType.Kind)
2105+
2106+
public init?(_ pixelKitEvent: MaliciousSiteProtection.Event) {
2107+
switch pixelKitEvent {
2108+
case .errorPageShown(category: let category, clientSideHit: let clientSideHit):
2109+
self = .errorPageShown(category: category, clientSideHit: clientSideHit)
2110+
case .visitSite(category: let category):
2111+
self = .visitSite(category: category)
2112+
case .iframeLoaded(category: let category):
2113+
self = .iframeLoaded(category: category)
2114+
case .settingToggled(let enabled):
2115+
self = .settingToggled(to: enabled)
2116+
case .matchesApiTimeout:
2117+
self = .matchesApiTimeout
2118+
case .matchesApiFailure:
2119+
return nil
2120+
case .failedToDownloadInitialDataSets(category: let category, type: let type):
2121+
self = .failedToDownloadInitialDataSets(category: category, type: type)
2122+
}
2123+
}
2124+
2125+
private var event: PixelKitEventV2 {
2126+
switch self {
2127+
case .errorPageShown(let category, let clientSideHit):
2128+
return MaliciousSiteProtection.Event.errorPageShown(category: category, clientSideHit: clientSideHit)
2129+
case .visitSite(let category):
2130+
return MaliciousSiteProtection.Event.visitSite(category: category)
2131+
case .iframeLoaded(let category):
2132+
return MaliciousSiteProtection.Event.iframeLoaded(category: category)
2133+
case .settingToggled(let enabled):
2134+
return MaliciousSiteProtection.Event.settingToggled(to: enabled)
2135+
case .matchesApiTimeout:
2136+
return MaliciousSiteProtection.Event.matchesApiTimeout
2137+
case .failedToDownloadInitialDataSets(let category, let type):
2138+
return MaliciousSiteProtection.Event.failedToDownloadInitialDataSets(category: category, type: type)
2139+
}
2140+
}
2141+
2142+
var name: String {
2143+
switch self {
2144+
case .failedToDownloadInitialDataSets:
2145+
return "debug_\(event.name)"
2146+
default:
2147+
return event.name
2148+
}
2149+
}
2150+
2151+
public var parameters: [String: String] {
2152+
event.parameters ?? [:]
2153+
}
2154+
}
2155+
}

Core/UserAgentManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ struct UserAgent {
283283
isDesktop: Bool,
284284
privacyConfig: PrivacyConfiguration) -> String {
285285
if isDesktop {
286-
return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15"
286+
return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15"
287287
}
288288
return "Mozilla/5.0 (" + deviceProfile + ") AppleWebKit/605.1.15 (KHTML, like Gecko) \(versionComponent) Mobile/15E148 Safari/604.1"
289289
}

Core/UserDefaultsPropertyWrapper.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ public struct UserDefaultsWrapper<T> {
182182

183183
// TipKit
184184
case resetTipKitOnNextLaunch = "com.duckduckgo.ios.tipKit.resetOnNextLaunch"
185+
186+
// Malicious Site Protection
187+
case maliciousSiteProtectionEnabled = "com.duckduckgo.ios.maliciousSiteProtection.enabled"
185188
}
186189

187190
private let key: Key

0 commit comments

Comments
 (0)