freerasp-react-native 3.13.0 → 3.14.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.
- package/CHANGELOG.md +55 -0
- package/README.md +4 -2
- package/android/build.gradle +3 -3
- package/android/gradle.properties +2 -2
- package/android/proguard-rules.pro +8 -0
- package/android/src/main/java/com/freeraspreactnative/FreeraspReactNativeModule.kt +59 -10
- package/android/src/main/java/com/freeraspreactnative/FreeraspThreatHandler.kt +8 -0
- package/android/src/main/java/com/freeraspreactnative/ScreenProtector.kt +164 -0
- package/android/src/main/java/com/freeraspreactnative/Threat.kt +5 -1
- package/android/src/main/java/com/freeraspreactnative/utils/Extensions.kt +1 -1
- package/example/Gemfile +6 -2
- package/example/Gemfile.lock +121 -0
- package/example/android/app/build.gradle +64 -265
- package/example/android/app/src/debug/AndroidManifest.xml +1 -5
- package/example/android/app/src/main/AndroidManifest.xml +5 -3
- package/example/android/app/src/main/java/com/freerasp/rn/example/MainActivity.kt +22 -0
- package/example/android/app/src/main/java/com/freerasp/rn/example/MainApplication.kt +44 -0
- package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +3 -2
- package/example/android/app/src/main/res/values/strings.xml +1 -1
- package/example/android/build.gradle +16 -45
- package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/example/android/gradle/wrapper/gradle-wrapper.properties +3 -1
- package/example/android/gradle.properties +5 -6
- package/example/android/gradlew +30 -13
- package/example/android/gradlew.bat +21 -16
- package/example/android/settings.gradle +5 -10
- package/example/app.json +3 -3
- package/example/index.js +4 -0
- package/example/ios/FreeraspRNExample/AppDelegate.swift +30 -0
- package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/Info.plist +8 -12
- package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/LaunchScreen.storyboard +1 -1
- package/example/ios/FreeraspRNExample/PrivacyInfo.xcprivacy +37 -0
- package/example/ios/FreeraspRNExample.xcodeproj/project.pbxproj +488 -0
- package/example/ios/{FreeraspReactNativeExample.xcodeproj/xcshareddata/xcschemes/FreeraspReactNativeExample.xcscheme → FreeraspRNExample.xcodeproj/xcshareddata/xcschemes/FreeraspRNExample.xcscheme} +12 -12
- package/example/ios/{FreeraspReactNativeExample.xcworkspace → FreeraspRNExample.xcworkspace}/contents.xcworkspacedata +1 -1
- package/example/ios/Podfile +19 -32
- package/example/metro.config.js +13 -14
- package/example/package.json +23 -12
- package/example/src/App.tsx +18 -0
- package/example/src/DemoApp.tsx +181 -79
- package/example/src/MalwareModal.tsx +2 -12
- package/example/src/checks.ts +2 -0
- package/example/yarn.lock +3825 -1613
- package/ios/FreeraspReactNative.swift +6 -2
- package/ios/TalsecRuntime.xcframework/Info.plist +5 -5
- package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeDirectory +0 -0
- package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
- package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeResources +87 -87
- package/ios/TalsecRuntime.xcframework/_CodeSignature/CodeSignature +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/curl.h +7 -7
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/multi.h +4 -4
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/options.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Headers/urlapi.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.abi.json +316 -178
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.private.swiftinterface +2 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios.swiftinterface +2 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/CurlWrapper.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/TalsecRuntime-Swift.h +2 -2
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/curl.h +7 -7
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/multi.h +4 -4
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/options.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Headers/urlapi.h +1 -1
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Info.plist +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.abi.json +316 -178
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +2 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/arm64-apple-ios-simulator.swiftinterface +2 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.abi.json +316 -178
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +2 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/Modules/TalsecRuntime.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +2 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/TalsecRuntime +0 -0
- package/ios/TalsecRuntime.xcframework/ios-arm64_x86_64-simulator/TalsecRuntime.framework/_CodeSignature/CodeResources +33 -33
- package/lib/commonjs/index.js +25 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/threat.js +3 -1
- package/lib/commonjs/threat.js.map +1 -1
- package/lib/module/index.js +19 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/threat.js +3 -1
- package/lib/module/threat.js.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/threat.d.ts +2 -0
- package/lib/typescript/src/threat.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +2 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +24 -0
- package/src/threat.ts +6 -0
- package/src/types.ts +2 -0
- package/example/android/app/_BUCK +0 -55
- package/example/android/app/build_defs.bzl +0 -19
- package/example/android/app/src/debug/java/com/freeraspreactnativeexample/ReactNativeFlipper.java +0 -73
- package/example/android/app/src/main/java/com/freeraspreactnativeexample/MainActivity.java +0 -48
- package/example/android/app/src/main/java/com/freeraspreactnativeexample/MainApplication.java +0 -91
- package/example/android/app/src/main/java/com/freeraspreactnativeexample/newarchitecture/MainApplicationReactNativeHost.java +0 -116
- package/example/android/app/src/main/java/com/freeraspreactnativeexample/newarchitecture/components/MainComponentsRegistry.java +0 -36
- package/example/android/app/src/main/java/com/freeraspreactnativeexample/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java +0 -48
- package/example/android/app/src/main/jni/CMakeLists.txt +0 -7
- package/example/android/app/src/main/jni/MainApplicationModuleProvider.cpp +0 -32
- package/example/android/app/src/main/jni/MainApplicationModuleProvider.h +0 -16
- package/example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp +0 -45
- package/example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h +0 -38
- package/example/android/app/src/main/jni/MainComponentsRegistry.cpp +0 -65
- package/example/android/app/src/main/jni/MainComponentsRegistry.h +0 -32
- package/example/android/app/src/main/jni/OnLoad.cpp +0 -11
- package/example/ios/File.swift +0 -6
- package/example/ios/FreeraspReactNativeExample/AppDelegate.h +0 -8
- package/example/ios/FreeraspReactNativeExample/AppDelegate.mm +0 -133
- package/example/ios/FreeraspReactNativeExample/main.m +0 -10
- package/example/ios/FreeraspReactNativeExample-Bridging-Header.h +0 -3
- package/example/ios/FreeraspReactNativeExample.xcodeproj/project.pbxproj +0 -729
- package/example/ios/FreeraspReactNativeExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/example/ios/FreeraspReactNativeExampleTests/FreeraspReactNativeExampleTests.m +0 -66
- package/example/ios/FreeraspReactNativeExampleTests/Info.plist +0 -24
- /package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/Images.xcassets/AppIcon.appiconset/Contents.json +0 -0
- /package/example/ios/{FreeraspReactNativeExample → FreeraspRNExample}/Images.xcassets/Contents.json +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,61 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.14.1] - 2024-03-10
|
|
9
|
+
|
|
10
|
+
- iOS SDK version: 6.8.0
|
|
11
|
+
- Android SDK version: 14.0.1
|
|
12
|
+
|
|
13
|
+
### React Native
|
|
14
|
+
|
|
15
|
+
#### Fixed
|
|
16
|
+
|
|
17
|
+
- Take Android targetSdkVersion, compileSdkVersion from plugin only
|
|
18
|
+
|
|
19
|
+
## [3.14.0] - 2024-03-05
|
|
20
|
+
|
|
21
|
+
- iOS SDK version: 6.8.0
|
|
22
|
+
- Android SDK version: 14.0.1
|
|
23
|
+
|
|
24
|
+
### React Native
|
|
25
|
+
|
|
26
|
+
#### Added
|
|
27
|
+
|
|
28
|
+
- `blockScreenCapture` method to block/unblock screen capture
|
|
29
|
+
- `isScreenCaptureBlocked` method to get the current screen capture blocking status
|
|
30
|
+
- New callbacks:
|
|
31
|
+
- `screenshot`: Detects when a screenshot is taken
|
|
32
|
+
- `screenRecording`: Detects when screen recording is active
|
|
33
|
+
|
|
34
|
+
#### Changed
|
|
35
|
+
|
|
36
|
+
- Raised Android compileSDK level to 35
|
|
37
|
+
|
|
38
|
+
#### Fixed
|
|
39
|
+
|
|
40
|
+
- Compatibility issues with RN New Architecture
|
|
41
|
+
- Added proguard rules for malware data serialization in release mode on Android
|
|
42
|
+
|
|
43
|
+
### Android
|
|
44
|
+
|
|
45
|
+
#### Added
|
|
46
|
+
|
|
47
|
+
- Passive and active screenshot/screen recording protection
|
|
48
|
+
|
|
49
|
+
#### Changed
|
|
50
|
+
|
|
51
|
+
- Improved root detection
|
|
52
|
+
|
|
53
|
+
#### Fixed
|
|
54
|
+
|
|
55
|
+
- Proguard rules to address warnings from okhttp dependency
|
|
56
|
+
|
|
57
|
+
### iOS
|
|
58
|
+
|
|
59
|
+
#### Added
|
|
60
|
+
|
|
61
|
+
- Passive Screenshot/Screen Recording detection
|
|
62
|
+
|
|
8
63
|
## [3.13.0] - 2024-12-20
|
|
9
64
|
|
|
10
65
|
- iOS SDK version: 6.6.3
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
    [](https://42matters.com/sdks/android/talsec)
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
freeRASP for React Native is a mobile in-app protection and security monitoring plugin. It aims to cover the main aspects of RASP (Runtime App Self Protection) and application shielding.
|
|
10
10
|
|
|
11
|
-
:loudspeaker: The official documentation has been moved to a new location. You can now find it
|
|
11
|
+
:loudspeaker: [The official documentation has been moved to a new location. You can now find it here](https://docs.talsec.app/docs-and-articles-portal). :loudspeaker:
|
|
12
12
|
|
|
13
13
|
# Overview
|
|
14
14
|
|
|
@@ -54,6 +54,8 @@ After the integration of freeRASP, make sure you visit the [freeMalwareDetection
|
|
|
54
54
|
|
|
55
55
|
Visit the [GitBook page](https://docs.talsec.app/freerasp) for comprehensive and up-to-date guides, tutorials, and technical documentation specifically for freeRASP. It serves as your go-to resource, offering everything from basic instructions to advanced tips and tricks to help you get the most out of the project.
|
|
56
56
|
|
|
57
|
+
:loudspeaker: [The official documentation has been moved to a new location. You can now find it here](https://docs.talsec.app/docs-and-articles-portal). :loudspeaker:
|
|
58
|
+
|
|
57
59
|
## :link: Integration Guide
|
|
58
60
|
|
|
59
61
|
For integrating freeRASP on the React Native platform, be sure to follow all the steps in the [Integration Guide](https://docs.talsec.app/freerasp/integration). This guide provides detailed instructions to help you achieve a smooth and efficient integration.
|
package/android/build.gradle
CHANGED
|
@@ -40,11 +40,11 @@ def getIntegerDefault(name) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
android {
|
|
43
|
-
compileSdkVersion
|
|
43
|
+
compileSdkVersion getIntegerDefault("compileSdkVersion")
|
|
44
44
|
|
|
45
45
|
defaultConfig {
|
|
46
46
|
minSdkVersion getIntegerDefault("minSdkVersion")
|
|
47
|
-
targetSdkVersion
|
|
47
|
+
targetSdkVersion getIntegerDefault("targetSdkVersion")
|
|
48
48
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
49
49
|
}
|
|
50
50
|
buildTypes {
|
|
@@ -90,7 +90,7 @@ dependencies {
|
|
|
90
90
|
implementation "com.facebook.react:react-native:$react_native_version"
|
|
91
91
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
92
92
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
|
|
93
|
-
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:
|
|
93
|
+
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:14.0.1"
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
if (isNewArchitectureEnabled()) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
FreeraspReactNative_kotlinVersion=1.7.0
|
|
2
2
|
FreeraspReactNative_minSdkVersion=23
|
|
3
|
-
FreeraspReactNative_targetSdkVersion=
|
|
4
|
-
FreeraspReactNative_compileSdkVersion=
|
|
3
|
+
FreeraspReactNative_targetSdkVersion=35
|
|
4
|
+
FreeraspReactNative_compileSdkVersion=35
|
|
5
5
|
FreeraspReactNative_ndkversion=21.4.7075529
|
|
6
6
|
FreeraspReactNative_reactNativeVersion=+
|
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
-dontwarn java.lang.invoke.StringConcatFactory
|
|
2
2
|
-keep class com.freeraspreactnative.FreeraspReactNativePackage { public *; }
|
|
3
|
+
|
|
4
|
+
-if @kotlinx.serialization.Serializable class **
|
|
5
|
+
-keep class <1> {
|
|
6
|
+
*;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
-keep class com.freeraspreactnative.models.RNSuspiciousAppInfo$Companion
|
|
10
|
+
-keep class com.freeraspreactnative.models.RNPackageInfo$Companion
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.freeraspreactnative
|
|
2
2
|
|
|
3
|
+
import android.os.Build
|
|
3
4
|
import android.os.Handler
|
|
4
5
|
import android.os.HandlerThread
|
|
5
6
|
import android.os.Looper
|
|
@@ -31,11 +32,15 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
|
|
|
31
32
|
private val listener = ThreatListener(FreeraspThreatHandler, FreeraspThreatHandler)
|
|
32
33
|
private val lifecycleListener = object : LifecycleEventListener {
|
|
33
34
|
override fun onHostResume() {
|
|
34
|
-
|
|
35
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
36
|
+
currentActivity?.let { ScreenProtector.register(it) }
|
|
37
|
+
}
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
override fun onHostPause() {
|
|
38
|
-
|
|
41
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
42
|
+
currentActivity?.let { ScreenProtector.unregister(it) }
|
|
43
|
+
}
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
override fun onHostDestroy() {
|
|
@@ -54,8 +59,7 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
|
|
|
54
59
|
|
|
55
60
|
@ReactMethod
|
|
56
61
|
fun talsecStart(
|
|
57
|
-
options: ReadableMap,
|
|
58
|
-
promise: Promise
|
|
62
|
+
options: ReadableMap, promise: Promise
|
|
59
63
|
) {
|
|
60
64
|
|
|
61
65
|
try {
|
|
@@ -64,10 +68,18 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
|
|
|
64
68
|
listener.registerListener(reactContext)
|
|
65
69
|
runOnUiThread {
|
|
66
70
|
Talsec.start(reactContext, config)
|
|
71
|
+
mainHandler.post {
|
|
72
|
+
talsecStarted = true
|
|
73
|
+
// This code must be called only AFTER Talsec.start
|
|
74
|
+
currentActivity?.let { activity ->
|
|
75
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
76
|
+
ScreenProtector.register(activity)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
promise.resolve("freeRASP started")
|
|
80
|
+
}
|
|
67
81
|
}
|
|
68
82
|
|
|
69
|
-
promise.resolve("freeRASP started")
|
|
70
|
-
|
|
71
83
|
} catch (e: Exception) {
|
|
72
84
|
promise.reject("TalsecInitializationError", e.message, e)
|
|
73
85
|
}
|
|
@@ -136,6 +148,43 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
|
|
|
136
148
|
}
|
|
137
149
|
}
|
|
138
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Method Block/Unblock screen capture
|
|
153
|
+
* @param enable boolean for whether want to block or unblock the screen capture
|
|
154
|
+
*/
|
|
155
|
+
@ReactMethod
|
|
156
|
+
fun blockScreenCapture(enable: Boolean, promise: Promise) {
|
|
157
|
+
val activity = currentActivity ?: run {
|
|
158
|
+
promise.reject(
|
|
159
|
+
"NativePluginError", "Cannot block screen capture, activity is null."
|
|
160
|
+
)
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
runOnUiThread {
|
|
165
|
+
try {
|
|
166
|
+
Talsec.blockScreenCapture(activity, enable)
|
|
167
|
+
promise.resolve("Screen capture is now ${if (enable) "Blocked" else "Enabled"}.")
|
|
168
|
+
} catch (e: Exception) {
|
|
169
|
+
promise.reject("NativePluginError", "Error in blockScreenCapture: ${e.message}")
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Method Returns whether screen capture is blocked or not
|
|
176
|
+
* @return boolean for is screem capture blocked or not
|
|
177
|
+
*/
|
|
178
|
+
@ReactMethod
|
|
179
|
+
fun isScreenCaptureBlocked(promise: Promise) {
|
|
180
|
+
try {
|
|
181
|
+
val isBlocked = Talsec.isScreenCaptureBlocked()
|
|
182
|
+
promise.resolve(isBlocked)
|
|
183
|
+
} catch (e: Exception) {
|
|
184
|
+
promise.reject("NativePluginError", "Error in isScreenCaptureBlocked: ${e.message}")
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
139
188
|
private fun buildTalsecConfig(config: ReadableMap): TalsecConfig {
|
|
140
189
|
val androidConfig = config.getMapThrowing("androidConfig")
|
|
141
190
|
val packageName = androidConfig.getStringThrowing("packageName")
|
|
@@ -172,11 +221,12 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
|
|
|
172
221
|
|
|
173
222
|
private lateinit var appReactContext: ReactApplicationContext
|
|
174
223
|
|
|
224
|
+
internal var talsecStarted = false
|
|
225
|
+
|
|
175
226
|
private fun notifyListeners(threat: Threat) {
|
|
176
227
|
val params = Arguments.createMap()
|
|
177
228
|
params.putInt(THREAT_CHANNEL_KEY, threat.value)
|
|
178
|
-
appReactContext
|
|
179
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
229
|
+
appReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
180
230
|
.emit(THREAT_CHANNEL_NAME, params)
|
|
181
231
|
}
|
|
182
232
|
|
|
@@ -196,8 +246,7 @@ class FreeraspReactNativeModule(private val reactContext: ReactApplicationContex
|
|
|
196
246
|
MALWARE_CHANNEL_KEY, encodedSuspiciousApps
|
|
197
247
|
)
|
|
198
248
|
|
|
199
|
-
appReactContext
|
|
200
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
249
|
+
appReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
201
250
|
.emit(THREAT_CHANNEL_NAME, params)
|
|
202
251
|
}
|
|
203
252
|
}
|
|
@@ -63,6 +63,14 @@ internal object FreeraspThreatHandler : ThreatListener.ThreatDetected, ThreatLis
|
|
|
63
63
|
listener?.threatDetected(Threat.SystemVPN)
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
override fun onScreenshotDetected() {
|
|
67
|
+
listener?.threatDetected(Threat.Screenshot)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
override fun onScreenRecordingDetected() {
|
|
71
|
+
listener?.threatDetected(Threat.ScreenRecording)
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
internal interface TalsecReactNative {
|
|
67
75
|
fun threatDetected(threatType: Threat)
|
|
68
76
|
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
package com.freeraspreactnative
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.annotation.TargetApi
|
|
5
|
+
import android.app.Activity
|
|
6
|
+
import android.app.Activity.ScreenCaptureCallback
|
|
7
|
+
import android.content.Context
|
|
8
|
+
import android.content.pm.PackageManager
|
|
9
|
+
import android.os.Build
|
|
10
|
+
import android.util.Log
|
|
11
|
+
import android.view.WindowManager.SCREEN_RECORDING_STATE_VISIBLE
|
|
12
|
+
import androidx.annotation.RequiresApi
|
|
13
|
+
import androidx.core.content.ContextCompat
|
|
14
|
+
|
|
15
|
+
import com.aheaditec.talsec_security.security.api.Talsec
|
|
16
|
+
import java.util.function.Consumer
|
|
17
|
+
|
|
18
|
+
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
|
19
|
+
internal object ScreenProtector {
|
|
20
|
+
private const val TAG = "TalsecScreenProtector"
|
|
21
|
+
private const val SCREEN_CAPTURE_PERMISSION = "android.permission.DETECT_SCREEN_CAPTURE"
|
|
22
|
+
private const val SCREEN_RECORDING_PERMISSION = "android.permission.DETECT_SCREEN_RECORDING"
|
|
23
|
+
private var registered = false
|
|
24
|
+
private val screenCaptureCallback = ScreenCaptureCallback { Talsec.onScreenshotDetected() }
|
|
25
|
+
private val screenRecordCallback: Consumer<Int> = Consumer<Int> { state ->
|
|
26
|
+
if (state == SCREEN_RECORDING_STATE_VISIBLE) {
|
|
27
|
+
Talsec.onScreenRecordingDetected()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Registers screenshot and screen recording detector with the given activity
|
|
33
|
+
*
|
|
34
|
+
* **IMPORTANT**: android.permission.DETECT_SCREEN_CAPTURE and
|
|
35
|
+
* android.permission.DETECT_SCREEN_RECORDING must be
|
|
36
|
+
* granted for the app in the AndroidManifest.xml
|
|
37
|
+
*/
|
|
38
|
+
internal fun register(activity: Activity) {
|
|
39
|
+
if (!FreeraspReactNativeModule.talsecStarted || registered) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
44
|
+
registerScreenCapture(activity)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
48
|
+
registerScreenRecording(activity)
|
|
49
|
+
}
|
|
50
|
+
registered = true
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Register Talsec Screen Capture (screenshot) Detector for given activity instance.
|
|
55
|
+
* The MainActivity of the app is registered by the plugin itself, other
|
|
56
|
+
* activities bust be registered manually as described in the integration guide.
|
|
57
|
+
*
|
|
58
|
+
* Missing permission is suppressed because the decision to use the screen
|
|
59
|
+
* capture API is made by developer, and not enforced by the library.
|
|
60
|
+
*
|
|
61
|
+
* **IMPORTANT**: android.permission.DETECT_SCREEN_CAPTURE (API 34+) must be
|
|
62
|
+
* granted for the app in the AndroidManifest.xml
|
|
63
|
+
*/
|
|
64
|
+
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
|
65
|
+
@SuppressLint("MissingPermission")
|
|
66
|
+
private fun registerScreenCapture(activity: Activity) {
|
|
67
|
+
val context = activity.applicationContext
|
|
68
|
+
if (!hasPermission(context, SCREEN_CAPTURE_PERMISSION)) {
|
|
69
|
+
reportMissingPermission("screenshot", SCREEN_CAPTURE_PERMISSION)
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
activity.registerScreenCaptureCallback(context.mainExecutor, screenCaptureCallback)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Register Talsec Screen Recording Detector for given activity instance.
|
|
78
|
+
* The MainActivity of the app is registered by the plugin itself, other
|
|
79
|
+
* activities bust be registered manually as described in the integration guide.
|
|
80
|
+
*
|
|
81
|
+
* Missing permission is suppressed because the decision to use the screen
|
|
82
|
+
* capture API is made by developer, and not enforced by the library.
|
|
83
|
+
*
|
|
84
|
+
* **IMPORTANT**: android.permission.DETECT_SCREEN_RECORDING (API 35+) must be
|
|
85
|
+
* granted for the app in the AndroidManifest.xml
|
|
86
|
+
*/
|
|
87
|
+
@SuppressLint("MissingPermission")
|
|
88
|
+
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
|
89
|
+
private fun registerScreenRecording(activity: Activity) {
|
|
90
|
+
val context = activity.applicationContext
|
|
91
|
+
if (!hasPermission(context, SCREEN_RECORDING_PERMISSION)) {
|
|
92
|
+
reportMissingPermission("screen record", SCREEN_RECORDING_PERMISSION)
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
val initialState = activity.windowManager.addScreenRecordingCallback(
|
|
97
|
+
context.mainExecutor, screenRecordCallback
|
|
98
|
+
)
|
|
99
|
+
screenRecordCallback.accept(initialState)
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Unregisters screenshot and screen recording detector with the given activity
|
|
105
|
+
*
|
|
106
|
+
* **IMPORTANT**: android.permission.DETECT_SCREEN_CAPTURE and
|
|
107
|
+
* android.permission.DETECT_SCREEN_RECORDING must be
|
|
108
|
+
* granted for the app in the AndroidManifest.xml
|
|
109
|
+
*/
|
|
110
|
+
@SuppressLint("MissingPermission")
|
|
111
|
+
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
|
112
|
+
internal fun unregister(activity: Activity) {
|
|
113
|
+
if (!FreeraspReactNativeModule.talsecStarted || !registered) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
118
|
+
unregisterScreenCapture(activity)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
122
|
+
unregisterScreenRecording(activity)
|
|
123
|
+
}
|
|
124
|
+
registered = false
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Missing permission is suppressed because the decision to use the screen capture API is made
|
|
128
|
+
// by developer, and not enforced by the library.
|
|
129
|
+
@SuppressLint("MissingPermission")
|
|
130
|
+
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
|
131
|
+
private fun unregisterScreenCapture(activity: Activity) {
|
|
132
|
+
val context = activity.applicationContext
|
|
133
|
+
if (!hasPermission(context, SCREEN_CAPTURE_PERMISSION)) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
activity.unregisterScreenCaptureCallback(screenCaptureCallback)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Missing permission is suppressed because the decision to use the screen capture API is made
|
|
140
|
+
// by developer, and not enforced by the library.
|
|
141
|
+
@SuppressLint("MissingPermission")
|
|
142
|
+
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
|
143
|
+
private fun unregisterScreenRecording(activity: Activity) {
|
|
144
|
+
val context = activity.applicationContext
|
|
145
|
+
if (!hasPermission(context, SCREEN_RECORDING_PERMISSION)) {
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
activity.windowManager?.removeScreenRecordingCallback(screenRecordCallback)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private fun hasPermission(context: Context, permission: String): Boolean {
|
|
153
|
+
return ContextCompat.checkSelfPermission(
|
|
154
|
+
context, permission
|
|
155
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private fun reportMissingPermission(protectionType: String, permission: String) {
|
|
159
|
+
Log.e(
|
|
160
|
+
TAG,
|
|
161
|
+
"Failed to register $protectionType callback. Check if $permission permission is granted in AndroidManifest.xml"
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -25,6 +25,8 @@ internal sealed class Threat(val value: Int) {
|
|
|
25
25
|
object DevMode : Threat((10000..999999999).random())
|
|
26
26
|
object Malware : Threat((10000..999999999).random())
|
|
27
27
|
object ADBEnabled : Threat((10000..999999999).random())
|
|
28
|
+
object Screenshot : Threat((10000..999999999).random())
|
|
29
|
+
object ScreenRecording : Threat((10000..999999999).random())
|
|
28
30
|
|
|
29
31
|
companion object {
|
|
30
32
|
internal fun getThreatValues(): WritableArray {
|
|
@@ -43,7 +45,9 @@ internal sealed class Threat(val value: Int) {
|
|
|
43
45
|
ObfuscationIssues.value,
|
|
44
46
|
DevMode.value,
|
|
45
47
|
Malware.value,
|
|
46
|
-
ADBEnabled.value
|
|
48
|
+
ADBEnabled.value,
|
|
49
|
+
Screenshot.value,
|
|
50
|
+
ScreenRecording.value
|
|
47
51
|
)
|
|
48
52
|
)
|
|
49
53
|
}
|
|
@@ -61,7 +61,7 @@ internal fun ReadableMap.getNestedArraySafe(key: String): Array<Array<String>> {
|
|
|
61
61
|
if (this.hasKey(key)) {
|
|
62
62
|
val inputArray = this.getArray(key)!!
|
|
63
63
|
for (i in 0 until inputArray.size()) {
|
|
64
|
-
|
|
64
|
+
inputArray.getArray(i)?.let { outArray.add(it.toPrimitiveArray()) }
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
return outArray.toTypedArray()
|
package/example/Gemfile
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
3
|
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
|
4
|
-
ruby
|
|
4
|
+
ruby ">= 2.6.10"
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
|
|
7
|
+
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
|
|
8
|
+
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
|
|
9
|
+
gem 'xcodeproj', '< 1.26.0'
|
|
10
|
+
gem 'concurrent-ruby', '< 1.3.4'
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: https://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
CFPropertyList (3.0.7)
|
|
5
|
+
base64
|
|
6
|
+
nkf
|
|
7
|
+
rexml
|
|
8
|
+
activesupport (7.1.5.1)
|
|
9
|
+
base64
|
|
10
|
+
benchmark (>= 0.3)
|
|
11
|
+
bigdecimal
|
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
13
|
+
connection_pool (>= 2.2.5)
|
|
14
|
+
drb
|
|
15
|
+
i18n (>= 1.6, < 2)
|
|
16
|
+
logger (>= 1.4.2)
|
|
17
|
+
minitest (>= 5.1)
|
|
18
|
+
mutex_m
|
|
19
|
+
securerandom (>= 0.3)
|
|
20
|
+
tzinfo (~> 2.0)
|
|
21
|
+
addressable (2.8.7)
|
|
22
|
+
public_suffix (>= 2.0.2, < 7.0)
|
|
23
|
+
algoliasearch (1.27.5)
|
|
24
|
+
httpclient (~> 2.8, >= 2.8.3)
|
|
25
|
+
json (>= 1.5.1)
|
|
26
|
+
atomos (0.1.3)
|
|
27
|
+
base64 (0.2.0)
|
|
28
|
+
benchmark (0.4.0)
|
|
29
|
+
bigdecimal (3.1.9)
|
|
30
|
+
claide (1.1.0)
|
|
31
|
+
cocoapods (1.15.2)
|
|
32
|
+
addressable (~> 2.8)
|
|
33
|
+
claide (>= 1.0.2, < 2.0)
|
|
34
|
+
cocoapods-core (= 1.15.2)
|
|
35
|
+
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
|
36
|
+
cocoapods-downloader (>= 2.1, < 3.0)
|
|
37
|
+
cocoapods-plugins (>= 1.0.0, < 2.0)
|
|
38
|
+
cocoapods-search (>= 1.0.0, < 2.0)
|
|
39
|
+
cocoapods-trunk (>= 1.6.0, < 2.0)
|
|
40
|
+
cocoapods-try (>= 1.1.0, < 2.0)
|
|
41
|
+
colored2 (~> 3.1)
|
|
42
|
+
escape (~> 0.0.4)
|
|
43
|
+
fourflusher (>= 2.3.0, < 3.0)
|
|
44
|
+
gh_inspector (~> 1.0)
|
|
45
|
+
molinillo (~> 0.8.0)
|
|
46
|
+
nap (~> 1.0)
|
|
47
|
+
ruby-macho (>= 2.3.0, < 3.0)
|
|
48
|
+
xcodeproj (>= 1.23.0, < 2.0)
|
|
49
|
+
cocoapods-core (1.15.2)
|
|
50
|
+
activesupport (>= 5.0, < 8)
|
|
51
|
+
addressable (~> 2.8)
|
|
52
|
+
algoliasearch (~> 1.0)
|
|
53
|
+
concurrent-ruby (~> 1.1)
|
|
54
|
+
fuzzy_match (~> 2.0.4)
|
|
55
|
+
nap (~> 1.0)
|
|
56
|
+
netrc (~> 0.11)
|
|
57
|
+
public_suffix (~> 4.0)
|
|
58
|
+
typhoeus (~> 1.0)
|
|
59
|
+
cocoapods-deintegrate (1.0.5)
|
|
60
|
+
cocoapods-downloader (2.1)
|
|
61
|
+
cocoapods-plugins (1.0.0)
|
|
62
|
+
nap
|
|
63
|
+
cocoapods-search (1.0.1)
|
|
64
|
+
cocoapods-trunk (1.6.0)
|
|
65
|
+
nap (>= 0.8, < 2.0)
|
|
66
|
+
netrc (~> 0.11)
|
|
67
|
+
cocoapods-try (1.2.0)
|
|
68
|
+
colored2 (3.1.2)
|
|
69
|
+
concurrent-ruby (1.3.3)
|
|
70
|
+
connection_pool (2.5.0)
|
|
71
|
+
drb (2.2.1)
|
|
72
|
+
escape (0.0.4)
|
|
73
|
+
ethon (0.16.0)
|
|
74
|
+
ffi (>= 1.15.0)
|
|
75
|
+
ffi (1.17.1)
|
|
76
|
+
fourflusher (2.3.1)
|
|
77
|
+
fuzzy_match (2.0.4)
|
|
78
|
+
gh_inspector (1.1.3)
|
|
79
|
+
httpclient (2.9.0)
|
|
80
|
+
mutex_m
|
|
81
|
+
i18n (1.14.7)
|
|
82
|
+
concurrent-ruby (~> 1.0)
|
|
83
|
+
json (2.10.1)
|
|
84
|
+
logger (1.6.6)
|
|
85
|
+
minitest (5.25.4)
|
|
86
|
+
molinillo (0.8.0)
|
|
87
|
+
mutex_m (0.3.0)
|
|
88
|
+
nanaimo (0.3.0)
|
|
89
|
+
nap (1.1.0)
|
|
90
|
+
netrc (0.11.0)
|
|
91
|
+
nkf (0.2.0)
|
|
92
|
+
public_suffix (4.0.7)
|
|
93
|
+
rexml (3.4.1)
|
|
94
|
+
ruby-macho (2.5.1)
|
|
95
|
+
securerandom (0.3.2)
|
|
96
|
+
typhoeus (1.4.1)
|
|
97
|
+
ethon (>= 0.9.0)
|
|
98
|
+
tzinfo (2.0.6)
|
|
99
|
+
concurrent-ruby (~> 1.0)
|
|
100
|
+
xcodeproj (1.25.1)
|
|
101
|
+
CFPropertyList (>= 2.3.3, < 4.0)
|
|
102
|
+
atomos (~> 0.1.3)
|
|
103
|
+
claide (>= 1.0.2, < 2.0)
|
|
104
|
+
colored2 (~> 3.1)
|
|
105
|
+
nanaimo (~> 0.3.0)
|
|
106
|
+
rexml (>= 3.3.6, < 4.0)
|
|
107
|
+
|
|
108
|
+
PLATFORMS
|
|
109
|
+
ruby
|
|
110
|
+
|
|
111
|
+
DEPENDENCIES
|
|
112
|
+
activesupport (>= 6.1.7.5, != 7.1.0)
|
|
113
|
+
cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
|
|
114
|
+
concurrent-ruby (< 1.3.4)
|
|
115
|
+
xcodeproj (< 1.26.0)
|
|
116
|
+
|
|
117
|
+
RUBY VERSION
|
|
118
|
+
ruby 2.7.6p219
|
|
119
|
+
|
|
120
|
+
BUNDLED WITH
|
|
121
|
+
2.1.4
|