@react-native-firebase/app-check 23.8.0 → 23.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +784 -0
  2. package/RNFBAppCheck.podspec +50 -0
  3. package/android/.editorconfig +10 -0
  4. package/android/build.gradle +110 -0
  5. package/android/lint.xml +5 -0
  6. package/android/settings.gradle +1 -0
  7. package/android/src/main/AndroidManifest.xml +7 -0
  8. package/android/src/main/java/io/invertase/firebase/appcheck/ReactNativeFirebaseAppCheckModule.java +281 -0
  9. package/android/src/main/java/io/invertase/firebase/appcheck/ReactNativeFirebaseAppCheckPackage.java +41 -0
  10. package/android/src/main/java/io/invertase/firebase/appcheck/ReactNativeFirebaseAppCheckProvider.java +97 -0
  11. package/android/src/main/java/io/invertase/firebase/appcheck/ReactNativeFirebaseAppCheckProviderFactory.java +67 -0
  12. package/app.plugin.js +1 -0
  13. package/dist/commonjs/version.js +1 -1
  14. package/dist/commonjs/web/RNFBAppCheckModule.android.js +3 -2
  15. package/dist/commonjs/web/RNFBAppCheckModule.android.js.map +1 -2
  16. package/dist/commonjs/web/RNFBAppCheckModule.ios.js +3 -2
  17. package/dist/commonjs/web/RNFBAppCheckModule.ios.js.map +1 -2
  18. package/dist/commonjs/web/RNFBAppCheckModule.js +5 -11
  19. package/dist/commonjs/web/RNFBAppCheckModule.js.map +1 -1
  20. package/dist/module/version.js +1 -1
  21. package/dist/module/web/RNFBAppCheckModule.android.js +3 -2
  22. package/dist/module/web/RNFBAppCheckModule.android.js.map +1 -2
  23. package/dist/module/web/RNFBAppCheckModule.ios.js +3 -2
  24. package/dist/module/web/RNFBAppCheckModule.ios.js.map +1 -2
  25. package/dist/module/web/RNFBAppCheckModule.js +6 -7
  26. package/dist/module/web/RNFBAppCheckModule.js.map +1 -1
  27. package/dist/typescript/commonjs/lib/namespaced.d.ts +1 -1
  28. package/dist/typescript/commonjs/lib/version.d.ts +1 -1
  29. package/dist/typescript/module/lib/namespaced.d.ts +1 -1
  30. package/dist/typescript/module/lib/version.d.ts +1 -1
  31. package/ios/RNFBAppCheck/RNFBAppCheckModule.h +30 -0
  32. package/ios/RNFBAppCheck/RNFBAppCheckModule.m +171 -0
  33. package/ios/RNFBAppCheck/RNFBAppCheckProvider.h +33 -0
  34. package/ios/RNFBAppCheck/RNFBAppCheckProvider.m +90 -0
  35. package/ios/RNFBAppCheck/RNFBAppCheckProviderFactory.h +28 -0
  36. package/ios/RNFBAppCheck/RNFBAppCheckProviderFactory.m +61 -0
  37. package/ios/RNFBAppCheck.xcodeproj/project.pbxproj +349 -0
  38. package/ios/RNFBAppCheck.xcodeproj/xcshareddata/IDETemplateMacros.plist +24 -0
  39. package/lib/version.ts +1 -1
  40. package/package.json +5 -15
  41. package/plugin/build/index.d.ts +3 -0
  42. package/plugin/build/index.js +15 -0
  43. package/plugin/build/ios/appDelegate.d.ts +6 -0
  44. package/plugin/build/ios/appDelegate.js +137 -0
  45. package/plugin/build/ios/index.d.ts +2 -0
  46. package/plugin/build/ios/index.js +5 -0
  47. package/plugin/tsconfig.tsbuildinfo +1 -0
  48. package/lib/web/RNFBAppCheckModule.android.js +0 -2
  49. package/lib/web/RNFBAppCheckModule.ios.js +0 -2
  50. package/lib/web/RNFBAppCheckModule.js +0 -95
@@ -0,0 +1,50 @@
1
+ require 'json'
2
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
3
+ appPackage = JSON.parse(File.read(File.join('..', 'app', 'package.json')))
4
+
5
+ coreVersionDetected = appPackage['version']
6
+ coreVersionRequired = package['peerDependencies'][appPackage['name']]
7
+ firebase_sdk_version = appPackage['sdkVersions']['ios']['firebase']
8
+ if coreVersionDetected != coreVersionRequired
9
+ Pod::UI.warn "NPM package '#{package['name']}' depends on '#{appPackage['name']}' v#{coreVersionRequired} but found v#{coreVersionDetected}, this might cause build issues or runtime crashes."
10
+ end
11
+ firebase_ios_target = appPackage['sdkVersions']['ios']['iosTarget']
12
+ firebase_macos_target = appPackage['sdkVersions']['ios']['macosTarget']
13
+ firebase_tvos_target = appPackage['sdkVersions']['ios']['tvosTarget']
14
+
15
+ Pod::Spec.new do |s|
16
+ s.name = "RNFBAppCheck"
17
+ s.version = package["version"]
18
+ s.description = package["description"]
19
+ s.summary = <<-DESC
20
+ A well tested feature rich Firebase implementation for React Native, supporting iOS & Android.
21
+ DESC
22
+ s.homepage = "http://invertase.io/oss/react-native-firebase"
23
+ s.license = package['license']
24
+ s.authors = "Invertase Limited"
25
+ s.source = { :git => "https://github.com/invertase/react-native-firebase.git", :tag => "v#{s.version}" }
26
+ s.social_media_url = 'http://twitter.com/invertaseio'
27
+ s.ios.deployment_target = firebase_ios_target
28
+ s.macos.deployment_target = firebase_macos_target
29
+ s.tvos.deployment_target = firebase_tvos_target
30
+ s.source_files = 'ios/**/*.{h,m}'
31
+
32
+ # React Native dependencies
33
+ s.dependency 'React-Core'
34
+ s.dependency 'RNFBApp'
35
+
36
+ if defined?($FirebaseSDKVersion)
37
+ Pod::UI.puts "#{s.name}: Using user specified Firebase SDK version '#{$FirebaseSDKVersion}'"
38
+ firebase_sdk_version = $FirebaseSDKVersion
39
+ end
40
+
41
+ # Firebase dependencies
42
+ s.dependency 'Firebase/AppCheck', firebase_sdk_version
43
+
44
+ if defined?($RNFirebaseAsStaticFramework)
45
+ Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNFirebaseAsStaticFramework}'"
46
+ s.static_framework = $RNFirebaseAsStaticFramework
47
+ else
48
+ s.static_framework = false
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ # editorconfig
2
+ root = true
3
+
4
+ [*]
5
+ indent_style = space
6
+ indent_size = 2
7
+ end_of_line = lf
8
+ charset = utf-8
9
+ trim_trailing_whitespace = true
10
+ insert_final_newline = true
@@ -0,0 +1,110 @@
1
+ import com.android.Version
2
+ import io.invertase.gradle.common.PackageJson
3
+
4
+ buildscript {
5
+ // The Android Gradle plugin is only required when opening the android folder stand-alone.
6
+ // This avoids unnecessary downloads and potential conflicts when the library is included as a
7
+ // module dependency in an application project.
8
+ if (project == rootProject) {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+
14
+ dependencies {
15
+ classpath("com.android.tools.build:gradle:8.4.0")
16
+ }
17
+ }
18
+ }
19
+
20
+ plugins {
21
+ id 'io.invertase.gradle.build' version '1.5'
22
+ }
23
+
24
+ def appProject
25
+ if (findProject(':@react-native-firebase_app')) {
26
+ appProject = project(':@react-native-firebase_app')
27
+ } else if (findProject(':react-native-firebase_app')) {
28
+ appProject = project(':react-native-firebase_app')
29
+ } else {
30
+ throw new GradleException('Could not find the react-native-firebase/app package, have you installed it?')
31
+ }
32
+ def packageJson = PackageJson.getForProject(project)
33
+ def appPackageJson = PackageJson.getForProject(appProject)
34
+ def firebaseBomVersion = appPackageJson['sdkVersions']['android']['firebase']
35
+ def jsonMinSdk = appPackageJson['sdkVersions']['android']['minSdk']
36
+ def jsonTargetSdk = appPackageJson['sdkVersions']['android']['targetSdk']
37
+ def jsonCompileSdk = appPackageJson['sdkVersions']['android']['compileSdk']
38
+ def coreVersionDetected = appPackageJson['version']
39
+ def coreVersionRequired = packageJson['peerDependencies'][appPackageJson['name']]
40
+ if (coreVersionDetected != coreVersionRequired) {
41
+ project.logger.warn("ReactNativeFirebase WARNING: NPM package '${packageJson['name']}' depends on '${appPackageJson['name']}' v${coreVersionRequired} but found v${coreVersionDetected}, this might cause build issues or runtime crashes.")
42
+ }
43
+
44
+ project.ext {
45
+ set('react-native', [
46
+ versions: [
47
+ android : [
48
+ minSdk : jsonMinSdk,
49
+ targetSdk : jsonTargetSdk,
50
+ compileSdk: jsonCompileSdk,
51
+ ],
52
+
53
+ firebase: [
54
+ bom: firebaseBomVersion,
55
+ ],
56
+ ],
57
+ ])
58
+ }
59
+
60
+ android {
61
+ def agpVersion = Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()
62
+ if (agpVersion >= 7) {
63
+ namespace = 'io.invertase.firebase.appcheck'
64
+ }
65
+
66
+ defaultConfig {
67
+ multiDexEnabled = true
68
+ // Here we add a build config field to allow devs to provide a
69
+ // FIREBASE_APP_CHECK_DEBUG_TOKEN to be used in debug mode.
70
+ buildConfigField "String", "FIREBASE_APP_CHECK_DEBUG_TOKEN", "\"${System.env.FIREBASE_APP_CHECK_DEBUG_TOKEN}\""
71
+ }
72
+
73
+ buildFeatures {
74
+ // AGP 8 no longer builds config by default
75
+ buildConfig = true
76
+ }
77
+
78
+ lintOptions {
79
+ disable 'GradleCompatible'
80
+ abortOnError = false
81
+ }
82
+ if (agpVersion < 8) {
83
+ compileOptions {
84
+ sourceCompatibility = JavaVersion.VERSION_11
85
+ targetCompatibility = JavaVersion.VERSION_11
86
+ }
87
+ }
88
+ sourceSets {
89
+ main {
90
+ java.srcDirs = ['src/main/java', 'src/reactnative/java']
91
+ }
92
+ }
93
+ }
94
+
95
+ repositories {
96
+ google()
97
+ mavenCentral()
98
+ }
99
+
100
+ dependencies {
101
+ api appProject
102
+ implementation platform("com.google.firebase:firebase-bom:${ReactNative.ext.getVersion('firebase', 'bom')}")
103
+ implementation 'com.google.firebase:firebase-appcheck-playintegrity'
104
+ implementation "com.google.firebase:firebase-appcheck-debug"
105
+ }
106
+
107
+ ReactNative.shared.applyPackageVersion()
108
+ ReactNative.shared.applyDefaultExcludes()
109
+ ReactNative.module.applyAndroidVersions()
110
+ ReactNative.module.applyReactNativeDependency('api')
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <lint>
3
+ <!-- Disable the given check in this project -->
4
+ <issue id="GradleCompatible" severity="ignore" />
5
+ </lint>
@@ -0,0 +1 @@
1
+ rootProject.name = '@react-native-firebase_app-check'
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.invertase.firebase.appcheck">
3
+
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
6
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7
+ </manifest>
@@ -0,0 +1,281 @@
1
+ package io.invertase.firebase.appcheck;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import android.content.pm.ApplicationInfo;
21
+ import android.content.pm.PackageManager;
22
+ import android.util.Log;
23
+ import com.facebook.react.bridge.*;
24
+ import com.google.android.gms.tasks.Tasks;
25
+ import com.google.firebase.FirebaseApp;
26
+ import com.google.firebase.appcheck.FirebaseAppCheck;
27
+ import io.invertase.firebase.common.ReactNativeFirebaseEvent;
28
+ import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter;
29
+ import io.invertase.firebase.common.ReactNativeFirebaseJSON;
30
+ import io.invertase.firebase.common.ReactNativeFirebaseMeta;
31
+ import io.invertase.firebase.common.ReactNativeFirebaseModule;
32
+ import io.invertase.firebase.common.ReactNativeFirebasePreferences;
33
+ import java.util.HashMap;
34
+ import java.util.Iterator;
35
+ import java.util.Map;
36
+
37
+ public class ReactNativeFirebaseAppCheckModule extends ReactNativeFirebaseModule {
38
+ private static final String TAG = "AppCheck";
39
+ private static final String LOGTAG = "RNFBAppCheck";
40
+ private static final String KEY_APPCHECK_TOKEN_REFRESH_ENABLED = "app_check_token_auto_refresh";
41
+
42
+ private static HashMap<String, FirebaseAppCheck.AppCheckListener> mAppCheckListeners =
43
+ new HashMap<>();
44
+
45
+ ReactNativeFirebaseAppCheckProviderFactory providerFactory =
46
+ new ReactNativeFirebaseAppCheckProviderFactory();
47
+
48
+ static boolean isAppCheckTokenRefreshEnabled() {
49
+ boolean enabled;
50
+ ReactNativeFirebaseJSON json = ReactNativeFirebaseJSON.getSharedInstance();
51
+ ReactNativeFirebaseMeta meta = ReactNativeFirebaseMeta.getSharedInstance();
52
+ ReactNativeFirebasePreferences prefs = ReactNativeFirebasePreferences.getSharedInstance();
53
+
54
+ if (prefs.contains(KEY_APPCHECK_TOKEN_REFRESH_ENABLED)) {
55
+ enabled = prefs.getBooleanValue(KEY_APPCHECK_TOKEN_REFRESH_ENABLED, true);
56
+ Log.d(LOGTAG, "isAppCheckCollectionEnabled via RNFBPreferences: " + enabled);
57
+ } else if (json.contains(KEY_APPCHECK_TOKEN_REFRESH_ENABLED)) {
58
+ enabled = json.getBooleanValue(KEY_APPCHECK_TOKEN_REFRESH_ENABLED, true);
59
+ Log.d(LOGTAG, "isAppCheckCollectionEnabled via RNFBJSON: " + enabled);
60
+ } else {
61
+ enabled = meta.getBooleanValue(KEY_APPCHECK_TOKEN_REFRESH_ENABLED, true);
62
+ Log.d(LOGTAG, "isAppCheckCollectionEnabled via RNFBMeta: " + enabled);
63
+ }
64
+
65
+ if (BuildConfig.DEBUG) {
66
+ if (!json.getBooleanValue(KEY_APPCHECK_TOKEN_REFRESH_ENABLED, false)) {
67
+ enabled = false;
68
+ }
69
+ Log.d(
70
+ LOGTAG,
71
+ "isAppCheckTokenRefreshEnabled after checking "
72
+ + KEY_APPCHECK_TOKEN_REFRESH_ENABLED
73
+ + ": "
74
+ + enabled);
75
+ }
76
+
77
+ Log.d(LOGTAG, "isAppCheckTokenRefreshEnabled final value: " + enabled);
78
+ return enabled;
79
+ }
80
+
81
+ private boolean isAppDebuggable() throws Exception {
82
+ boolean isDebuggable = false;
83
+ PackageManager pm = getContext().getPackageManager();
84
+ if (pm != null) {
85
+ isDebuggable =
86
+ (0
87
+ != (pm.getApplicationInfo(getContext().getPackageName(), 0).flags
88
+ & ApplicationInfo.FLAG_DEBUGGABLE));
89
+ }
90
+ Log.d(LOGTAG, "debuggable status? " + isDebuggable);
91
+ return isDebuggable;
92
+ }
93
+
94
+ ReactNativeFirebaseAppCheckModule(ReactApplicationContext reactContext) {
95
+ super(reactContext, TAG);
96
+
97
+ // Our default token refresh config comes from config files, set it
98
+ FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
99
+ firebaseAppCheck.setTokenAutoRefreshEnabled(isAppCheckTokenRefreshEnabled());
100
+ }
101
+
102
+ @Override
103
+ public void invalidate() {
104
+ super.invalidate();
105
+ Log.d(TAG, "instance-destroyed");
106
+
107
+ Iterator appCheckListenerIterator = mAppCheckListeners.entrySet().iterator();
108
+
109
+ while (appCheckListenerIterator.hasNext()) {
110
+ Map.Entry pair = (Map.Entry) appCheckListenerIterator.next();
111
+ String appName = (String) pair.getKey();
112
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
113
+ FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance(firebaseApp);
114
+ FirebaseAppCheck.AppCheckListener mAppCheckListener =
115
+ (FirebaseAppCheck.AppCheckListener) pair.getValue();
116
+ firebaseAppCheck.removeAppCheckListener(mAppCheckListener);
117
+ appCheckListenerIterator.remove();
118
+ }
119
+ }
120
+
121
+ @ReactMethod
122
+ public void configureProvider(
123
+ String appName, String providerName, String debugToken, Promise promise) {
124
+ Log.d(
125
+ LOGTAG,
126
+ "configureProvider - appName/providerName/debugToken: "
127
+ + appName
128
+ + "/"
129
+ + providerName
130
+ + (debugToken != null ? "/(not shown)" : "/null"));
131
+ try {
132
+ providerFactory.configure(appName, providerName, debugToken);
133
+ FirebaseAppCheck.getInstance(FirebaseApp.getInstance(appName))
134
+ .installAppCheckProviderFactory(providerFactory);
135
+ promise.resolve(null);
136
+ } catch (Exception e) {
137
+ rejectPromiseWithCodeAndMessage(promise, "unknown", "internal-error", e.getMessage());
138
+ }
139
+ }
140
+
141
+ @ReactMethod
142
+ public void activate(
143
+ String appName, String siteKeyProvider, boolean isTokenAutoRefreshEnabled, Promise promise) {
144
+ try {
145
+
146
+ FirebaseAppCheck firebaseAppCheck =
147
+ FirebaseAppCheck.getInstance(FirebaseApp.getInstance(appName));
148
+ firebaseAppCheck.setTokenAutoRefreshEnabled(isTokenAutoRefreshEnabled);
149
+
150
+ // Configure our new proxy factory in a backwards-compatible way for old API
151
+ if (isAppDebuggable()) {
152
+ Log.d(LOGTAG, "app is debuggable, configuring AppCheck for testing mode");
153
+ if (BuildConfig.FIREBASE_APP_CHECK_DEBUG_TOKEN != "null") {
154
+ Log.d(LOGTAG, "debug app check token found in BuildConfig. Installing known token.");
155
+ providerFactory.configure(appName, "debug", BuildConfig.FIREBASE_APP_CHECK_DEBUG_TOKEN);
156
+ } else {
157
+ Log.d(
158
+ LOGTAG,
159
+ "no debug app check token found in BuildConfig. Check Log for dynamic test token to"
160
+ + " configure in console.");
161
+ providerFactory.configure(appName, "debug", null);
162
+ }
163
+ } else {
164
+ providerFactory.configure(appName, "safetyNet", null);
165
+ }
166
+
167
+ FirebaseAppCheck.getInstance(FirebaseApp.getInstance(appName))
168
+ .installAppCheckProviderFactory(providerFactory);
169
+ promise.resolve(null);
170
+ } catch (Exception e) {
171
+ rejectPromiseWithCodeAndMessage(promise, "unknown", "internal-error", e.getMessage());
172
+ }
173
+ }
174
+
175
+ @ReactMethod
176
+ public void setTokenAutoRefreshEnabled(String appName, boolean isTokenAutoRefreshEnabled) {
177
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
178
+ FirebaseAppCheck.getInstance(firebaseApp).setTokenAutoRefreshEnabled(isTokenAutoRefreshEnabled);
179
+ }
180
+
181
+ @ReactMethod
182
+ public void getToken(String appName, boolean forceRefresh, Promise promise) {
183
+ Log.d(LOGTAG, "getToken appName/forceRefresh: " + appName + "/" + forceRefresh);
184
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
185
+ Tasks.call(
186
+ getExecutor(),
187
+ () -> {
188
+ return Tasks.await(
189
+ FirebaseAppCheck.getInstance(firebaseApp).getAppCheckToken(forceRefresh));
190
+ })
191
+ .addOnCompleteListener(
192
+ getExecutor(),
193
+ (task) -> {
194
+ if (task.isSuccessful()) {
195
+ WritableMap tokenResultMap = Arguments.createMap();
196
+ tokenResultMap.putString("token", task.getResult().getToken());
197
+ promise.resolve(tokenResultMap);
198
+ } else {
199
+ Log.e(
200
+ LOGTAG,
201
+ "RNFB: Unknown error while fetching AppCheck token "
202
+ + task.getException().getMessage());
203
+ rejectPromiseWithCodeAndMessage(
204
+ promise, "token-error", task.getException().getMessage());
205
+ }
206
+ });
207
+ }
208
+
209
+ @ReactMethod
210
+ public void getLimitedUseToken(String appName, Promise promise) {
211
+ Log.d(LOGTAG, "getLimitedUseToken appName: " + appName);
212
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
213
+
214
+ Tasks.call(
215
+ getExecutor(),
216
+ () -> {
217
+ return Tasks.await(
218
+ FirebaseAppCheck.getInstance(firebaseApp).getLimitedUseAppCheckToken());
219
+ })
220
+ .addOnCompleteListener(
221
+ getExecutor(),
222
+ (task) -> {
223
+ if (task.isSuccessful()) {
224
+ WritableMap tokenResultMap = Arguments.createMap();
225
+ tokenResultMap.putString("token", task.getResult().getToken());
226
+ promise.resolve(tokenResultMap);
227
+ } else {
228
+ Log.e(
229
+ LOGTAG,
230
+ "Unknown error while fetching limited-use AppCheck token "
231
+ + task.getException().getMessage());
232
+ rejectPromiseWithCodeAndMessage(
233
+ promise, "token-error", task.getException().getMessage());
234
+ }
235
+ });
236
+ }
237
+
238
+ /** Add a new token change listener - if one doesn't exist already */
239
+ @ReactMethod
240
+ public void addAppCheckListener(final String appName) {
241
+ Log.d(TAG, "addAppCheckListener " + appName);
242
+
243
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
244
+ FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance(firebaseApp);
245
+
246
+ if (mAppCheckListeners.get(appName) == null) {
247
+ FirebaseAppCheck.AppCheckListener newAppCheckListener =
248
+ appCheckToken -> {
249
+ WritableMap eventBody = Arguments.createMap();
250
+ eventBody.putString("appName", appName); // for js side distribution
251
+ eventBody.putString("token", appCheckToken.getToken());
252
+ eventBody.putDouble("expireTimeMillis", appCheckToken.getExpireTimeMillis());
253
+
254
+ ReactNativeFirebaseEventEmitter emitter =
255
+ ReactNativeFirebaseEventEmitter.getSharedInstance();
256
+ ReactNativeFirebaseEvent event =
257
+ new ReactNativeFirebaseEvent("appCheck_token_changed", eventBody, appName);
258
+ emitter.sendEvent(event);
259
+ };
260
+
261
+ firebaseAppCheck.addAppCheckListener(newAppCheckListener);
262
+ mAppCheckListeners.put(appName, newAppCheckListener);
263
+ }
264
+ }
265
+
266
+ /** Removes the current token change listener */
267
+ @ReactMethod
268
+ public void removeAppCheckListener(String appName) {
269
+ Log.d(TAG, "removeAppCheckListener " + appName);
270
+
271
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
272
+ FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance(firebaseApp);
273
+
274
+ FirebaseAppCheck.AppCheckListener mAppCheckListener = mAppCheckListeners.get(appName);
275
+
276
+ if (mAppCheckListener != null) {
277
+ firebaseAppCheck.removeAppCheckListener(mAppCheckListener);
278
+ mAppCheckListeners.remove(appName);
279
+ }
280
+ }
281
+ }
@@ -0,0 +1,41 @@
1
+ package io.invertase.firebase.appcheck;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import com.facebook.react.ReactPackage;
21
+ import com.facebook.react.bridge.NativeModule;
22
+ import com.facebook.react.bridge.ReactApplicationContext;
23
+ import com.facebook.react.uimanager.ViewManager;
24
+ import java.util.ArrayList;
25
+ import java.util.Collections;
26
+ import java.util.List;
27
+
28
+ @SuppressWarnings("unused")
29
+ public class ReactNativeFirebaseAppCheckPackage implements ReactPackage {
30
+ @Override
31
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
32
+ List<NativeModule> modules = new ArrayList<>();
33
+ modules.add(new ReactNativeFirebaseAppCheckModule(reactContext));
34
+ return modules;
35
+ }
36
+
37
+ @Override
38
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
39
+ return Collections.emptyList();
40
+ }
41
+ }
@@ -0,0 +1,97 @@
1
+ package io.invertase.firebase.appcheck;
2
+
3
+ /*
4
+ * Copyright (c) 2023-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import android.util.Log;
21
+ import androidx.annotation.NonNull;
22
+ import com.google.android.gms.tasks.Task;
23
+ import com.google.firebase.FirebaseApp;
24
+ import com.google.firebase.appcheck.AppCheckProvider;
25
+ import com.google.firebase.appcheck.AppCheckToken;
26
+ import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory;
27
+ import com.google.firebase.appcheck.debug.InternalDebugSecretProvider;
28
+ import com.google.firebase.appcheck.debug.internal.DebugAppCheckProvider;
29
+ import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory;
30
+ import com.google.firebase.inject.Provider;
31
+ import java.util.concurrent.ExecutorService;
32
+ import java.util.concurrent.Executors;
33
+
34
+ // Facade for all possible provider factory delegates,
35
+ // configurable dynamically instead of at startup
36
+ public class ReactNativeFirebaseAppCheckProvider implements AppCheckProvider {
37
+ private static final String LOGTAG = "RNFBAppCheck";
38
+
39
+ AppCheckProvider delegateProvider;
40
+
41
+ @NonNull
42
+ @Override
43
+ public Task<AppCheckToken> getToken() {
44
+ Log.d(LOGTAG, "Provider::getToken - delegating to native provider");
45
+ return delegateProvider.getToken();
46
+ }
47
+
48
+ public void configure(String appName, String providerName, String debugToken) {
49
+ Log.d(
50
+ LOGTAG,
51
+ "Provider::configure with appName/providerName/debugToken: "
52
+ + appName
53
+ + "/"
54
+ + providerName
55
+ + "/"
56
+ + (debugToken != null ? "(not shown)" : "null"));
57
+
58
+ try {
59
+ FirebaseApp app = FirebaseApp.getInstance(appName);
60
+
61
+ if ("debug".equals(providerName)) {
62
+
63
+ // the debug configuration may have a token, or may not
64
+ if (debugToken != null) {
65
+ // To use this token, create debug provider using local secret provider + standard thread
66
+ // pool
67
+ ExecutorService executor = Executors.newCachedThreadPool();
68
+ delegateProvider =
69
+ new DebugAppCheckProvider(
70
+ app,
71
+ new Provider<InternalDebugSecretProvider>() {
72
+ public InternalDebugSecretProvider get() {
73
+ return new InternalDebugSecretProvider() {
74
+ public String getDebugSecret() {
75
+ return debugToken;
76
+ }
77
+ };
78
+ }
79
+ },
80
+ executor,
81
+ executor,
82
+ executor);
83
+
84
+ } else {
85
+ delegateProvider = DebugAppCheckProviderFactory.getInstance().create(app);
86
+ }
87
+ }
88
+
89
+ if ("playIntegrity".equals(providerName)) {
90
+ delegateProvider = PlayIntegrityAppCheckProviderFactory.getInstance().create(app);
91
+ }
92
+ } catch (Exception e) {
93
+ // This will bubble up and result in a rejected promise with the underlying message
94
+ throw new RuntimeException(e.getMessage());
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,67 @@
1
+ package io.invertase.firebase.appcheck;
2
+
3
+ /*
4
+ * Copyright (c) 2023-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import android.util.Log;
21
+ import androidx.annotation.NonNull;
22
+ import com.google.firebase.FirebaseApp;
23
+ import com.google.firebase.appcheck.AppCheckProvider;
24
+ import com.google.firebase.appcheck.AppCheckProviderFactory;
25
+ import java.util.HashMap;
26
+
27
+ public class ReactNativeFirebaseAppCheckProviderFactory implements AppCheckProviderFactory {
28
+ private static final String LOGTAG = "RNFBAppCheck";
29
+
30
+ // This object has one job - create + maintain control over one provider per app
31
+ public HashMap<String, ReactNativeFirebaseAppCheckProvider> providers = new HashMap<>();
32
+
33
+ // Our provider will serve as a facade to all the supported native providers,
34
+ // we will just pass through configuration calls to it
35
+ public void configure(String appName, String providerName, String debugToken) {
36
+ Log.d(
37
+ LOGTAG,
38
+ "ProviderFactory::configure - appName/providerName/debugToken: "
39
+ + appName
40
+ + "/"
41
+ + providerName
42
+ + (debugToken != null ? "/(not shown)" : "/null"));
43
+
44
+ ReactNativeFirebaseAppCheckProvider provider;
45
+
46
+ // Look up the correct provider for the given appName, create it if not created
47
+ provider = providers.get(appName);
48
+ if (provider == null) {
49
+ provider = new ReactNativeFirebaseAppCheckProvider();
50
+ providers.put(appName, provider);
51
+ }
52
+ provider.configure(appName, providerName, debugToken);
53
+ }
54
+
55
+ @NonNull
56
+ public AppCheckProvider create(FirebaseApp firebaseApp) {
57
+ String appName = firebaseApp.getName();
58
+ Log.d(LOGTAG, "ProviderFactory::create - fetching provider for app " + appName);
59
+ ReactNativeFirebaseAppCheckProvider provider = providers.get(appName);
60
+ if (provider == null) {
61
+ Log.d(LOGTAG, "ProviderFactory::create - provider not configured for this app.");
62
+ throw new RuntimeException(
63
+ "ReactNativeFirebaseAppCheckProvider not configured for app " + appName);
64
+ }
65
+ return provider;
66
+ }
67
+ }
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./plugin/build');