Visitar URL original
fix(appcheck,macos): fix how appAttestWithDeviceCheckFallback is work… · firebase/flutterfire@a08ff65 · GitHub
Skip to content

Commit a08ff65

Browse files
authored
fix(appcheck,macos): fix how appAttestWithDeviceCheckFallback is working on fallback (#18568)
* fix(appcheck,macos): fix how appAttestWithDeviceCheckFallback is working on fallback * test(appcheck): assert App Attest is not selected instead of matching any unsupported-provider error iOS simulators do not support DeviceCheck, so the fallback path legitimately errors with "DeviceCheckProvider is not supported". Narrow the assertion to AppAttestProvider, which is the regression being guarded.
1 parent 11daba2 commit a08ff65

2 files changed

Lines changed: 42 additions & 4 deletions

File tree

‎packages/firebase_app_check/firebase_app_check/example/integration_test/e2e_test.dart‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,38 @@ void main() {
140140
skip: defaultTargetPlatform != TargetPlatform.iOS,
141141
);
142142

143+
test(
144+
'appAttestWithDeviceCheckFallback falls back rather than erroring',
145+
() async {
146+
await FirebaseAppCheck.instance.activate(
147+
providerApple:
148+
const AppleAppAttestWithDeviceCheckFallbackProvider(),
149+
);
150+
151+
// On devices without App Attest support — most Macs, and every
152+
// simulator — the provider has to fall back to DeviceCheck. It used
153+
// to pick App Attest purely on OS version and fail with "The
154+
// attestation provider AppAttestProvider is not supported on current
155+
// platform and OS version", so App Attest must not be the provider
156+
// named in any error. Fetching a token can still fail beyond that
157+
// (simulators do not support DeviceCheck either, and there is no
158+
// debug token configured), which is fine here.
159+
try {
160+
await FirebaseAppCheck.instance.getToken(true);
161+
} on FirebaseException catch (e) {
162+
expect(
163+
'${e.message}',
164+
isNot(contains('AppAttestProvider')),
165+
reason: 'the DeviceCheck fallback did not engage',
166+
);
167+
}
168+
},
169+
skip: defaultTargetPlatform != TargetPlatform.macOS &&
170+
defaultTargetPlatform != TargetPlatform.iOS
171+
? 'Apple platforms only.'
172+
: null,
173+
);
174+
143175
test(
144176
'uses Apple debug token when both Android and Apple debug tokens are configured',
145177
() async {

‎packages/firebase_app_check/firebase_app_check/ios/firebase_app_check/Sources/firebase_app_check/FirebaseAppCheckPlugin.swift‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import DeviceCheck
56
import FirebaseAppCheck
67
import FirebaseCore
78

@@ -371,11 +372,16 @@ class AppCheckProviderWrapper: NSObject, AppCheckProvider {
371372
delegateProvider = AppCheckDebugProvider(app: app)
372373
}
373374
case "appAttestWithDeviceCheckFallback":
374-
if #available(iOS 14.0, macOS 14.0, *) {
375-
delegateProvider = AppAttestProvider(app: app)
376-
} else {
377-
delegateProvider = DeviceCheckProvider(app: app)
375+
// A new enough OS is not sufficient: the device must also support App
376+
// Attest, which is often false on macOS. The SDK only reports that when a
377+
// token is first requested, so check the same capability it checks —
378+
// otherwise this provider never actually falls back. Typed as the
379+
// protocol to keep the availability-annotated type inside `#available`.
380+
var appAttestProvider: (any AppCheckProvider)?
381+
if #available(iOS 14.0, macOS 14.0, *), DCAppAttestService.shared.isSupported {
382+
appAttestProvider = AppAttestProvider(app: app)
378383
}
384+
delegateProvider = appAttestProvider ?? DeviceCheckProvider(app: app)
379385
case "recaptcha":
380386
#if os(iOS)
381387
if let recaptchaSiteKey {

0 commit comments

Comments
 (0)