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

Commit 970750c

Browse files
authored
Changes to Credit Card Autofill behaviour (#1928)
Task/Issue URL: https://app.asana.com/0/1175293949586521/1206085730384194/f Tech Design URL: CC: Description: Updates Credit Card autofill to always require device authentication before filling forms (with 10 second grace period)
1 parent 3fa0135 commit 970750c

File tree

8 files changed

+49
-13
lines changed

8 files changed

+49
-13
lines changed

DuckDuckGo.xcodeproj/project.pbxproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -12752,7 +12752,7 @@
1275212752
repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit";
1275312753
requirement = {
1275412754
kind = exactVersion;
12755-
version = 92.0.3;
12755+
version = 92.0.4;
1275612756
};
1275712757
};
1275812758
AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */ = {

DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
"kind" : "remoteSourceControl",
1515
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
1616
"state" : {
17-
"revision" : "5ca0b3d915ab73de43744db40edf41c1d5060034",
18-
"version" : "92.0.3"
17+
"revision" : "33e55105acc9d6d69ae1326fd5c506cefb89d5cc",
18+
"version" : "92.0.4"
1919
}
2020
},
2121
{
@@ -32,8 +32,8 @@
3232
"kind" : "remoteSourceControl",
3333
"location" : "https://github.com/duckduckgo/duckduckgo-autofill.git",
3434
"state" : {
35-
"revision" : "93677cc02cfe650ce7f417246afd0e8e972cd83e",
36-
"version" : "10.0.0"
35+
"revision" : "dbecae0df07650a21b5632a92fa2e498c96af7b5",
36+
"version" : "10.0.1"
3737
}
3838
},
3939
{

DuckDuckGo/Autofill/ContentOverlayViewController.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ extension ContentOverlayViewController: SecureVaultManagerDelegate {
302302
}
303303

304304
public func secureVaultManager(_: SecureVaultManager, didRequestAuthenticationWithCompletionHandler handler: @escaping (Bool) -> Void) {
305-
DeviceAuthenticator.shared.authenticateUser(reason: .autofill) { authenticationResult in
305+
DeviceAuthenticator.shared.authenticateUser(reason: .autofillCreditCards) { authenticationResult in
306306
handler(authenticationResult.authenticated)
307307
}
308308
}

DuckDuckGo/Common/Localizables/UserText.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ struct UserText {
374374
static let autofillAutoLock = NSLocalizedString("autofill.auto-lock", value: "Auto-lock", comment: "Autofill settings section title")
375375
static let autofillLockWhenIdle = NSLocalizedString("autofill.lock-when-idle", value: "Lock Autofill after computer is idle for", comment: "Autofill auto-lock setting")
376376
static let autofillNeverLock = NSLocalizedString("autofill.never-lock", value: "Never lock Autofill", comment: "Autofill auto-lock setting")
377-
static let autofillNeverLockWarning = NSLocalizedString("autofill.never-lock-warning", value: "Anyone with access to your device will be able to use and modify your Autofill data if not locked.", comment: "Autofill disabled auto-lock warning")
378-
static let autolockLocksFormFill = NSLocalizedString("autofill.autolock-locks-form-filling", value: "Also lock access to Login and Credit Card form fill.", comment: "Lock form filling when auto-lock is active text")
377+
static let autofillNeverLockWarning = NSLocalizedString("autofill.never-lock-warning", value: "If not locked, anyone with access to your device will be able to use and modify your autofill data. For security purposes, saved credit cards always require authentication.", comment: "Autofill disabled auto-lock warning")
378+
static let autolockLocksFormFill = NSLocalizedString("autofill.autolock-locks-form-filling", value: "Also lock password form fill", comment: "Lock form filling when auto-lock is active text")
379379

380380

381381
static let downloadsLocation = NSLocalizedString("downloads.location", value: "Location", comment: "Downloads directory location")

DuckDuckGo/DeviceAuthentication/DeviceAuthenticator.swift

+38-2
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ final class DeviceAuthenticator: UserAuthenticating {
3434

3535
enum AuthenticationReason {
3636
case autofill
37+
case autofillCreditCards
3738
case changeLoginsSettings
3839
case unlockLogins
3940
case exportLogins
4041

4142
var localizedDescription: String {
4243
switch self {
43-
case .autofill: return UserText.pmAutoLockPromptAutofill
44+
case .autofill, .autofillCreditCards: return UserText.pmAutoLockPromptAutofill
4445
case .changeLoginsSettings: return UserText.pmAutoLockPromptChangeLoginsSettings
4546
case .unlockLogins: return UserText.pmAutoLockPromptUnlockLogins
4647
case .exportLogins: return UserText.pmAutoLockPromptExportLogins
@@ -50,6 +51,7 @@ final class DeviceAuthenticator: UserAuthenticating {
5051

5152
internal enum Constants {
5253
static var intervalBetweenIdleChecks: TimeInterval = 1
54+
static var intervalBetweenCreditCardAutofillChecks: TimeInterval = 10
5355
}
5456

5557
static var deviceSupportsBiometrics: Bool {
@@ -91,6 +93,7 @@ final class DeviceAuthenticator: UserAuthenticating {
9193
private let queue = DispatchQueue(label: "Device Authenticator Queue")
9294

9395
private var timer: Timer?
96+
private var timerCreditCard: Timer?
9497

9598
private var _isAuthenticating: Bool = false
9699
private var _deviceIsLocked: Bool = false
@@ -144,7 +147,7 @@ final class DeviceAuthenticator: UserAuthenticating {
144147
}
145148

146149
func authenticateUser(reason: AuthenticationReason, result: @escaping (DeviceAuthenticationResult) -> Void) {
147-
guard requiresAuthentication else {
150+
guard (reason == .autofillCreditCards && creditCardTimeIntervalExpired()) || requiresAuthentication else {
148151
result(.success)
149152
return
150153
}
@@ -162,6 +165,7 @@ final class DeviceAuthenticator: UserAuthenticating {
162165
if authenticationResult.authenticated {
163166
// Now that the user has unlocked the device, begin the idle timer again.
164167
self.beginIdleCheckTimer()
168+
self.beginCreditCardAutofillTimer()
165169
}
166170

167171
result(authenticationResult)
@@ -233,4 +237,36 @@ final class DeviceAuthenticator: UserAuthenticating {
233237
}
234238
}
235239

240+
// MARK: - Credit Card Autofill Timer
241+
242+
private func beginCreditCardAutofillTimer() {
243+
os_log("Beginning credit card autofill timer", log: .autoLock)
244+
245+
self.timerCreditCard?.invalidate()
246+
self.timerCreditCard = nil
247+
248+
let timer = Timer(timeInterval: Constants.intervalBetweenCreditCardAutofillChecks, repeats: false) { [weak self] _ in
249+
guard let self = self else {
250+
return
251+
}
252+
self.cancelCreditCardAutofillTimer()
253+
}
254+
255+
self.timerCreditCard = timer
256+
RunLoop.current.add(timer, forMode: .common)
257+
}
258+
259+
private func cancelCreditCardAutofillTimer() {
260+
os_log("Cancelling credit card autofill timer", log: .autoLock)
261+
self.timerCreditCard?.invalidate()
262+
self.timerCreditCard = nil
263+
}
264+
265+
private func creditCardTimeIntervalExpired() -> Bool {
266+
guard let timer = timerCreditCard else {
267+
return true
268+
}
269+
return timer.timeInterval >= Constants.intervalBetweenCreditCardAutofillChecks
270+
}
271+
236272
}

LocalPackages/Account/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ let package = Package(
1212
targets: ["Account"]),
1313
],
1414
dependencies: [
15-
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "92.0.3"),
15+
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "92.0.4"),
1616
.package(path: "../Purchase")
1717
],
1818
targets: [

LocalPackages/DataBrokerProtection/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ let package = Package(
2929
targets: ["DataBrokerProtection"])
3030
],
3131
dependencies: [
32-
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "92.0.3"),
32+
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "92.0.4"),
3333
.package(path: "../PixelKit"),
3434
.package(path: "../SwiftUIExtensions"),
3535
.package(path: "../XPCHelper")

LocalPackages/NetworkProtectionMac/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ let package = Package(
3030
.library(name: "NetworkProtectionUI", targets: ["NetworkProtectionUI"])
3131
],
3232
dependencies: [
33-
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "92.0.3"),
33+
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "92.0.4"),
3434
.package(path: "../XPCHelper"),
3535
.package(path: "../SwiftUIExtensions")
3636
],

0 commit comments

Comments
 (0)