Skip to content

Commit b853386

Browse files
authored
feat(messaging, web): add support for debug tokens on Web (#18057)
* feat(messaging, web): add support for debug tokens on Web * format * fix analyze
1 parent e1a93a0 commit b853386

File tree

5 files changed

+62
-12
lines changed

5 files changed

+62
-12
lines changed

packages/firebase_app_check/firebase_app_check/example/lib/main.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ Future<void> main() async {
2323
await FirebaseAppCheck.instance
2424
// Your personal reCaptcha public key goes here:
2525
.activate(
26-
providerWeb: ReCaptchaV3Provider(kWebRecaptchaSiteKey),
26+
providerWeb: kDebugMode
27+
? WebDebugProvider()
28+
: ReCaptchaV3Provider(kWebRecaptchaSiteKey),
2729
providerAndroid: const AndroidDebugProvider(),
2830
providerApple: const AppleDebugProvider(),
2931
);

packages/firebase_app_check/firebase_app_check/lib/firebase_app_check.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ export 'package:firebase_app_check_platform_interface/firebase_app_check_platfor
2020
AppleAppAttestProvider,
2121
AppleAppAttestWithDeviceCheckFallbackProvider,
2222
ReCaptchaEnterpriseProvider,
23-
ReCaptchaV3Provider;
23+
ReCaptchaV3Provider,
24+
WebDebugProvider;
2425
export 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'
2526
show FirebaseException;
2627

packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/web_providers.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,19 @@ class ReCaptchaV3Provider extends WebProvider {
1515
class ReCaptchaEnterpriseProvider extends WebProvider {
1616
ReCaptchaEnterpriseProvider(String siteKey) : super(siteKey);
1717
}
18+
19+
/// Debug provider for Web.
20+
///
21+
/// Sets `self.FIREBASE_APPCHECK_DEBUG_TOKEN` before initializing App Check.
22+
/// If [debugToken] is provided, that token is used. Otherwise the Firebase JS
23+
/// SDK auto-generates one and prints it to the browser console — you then
24+
/// register that token in the Firebase Console.
25+
///
26+
/// See documentation: https://firebase.google.com/docs/app-check/web/debug-provider
27+
class WebDebugProvider extends WebProvider {
28+
/// Creates a web debug provider with an optional debug token.
29+
WebDebugProvider({this.debugToken}) : super('');
30+
31+
/// The debug token for this provider.
32+
final String? debugToken;
33+
}

packages/firebase_app_check/firebase_app_check_web/lib/firebase_app_check_web.dart

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {
2222
static const String _libraryName = 'flutter-fire-app-check';
2323
static const recaptchaTypeV3 = 'recaptcha-v3';
2424
static const recaptchaTypeEnterprise = 'enterprise';
25+
static const recaptchaTypeDebug = 'debug';
2526
static Map<String, StreamController<String?>> _tokenChangesListeners = {};
2627

2728
/// Stub initializer to allow the [registerWith] to create an instance without
@@ -56,14 +57,22 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {
5657
.getItem(_sessionKeyRecaptchaSiteKey(firebaseApp.name));
5758
}
5859

59-
if (recaptchaType != null && recaptchaSiteKey != null) {
60+
if (recaptchaType != null) {
6061
final WebProvider provider;
61-
if (recaptchaType == recaptchaTypeV3) {
62-
provider = ReCaptchaV3Provider(recaptchaSiteKey);
63-
} else if (recaptchaType == recaptchaTypeEnterprise) {
64-
provider = ReCaptchaEnterpriseProvider(recaptchaSiteKey);
62+
if (recaptchaType == recaptchaTypeDebug) {
63+
final debugToken =
64+
recaptchaSiteKey?.isNotEmpty ?? false ? recaptchaSiteKey : null;
65+
provider = WebDebugProvider(debugToken: debugToken);
66+
} else if (recaptchaSiteKey != null) {
67+
if (recaptchaType == recaptchaTypeV3) {
68+
provider = ReCaptchaV3Provider(recaptchaSiteKey);
69+
} else if (recaptchaType == recaptchaTypeEnterprise) {
70+
provider = ReCaptchaEnterpriseProvider(recaptchaSiteKey);
71+
} else {
72+
throw Exception('Invalid recaptcha type: $recaptchaType');
73+
}
6574
} else {
66-
throw Exception('Invalid recaptcha type: $recaptchaType');
75+
return;
6776
}
6877
await instance.activate(webProvider: provider);
6978
}
@@ -127,7 +136,9 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {
127136
// save the recaptcha type and site key for future startups
128137
if (webProvider != null) {
129138
final String recaptchaType;
130-
if (webProvider is ReCaptchaV3Provider) {
139+
if (webProvider is WebDebugProvider) {
140+
recaptchaType = recaptchaTypeDebug;
141+
} else if (webProvider is ReCaptchaV3Provider) {
131142
recaptchaType = recaptchaTypeV3;
132143
} else if (webProvider is ReCaptchaEnterpriseProvider) {
133144
recaptchaType = recaptchaTypeEnterprise;
@@ -136,8 +147,11 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {
136147
}
137148
web.window.localStorage
138149
.setItem(_sessionKeyRecaptchaType(app.name), recaptchaType);
139-
web.window.localStorage
140-
.setItem(_sessionKeyRecaptchaSiteKey(app.name), webProvider.siteKey);
150+
web.window.localStorage.setItem(
151+
_sessionKeyRecaptchaSiteKey(app.name),
152+
webProvider is WebDebugProvider
153+
? webProvider.debugToken ?? ''
154+
: webProvider.siteKey);
141155
}
142156

143157
// activate API no longer exists, recaptcha key has to be passed on initialization of app-check instance.

packages/firebase_app_check/firebase_app_check_web/lib/src/interop/app_check.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,24 @@ export 'app_check_interop.dart';
1818
AppCheck? getAppCheckInstance([App? app, WebProvider? provider]) {
1919
late app_check_interop.ReCaptchaProvider jsProvider;
2020

21-
if (provider is ReCaptchaV3Provider) {
21+
if (provider is WebDebugProvider) {
22+
// Set the debug token global before initializing App Check.
23+
// The Firebase JS SDK reads this and creates a DebugProvider internally.
24+
if (provider.debugToken != null) {
25+
globalContext.setProperty(
26+
'FIREBASE_APPCHECK_DEBUG_TOKEN'.toJS,
27+
provider.debugToken!.toJS,
28+
);
29+
} else {
30+
globalContext.setProperty(
31+
'FIREBASE_APPCHECK_DEBUG_TOKEN'.toJS,
32+
true.toJS,
33+
);
34+
}
35+
// A provider is still required by initializeAppCheck, but the debug
36+
// token global overrides it.
37+
jsProvider = app_check_interop.ReCaptchaV3Provider('debug'.toJS);
38+
} else if (provider is ReCaptchaV3Provider) {
2239
jsProvider = app_check_interop.ReCaptchaV3Provider(provider.siteKey.toJS);
2340
} else if (provider is ReCaptchaEnterpriseProvider) {
2441
jsProvider =

0 commit comments

Comments
 (0)