Skip to content

Commit 4474839

Browse files
authored
[PM-24715] [RC] Fix iOS autofill extension app initialization URLs (#1858)
1 parent 27a9d9c commit 4474839

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

BitwardenAutoFillExtension/CredentialProviderViewController.swift

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ class CredentialProviderViewController: ASCredentialProviderViewController {
6868
return
6969
}
7070

71-
initializeApp(
72-
with: DefaultCredentialProviderContext(.autofillCredential(credentialIdentity, userInteraction: false))
73-
)
74-
provideCredential(for: recordIdentifier)
71+
Task {
72+
await initializeAppWithoutUserInteraction(
73+
with: DefaultCredentialProviderContext(.autofillCredential(credentialIdentity, userInteraction: false))
74+
)
75+
provideCredential(for: recordIdentifier)
76+
}
7577
}
7678

7779
@available(iOSApplicationExtension 17.0, *)
@@ -82,12 +84,14 @@ class CredentialProviderViewController: ASCredentialProviderViewController {
8284
provideCredentialWithoutUserInteraction(for: passwordIdentity)
8385
}
8486
case let passkeyRequest as ASPasskeyCredentialRequest:
85-
initializeApp(
86-
with: DefaultCredentialProviderContext(
87-
.autofillFido2Credential(passkeyRequest, userInteraction: false)
87+
Task {
88+
await initializeAppWithoutUserInteraction(
89+
with: DefaultCredentialProviderContext(
90+
.autofillFido2Credential(passkeyRequest, userInteraction: false)
91+
)
8892
)
89-
)
90-
provideFido2Credential(for: passkeyRequest)
93+
provideFido2Credential(for: passkeyRequest)
94+
}
9195
default:
9296
if #available(iOSApplicationExtension 18.0, *),
9397
let otpRequest = credentialRequest as? ASOneTimeCodeCredentialRequest,
@@ -162,6 +166,15 @@ class CredentialProviderViewController: ASCredentialProviderViewController {
162166
}
163167
}
164168
}
169+
170+
/// Sets up and initializes the app without user interaction.
171+
/// - Parameter context: The context that describes how the extension is being used.
172+
private func initializeAppWithoutUserInteraction(
173+
with context: CredentialProviderContext
174+
) async {
175+
initializeApp(with: context)
176+
await appProcessor?.prepareEnvironmentConfig()
177+
}
165178

166179
/// Attempts to provide the credential with the specified ID to the extension context to handle
167180
/// autofill.
@@ -264,10 +277,12 @@ class CredentialProviderViewController: ASCredentialProviderViewController {
264277
return
265278
}
266279

267-
initializeApp(
268-
with: DefaultCredentialProviderContext(.autofillOTPCredential(otpIdentity, userInteraction: false))
269-
)
270-
provideOTPCredential(for: recordIdentifier)
280+
Task {
281+
await initializeAppWithoutUserInteraction(
282+
with: DefaultCredentialProviderContext(.autofillOTPCredential(otpIdentity, userInteraction: false))
283+
)
284+
provideOTPCredential(for: recordIdentifier)
285+
}
271286
}
272287
}
273288

BitwardenShared/UI/Platform/Application/AppProcessor.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,7 @@ public class AppProcessor {
183183
)
184184

185185
await services.migrationService.performMigrations()
186-
await services.environmentService.loadURLsForActiveAccount()
187-
_ = await services.configService.getConfig()
186+
await prepareEnvironmentConfig()
188187
await completeAutofillAccountSetupIfEnabled()
189188

190189
if let initialRoute {
@@ -243,6 +242,13 @@ public class AppProcessor {
243242
await checkIfLockedAndPerformNavigation(route: route)
244243
}
245244

245+
/// Perpares the current environment configuration by loading the URLs for the active account
246+
/// and getting the current server config.
247+
public func prepareEnvironmentConfig() async {
248+
await services.environmentService.loadURLsForActiveAccount()
249+
_ = await services.configService.getConfig()
250+
}
251+
246252
// MARK: Autofill Methods
247253

248254
/// Returns a `ASPasswordCredential` that matches the user-requested credential which can be

BitwardenShared/UI/Platform/Application/AppProcessorTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class AppProcessorTests: BitwardenTestCase { // swiftlint:disable:this type_body
2121
var clientService: MockClientService!
2222
var configService: MockConfigService!
2323
var coordinator: MockCoordinator<AppRoute, AppEvent>!
24+
var environmentService: MockEnvironmentService!
2425
var errorReporter: MockErrorReporter!
2526
var fido2UserInterfaceHelper: MockFido2UserInterfaceHelper!
2627
var eventService: MockEventService!
@@ -56,6 +57,7 @@ class AppProcessorTests: BitwardenTestCase { // swiftlint:disable:this type_body
5657
coordinator = MockCoordinator()
5758
appModule.authRouter = router
5859
appModule.appCoordinator = coordinator
60+
environmentService = MockEnvironmentService()
5961
errorReporter = MockErrorReporter()
6062
fido2UserInterfaceHelper = MockFido2UserInterfaceHelper()
6163
eventService = MockEventService()
@@ -81,6 +83,7 @@ class AppProcessorTests: BitwardenTestCase { // swiftlint:disable:this type_body
8183
autofillCredentialService: autofillCredentialService,
8284
clientService: clientService,
8385
configService: configService,
86+
environmentService: environmentService,
8487
errorReporter: errorReporter,
8588
eventService: eventService,
8689
fido2UserInterfaceHelper: fido2UserInterfaceHelper,
@@ -107,6 +110,7 @@ class AppProcessorTests: BitwardenTestCase { // swiftlint:disable:this type_body
107110
clientService = nil
108111
configService = nil
109112
coordinator = nil
113+
environmentService = nil
110114
errorReporter = nil
111115
fido2UserInterfaceHelper = nil
112116
eventService = nil
@@ -1440,4 +1444,12 @@ class AppProcessorTests: BitwardenTestCase { // swiftlint:disable:this type_body
14401444
XCTAssertTrue(coordinator.isLoadingOverlayShowing)
14411445
XCTAssertTrue(coordinator.events.isEmpty)
14421446
}
1447+
1448+
/// `prepareEnvironmentConfig()` loads the URLs for the active account and the configuration.
1449+
@MainActor
1450+
func test_prepareEnvironmentConfig() async throws {
1451+
await subject.prepareEnvironmentConfig()
1452+
XCTAssertTrue(environmentService.didLoadURLsForActiveAccount)
1453+
XCTAssertTrue(configService.configMocker.called)
1454+
}
14431455
}

0 commit comments

Comments
 (0)