Skip to content
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
27c2afa
Feature flag
tomasstrba Nov 25, 2025
bb08041
Legacy permission flow disabled when feature flag is on
tomasstrba Nov 25, 2025
2fe76f4
New permission center button
tomasstrba Nov 26, 2025
fabef1e
Feature flag fix
tomasstrba Nov 26, 2025
cf774e5
Comment corrected
tomasstrba Nov 26, 2025
0f89263
SwiftLint
tomasstrba Nov 26, 2025
4bfa91e
Update macOS/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewContr…
tomasstrba Nov 27, 2025
6cfc29a
Basic authorization prompt
tomasstrba Nov 27, 2025
c0a1f56
Popover reorganized
tomasstrba Nov 27, 2025
55c017e
Code improvements
tomasstrba Nov 27, 2025
6cb966a
Using correct popover for blocked popup
tomasstrba Nov 27, 2025
65e817d
Merge branch 'main' into tom/new-permission-view
tomasstrba Nov 27, 2025
60ec18f
Merge branch 'tom/new-permission-view' of github.com:duckduckgo/apple…
tomasstrba Nov 27, 2025
c083a9c
Improvements after code review
tomasstrba Nov 28, 2025
22509d0
Refactoring
tomasstrba Nov 28, 2025
4b472d1
Merge branch 'tom/new-permission-view' into tom/new-permission-view-a…
tomasstrba Nov 28, 2025
f480f2b
Various kinds of permissions in new authorization dialog
tomasstrba Nov 28, 2025
25cdbfe
Padding adjusted
tomasstrba Nov 28, 2025
7b12a02
SystemPermissionManager
tomasstrba Nov 28, 2025
09bf206
System authorization UI
tomasstrba Nov 28, 2025
fbab23a
Permission assertions handled
tomasstrba Nov 29, 2025
841b807
External schemes authorization flow finalized
tomasstrba Nov 29, 2025
631d17d
Merge branch 'main' into tom/new-permission-view-authorization
tomasstrba Nov 29, 2025
d23abcf
Refactoring and polishing of the experience
tomasstrba Nov 29, 2025
346e667
Changes to state when system geolocation permission is denied
tomasstrba Nov 29, 2025
eb020a3
Refactoring SystemPermissionManager to only contain what's necessary
tomasstrba Nov 30, 2025
4c29deb
Foundation for permission center
tomasstrba Nov 30, 2025
561413d
Positioning of permission center fixed
tomasstrba Nov 30, 2025
09359a5
Permission center view polished
tomasstrba Nov 30, 2025
4262bd2
Edge case when system permissions are disabled polished in permission…
tomasstrba Nov 30, 2025
5f4b3fa
Removing (and revoking) permission from permission center
tomasstrba Nov 30, 2025
085136b
Skip sending permissions state to Privacy Dashboard when new permissi…
tomasstrba Nov 30, 2025
8847ce6
External schemes handled
tomasstrba Nov 30, 2025
d5d879a
Merge branch 'main' into tom/new-permission-view-authorization
tomasstrba Dec 1, 2025
169c4d8
Merge branch 'main' into tom/new-permission-view-authorization
tomasstrba Dec 1, 2025
37b8092
Swiftlint
tomasstrba Dec 1, 2025
f792f6c
Merge branch 'tom/new-permission-view-authorization' of github.com:du…
tomasstrba Dec 1, 2025
cca0bf9
Unit test compilation
tomasstrba Dec 1, 2025
3d9b985
Addressing feedback from PR
tomasstrba Dec 1, 2025
9d27ec1
Solving camera&microphone in one request
tomasstrba Dec 1, 2025
88b1b25
Default argument removed
tomasstrba Dec 2, 2025
657094e
No reloading of website after removing of permission
tomasstrba Dec 2, 2025
b327740
Assertion failure added + also handled local URLs as localhost domain…
tomasstrba Dec 2, 2025
30c0fec
Assertion failure added
tomasstrba Dec 2, 2025
9e8363e
PermissionAuthorizationTypeTests
tomasstrba Dec 2, 2025
8b4f8b2
Merge branch 'main' into tom/new-permission-view-authorization
tomasstrba Dec 3, 2025
c246a74
Sync local state when the item's decision changes from external source
tomasstrba Dec 3, 2025
13003ad
Code review adjustments
tomasstrba Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public enum MacOSBrowserConfigSubfeature: String, PrivacySubfeature {
/// Tab closing event recreation feature flag (failsafe for removing private API)
/// https://app.asana.com/1/137249556945/project/1211834678943996/task/1212206087745586?focus=true
case tabClosingEventRecreation

}

public enum iOSBrowserConfigSubfeature: String, PrivacySubfeature {
Expand Down
44 changes: 44 additions & 0 deletions macOS/DuckDuckGo-macOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions macOS/DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -705,16 +705,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
if AppVersion.runType.requiresEnvironment {
fireproofDomains = FireproofDomains(store: FireproofDomainsStore(database: database.db, tableName: "FireproofDomains"), tld: tld)
faviconManager = FaviconManager(cacheType: .standard(database.db), bookmarkManager: bookmarkManager, fireproofDomains: fireproofDomains)
permissionManager = PermissionManager(store: LocalPermissionStore(database: database.db))
permissionManager = PermissionManager(store: LocalPermissionStore(database: database.db), featureFlagger: featureFlagger)
} else {
fireproofDomains = FireproofDomains(store: FireproofDomainsStore(context: nil), tld: tld)
faviconManager = FaviconManager(cacheType: .inMemory, bookmarkManager: bookmarkManager, fireproofDomains: fireproofDomains)
permissionManager = PermissionManager(store: LocalPermissionStore(database: nil))
permissionManager = PermissionManager(store: LocalPermissionStore(database: nil), featureFlagger: featureFlagger)
}
#else
fireproofDomains = FireproofDomains(store: FireproofDomainsStore(database: database.db, tableName: "FireproofDomains"), tld: tld)
faviconManager = FaviconManager(cacheType: .standard(database.db), bookmarkManager: bookmarkManager, fireproofDomains: fireproofDomains)
permissionManager = PermissionManager(store: LocalPermissionStore(database: database.db))
permissionManager = PermissionManager(store: LocalPermissionStore(database: database.db), featureFlagger: featureFlagger)
#endif

webCacheManager = WebCacheManager(fireproofDomains: fireproofDomains)
Expand Down
12 changes: 12 additions & 0 deletions macOS/DuckDuckGo/Common/Extensions/NSColorExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ extension NSColor {
.blackWhite10
}

/// Background color for permission warning rows (system permission disabled)
/// Light mode: #FFF0C2, Dark mode: #C18010 at 16% opacity
static var permissionWarningBackground: NSColor {
NSColor(name: nil) { appearance in
if appearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua {
return NSColor(red: 0xC1 / 255.0, green: 0x80 / 255.0, blue: 0x10 / 255.0, alpha: 0.16)
} else {
return NSColor(red: 0xFF / 255.0, green: 0xF0 / 255.0, blue: 0xC2 / 255.0, alpha: 1.0)
}
}
}

// MARK: - Helpers

var ciColor: CIColor {
Expand Down
22 changes: 22 additions & 0 deletions macOS/DuckDuckGo/Common/Localizables/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -978,11 +978,33 @@ struct UserText {
static let permissionPopupLearnMoreLink = NSLocalizedString("permission.popup.learn-more.link", value: "Learn more about location services", comment: "Text of link that leads to web page with more informations about location services.")
static let permissionPopupAllowButton = NSLocalizedString("permission.popup.allow.button", value: "Allow", comment: "Button that the user can use to authorise a web site to for, for example access location or camera and microphone etc.")

static let permissionPopupDenyButton = NSLocalizedString("permission.popup.deny.button", value: "Deny", comment: "Button that denies permission for this request only")
static let permissionPopupAlwaysDenyButton = NSLocalizedString("permission.popup.always.deny.button", value: "Never Allow", comment: "Button that denies permission and remembers the decision for future requests")
static let permissionPopupAlwaysAllowButton = NSLocalizedString("permission.popup.always.allow.button", value: "Always Allow", comment: "Button that grants permission and remembers the decision for future requests")

static let privacyDashboardPermissionAsk = NSLocalizedString("dashboard.permission.ask", value: "Ask every time", comment: "Privacy Dashboard: Website should always Ask for permission for input media device access")
static let privacyDashboardPermissionAlwaysAllow = NSLocalizedString("dashboard.permission.allow", value: "Always allow", comment: "Privacy Dashboard: Website can always access input media device")
static let privacyDashboardPermissionAlwaysDeny = NSLocalizedString("dashboard.permission.deny", value: "Always deny", comment: "Privacy Dashboard: Website can never access input media device")
static let permissionPopoverDenyButton = NSLocalizedString("permission.popover.deny", value: "Deny", comment: "Permission Popover: Deny Website input media device access")

// Two-step permission authorization (geolocation)
static let permissionSystemLocationEnable = NSLocalizedString("permission.system.location.enable", value: "Enable System Location", comment: "Button to enable system location services")
static let permissionSystemLocationWaiting = NSLocalizedString("permission.system.location.waiting", value: "Waiting for system permission…", comment: "Text shown while waiting for user to respond to system location permission dialog")
static let permissionSystemLocationEnabled = NSLocalizedString("permission.system.location.enabled", value: "System location enabled!", comment: "Text shown after system location permission has been granted")
static let permissionSystemLocationDisabled = NSLocalizedString("permission.system.location.disabled", value: "System location disabled. Turn it on in ", comment: "Text shown when system location was previously denied. Followed by a link to System Settings")
static let permissionSystemSettingsLocation = NSLocalizedString("permission.system.settings.location", value: "System Settings → Privacy", comment: "Link text to open System Settings Privacy section for location")
static let permissionRestartApp = NSLocalizedString("permission.restart.app", value: "Restart the DuckDuckGo application", comment: "Text shown when app restart is required for permission changes to take effect")
static let permissionGeolocationPromptFormat = NSLocalizedString("permission.geolocation.prompt.format", value: "Allow %@ to use your current location?", comment: "Prompt asking if domain %@ can use location")
static let permissionPopupNeverAllowButton = NSLocalizedString("permission.popup.never.allow.button", value: "Never Allow", comment: "Button that denies permission and remembers the decision for future requests")

// Permission Center
static let permissionCenterTitle = NSLocalizedString("permission.center.title", value: "Permissions for \"%@\"", comment: "Title for permission center popover, %@ is the domain name")
static let permissionCenterAlwaysAsk = NSLocalizedString("permission.center.always.ask", value: "Always Ask", comment: "Permission center dropdown option to always ask for permission")
static let permissionCenterAlwaysAllow = NSLocalizedString("permission.center.always.allow", value: "Always Allow", comment: "Permission center dropdown option to always allow permission")
static let permissionCenterNeverAllow = NSLocalizedString("permission.center.never.allow", value: "Never Allow", comment: "Permission center dropdown option to never allow permission")
static let permissionCenterExternalSchemeDescription = NSLocalizedString("permission.center.external.scheme.description", value: "%@ to open \"%@\" links", comment: "Description for external scheme permission, first %@ is domain, second %@ is scheme name")
static let permissionCenterExternalApps = NSLocalizedString("permission.center.external.apps", value: "External Apps", comment: "Permission center header for external app permissions")

static let privacyDashboardPopupsAlwaysAsk = NSLocalizedString("dashboard.popups.ask", value: "Notify", comment: "Make pop-up windows always request permission for the current domain")

static let settings = NSLocalizedString("settings", value: "Settings", comment: "Menu item for opening settings")
Expand Down
Loading