react-native-shield-fraud-plugin 1.0.10 → 2.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.
- package/android/build.gradle +30 -12
- package/android/src/main/java/com/shieldfraudplugin/ShieldFraudPluginModule.java +354 -123
- package/android/src/main/java/com/shieldfraudplugin/ShieldFraudPluginPackage.java +71 -21
- package/android/src/newarch/java/com/shieldfraudplugin/ShieldFraudPluginSpec.java +41 -0
- package/android/src/oldarch/java/com/shieldfraudplugin/ShieldFraudPluginSpec.java +36 -0
- package/ios/ShieldFraudPlugin.h +11 -2
- package/ios/ShieldFraudPlugin.mm +289 -0
- package/lib/commonjs/NativeShieldFraudPlugin.js +15 -0
- package/lib/commonjs/NativeShieldFraudPlugin.js.map +1 -0
- package/lib/commonjs/index.js +80 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeShieldFraudPlugin.js +10 -0
- package/lib/module/NativeShieldFraudPlugin.js.map +1 -0
- package/lib/module/index.js +81 -9
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/NativeShieldFraudPlugin.d.ts +52 -0
- package/lib/typescript/NativeShieldFraudPlugin.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +41 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +10 -2
- package/react-native-shield-fraud-plugin.podspec +13 -3
- package/src/NativeShieldFraudPlugin.ts +85 -0
- package/src/index.tsx +115 -11
- package/ios/ShieldFraudPlugin.m +0 -98
- package/ios/ShieldFraudPlugin.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/ios/ShieldFraudPlugin.xcodeproj/project.xcworkspace/xcuserdata/deepakraj.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/ShieldFraudPlugin.xcodeproj/xcuserdata/deepakraj.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
|
@@ -2,27 +2,77 @@ package com.shieldfraudplugin;
|
|
|
2
2
|
|
|
3
3
|
import androidx.annotation.NonNull;
|
|
4
4
|
|
|
5
|
-
import com.facebook.react.
|
|
5
|
+
import com.facebook.react.TurboReactPackage;
|
|
6
6
|
import com.facebook.react.bridge.NativeModule;
|
|
7
7
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
-
import com.facebook.react.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import java.util.
|
|
12
|
-
import java.util.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
import com.facebook.react.module.model.ReactModuleInfo;
|
|
9
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
|
10
|
+
|
|
11
|
+
import java.util.HashMap;
|
|
12
|
+
import java.util.Map;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Package registration for ShieldFraudPlugin — works on both architectures.
|
|
16
|
+
*
|
|
17
|
+
* Why TurboReactPackage instead of ReactPackage
|
|
18
|
+
* ─────────────────────────────────────────────
|
|
19
|
+
* TurboReactPackage is a drop-in replacement for the legacy ReactPackage that
|
|
20
|
+
* adds support for Turbo Modules (New Architecture) while remaining fully
|
|
21
|
+
* backward-compatible with the Old Architecture bridge.
|
|
22
|
+
*
|
|
23
|
+
* On Old Architecture the isTurboModule flag in ReactModuleInfo is simply
|
|
24
|
+
* ignored and the module is loaded via the bridge as normal.
|
|
25
|
+
* On New Architecture the flag tells the runtime to resolve the module through
|
|
26
|
+
* the Turbo Module system (JSI) instead of the bridge.
|
|
27
|
+
*
|
|
28
|
+
* The isTurboModule flag is driven by BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
|
|
29
|
+
* which build.gradle sets to true/false based on the newArchEnabled property:
|
|
30
|
+
*
|
|
31
|
+
* buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED",
|
|
32
|
+
* isNewArchitectureEnabled().toString()
|
|
33
|
+
*/
|
|
34
|
+
public class ShieldFraudPluginPackage extends TurboReactPackage {
|
|
35
|
+
|
|
36
|
+
// =========================================================================
|
|
37
|
+
// Module instantiation
|
|
38
|
+
// =========================================================================
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public NativeModule getModule(@NonNull String name,
|
|
42
|
+
@NonNull ReactApplicationContext reactContext) {
|
|
43
|
+
if (name.equals(ShieldFraudPluginModule.NAME)) {
|
|
44
|
+
return new ShieldFraudPluginModule(reactContext);
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// =========================================================================
|
|
50
|
+
// Module metadata
|
|
51
|
+
//
|
|
52
|
+
// ReactModuleInfoProvider returns the metadata the runtime needs to decide
|
|
53
|
+
// how to load the module:
|
|
54
|
+
// • Old Arch → isTurboModule=false → loaded via JS bridge
|
|
55
|
+
// • New Arch → isTurboModule=true → loaded via JSI (Turbo Module)
|
|
56
|
+
// =========================================================================
|
|
57
|
+
|
|
58
|
+
@Override
|
|
59
|
+
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
|
60
|
+
return () -> {
|
|
61
|
+
final boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
|
62
|
+
Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
|
|
63
|
+
moduleInfos.put(
|
|
64
|
+
ShieldFraudPluginModule.NAME,
|
|
65
|
+
new ReactModuleInfo(
|
|
66
|
+
ShieldFraudPluginModule.NAME, // name
|
|
67
|
+
ShieldFraudPluginModule.NAME, // className
|
|
68
|
+
false, // canOverrideExistingModule
|
|
69
|
+
false, // needsEagerInit
|
|
70
|
+
true, // hasConstants
|
|
71
|
+
false, // isCxxModule
|
|
72
|
+
isTurboModule // isTurboModule
|
|
73
|
+
)
|
|
74
|
+
);
|
|
75
|
+
return moduleInfos;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
28
78
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package com.shieldfraudplugin;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* New Architecture base class for ShieldFraudPluginModule.
|
|
7
|
+
*
|
|
8
|
+
* Selected by Gradle when newArchEnabled=true.
|
|
9
|
+
* Extends NativeShieldFraudPluginSpec — the abstract class generated by React
|
|
10
|
+
* Native's codegen from the TypeScript spec at src/NativeShieldFraudPlugin.ts.
|
|
11
|
+
*
|
|
12
|
+
* How the source-set swap works
|
|
13
|
+
* ─────────────────────────────
|
|
14
|
+
* build.gradle adds either src/oldarch or src/newarch to the Java source
|
|
15
|
+
* directories depending on the newArchEnabled project property:
|
|
16
|
+
*
|
|
17
|
+
* sourceSets {
|
|
18
|
+
* main {
|
|
19
|
+
* if (isNewArchitectureEnabled()) {
|
|
20
|
+
* java.srcDirs += ['src/newarch'] // this file is included
|
|
21
|
+
* } else {
|
|
22
|
+
* java.srcDirs += ['src/oldarch'] // this file is excluded
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* ShieldFraudPluginModule (in src/main/) always extends ShieldFraudPluginSpec,
|
|
28
|
+
* so it compiles correctly regardless of which shim is selected.
|
|
29
|
+
*
|
|
30
|
+
* NativeShieldFraudPluginSpec is generated at build time by the React Native
|
|
31
|
+
* Gradle plugin (com.facebook.react) when New Architecture is enabled.
|
|
32
|
+
* It declares all methods from the TypeScript spec as abstract — this shim
|
|
33
|
+
* exists purely to bridge the inheritance chain so ShieldFraudPluginModule
|
|
34
|
+
* does not need to import the codegen class directly.
|
|
35
|
+
*/
|
|
36
|
+
abstract class ShieldFraudPluginSpec extends NativeShieldFraudPluginSpec {
|
|
37
|
+
|
|
38
|
+
protected ShieldFraudPluginSpec(ReactApplicationContext context) {
|
|
39
|
+
super(context);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
package com.shieldfraudplugin;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
4
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Old Architecture base class for ShieldFraudPluginModule.
|
|
8
|
+
*
|
|
9
|
+
* Selected by Gradle when newArchEnabled=false (the default).
|
|
10
|
+
* Extends ReactContextBaseJavaModule — the standard base class for modules
|
|
11
|
+
* that communicate with JS over the legacy bridge.
|
|
12
|
+
*
|
|
13
|
+
* How the source-set swap works
|
|
14
|
+
* ─────────────────────────────
|
|
15
|
+
* build.gradle adds either src/oldarch or src/newarch to the Java source
|
|
16
|
+
* directories depending on the newArchEnabled project property:
|
|
17
|
+
*
|
|
18
|
+
* sourceSets {
|
|
19
|
+
* main {
|
|
20
|
+
* if (isNewArchitectureEnabled()) {
|
|
21
|
+
* java.srcDirs += ['src/newarch'] // this file is excluded
|
|
22
|
+
* } else {
|
|
23
|
+
* java.srcDirs += ['src/oldarch'] // this file is included
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* ShieldFraudPluginModule (in src/main/) always extends ShieldFraudPluginSpec,
|
|
29
|
+
* so it compiles correctly regardless of which shim is selected.
|
|
30
|
+
*/
|
|
31
|
+
abstract class ShieldFraudPluginSpec extends ReactContextBaseJavaModule {
|
|
32
|
+
|
|
33
|
+
protected ShieldFraudPluginSpec(ReactApplicationContext context) {
|
|
34
|
+
super(context);
|
|
35
|
+
}
|
|
36
|
+
}
|
package/ios/ShieldFraudPlugin.h
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
|
|
2
2
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
3
|
+
// New Architecture: conform to the codegen-generated spec protocol.
|
|
4
|
+
// RCTEventEmitter is still used as the base so that sendEventWithName: works.
|
|
5
|
+
#import <React/RCTEventEmitter.h>
|
|
3
6
|
#import "RNShieldFraudPluginSpec.h"
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
// Forward-declare the protocol — the full definition is imported in the .mm file.
|
|
9
|
+
// A forward declaration is sufficient for the @interface conformance declaration.
|
|
10
|
+
@protocol DeviceShieldCallback;
|
|
11
|
+
|
|
12
|
+
@interface ShieldFraudPlugin : RCTEventEmitter <NativeShieldFraudPluginSpec, DeviceShieldCallback>
|
|
6
13
|
#else
|
|
14
|
+
// Old Architecture: standard bridge module + event emitter.
|
|
7
15
|
#import <React/RCTBridgeModule.h>
|
|
8
16
|
#import <React/RCTEventEmitter.h>
|
|
9
17
|
|
|
10
|
-
|
|
18
|
+
// Forward-declare the protocol — full definition imported in the .mm file.
|
|
19
|
+
@protocol DeviceShieldCallback;
|
|
11
20
|
|
|
12
21
|
@interface ShieldFraudPlugin : RCTEventEmitter <RCTBridgeModule, DeviceShieldCallback>
|
|
13
22
|
#endif
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#import "ShieldFraudPlugin.h"
|
|
2
|
+
|
|
3
|
+
// Import the auto-generated Swift→ObjC header.
|
|
4
|
+
// This exposes all Swift-exported types (Configuration, Shield, BlockedDialog,
|
|
5
|
+
// LogLevel, Environment, ShieldCrossPlatformHelper, DeviceShieldCallback, …)
|
|
6
|
+
// without requiring Clang module syntax (@import), which fails in Obj-C++ files
|
|
7
|
+
// when C++ modules are not enabled (e.g. when the New Architecture codegen
|
|
8
|
+
// headers are included and the file is compiled as Obj-C++).
|
|
9
|
+
#import <ShieldFraud/ShieldFraud-Swift.h>
|
|
10
|
+
|
|
11
|
+
@implementation ShieldFraudPlugin
|
|
12
|
+
|
|
13
|
+
static BOOL isShieldInitialized = NO;
|
|
14
|
+
|
|
15
|
+
RCT_EXPORT_MODULE();
|
|
16
|
+
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// MARK: - Shared methods (Old Architecture & New Architecture)
|
|
19
|
+
//
|
|
20
|
+
// These methods have identical signatures in both architectures.
|
|
21
|
+
// RCT_EXPORT_METHOD registers them with the bridge for Old Arch, and the
|
|
22
|
+
// matching Obj-C selectors satisfy the codegen protocol for New Arch.
|
|
23
|
+
// =============================================================================
|
|
24
|
+
|
|
25
|
+
// Cross-platform SDK metadata (React Native wrapper version / name)
|
|
26
|
+
RCT_EXPORT_METHOD(setCrossPlatformParameters:(NSString *)crossPlatformName
|
|
27
|
+
crossPlatformVersion:(NSString *)crossPlatformVersion)
|
|
28
|
+
{
|
|
29
|
+
ShieldCrossPlatformParams *params = [[ShieldCrossPlatformParams alloc]
|
|
30
|
+
initWithName:crossPlatformName
|
|
31
|
+
version:crossPlatformVersion];
|
|
32
|
+
[ShieldCrossPlatformHelper setCrossPlatformParameters:params];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Retrieve the most-recently-computed device result
|
|
36
|
+
RCT_EXPORT_METHOD(getLatestDeviceResult:(RCTResponseSenderBlock)successCallback
|
|
37
|
+
errorCallback:(RCTResponseSenderBlock)errorCallback)
|
|
38
|
+
{
|
|
39
|
+
NSDictionary<NSString *, id> *result = [[Shield shared] getLatestDeviceResult];
|
|
40
|
+
if (result != NULL) {
|
|
41
|
+
successCallback(@[result]);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
NSError *error = [[Shield shared] getErrorResponse];
|
|
46
|
+
if (error != NULL) {
|
|
47
|
+
errorCallback(@[[error localizedDescription]]);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
errorCallback(@[@"No device result available yet."]);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Subscribe to real-time device-result state changes
|
|
55
|
+
RCT_EXPORT_METHOD(setDeviceResultStateListener)
|
|
56
|
+
{
|
|
57
|
+
double delayInSeconds = 1.5;
|
|
58
|
+
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,
|
|
59
|
+
(int64_t)(delayInSeconds * NSEC_PER_SEC));
|
|
60
|
+
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
|
|
61
|
+
[[Shield shared] setDeviceResultStateListener:^{
|
|
62
|
+
[self sendEventWithName:@"device_result_state"
|
|
63
|
+
body:@{@"status": @"isSDKReady"}];
|
|
64
|
+
}];
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Attach arbitrary screen-level attributes
|
|
69
|
+
RCT_EXPORT_METHOD(sendAttributes:(NSString *)screenName
|
|
70
|
+
data:(NSDictionary *)data)
|
|
71
|
+
{
|
|
72
|
+
[[Shield shared] sendAttributesWithScreenName:screenName data:data];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
RCT_EXPORT_METHOD(sendAttributesWithCallback:(NSString *)screenName
|
|
76
|
+
data:(NSDictionary *)data
|
|
77
|
+
successCallback:(RCTResponseSenderBlock)successCallback
|
|
78
|
+
errorCallback:(RCTResponseSenderBlock)errorCallback)
|
|
79
|
+
{
|
|
80
|
+
[[Shield shared] sendAttributesWithScreenName:screenName
|
|
81
|
+
data:data
|
|
82
|
+
:^(BOOL success, NSError *error) {
|
|
83
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
84
|
+
if (success) {
|
|
85
|
+
successCallback(@[@(YES)]);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
NSString *errorMessage = error != nil
|
|
90
|
+
? [error localizedDescription]
|
|
91
|
+
: @"Failed to send attributes.";
|
|
92
|
+
errorCallback(@[errorMessage]);
|
|
93
|
+
});
|
|
94
|
+
}];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Trigger a device signature computation for a given screen name.
|
|
98
|
+
// The completionHandler fires when the SDK is done; results and errors
|
|
99
|
+
// are read back from getLatestDeviceResult / getErrorResponse.
|
|
100
|
+
RCT_EXPORT_METHOD(sendDeviceSignature:(NSString *)screenName
|
|
101
|
+
successCallback:(RCTResponseSenderBlock)successCallback
|
|
102
|
+
errorCallback:(RCTResponseSenderBlock)errorCallback)
|
|
103
|
+
{
|
|
104
|
+
[[Shield shared] sendDeviceSignatureWithScreenName:screenName
|
|
105
|
+
completionHandler:^{
|
|
106
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
107
|
+
NSDictionary<NSString *, id> *deviceResult = [[Shield shared] getLatestDeviceResult];
|
|
108
|
+
if (deviceResult != nil) {
|
|
109
|
+
successCallback(@[deviceResult]);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
NSError *error = [[Shield shared] getErrorResponse];
|
|
114
|
+
if (error != nil) {
|
|
115
|
+
errorCallback(@[[error localizedDescription]]);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
errorCallback(@[@"No device result available."]);
|
|
120
|
+
});
|
|
121
|
+
}];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// RCTEventEmitter — declare the events this module can emit
|
|
125
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
126
|
+
{
|
|
127
|
+
return @[@"success", @"error", @"device_result_state"];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// RCTEventEmitter — required overrides (no-op wrappers keep the base class happy)
|
|
131
|
+
- (void)addListener:(NSString *)eventName
|
|
132
|
+
{
|
|
133
|
+
[super addListener:eventName];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
- (void)removeListeners:(double)count
|
|
137
|
+
{
|
|
138
|
+
[super removeListeners:count];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// DeviceShieldCallback delegate — forwarded as JS events
|
|
142
|
+
- (void)didErrorWithError:(NSError *)error
|
|
143
|
+
{
|
|
144
|
+
[self sendEventWithName:@"error" body:[error localizedDescription]];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
- (void)didSuccessWithResult:(NSDictionary<NSString *, id> *)result
|
|
148
|
+
{
|
|
149
|
+
[self sendEventWithName:@"success" body:result];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
// =============================================================================
|
|
154
|
+
// MARK: - Architecture-specific methods
|
|
155
|
+
// =============================================================================
|
|
156
|
+
|
|
157
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
158
|
+
|
|
159
|
+
// -----------------------------------------------------------------------------
|
|
160
|
+
// New Architecture (Turbo Modules / JSI)
|
|
161
|
+
//
|
|
162
|
+
// Methods are implemented as plain Obj-C methods to directly satisfy the
|
|
163
|
+
// codegen-generated NativeShieldFraudPluginSpec protocol.
|
|
164
|
+
//
|
|
165
|
+
// Key differences from Old Arch:
|
|
166
|
+
// • initShield — logLevel/environmentInfo are `double` (JS numbers are
|
|
167
|
+
// always doubles); resolve/reject blocks are added for the
|
|
168
|
+
// Promise<void> return type declared in the TS spec.
|
|
169
|
+
// • getSessionId / isShieldInitialized — synchronous return values are
|
|
170
|
+
// supported natively by JSI (no blocking-synchronous macro).
|
|
171
|
+
// • isShieldInitialized — protocol requires NSNumber* so JSI can marshal
|
|
172
|
+
// the boolean; returning plain BOOL would be a type mismatch.
|
|
173
|
+
// • getTurboModule: — wires this Obj-C class into the JSI runtime.
|
|
174
|
+
// -----------------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
- (void)initShield:(NSString *)siteID
|
|
177
|
+
secretKey:(NSString *)secretKey
|
|
178
|
+
isOptimizedListener:(BOOL)isOptimizedListener
|
|
179
|
+
blockedDialog:(NSDictionary * _Nullable)blockedDialog
|
|
180
|
+
logLevel:(double)logLevel
|
|
181
|
+
environmentInfo:(double)environmentInfo
|
|
182
|
+
blockScreenRecording:(BOOL)blockScreenRecording
|
|
183
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
184
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
185
|
+
{
|
|
186
|
+
if (!isShieldInitialized) {
|
|
187
|
+
Configuration *config = [[Configuration alloc] initWithSiteId:siteID
|
|
188
|
+
secretKey:secretKey];
|
|
189
|
+
if (isOptimizedListener) {
|
|
190
|
+
config.deviceShieldCallback = self;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (blockedDialog != nil) {
|
|
194
|
+
NSString *title = [blockedDialog objectForKey:@"title"];
|
|
195
|
+
NSString *body = [blockedDialog objectForKey:@"body"];
|
|
196
|
+
config.defaultBlockedDialog = [[BlockedDialog alloc] initWithTitle:title
|
|
197
|
+
body:body];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// JS numbers arrive as double; cast explicitly to Swift-bridged enum types.
|
|
201
|
+
config.logLevel = (LogLevel)(NSInteger)logLevel;
|
|
202
|
+
config.environment = (Environment)(NSInteger)environmentInfo;
|
|
203
|
+
|
|
204
|
+
[Shield setUpWith:config];
|
|
205
|
+
isShieldInitialized = YES;
|
|
206
|
+
}
|
|
207
|
+
resolve(nil);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
- (NSString *)getSessionId
|
|
211
|
+
{
|
|
212
|
+
return [[Shield shared] sessionId];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
- (NSNumber *)isShieldInitialized
|
|
216
|
+
{
|
|
217
|
+
return @(isShieldInitialized);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Wires this Obj-C class into the JSI runtime.
|
|
221
|
+
// The generated class name follows the codegenConfig "name" in package.json:
|
|
222
|
+
// "RNShieldFraudPluginSpec" → NativeShieldFraudPluginSpecJSI
|
|
223
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
224
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
225
|
+
{
|
|
226
|
+
return std::make_shared<facebook::react::NativeShieldFraudPluginSpecJSI>(params);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
#else
|
|
230
|
+
|
|
231
|
+
// -----------------------------------------------------------------------------
|
|
232
|
+
// Old Architecture (Bridge)
|
|
233
|
+
//
|
|
234
|
+
// RCT_EXPORT_METHOD — registers void-return methods with the JS bridge.
|
|
235
|
+
// RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD — bridge-only macro for synchronous
|
|
236
|
+
// return values; has no JSI equivalent and must stay inside #else.
|
|
237
|
+
//
|
|
238
|
+
// Key differences from New Arch:
|
|
239
|
+
// • initShield — logLevel/environmentInfo are NSInteger (bridge coerces
|
|
240
|
+
// from NSNumber); no resolve/reject (bridge wraps the void
|
|
241
|
+
// return automatically).
|
|
242
|
+
// • getSessionId / isShieldInitialized — must use the blocking-synchronous
|
|
243
|
+
// macro so the bridge returns the value to JS synchronously.
|
|
244
|
+
// -----------------------------------------------------------------------------
|
|
245
|
+
|
|
246
|
+
RCT_EXPORT_METHOD(initShield:(NSString *)siteID
|
|
247
|
+
secretKey:(NSString *)secretKey
|
|
248
|
+
isOptimizedListener:(BOOL)isOptimizedListener
|
|
249
|
+
blockedDialog:(NSDictionary *)blockedDialog
|
|
250
|
+
logLevel:(NSInteger)logLevel
|
|
251
|
+
environmentInfo:(NSInteger)environmentInfo
|
|
252
|
+
blockScreenRecording:(BOOL)blockScreenRecording)
|
|
253
|
+
{
|
|
254
|
+
if (!isShieldInitialized) {
|
|
255
|
+
Configuration *config = [[Configuration alloc] initWithSiteId:siteID
|
|
256
|
+
secretKey:secretKey];
|
|
257
|
+
if (isOptimizedListener) {
|
|
258
|
+
config.deviceShieldCallback = self;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (blockedDialog != nil) {
|
|
262
|
+
NSString *title = [blockedDialog objectForKey:@"title"];
|
|
263
|
+
NSString *body = [blockedDialog objectForKey:@"body"];
|
|
264
|
+
config.defaultBlockedDialog = [[BlockedDialog alloc] initWithTitle:title
|
|
265
|
+
body:body];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Cast NSInteger to Swift-bridged enum types explicitly.
|
|
269
|
+
config.logLevel = (LogLevel)logLevel;
|
|
270
|
+
config.environment = (Environment)environmentInfo;
|
|
271
|
+
|
|
272
|
+
[Shield setUpWith:config];
|
|
273
|
+
isShieldInitialized = YES;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getSessionId)
|
|
278
|
+
{
|
|
279
|
+
return [[Shield shared] sessionId];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isShieldInitialized)
|
|
283
|
+
{
|
|
284
|
+
return @(isShieldInitialized);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
288
|
+
|
|
289
|
+
@end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _reactNative = require("react-native");
|
|
8
|
+
/**
|
|
9
|
+
* TypeScript spec for the ShieldFraudPlugin Turbo Module.
|
|
10
|
+
* This file is used by React Native codegen to auto-generate
|
|
11
|
+
* native interface code for both iOS and Android.
|
|
12
|
+
*/
|
|
13
|
+
var _default = _reactNative.TurboModuleRegistry.getEnforcing('ShieldFraudPlugin');
|
|
14
|
+
exports.default = _default;
|
|
15
|
+
//# sourceMappingURL=NativeShieldFraudPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_default","TurboModuleRegistry","getEnforcing","exports","default"],"sourceRoot":"../../src","sources":["NativeShieldFraudPlugin.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAEA;AACA;AACA;AACA;AACA;AAJA,IAAAC,QAAA,GAiFeC,gCAAmB,CAACC,YAAY,CAAO,mBAAmB,CAAC;AAAAC,OAAA,CAAAC,OAAA,GAAAJ,QAAA"}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -5,10 +5,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.LogLevel = exports.EnvironmentInfo = void 0;
|
|
7
7
|
var _reactNative = require("react-native");
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the native module through TurboModuleRegistry (New Architecture)
|
|
10
|
+
* with a fallback to NativeModules bridge (Old Architecture).
|
|
11
|
+
*/
|
|
12
|
+
const ShieldFraudPluginNativeModule = _reactNative.TurboModuleRegistry.get("ShieldFraudPlugin") ?? _reactNative.NativeModules.ShieldFraudPlugin;
|
|
13
|
+
|
|
8
14
|
/**
|
|
9
15
|
* Enum representing the log levels for ShieldFraud.
|
|
10
16
|
*/
|
|
11
17
|
let LogLevel = /*#__PURE__*/function (LogLevel) {
|
|
18
|
+
LogLevel[LogLevel["LogLevelVerbose"] = 4] = "LogLevelVerbose";
|
|
12
19
|
LogLevel[LogLevel["LogLevelDebug"] = 3] = "LogLevelDebug";
|
|
13
20
|
LogLevel[LogLevel["LogLevelInfo"] = 2] = "LogLevelInfo";
|
|
14
21
|
LogLevel[LogLevel["LogLevelNone"] = 1] = "LogLevelNone";
|
|
@@ -21,9 +28,9 @@ exports.LogLevel = LogLevel;
|
|
|
21
28
|
let EnvironmentInfo = /*#__PURE__*/function (EnvironmentInfo) {
|
|
22
29
|
EnvironmentInfo[EnvironmentInfo["EnvironmentProd"] = 0] = "EnvironmentProd";
|
|
23
30
|
EnvironmentInfo[EnvironmentInfo["EnvironmentDev"] = 1] = "EnvironmentDev";
|
|
24
|
-
EnvironmentInfo[EnvironmentInfo["
|
|
31
|
+
EnvironmentInfo[EnvironmentInfo["EnvironmentStaging"] = 2] = "EnvironmentStaging";
|
|
25
32
|
return EnvironmentInfo;
|
|
26
|
-
}({});
|
|
33
|
+
}({}); // Environment.STAGING
|
|
27
34
|
/**
|
|
28
35
|
* Configuration object for initializing ShieldFraud.
|
|
29
36
|
*/
|
|
@@ -45,8 +52,10 @@ exports.EnvironmentInfo = EnvironmentInfo;
|
|
|
45
52
|
class ShieldFraud {
|
|
46
53
|
/**
|
|
47
54
|
* The native module for accessing the ShieldFraudPlugin.
|
|
55
|
+
* Resolved via TurboModuleRegistry on New Architecture, with
|
|
56
|
+
* a NativeModules bridge fallback for Old Architecture.
|
|
48
57
|
*/
|
|
49
|
-
static PlatformWrapper =
|
|
58
|
+
static PlatformWrapper = ShieldFraudPluginNativeModule;
|
|
50
59
|
|
|
51
60
|
/**
|
|
52
61
|
* The event emitter for listening to success and error events.
|
|
@@ -68,14 +77,32 @@ class ShieldFraud {
|
|
|
68
77
|
// Set default values if environmentInfo is not provided
|
|
69
78
|
const environmentInfo = config.environmentInfo || EnvironmentInfo.EnvironmentProd;
|
|
70
79
|
|
|
80
|
+
// Set cross-platform parameters internally (React Native and version from package.json)
|
|
81
|
+
ShieldFraud.setCrossPlatformParameters();
|
|
82
|
+
|
|
83
|
+
// blockScreenRecording is Android-only; iOS native ignores the value.
|
|
84
|
+
// Always send a real boolean — the Old Arch bridge cannot handle null
|
|
85
|
+
// for boolean parameters (causes NPE in ReadableNativeArray.getBoolean).
|
|
86
|
+
const blockScreenRecording = _reactNative.Platform.OS === "android" ? config.blockScreenRecording ?? false : false;
|
|
87
|
+
|
|
71
88
|
// Call the native method to initialize ShieldFraud with the provided configuration.
|
|
72
|
-
await ShieldFraud.PlatformWrapper.initShield(config.siteID, config.secretKey, isOptimizedListener, config.blockedDialog, logLevel, environmentInfo);
|
|
89
|
+
await ShieldFraud.PlatformWrapper.initShield(config.siteID, config.secretKey, isOptimizedListener, config.blockedDialog ?? null, logLevel, environmentInfo, blockScreenRecording);
|
|
73
90
|
if (isOptimizedListener) {
|
|
74
91
|
// Set up listeners for success and error events if callbacks are provided.
|
|
75
92
|
ShieldFraud.listeners(callbacks);
|
|
76
93
|
}
|
|
77
94
|
}
|
|
78
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Private method to set cross-platform parameters.
|
|
98
|
+
* The cross-platform name and the version is fetched from package.json.
|
|
99
|
+
*/
|
|
100
|
+
static setCrossPlatformParameters() {
|
|
101
|
+
const crossPlatformName = "react-native-shield-fraud-plugin";
|
|
102
|
+
const crossPlatformVersion = "2.0.0";
|
|
103
|
+
ShieldFraud.PlatformWrapper.setCrossPlatformParameters(crossPlatformName, crossPlatformVersion);
|
|
104
|
+
}
|
|
105
|
+
|
|
79
106
|
/**
|
|
80
107
|
* Sets up event listeners for success and error events.
|
|
81
108
|
*
|
|
@@ -116,12 +143,22 @@ class ShieldFraud {
|
|
|
116
143
|
}
|
|
117
144
|
|
|
118
145
|
/**
|
|
119
|
-
*
|
|
146
|
+
* iOS only — checks if the ShieldFraud SDK is ready and invokes the provided
|
|
147
|
+
* callback with the readiness state.
|
|
148
|
+
*
|
|
149
|
+
* On Android (SDK 2.x) device result events fire automatically via the
|
|
150
|
+
* Sentinel inside createShieldWithCallback. There is no subscription call
|
|
151
|
+
* and no reliable way to intercept the event after the fact, so this method
|
|
152
|
+
* is a no-op on Android. Use the `callbacks` parameter of `initShield`
|
|
153
|
+
* instead to receive device results on Android.
|
|
120
154
|
*
|
|
121
155
|
* @param callback - A callback function to be invoked with the readiness state.
|
|
122
|
-
* - `isReady` (boolean):
|
|
156
|
+
* - `isReady` (boolean): true when the SDK has produced a device result.
|
|
123
157
|
*/
|
|
124
158
|
static async isSDKready(callback) {
|
|
159
|
+
if (_reactNative.Platform.OS !== "ios") {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
125
162
|
try {
|
|
126
163
|
// Adding a timeout of 100 milliseconds
|
|
127
164
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
@@ -138,6 +175,8 @@ class ShieldFraud {
|
|
|
138
175
|
}
|
|
139
176
|
};
|
|
140
177
|
ShieldFraud.eventEmitter.addListener("device_result_state", deviceResultListener);
|
|
178
|
+
|
|
179
|
+
// Trigger the SDK subscription — iOS 1.x requires this explicit call.
|
|
141
180
|
ShieldFraud.PlatformWrapper.setDeviceResultStateListener();
|
|
142
181
|
} catch (error) {
|
|
143
182
|
console.error("An error occurred:", error);
|
|
@@ -155,6 +194,23 @@ class ShieldFraud {
|
|
|
155
194
|
ShieldFraud.PlatformWrapper.sendAttributes(screenName, data);
|
|
156
195
|
}
|
|
157
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Sends attributes and resolves with `true` when the native SDK confirms success.
|
|
199
|
+
*
|
|
200
|
+
* @param screenName - The name of the screen.
|
|
201
|
+
* @param data - The attribute data object.
|
|
202
|
+
* @returns A Promise that resolves to true on success and rejects on error.
|
|
203
|
+
*/
|
|
204
|
+
static sendAttributesWithCallback(screenName, data) {
|
|
205
|
+
return new Promise((resolve, reject) => {
|
|
206
|
+
ShieldFraud.PlatformWrapper.sendAttributesWithCallback(screenName, data, result => {
|
|
207
|
+
resolve(!!result);
|
|
208
|
+
}, error => {
|
|
209
|
+
reject(error);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
158
214
|
/**
|
|
159
215
|
* Retrieves the latest device result from the ShieldFraud plugin.
|
|
160
216
|
*
|
|
@@ -163,10 +219,26 @@ class ShieldFraud {
|
|
|
163
219
|
static getLatestDeviceResult() {
|
|
164
220
|
return new Promise((resolve, reject) => {
|
|
165
221
|
ShieldFraud.PlatformWrapper.getLatestDeviceResult(result => {
|
|
166
|
-
// Handle success with the result object
|
|
167
222
|
resolve(result);
|
|
168
223
|
}, error => {
|
|
169
|
-
|
|
224
|
+
reject(error);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Triggers a device signature computation for a given screen name.
|
|
231
|
+
* On success, resolves with the latest device result object.
|
|
232
|
+
* On failure, rejects with the error message.
|
|
233
|
+
*
|
|
234
|
+
* @param screenName - The name of the screen triggering the signature.
|
|
235
|
+
* @returns A Promise that resolves with the device result or rejects with an error.
|
|
236
|
+
*/
|
|
237
|
+
static sendDeviceSignature(screenName) {
|
|
238
|
+
return new Promise((resolve, reject) => {
|
|
239
|
+
ShieldFraud.PlatformWrapper.sendDeviceSignature(screenName, result => {
|
|
240
|
+
resolve(result);
|
|
241
|
+
}, error => {
|
|
170
242
|
reject(error);
|
|
171
243
|
});
|
|
172
244
|
});
|