@react-native-firebase/app-check 26.3.3 → 27.0.0

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 (35) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/RNFBAppCheck.podspec +8 -2
  3. package/android/build.gradle +5 -0
  4. package/android/src/main/java/io/invertase/firebase/appcheck/AppCheckListenerHandle.java +26 -0
  5. package/android/src/main/java/io/invertase/firebase/appcheck/NativeRNFBTurboAppCheck.java +24 -44
  6. package/android/src/main/java/io/invertase/firebase/appcheck/RNFBAppCheckListenerRegistry.kt +72 -0
  7. package/android/src/test/java/io/invertase/firebase/appcheck/RNFBAppCheckListenerRegistryTest.java +171 -0
  8. package/dist/module/index.js +1 -2
  9. package/dist/module/index.js.map +1 -1
  10. package/dist/module/version.js +1 -1
  11. package/dist/typescript/lib/index.d.ts +1 -1
  12. package/dist/typescript/lib/index.d.ts.map +1 -1
  13. package/dist/typescript/lib/version.d.ts +1 -1
  14. package/ios/RNFBAppCheck/RNFBAppCheckHelper.h +61 -0
  15. package/ios/RNFBAppCheck/RNFBAppCheckHelper.m +213 -0
  16. package/ios/RNFBAppCheck/RNFBAppCheckModule.mm +22 -155
  17. package/ios/RNFBAppCheck/RNFBAppCheckRejectCodeMapper.swift +50 -0
  18. package/ios/RNFBAppCheck.xcodeproj/project.pbxproj +14 -0
  19. package/ios/RNFBAppCheckUnitTests/HostStubs/Firebase/FIRAppCheckHostStub.m +109 -0
  20. package/ios/RNFBAppCheckUnitTests/HostStubs/Firebase/Firebase.h +47 -0
  21. package/ios/RNFBAppCheckUnitTests/HostStubs/RNFBApp/RCTConvert+FIRApp.h +13 -0
  22. package/ios/RNFBAppCheckUnitTests/HostStubs/RNFBApp/RCTConvert+FIRAppHostStub.m +27 -0
  23. package/ios/RNFBAppCheckUnitTests/HostStubs/RNFBApp/RNFBSharedUtils.h +18 -0
  24. package/ios/RNFBAppCheckUnitTests/HostStubs/RNFBApp/RNFBSharedUtilsHostStub.m +18 -0
  25. package/ios/RNFBAppCheckUnitTests/HostStubs/RNFBAppCheck/RNFBAppCheckProviderHostStub.m +48 -0
  26. package/ios/RNFBAppCheckUnitTests/HostStubs/React/RCTBridgeModule.h +10 -0
  27. package/ios/RNFBAppCheckUnitTests/RNFBAppCheckHelperHostStubTests.m +197 -0
  28. package/ios/RNFBAppCheckUnitTests/RNFBAppCheckRejectCodeMapperTests.swift +85 -0
  29. package/ios/RNFBAppCheckUnitTests/RNFBAppCheckUnitTests.xcodeproj/project.pbxproj +277 -0
  30. package/ios/RNFBAppCheckUnitTests/RNFBAppCheckUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBAppCheckUnitTests.xcscheme +69 -0
  31. package/lib/index.ts +1 -1
  32. package/lib/version.ts +1 -1
  33. package/package.json +5 -4
  34. package/plugin/build/ios/appDelegate.js +12 -13
  35. package/plugin/src/ios/appDelegate.ts +13 -14
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ * Enough of Firebase Core / App Check for compiling RNFBAppCheckHelper.m
4
+ * and driving token completion branches without linking the SDK.
5
+ */
6
+ #import <Foundation/Foundation.h>
7
+
8
+ @interface FIRApp : NSObject
9
+ @property(nonatomic, copy) NSString *name;
10
+ - (instancetype)initWithName:(NSString *)name;
11
+ @end
12
+
13
+ @interface FIRAppCheckToken : NSObject
14
+ @property(nonatomic, readonly, copy) NSString *token;
15
+ - (instancetype)initWithToken:(NSString *)token;
16
+ @end
17
+
18
+ @protocol FIRAppCheckProvider <NSObject>
19
+ @end
20
+
21
+ @protocol FIRAppCheckProviderFactory <NSObject>
22
+ - (nullable id<FIRAppCheckProvider>)createProviderWithApp:(FIRApp *)app;
23
+ @end
24
+
25
+ typedef void (^FIRAppCheckTokenCompletionBlock)(FIRAppCheckToken *_Nullable token,
26
+ NSError *_Nullable error);
27
+
28
+ @interface FIRAppCheck : NSObject
29
+
30
+ @property(nonatomic, assign) BOOL isTokenAutoRefreshEnabled;
31
+
32
+ + (void)setAppCheckProviderFactory:(nullable id<FIRAppCheckProviderFactory>)factory;
33
+ + (instancetype)appCheckWithApp:(FIRApp *)app;
34
+
35
+ - (void)tokenForcingRefresh:(BOOL)forceRefresh
36
+ completion:(FIRAppCheckTokenCompletionBlock)completion;
37
+ - (void)limitedUseTokenWithCompletion:(FIRAppCheckTokenCompletionBlock)completion;
38
+
39
+ /** Test seam: when set, invoked instead of a network/token fetch. */
40
+ @property(class, nonatomic, copy, nullable) void (^tokenForcingRefreshHandler)
41
+ (BOOL forceRefresh, FIRAppCheckTokenCompletionBlock completion);
42
+ @property(class, nonatomic, copy, nullable) void (^limitedUseTokenHandler)
43
+ (FIRAppCheckTokenCompletionBlock completion);
44
+
45
+ + (void)resetTestState;
46
+
47
+ @end
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ */
4
+ #import <Foundation/Foundation.h>
5
+
6
+ @class FIRApp;
7
+
8
+ @interface RCTConvert : NSObject
9
+ + (FIRApp *)firAppFromString:(NSString *)appName;
10
+ /** Test seam: map appName → FIRApp. Cleared via resetTestState. */
11
+ + (void)setFirAppFromStringHandler:(FIRApp * (^)(NSString *appName))handler;
12
+ + (void)resetTestState;
13
+ @end
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ */
4
+ #import "RNFBApp/RCTConvert+FIRApp.h"
5
+
6
+ #import <Firebase/Firebase.h>
7
+
8
+ @implementation RCTConvert
9
+
10
+ static FIRApp * (^sFirAppFromStringHandler)(NSString *appName);
11
+
12
+ + (FIRApp *)firAppFromString:(NSString *)appName {
13
+ if (sFirAppFromStringHandler != nil) {
14
+ return sFirAppFromStringHandler(appName);
15
+ }
16
+ return [[FIRApp alloc] initWithName:appName ?: @"[DEFAULT]"];
17
+ }
18
+
19
+ + (void)setFirAppFromStringHandler:(FIRApp * (^)(NSString *appName))handler {
20
+ sFirAppFromStringHandler = [handler copy];
21
+ }
22
+
23
+ + (void)resetTestState {
24
+ sFirAppFromStringHandler = nil;
25
+ }
26
+
27
+ @end
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ */
4
+ #import <Foundation/Foundation.h>
5
+ #import <React/RCTBridgeModule.h>
6
+
7
+ #ifdef DEBUG
8
+ #define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
9
+ #else
10
+ #define DLog(...)
11
+ #endif
12
+
13
+ @interface RNFBSharedUtils : NSObject
14
+
15
+ + (void)rejectPromiseWithUserInfo:(RCTPromiseRejectBlock)reject
16
+ userInfo:(NSMutableDictionary *)userInfo;
17
+
18
+ @end
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ */
4
+ #import "RNFBApp/RNFBSharedUtils.h"
5
+
6
+ @implementation RNFBSharedUtils
7
+
8
+ + (void)rejectPromiseWithUserInfo:(RCTPromiseRejectBlock)reject
9
+ userInfo:(NSMutableDictionary *)userInfo {
10
+ if (reject == nil) {
11
+ return;
12
+ }
13
+ NSString *code = userInfo[@"code"] ?: @"unknown";
14
+ NSString *message = userInfo[@"message"] ?: @"";
15
+ reject(code, message, nil);
16
+ }
17
+
18
+ @end
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ * Replaces production RNFBAppCheckProvider.m (DeviceCheck / App Attest / debug SDK).
4
+ */
5
+ #import "RNFBAppCheckProvider.h"
6
+
7
+ NSString *const kRNFBAppCheckProviderNotReadyMessage =
8
+ @"App Check provider is not ready. Call initializeAppCheck before requesting tokens.";
9
+
10
+ @interface RNFBAppCheckHostStubDelegateProvider : NSObject <FIRAppCheckProvider>
11
+ @end
12
+
13
+ @implementation RNFBAppCheckHostStubDelegateProvider
14
+ @end
15
+
16
+ @implementation RNFBAppCheckProvider
17
+
18
+ - (id)initWithApp:(FIRApp *)app {
19
+ self = [super init];
20
+ if (self) {
21
+ self.app = app;
22
+ }
23
+ return self;
24
+ }
25
+
26
+ - (void)configure:(FIRApp *)app
27
+ providerName:(NSString *)providerName
28
+ debugToken:(NSString *)debugToken {
29
+ (void)providerName;
30
+ (void)debugToken;
31
+ self.app = app;
32
+ // Mark ready so Helper RejectIfProviderNotReady allows token APIs.
33
+ self.delegateProvider = [[RNFBAppCheckHostStubDelegateProvider alloc] init];
34
+ }
35
+
36
+ - (void)getTokenWithCompletion:(nonnull void (^)(FIRAppCheckToken *_Nullable,
37
+ NSError *_Nullable))handler {
38
+ if (handler != nil) {
39
+ handler(nil, [NSError errorWithDomain:@"RNFBAppCheckHostStub"
40
+ code:0
41
+ userInfo:@{
42
+ @"code" : @"provider-not-ready",
43
+ NSLocalizedDescriptionKey : kRNFBAppCheckProviderNotReadyMessage,
44
+ }]);
45
+ }
46
+ }
47
+
48
+ @end
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Host-only stub for macOS XCTest. Not shipped in the production pod.
3
+ */
4
+ #import <Foundation/Foundation.h>
5
+
6
+ typedef void (^RCTPromiseResolveBlock)(id result);
7
+ typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);
8
+
9
+ @protocol RCTBridgeModule <NSObject>
10
+ @end
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import <XCTest/XCTest.h>
18
+
19
+ #import <Firebase/Firebase.h>
20
+ #import "RNFBApp/RCTConvert+FIRApp.h"
21
+ #import "RNFBAppCheckHelper.h"
22
+
23
+ @interface RNFBAppCheckHelperHostStubTests : XCTestCase
24
+ @end
25
+
26
+ @implementation RNFBAppCheckHelperHostStubTests
27
+
28
+ - (void)setUp {
29
+ [super setUp];
30
+ [FIRAppCheck resetTestState];
31
+ [RCTConvert resetTestState];
32
+ [RCTConvert setFirAppFromStringHandler:^FIRApp *(NSString *appName) {
33
+ return [[FIRApp alloc] initWithName:appName ?: @"[DEFAULT]"];
34
+ }];
35
+ }
36
+
37
+ - (void)tearDown {
38
+ [FIRAppCheck resetTestState];
39
+ [RCTConvert resetTestState];
40
+ [super tearDown];
41
+ }
42
+
43
+ - (void)testActivate_configuresDeviceCheckAndResolves {
44
+ __block id resolved = @"unset";
45
+ __block BOOL rejected = NO;
46
+
47
+ [RNFBAppCheckHelper activate:@"helper-activate"
48
+ siteKeyProvider:@"ignored"
49
+ isTokenAutoRefreshEnabled:YES
50
+ resolve:^(id result) {
51
+ resolved = result;
52
+ }
53
+ reject:^(NSString *code, NSString *message, NSError *error) {
54
+ (void)code;
55
+ (void)message;
56
+ (void)error;
57
+ rejected = YES;
58
+ }];
59
+
60
+ XCTAssertFalse(rejected);
61
+ XCTAssertEqualObjects(resolved, [NSNull null]);
62
+
63
+ FIRApp *app = [RCTConvert firAppFromString:@"helper-activate"];
64
+ FIRAppCheck *appCheck = [FIRAppCheck appCheckWithApp:app];
65
+ XCTAssertTrue(appCheck.isTokenAutoRefreshEnabled);
66
+ }
67
+
68
+ - (void)testGetToken_nilToken_rejectsTokenNull {
69
+ // activate installs a ready provider (HostStub sets delegateProvider).
70
+ [RNFBAppCheckHelper activate:@"helper-nil-token"
71
+ siteKeyProvider:nil
72
+ isTokenAutoRefreshEnabled:NO
73
+ resolve:^(id result) {
74
+ (void)result;
75
+ }
76
+ reject:^(NSString *code, NSString *message, NSError *error) {
77
+ (void)code;
78
+ (void)message;
79
+ (void)error;
80
+ }];
81
+
82
+ FIRAppCheck.tokenForcingRefreshHandler =
83
+ ^(BOOL forceRefresh, FIRAppCheckTokenCompletionBlock completion) {
84
+ (void)forceRefresh;
85
+ completion(nil, nil);
86
+ };
87
+
88
+ XCTestExpectation *expectation = [self expectationWithDescription:@"getToken nil rejects"];
89
+ __block NSString *rejectCode = nil;
90
+ __block NSString *rejectMessage = nil;
91
+
92
+ [RNFBAppCheckHelper getToken:@"helper-nil-token"
93
+ forceRefresh:NO
94
+ resolve:^(id result) {
95
+ (void)result;
96
+ XCTFail(@"expected reject for nil token");
97
+ [expectation fulfill];
98
+ }
99
+ reject:^(NSString *code, NSString *message, NSError *error) {
100
+ (void)error;
101
+ rejectCode = code;
102
+ rejectMessage = message;
103
+ [expectation fulfill];
104
+ }];
105
+
106
+ [self waitForExpectationsWithTimeout:1.0 handler:nil];
107
+ XCTAssertEqualObjects(rejectCode, @"token-null");
108
+ XCTAssertEqualObjects(rejectMessage, @"no token fetched");
109
+ }
110
+
111
+ - (void)testGetLimitedUseToken_error_rejectsMappedCode {
112
+ [RNFBAppCheckHelper activate:@"helper-limited-error"
113
+ siteKeyProvider:nil
114
+ isTokenAutoRefreshEnabled:NO
115
+ resolve:^(id result) {
116
+ (void)result;
117
+ }
118
+ reject:^(NSString *code, NSString *message, NSError *error) {
119
+ (void)code;
120
+ (void)message;
121
+ (void)error;
122
+ }];
123
+
124
+ NSError *fetchError = [NSError errorWithDomain:@"io.invertase.firebase.app-check.test"
125
+ code:9
126
+ userInfo:@{
127
+ NSLocalizedDescriptionKey : @"limited use failed",
128
+ @"code" : @"network",
129
+ }];
130
+ FIRAppCheck.limitedUseTokenHandler = ^(FIRAppCheckTokenCompletionBlock completion) {
131
+ completion(nil, fetchError);
132
+ };
133
+
134
+ XCTestExpectation *expectation =
135
+ [self expectationWithDescription:@"getLimitedUseToken error rejects"];
136
+ __block NSString *rejectCode = nil;
137
+ __block NSString *rejectMessage = nil;
138
+
139
+ [RNFBAppCheckHelper getLimitedUseToken:@"helper-limited-error"
140
+ resolve:^(id result) {
141
+ (void)result;
142
+ XCTFail(@"expected reject for error");
143
+ [expectation fulfill];
144
+ }
145
+ reject:^(NSString *code, NSString *message, NSError *error) {
146
+ (void)error;
147
+ rejectCode = code;
148
+ rejectMessage = message;
149
+ [expectation fulfill];
150
+ }];
151
+
152
+ [self waitForExpectationsWithTimeout:1.0 handler:nil];
153
+ XCTAssertEqualObjects(rejectCode, @"token-error");
154
+ XCTAssertEqualObjects(rejectMessage, @"limited use failed");
155
+ }
156
+
157
+ - (void)testGetLimitedUseToken_nilToken_rejectsTokenNull {
158
+ [RNFBAppCheckHelper activate:@"helper-limited-nil"
159
+ siteKeyProvider:nil
160
+ isTokenAutoRefreshEnabled:NO
161
+ resolve:^(id result) {
162
+ (void)result;
163
+ }
164
+ reject:^(NSString *code, NSString *message, NSError *error) {
165
+ (void)code;
166
+ (void)message;
167
+ (void)error;
168
+ }];
169
+
170
+ FIRAppCheck.limitedUseTokenHandler = ^(FIRAppCheckTokenCompletionBlock completion) {
171
+ completion(nil, nil);
172
+ };
173
+
174
+ XCTestExpectation *expectation =
175
+ [self expectationWithDescription:@"getLimitedUseToken nil rejects"];
176
+ __block NSString *rejectCode = nil;
177
+ __block NSString *rejectMessage = nil;
178
+
179
+ [RNFBAppCheckHelper getLimitedUseToken:@"helper-limited-nil"
180
+ resolve:^(id result) {
181
+ (void)result;
182
+ XCTFail(@"expected reject for nil token");
183
+ [expectation fulfill];
184
+ }
185
+ reject:^(NSString *code, NSString *message, NSError *error) {
186
+ (void)error;
187
+ rejectCode = code;
188
+ rejectMessage = message;
189
+ [expectation fulfill];
190
+ }];
191
+
192
+ [self waitForExpectationsWithTimeout:1.0 handler:nil];
193
+ XCTAssertEqualObjects(rejectCode, @"token-null");
194
+ XCTAssertEqualObjects(rejectMessage, @"no token fetched");
195
+ }
196
+
197
+ @end
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Copyright (c) 2016-present Invertase Limited & Contributors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this library except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import XCTest
18
+
19
+ final class RNFBAppCheckRejectCodeMapperTests: XCTestCase {
20
+ private let domain = "io.invertase.firebase.app-check.test"
21
+
22
+ private func error(code: Any?, underlying: Error? = nil) -> NSError {
23
+ var userInfo: [String: Any] = [:]
24
+ if let code {
25
+ userInfo["code"] = code
26
+ }
27
+ if let underlying {
28
+ userInfo[NSUnderlyingErrorKey] = underlying
29
+ }
30
+ return NSError(domain: domain, code: 1, userInfo: userInfo)
31
+ }
32
+
33
+ func testRejectCode_nilError_returnsTokenError() {
34
+ XCTAssertEqual(RNFBAppCheckRejectCodeMapper.rejectCode(for: nil), "token-error")
35
+ }
36
+
37
+ func testRejectCode_emptyUserInfo_returnsTokenError() {
38
+ let err = NSError(domain: domain, code: 1, userInfo: nil)
39
+ XCTAssertEqual(RNFBAppCheckRejectCodeMapper.rejectCode(for: err), "token-error")
40
+ }
41
+
42
+ func testRejectCode_topLevelProviderNotReady() {
43
+ let err = error(code: "provider-not-ready")
44
+ XCTAssertEqual(
45
+ RNFBAppCheckRejectCodeMapper.rejectCode(for: err), "provider-not-ready")
46
+ }
47
+
48
+ func testRejectCode_otherStringCode_returnsTokenError() {
49
+ let err = error(code: "token-null")
50
+ XCTAssertEqual(RNFBAppCheckRejectCodeMapper.rejectCode(for: err), "token-error")
51
+ }
52
+
53
+ func testRejectCode_nonStringCode_returnsTokenError() {
54
+ let err = error(code: NSNumber(value: 42))
55
+ XCTAssertEqual(RNFBAppCheckRejectCodeMapper.rejectCode(for: err), "token-error")
56
+ }
57
+
58
+ func testRejectCode_underlyingProviderNotReady() {
59
+ let inner = error(code: "provider-not-ready")
60
+ let outer = error(code: "wrapped", underlying: inner)
61
+ XCTAssertEqual(
62
+ RNFBAppCheckRejectCodeMapper.rejectCode(for: outer), "provider-not-ready")
63
+ }
64
+
65
+ func testRejectCode_deepChain_providerNotReadyInMiddle() {
66
+ let leaf = error(code: "other")
67
+ let middle = error(code: "provider-not-ready", underlying: leaf)
68
+ let outer = error(code: "sdk-wrap", underlying: middle)
69
+ XCTAssertEqual(
70
+ RNFBAppCheckRejectCodeMapper.rejectCode(for: outer), "provider-not-ready")
71
+ }
72
+
73
+ func testRejectCode_nonErrorUnderlying_stopsWalk() {
74
+ var userInfo: [String: Any] = ["code": "wrapped"]
75
+ userInfo[NSUnderlyingErrorKey] = "not-an-error"
76
+ let err = NSError(domain: domain, code: 1, userInfo: userInfo)
77
+ XCTAssertEqual(RNFBAppCheckRejectCodeMapper.rejectCode(for: err), "token-error")
78
+ }
79
+
80
+ func testRejectCode_underlyingWithoutProviderCode_returnsTokenError() {
81
+ let inner = error(code: "network")
82
+ let outer = error(code: nil, underlying: inner)
83
+ XCTAssertEqual(RNFBAppCheckRejectCodeMapper.rejectCode(for: outer), "token-error")
84
+ }
85
+ }