react-native-dev-guard 0.0.1 → 1.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/LICENSE +1 -1
- package/README.md +190 -44
- package/lib/index.js +17 -8
- package/lib/services/CacheService.d.ts +5 -1
- package/lib/services/CacheService.js +5 -1
- package/lib/services/DevGuardLogger.d.ts +1 -1
- package/lib/services/DevGuardLogger.js +13 -3
- package/lib/services/DeviceTokenService.d.ts +4 -1
- package/lib/services/DeviceTokenService.js +5 -2
- package/lib/services/HardwareService.d.ts +14 -1
- package/lib/services/HardwareService.js +63 -1
- package/package.json +20 -6
- package/react-native-dev-guard.podspec +19 -0
- package/screenshots/access-suspended.png +0 -0
- package/screenshots/payment-reminder.png +0 -0
- package/screenshots/welcome-screen.png +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/query/client-agp/cache-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/query/client-agp/cmakeFiles-v1 +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/query/client-agp/codemodel-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/reply/cache-v2-ca87e29d866016c47643.json +0 -1287
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/reply/cmakeFiles-v1-afc39e04c88d618b9499.json +0 -182
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/reply/codemodel-v2-004ad46f03b4d6b2acd6.json +0 -59
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/reply/index-2026-05-15T08-21-19-0083.json +0 -92
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.cmake/api/v1/reply/target-devguard-Debug-8c0ebbb0cdb88d164b64.json +0 -160
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.ninja_deps +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/.ninja_log +0 -15
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeCache.txt +0 -391
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/3.18.1-g262b901/CMakeCCompiler.cmake +0 -77
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/3.18.1-g262b901/CMakeCXXCompiler.cmake +0 -89
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_C.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_CXX.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/3.18.1-g262b901/CMakeSystem.cmake +0 -15
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/CMakeOutput.log +0 -236
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/TargetDirectories.txt +0 -3
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/cmake.check_cache +0 -1
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/devguard.dir/devguard-lib.cpp.o +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/CMakeFiles/rules.ninja +0 -74
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/additional_project_files.txt +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/android_gradle_build.json +0 -40
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/android_gradle_build_mini.json +0 -27
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/build.ninja +0 -154
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/build_file_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/cmake_install.cmake +0 -54
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/compile_commands.json +0 -12
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/compile_commands.json.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/configure_fingerprint.bin +0 -29
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/metadata_generation_command.txt +0 -19
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/prefab_config.json +0 -4
- package/android/.cxx/Debug/4s4f1av3/arm64-v8a/symbol_folder_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/query/client-agp/cache-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/query/client-agp/cmakeFiles-v1 +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/query/client-agp/codemodel-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/reply/cache-v2-02400eb6fc4793fa6bf2.json +0 -1287
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/reply/cmakeFiles-v1-d0fc95efa84cbe47849a.json +0 -379
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/reply/codemodel-v2-a7a363de64e45a261589.json +0 -59
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/reply/index-2026-05-15T08-21-21-0243.json +0 -92
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.cmake/api/v1/reply/target-devguard-Debug-53eeaa7145cf9770f3d7.json +0 -160
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.ninja_deps +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/.ninja_log +0 -10
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeCache.txt +0 -391
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/3.18.1-g262b901/CMakeCCompiler.cmake +0 -77
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/3.18.1-g262b901/CMakeCXXCompiler.cmake +0 -89
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_C.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_CXX.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/3.18.1-g262b901/CMakeSystem.cmake +0 -15
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/CMakeOutput.log +0 -240
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/TargetDirectories.txt +0 -3
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/cmake.check_cache +0 -1
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/devguard.dir/devguard-lib.cpp.o +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/CMakeFiles/rules.ninja +0 -74
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/additional_project_files.txt +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/android_gradle_build.json +0 -40
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/android_gradle_build_mini.json +0 -27
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/build.ninja +0 -154
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/build_file_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/cmake_install.cmake +0 -54
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/compile_commands.json +0 -12
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/compile_commands.json.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/configure_fingerprint.bin +0 -29
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/metadata_generation_command.txt +0 -19
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/prefab_config.json +0 -4
- package/android/.cxx/Debug/4s4f1av3/armeabi-v7a/symbol_folder_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/hash_key.txt +0 -26
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/query/client-agp/cache-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/query/client-agp/cmakeFiles-v1 +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/query/client-agp/codemodel-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/reply/cache-v2-ec883f5c922c646acf2d.json +0 -1287
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/reply/cmakeFiles-v1-028bf03c3b9bd0e609c0.json +0 -379
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/reply/codemodel-v2-6c0215a4bb6e3b0b5223.json +0 -59
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/reply/index-2026-05-15T08-21-22-0722.json +0 -92
- package/android/.cxx/Debug/4s4f1av3/x86/.cmake/api/v1/reply/target-devguard-Debug-2139b18dc63b630666db.json +0 -160
- package/android/.cxx/Debug/4s4f1av3/x86/.ninja_deps +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/.ninja_log +0 -10
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeCache.txt +0 -391
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/3.18.1-g262b901/CMakeCCompiler.cmake +0 -77
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/3.18.1-g262b901/CMakeCXXCompiler.cmake +0 -89
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_C.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_CXX.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/3.18.1-g262b901/CMakeSystem.cmake +0 -15
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/CMakeOutput.log +0 -230
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/TargetDirectories.txt +0 -3
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/cmake.check_cache +0 -1
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/devguard.dir/devguard-lib.cpp.o +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/CMakeFiles/rules.ninja +0 -74
- package/android/.cxx/Debug/4s4f1av3/x86/additional_project_files.txt +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/android_gradle_build.json +0 -40
- package/android/.cxx/Debug/4s4f1av3/x86/android_gradle_build_mini.json +0 -27
- package/android/.cxx/Debug/4s4f1av3/x86/build.ninja +0 -154
- package/android/.cxx/Debug/4s4f1av3/x86/build_file_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/x86/cmake_install.cmake +0 -54
- package/android/.cxx/Debug/4s4f1av3/x86/compile_commands.json +0 -12
- package/android/.cxx/Debug/4s4f1av3/x86/compile_commands.json.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86/configure_fingerprint.bin +0 -29
- package/android/.cxx/Debug/4s4f1av3/x86/metadata_generation_command.txt +0 -19
- package/android/.cxx/Debug/4s4f1av3/x86/prefab_config.json +0 -4
- package/android/.cxx/Debug/4s4f1av3/x86/symbol_folder_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/query/client-agp/cache-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/query/client-agp/cmakeFiles-v1 +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/query/client-agp/codemodel-v2 +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/reply/cache-v2-7ec870c116aeb770686e.json +0 -1287
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/reply/cmakeFiles-v1-f2e6a276d8adf420c6b9.json +0 -379
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/reply/codemodel-v2-a4f2c2fefb1e4261b2d6.json +0 -59
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/reply/index-2026-05-15T08-21-24-0187.json +0 -92
- package/android/.cxx/Debug/4s4f1av3/x86_64/.cmake/api/v1/reply/target-devguard-Debug-077cad881ac8d6864f8f.json +0 -160
- package/android/.cxx/Debug/4s4f1av3/x86_64/.ninja_deps +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/.ninja_log +0 -10
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeCache.txt +0 -391
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/3.18.1-g262b901/CMakeCCompiler.cmake +0 -77
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/3.18.1-g262b901/CMakeCXXCompiler.cmake +0 -89
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_C.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/3.18.1-g262b901/CMakeDetermineCompilerABI_CXX.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/3.18.1-g262b901/CMakeSystem.cmake +0 -15
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/CMakeOutput.log +0 -230
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/TargetDirectories.txt +0 -3
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/cmake.check_cache +0 -1
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/devguard.dir/devguard-lib.cpp.o +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/CMakeFiles/rules.ninja +0 -74
- package/android/.cxx/Debug/4s4f1av3/x86_64/additional_project_files.txt +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/android_gradle_build.json +0 -40
- package/android/.cxx/Debug/4s4f1av3/x86_64/android_gradle_build_mini.json +0 -27
- package/android/.cxx/Debug/4s4f1av3/x86_64/build.ninja +0 -154
- package/android/.cxx/Debug/4s4f1av3/x86_64/build_file_index.txt +0 -1
- package/android/.cxx/Debug/4s4f1av3/x86_64/cmake_install.cmake +0 -54
- package/android/.cxx/Debug/4s4f1av3/x86_64/compile_commands.json +0 -12
- package/android/.cxx/Debug/4s4f1av3/x86_64/compile_commands.json.bin +0 -0
- package/android/.cxx/Debug/4s4f1av3/x86_64/configure_fingerprint.bin +0 -29
- package/android/.cxx/Debug/4s4f1av3/x86_64/metadata_generation_command.txt +0 -19
- package/android/.cxx/Debug/4s4f1av3/x86_64/prefab_config.json +0 -4
- package/android/.cxx/Debug/4s4f1av3/x86_64/symbol_folder_index.txt +0 -1
- package/android/.cxx/tools/debug/arm64-v8a/compile_commands.json +0 -12
- package/android/.cxx/tools/debug/armeabi-v7a/compile_commands.json +0 -12
- package/android/.cxx/tools/debug/x86/compile_commands.json +0 -12
- package/android/.cxx/tools/debug/x86_64/compile_commands.json +0 -12
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build/.transforms/07ab8b2284230b9b98454cb3baa5db54/results.bin +0 -1
- package/android/build/.transforms/07ab8b2284230b9b98454cb3baa5db54/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/devguard/BuildConfig.dex +0 -0
- package/android/build/.transforms/07ab8b2284230b9b98454cb3baa5db54/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/devguard/DevGuardModule.dex +0 -0
- package/android/build/.transforms/07ab8b2284230b9b98454cb3baa5db54/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/devguard/DevGuardPackage.dex +0 -0
- package/android/build/.transforms/07ab8b2284230b9b98454cb3baa5db54/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
- package/android/build/.transforms/ae351402e6cba75b162136aa850e1ba2/results.bin +0 -1
- package/android/build/.transforms/ae351402e6cba75b162136aa850e1ba2/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/com/devguard/BuildConfig.java +0 -10
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -9
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/build_command_devguard +0 -4
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/build_model.json +0 -187
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/build_stderr_devguard.txt +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/build_stdout_devguard.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/generate_cxx_metadata_111_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/generate_cxx_metadata_1463_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/generate_cxx_metadata_324_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/generate_cxx_metadata_475_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/generate_cxx_metadata_622_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/arm64-v8a/metadata_generation_record.json +0 -41
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/build_command_devguard +0 -4
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/build_model.json +0 -187
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/build_stderr_devguard.txt +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/build_stdout_devguard.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/generate_cxx_metadata_111_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/generate_cxx_metadata_1459_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/generate_cxx_metadata_324_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/generate_cxx_metadata_475_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/generate_cxx_metadata_622_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/armeabi-v7a/metadata_generation_record.json +0 -41
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/build_command_devguard +0 -4
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/build_model.json +0 -187
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/build_stderr_devguard.txt +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/build_stdout_devguard.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/generate_cxx_metadata_111_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/generate_cxx_metadata_1459_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/generate_cxx_metadata_324_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/generate_cxx_metadata_475_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/generate_cxx_metadata_622_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86/metadata_generation_record.json +0 -41
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/build_command_devguard +0 -4
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/build_model.json +0 -187
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/build_stderr_devguard.txt +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/build_stdout_devguard.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/generate_cxx_metadata_111_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/generate_cxx_metadata_1459_timing.txt +0 -3
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/generate_cxx_metadata_324_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/generate_cxx_metadata_475_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/generate_cxx_metadata_622_timing.txt +0 -2
- package/android/build/intermediates/cxx/Debug/4s4f1av3/logs/x86_64/metadata_generation_record.json +0 -41
- package/android/build/intermediates/cxx/Debug/4s4f1av3/obj/arm64-v8a/libdevguard.so +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/obj/armeabi-v7a/libdevguard.so +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/obj/x86/libdevguard.so +0 -0
- package/android/build/intermediates/cxx/Debug/4s4f1av3/obj/x86_64/libdevguard.so +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +0 -2
- package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-dev-guard_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/devguard/BuildConfig.class +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/arm64-v8a/libdevguard.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/armeabi-v7a/libdevguard.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/x86/libdevguard.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/x86_64/libdevguard.so +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -11
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -9
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/arm64-v8a/libdevguard.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/armeabi-v7a/libdevguard.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/x86/libdevguard.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/x86_64/libdevguard.so +0 -0
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/react-native-dev-guard_debug.kotlin_module +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/devguard/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/devguard/DevGuardModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/devguard/DevGuardPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +0 -2
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -21
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-dev-guard_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/devguard/DevGuardModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/devguard/DevGuardPackage.class +0 -0
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,85 +1,231 @@
|
|
|
1
1
|
# React Native DevGuard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://devguard.uk"><img src="https://img.shields.io/badge/website-devguard.uk-6C47FF?style=flat-square" alt="Website" /></a>
|
|
5
|
+
<img src="https://img.shields.io/badge/platforms-iOS%20%7C%20Android-2D7DD2?style=flat-square" alt="Platforms" />
|
|
6
|
+
<img src="https://img.shields.io/badge/license-MIT-3CB371?style=flat-square" alt="License" />
|
|
7
|
+
</p>
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
**Protect your apps. Get paid.** DevGuard is a remote licensing and application-protection layer for React Native. Remotely **lock, warn, wipe, and monitor** your published apps from the DevGuard dashboard — ideal for agencies and developers who need to enforce payment terms or revoke access to client deliverables. Security-critical operations (HMAC signing, the shared secret, GZip telemetry) run inside a compiled **Native C++ module** so your keys never sit in plain JavaScript.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- GZip tunnel (`v1-gzip`) for compact telemetry
|
|
10
|
-
- Heartbeat and lifecycle sync policies
|
|
11
|
-
- Hardware fingerprinting and emulator blocking
|
|
12
|
-
- Nonce-based remote wipe
|
|
13
|
-
- Privacy-gated advanced telemetry (RAM, storage, battery)
|
|
11
|
+
> 👉 **Create your free account and grab your keys at [devguard.uk](https://devguard.uk).**
|
|
12
|
+
> You'll need a **Project ID** and a **Master Secret** to initialize the SDK.
|
|
14
13
|
|
|
15
|
-
##
|
|
14
|
+
## 📱 How it looks
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
- React 19.2.x
|
|
19
|
-
- iOS 15.1+ · Android minSdk 24
|
|
16
|
+
The Lock Screen, warning toast, and diagnostics overlay are all **built in** — you don't build any UI. DevGuard renders the right screen automatically based on the status returned by your dashboard.
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
<table>
|
|
19
|
+
<tr>
|
|
20
|
+
<td align="center" width="33%"><img src="screenshots/welcome-screen.png" width="240" alt="Active and protected app" /></td>
|
|
21
|
+
<td align="center" width="33%"><img src="screenshots/payment-reminder.png" width="240" alt="In-app warning toast" /></td>
|
|
22
|
+
<td align="center" width="33%"><img src="screenshots/access-suspended.png" width="240" alt="Access suspended lock screen" /></td>
|
|
23
|
+
</tr>
|
|
24
|
+
<tr>
|
|
25
|
+
<td align="center"><b>Active & Protected</b><br/>Your app runs normally · <code>ACTIVE</code></td>
|
|
26
|
+
<td align="center"><b>In-App Warning</b><br/>Non-blocking toast (e.g. payment reminder) · <code>WARNING</code></td>
|
|
27
|
+
<td align="center"><b>Access Suspended</b><br/>Automatic Lock Screen with your support contacts · <code>LOCKED</code></td>
|
|
28
|
+
</tr>
|
|
29
|
+
</table>
|
|
30
|
+
|
|
31
|
+
## ✨ Features
|
|
32
|
+
|
|
33
|
+
- **Glassmorphic Lock Screen**: Premium, built-in UI that blocks access instantly — with your WhatsApp / Email / Call support buttons and an optional unlock-key entry.
|
|
34
|
+
- **Native Security**: HMAC signing and the shared secret are handled in compiled C++ to prevent secret extraction.
|
|
35
|
+
- **GZip Tunneling**: Compact telemetry payloads for minimum data usage.
|
|
36
|
+
- **Remote Config**: Access server-defined JSON settings via the `response` object.
|
|
37
|
+
- **Heartbeat & Sync**: Automated background pings (with `lifecycleSync` / `syncPolicy` support) to keep license status fresh.
|
|
38
|
+
- **Hardware Fingerprinting**: Robust device identity that survives app re-installs.
|
|
39
|
+
- **Emulator Blocking**: When the project enables `blockEmulators`, the SDK locks on emulators/simulators automatically.
|
|
40
|
+
- **Hardened Remote Wipe**: Nonce-based remote wipe clears the response cache, usage logs, encrypted vault diagnostics, and stored device-user identity.
|
|
41
|
+
- **Privacy-Gated Telemetry**: Advanced metrics (RAM, storage, battery, network) are only collected after the server enables `advancedTelemetry`.
|
|
42
|
+
|
|
43
|
+
## 🚀 Getting Started
|
|
44
|
+
|
|
45
|
+
### 1. Create your DevGuard account
|
|
46
|
+
|
|
47
|
+
1. Sign up at **[devguard.uk](https://devguard.uk)**.
|
|
48
|
+
2. Create a **Project** in the dashboard.
|
|
49
|
+
3. Copy your **Project ID** and **Master Secret** (Settings → Master Secret). You'll pass both to the SDK below.
|
|
50
|
+
|
|
51
|
+
### 2. Install
|
|
22
52
|
|
|
23
53
|
```bash
|
|
24
54
|
npm install react-native-dev-guard react-native-device-info react-native-keychain @react-native-async-storage/async-storage
|
|
25
|
-
|
|
55
|
+
# or
|
|
56
|
+
yarn add react-native-dev-guard react-native-device-info react-native-keychain @react-native-async-storage/async-storage
|
|
26
57
|
```
|
|
27
58
|
|
|
28
|
-
|
|
59
|
+
`@react-native-async-storage/async-storage` is required by the bundled Vault Logger (encrypted local diagnostics). Use **v3.x** with React Native 0.85+; run `npx pod-install` after adding it on iOS.
|
|
60
|
+
|
|
61
|
+
### 3. Native setup
|
|
62
|
+
|
|
63
|
+
#### Requirements
|
|
64
|
+
- **React Native** `0.85.x` (tested on `0.85.3`)
|
|
65
|
+
- **React** `19.2.x`
|
|
66
|
+
- **iOS** 15.1+ · **Android** minSdk 24
|
|
67
|
+
|
|
68
|
+
#### iOS
|
|
69
|
+
1. Open `ios/Podfile` and ensure your target meets React Native's minimum iOS version (`min_ios_version_supported`, currently 15.1).
|
|
70
|
+
2. Run `npx pod-install`.
|
|
71
|
+
|
|
72
|
+
#### Android
|
|
73
|
+
Ensure your app `minSdkVersion` is at least **24** (matches the RN 0.85 template).
|
|
74
|
+
|
|
75
|
+
### 4. Protect your app
|
|
76
|
+
|
|
77
|
+
Wrap your application root with `DevGuardProvider`. That's it — once the status returned by your dashboard is `LOCKED`, the Lock Screen appears automatically.
|
|
29
78
|
|
|
30
79
|
```tsx
|
|
31
80
|
import React from 'react';
|
|
32
81
|
import { DevGuardProvider } from 'react-native-dev-guard';
|
|
33
82
|
|
|
34
|
-
const App = () =>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
83
|
+
const App = () => {
|
|
84
|
+
return (
|
|
85
|
+
<DevGuardProvider
|
|
86
|
+
projectId="your_project_id" // From the DevGuard dashboard
|
|
87
|
+
secret="YOUR_MASTER_SECRET" // Settings → Master Secret
|
|
88
|
+
autoProtect={true} // Auto-show the Lock Screen when LOCKED
|
|
89
|
+
failSafe="open" // 'open' or 'closed' (offline behavior, no cache)
|
|
90
|
+
>
|
|
91
|
+
<MainApp />
|
|
92
|
+
</DevGuardProvider>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export default App;
|
|
44
97
|
```
|
|
45
98
|
|
|
46
|
-
|
|
99
|
+
## 🧭 Status lifecycle
|
|
100
|
+
|
|
101
|
+
DevGuard syncs on app launch, on foreground/background, and on a server-defined heartbeat. The current `status` drives what the user sees:
|
|
102
|
+
|
|
103
|
+
| Status | Meaning | What the user sees |
|
|
104
|
+
| --- | --- | --- |
|
|
105
|
+
| `ACTIVE` | Valid license / access granted. | Your app, running normally. |
|
|
106
|
+
| `WARNING` | App still works, but a notice is shown. | A non-blocking toast (e.g. *"Payment reminder"*). |
|
|
107
|
+
| `LOCKED` | Access revoked by you. | The built-in **Lock Screen** (when `autoProtect`). |
|
|
108
|
+
| `EXPIRED` | License expired. | Treated as locked. |
|
|
109
|
+
| `PENDING` | Initial state before the first successful sync (`failSafe: open`). | Your app (optimistic). |
|
|
110
|
+
| `ERROR` | Sync failed. | Depends on `failSafe` (see below). |
|
|
111
|
+
|
|
112
|
+
## 🪝 API
|
|
113
|
+
|
|
114
|
+
### `<DevGuardProvider>` props
|
|
115
|
+
|
|
116
|
+
| Prop | Type | Default | Description |
|
|
117
|
+
| --- | --- | --- | --- |
|
|
118
|
+
| `projectId` | `string` | **required** | Your DevGuard project ID. |
|
|
119
|
+
| `secret` | `string` | — | Your account **Master Secret** (Settings → Master Secret), used to authenticate requests. |
|
|
120
|
+
| `autoProtect` | `boolean` | `true` | Automatically render the built-in Lock Screen when status is `LOCKED` / `EXPIRED`. |
|
|
121
|
+
| `failSafe` | `'open' \| 'closed'` | `'open'` | Behavior when the server is unreachable and no cache exists. `open` keeps the app usable; `closed` locks it. |
|
|
122
|
+
| `apiKey` | `string` | — | **Deprecated** alias for `secret`. |
|
|
123
|
+
|
|
124
|
+
### `useDevGuard()`
|
|
47
125
|
|
|
48
126
|
```tsx
|
|
49
127
|
import { useDevGuard } from 'react-native-dev-guard';
|
|
50
128
|
|
|
51
129
|
const MyComponent = () => {
|
|
52
130
|
const { status, response, isLocked, verify } = useDevGuard();
|
|
53
|
-
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<View>
|
|
134
|
+
<Text>Status: {status}</Text>
|
|
135
|
+
{response?.betaFeatures?.showBetaFeature && <BetaComponent />}
|
|
136
|
+
</View>
|
|
137
|
+
);
|
|
54
138
|
};
|
|
55
139
|
```
|
|
56
140
|
|
|
57
|
-
|
|
141
|
+
| Field | Type | Description |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `status` | `GuardStatus` | `ACTIVE` · `WARNING` · `LOCKED` · `EXPIRED` · `PENDING` · `ERROR`. |
|
|
144
|
+
| `isLocked` | `boolean` | `true` when status is `LOCKED` or `EXPIRED`. |
|
|
145
|
+
| `response` | `GuardResponse \| null` | Full server response (messages, contacts, `config`, `betaFeatures`, etc.). |
|
|
146
|
+
| `verify` | `(force?: boolean) => Promise<void>` | Manually trigger a license sync. |
|
|
147
|
+
| `unlock` | `(key: string) => Promise<boolean>` | Submit an unlock key; resolves `true` on success. |
|
|
148
|
+
| `setDeviceUser` | `(username?, email?, phone?, customData?) => Promise<void>` | Register the signed-in app user so they appear in the Developer Portal. |
|
|
149
|
+
|
|
150
|
+
### Track app users in the Developer Portal
|
|
58
151
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
152
|
+
When someone signs in or registers in your app, pass their profile to DevGuard. You'll then be able to see **how many users are using your application** in the **Developer Portal** — total user count, recent activity, and basic profile fields (username, email, phone, and any custom metadata you attach).
|
|
153
|
+
|
|
154
|
+
Call this after login or registration (all parameters are optional):
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
const { setDeviceUser } = useDevGuard();
|
|
158
|
+
|
|
159
|
+
await setDeviceUser(
|
|
160
|
+
'jane_doe', // username
|
|
161
|
+
'jane@example.com', // email
|
|
162
|
+
'+15551234567', // phone
|
|
163
|
+
{ plan: 'pro' } // any custom data
|
|
164
|
+
);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Open **Developer Portal → Users** to view your app's user base and engagement.
|
|
65
168
|
|
|
66
169
|
### Manual verification
|
|
67
170
|
|
|
171
|
+
Force a sync after a meaningful event (e.g. login or payment):
|
|
172
|
+
|
|
68
173
|
```tsx
|
|
69
174
|
const { verify } = useDevGuard();
|
|
70
|
-
await verify(true); //
|
|
175
|
+
await verify(true); // true forces a sync regardless of policy
|
|
71
176
|
```
|
|
72
177
|
|
|
73
|
-
###
|
|
178
|
+
### Unlock with a key
|
|
179
|
+
|
|
180
|
+
The built-in Lock Screen already includes an **"Enter Unlock Key"** flow, so most apps never call this directly — but it's available if you want a custom UI:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
const { unlock } = useDevGuard();
|
|
184
|
+
const ok = await unlock('USER-ENTERED-KEY');
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## 🐞 Diagnostic Overlay & Vault Logger
|
|
188
|
+
|
|
189
|
+
DevGuard includes an integrated diagnostic UI (the Bug Icon) and an encrypted local Vault Logger for advanced debugging without rebuilding your app.
|
|
190
|
+
|
|
191
|
+
### Vault Logger
|
|
192
|
+
The SDK bundles `react-native-vault-logger`. By default, it automatically intercepts and encrypts fatal JS errors and usage info, saving them securely to local storage using **per-device AES-256-CBC keys** derived from the hardware `deviceId` at init (no static secret in source).
|
|
193
|
+
You can manually log data to the Info Vault:
|
|
194
|
+
```tsx
|
|
195
|
+
import { DevGuardLogger } from 'react-native-dev-guard/src/services/DevGuardLogger';
|
|
196
|
+
|
|
197
|
+
DevGuardLogger.info('User completed onboarding', { userId: 123 });
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### The Bug Icon (Diagnostic Overlay)
|
|
201
|
+
To view telemetry and logs directly inside the running app without connecting a debugger:
|
|
202
|
+
1. Go to your DevGuard Admin Control Center.
|
|
203
|
+
2. Ensure you have configured a **6-digit Diagnostic Passcode**.
|
|
204
|
+
3. Under the project settings, toggle on **Enable Diagnostic Logs (Beta Feature)** for the desired devices.
|
|
205
|
+
4. A floating **🐛 Bug Icon** will appear in your app.
|
|
206
|
+
5. Tap it and enter your Passcode to view device telemetry and access the encrypted error vaults.
|
|
207
|
+
|
|
208
|
+
## ⚙️ Configuration
|
|
209
|
+
|
|
210
|
+
### Fail-Safe Modes
|
|
211
|
+
- **`open` (Default)**: If the server is unreachable and no cache exists, the app remains accessible.
|
|
212
|
+
- **`closed`**: The app will lock until a successful status is fetched.
|
|
213
|
+
|
|
214
|
+
## 🔐 Security Best Practices
|
|
215
|
+
|
|
216
|
+
1. **Obfuscation**: Always use `javascript-obfuscator` or similar tools for your JS bundle.
|
|
217
|
+
2. **Hermes**: Ensure Hermes is enabled in your `app/build.gradle` and `Podfile` to benefit from bytecode pre-compilation.
|
|
218
|
+
3. **ProGuard**: Use the included ProGuard rules to protect the native C++ library.
|
|
74
219
|
|
|
75
|
-
|
|
220
|
+
## 💬 Support & Contact
|
|
76
221
|
|
|
77
|
-
|
|
222
|
+
- 🌐 **Website / register:** [devguard.uk](https://devguard.uk)
|
|
223
|
+
- 📧 **Email:** [contact@devguard.uk](mailto:contact@devguard.uk)
|
|
224
|
+
- 🐛 **Issues:** [GitHub Issues](https://github.com/DevGuard-uk/react-native-dev-guard/issues)
|
|
78
225
|
|
|
79
|
-
|
|
80
|
-
- Enable Hermes and ProGuard (see `example/android/app/proguard-rules.pro`)
|
|
81
|
-
- Never commit your Master Secret to source control
|
|
226
|
+
## 📄 License
|
|
82
227
|
|
|
83
|
-
|
|
228
|
+
MIT © [DevGuard](https://devguard.uk)
|
|
84
229
|
|
|
85
|
-
|
|
230
|
+
---
|
|
231
|
+
*Secure by Design. Managed by You.*
|
package/lib/index.js
CHANGED
|
@@ -36,7 +36,11 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
36
36
|
const lastSyncTime = (0, react_1.useRef)(0);
|
|
37
37
|
const [showDiagnostics, setShowDiagnostics] = (0, react_1.useState)(false);
|
|
38
38
|
const lastLifecycleSyncTime = (0, react_1.useRef)(0);
|
|
39
|
-
//
|
|
39
|
+
// Mirror of `response` for use inside long-lived closures (AppState listener,
|
|
40
|
+
// heartbeat). Those callbacks are registered once, so reading the `response`
|
|
41
|
+
// state directly would capture a stale (initial null) value — breaking
|
|
42
|
+
// telemetry consent and lifecycle gating. The ref always holds the latest.
|
|
43
|
+
// (Parity with Flutter, where these reads hit the `_cachedResponse` field.)
|
|
40
44
|
const responseRef = (0, react_1.useRef)(null);
|
|
41
45
|
(0, react_1.useEffect)(() => {
|
|
42
46
|
responseRef.current = response;
|
|
@@ -187,7 +191,7 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
187
191
|
else {
|
|
188
192
|
console.warn('DevGuard: Missing server response signature.');
|
|
189
193
|
}
|
|
190
|
-
// Client-side enforcement (e.g. blockEmulators).
|
|
194
|
+
// Client-side enforcement (e.g. blockEmulators) — parity with Flutter.
|
|
191
195
|
const enforced = GuardEnforcement_1.GuardEnforcement.apply(result, metadata);
|
|
192
196
|
const finalStatus = String(enforced.status || 'ERROR').toUpperCase();
|
|
193
197
|
responseRef.current = enforced; // keep ref fresh for chained/triggered syncs
|
|
@@ -196,7 +200,7 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
196
200
|
setShowWarning(finalStatus === 'WARNING');
|
|
197
201
|
lastSyncTime.current = Date.now();
|
|
198
202
|
CacheService_1.CacheService.saveResponse(projectId, enforced);
|
|
199
|
-
// Handle
|
|
203
|
+
// Handle Beta Features (Parity with Flutter)
|
|
200
204
|
if (finalStatus === 'WARNING' && result.betaFeatures?.vibrateOnWarning === true) {
|
|
201
205
|
react_native_1.Vibration.vibrate();
|
|
202
206
|
}
|
|
@@ -206,11 +210,11 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
206
210
|
}
|
|
207
211
|
// Heartbeat management
|
|
208
212
|
startHeartbeat(result);
|
|
209
|
-
//
|
|
213
|
+
// Handle Device Token (Parity with Flutter)
|
|
210
214
|
if (result.deviceToken) {
|
|
211
215
|
await DeviceTokenService_1.DeviceTokenService.getInstance().saveToken(result.deviceToken, result.betaFeatures?.secureEnclave === true);
|
|
212
216
|
}
|
|
213
|
-
// Handle
|
|
217
|
+
// Handle Remote Commands (Parity with Flutter)
|
|
214
218
|
if (result.remoteCommand && result.remoteCommand !== 'none') {
|
|
215
219
|
await handleRemoteCommand(result.remoteCommand);
|
|
216
220
|
}
|
|
@@ -264,7 +268,11 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
264
268
|
await DeviceTokenService_1.DeviceTokenService.getInstance().clearToken();
|
|
265
269
|
}
|
|
266
270
|
};
|
|
267
|
-
/**
|
|
271
|
+
/**
|
|
272
|
+
* Hardened, nonce-based remote wipe (parity with Flutter + .cursorrules §3).
|
|
273
|
+
* Only triggers when the server nonce is greater than the last executed one,
|
|
274
|
+
* then persists the new nonce so the wipe runs exactly once per command.
|
|
275
|
+
*/
|
|
268
276
|
const executeRemoteWipe = async (nonce) => {
|
|
269
277
|
const lastHandled = await CacheService_1.CacheService.getLastWipeNonce(projectId);
|
|
270
278
|
if (lastHandled !== null && nonce <= lastHandled)
|
|
@@ -307,7 +315,7 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
307
315
|
const setDeviceUser = async (username, email, phone, customData) => {
|
|
308
316
|
await HardwareService_1.HardwareService.getInstance().setDeviceUser(username, email, phone, customData);
|
|
309
317
|
if (!username && !email && !phone && !customData)
|
|
310
|
-
return;
|
|
318
|
+
return; // "if all values will null then no request will need to trigger to server okay"
|
|
311
319
|
await verify(true);
|
|
312
320
|
};
|
|
313
321
|
(0, react_1.useEffect)(() => {
|
|
@@ -321,7 +329,8 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
321
329
|
// Run heavy operations safely in the background JS event loop
|
|
322
330
|
setTimeout(async () => {
|
|
323
331
|
try {
|
|
324
|
-
await
|
|
332
|
+
const deviceId = await HardwareService_1.HardwareService.getInstance().getDeviceId();
|
|
333
|
+
await DevGuardLogger_1.DevGuardLogger.init(deviceId);
|
|
325
334
|
const isJailbroken = await react_native_jailbreak_1.default.check();
|
|
326
335
|
if (isJailbroken) {
|
|
327
336
|
console.warn('DevGuard Security Alert: Compromised device detected.');
|
|
@@ -4,7 +4,11 @@ export declare class CacheService {
|
|
|
4
4
|
static saveResponse(projectId: string, response: any): Promise<void>;
|
|
5
5
|
static getResponse(projectId: string): Promise<any | null>;
|
|
6
6
|
static clear(): Promise<void>;
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Returns the last remote-wipe nonce this client has executed, or null.
|
|
9
|
+
* Stored separately from the response cache so it survives a cache wipe
|
|
10
|
+
* (parity with Flutter's nonce persistence).
|
|
11
|
+
*/
|
|
8
12
|
static getLastWipeNonce(projectId: string): Promise<number | null>;
|
|
9
13
|
static setLastWipeNonce(projectId: string, nonce: number): Promise<void>;
|
|
10
14
|
}
|
|
@@ -81,7 +81,11 @@ class CacheService {
|
|
|
81
81
|
console.warn('DevGuard Cache: Failed to clear cache', e);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Returns the last remote-wipe nonce this client has executed, or null.
|
|
86
|
+
* Stored separately from the response cache so it survives a cache wipe
|
|
87
|
+
* (parity with Flutter's nonce persistence).
|
|
88
|
+
*/
|
|
85
89
|
static async getLastWipeNonce(projectId) {
|
|
86
90
|
try {
|
|
87
91
|
const credentials = await Keychain.getGenericPassword({ service: this.WIPE_SERVICE });
|
|
@@ -3,7 +3,7 @@ export declare class DevGuardLogger {
|
|
|
3
3
|
static showConsoleLogs: boolean;
|
|
4
4
|
private static initialized;
|
|
5
5
|
private static infoLogs;
|
|
6
|
-
static init(): Promise<void>;
|
|
6
|
+
static init(deviceId: string): Promise<void>;
|
|
7
7
|
static enableConsoleLogs(): void;
|
|
8
8
|
static info(message: string, data?: Record<string, any>): void;
|
|
9
9
|
static warning(message: string, data?: Record<string, any>): void;
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.DevGuardLogger = void 0;
|
|
7
|
+
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
4
8
|
const react_native_vault_logger_1 = require("react-native-vault-logger");
|
|
9
|
+
function deriveVaultKeyMaterial(deviceId, salt) {
|
|
10
|
+
const hex = crypto_js_1.default.SHA256(`${deviceId}_${salt}`).toString(crypto_js_1.default.enc.Hex);
|
|
11
|
+
return crypto_js_1.default.enc.Hex.parse(hex).toString(crypto_js_1.default.enc.Latin1);
|
|
12
|
+
}
|
|
5
13
|
class DevGuardLogger {
|
|
6
14
|
static showConsoleLogs = false;
|
|
7
15
|
static initialized = false;
|
|
8
16
|
static infoLogs = [];
|
|
9
|
-
static async init() {
|
|
17
|
+
static async init(deviceId) {
|
|
10
18
|
if (this.initialized)
|
|
11
19
|
return;
|
|
12
20
|
try {
|
|
21
|
+
const encryptionKey = deriveVaultKeyMaterial(deviceId, 'dg_vault_key_v1');
|
|
22
|
+
const encryptionIV = deriveVaultKeyMaterial(deviceId, 'dg_vault_iv_v1').substring(0, 16);
|
|
13
23
|
await react_native_vault_logger_1.CrashLogService.init({
|
|
14
|
-
encryptionKey
|
|
15
|
-
encryptionIV
|
|
24
|
+
encryptionKey,
|
|
25
|
+
encryptionIV,
|
|
16
26
|
maxLogCount: 1000,
|
|
17
27
|
});
|
|
18
28
|
this.initialized = true;
|
|
@@ -10,7 +10,10 @@ export declare class DeviceTokenService {
|
|
|
10
10
|
* Reads from Keychain/Keystore if available, otherwise from in-memory cache.
|
|
11
11
|
*/
|
|
12
12
|
getToken(): Promise<string | null>;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Persists a registration token received from the server.
|
|
15
|
+
* Uses hardware-backed Keychain/Keystore when available (parity with Flutter's flutter_secure_storage).
|
|
16
|
+
*/
|
|
14
17
|
saveToken(token: string, useEnclave?: boolean): Promise<void>;
|
|
15
18
|
/**
|
|
16
19
|
* Removes the registration token. Only called on explicit admin revocation.
|
|
@@ -52,11 +52,14 @@ class DeviceTokenService {
|
|
|
52
52
|
// Fallback: in-memory token
|
|
53
53
|
return this.cachedToken;
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Persists a registration token received from the server.
|
|
57
|
+
* Uses hardware-backed Keychain/Keystore when available (parity with Flutter's flutter_secure_storage).
|
|
58
|
+
*/
|
|
56
59
|
async saveToken(token, useEnclave = false) {
|
|
57
60
|
let finalToken = token;
|
|
58
61
|
if (useEnclave) {
|
|
59
|
-
// Simulated
|
|
62
|
+
// Simulated Enclave: Reverse and prefix (parity with Flutter)
|
|
60
63
|
finalToken = `se:${token.split('').reverse().join('')}`;
|
|
61
64
|
}
|
|
62
65
|
// Primary: Keychain/Keystore (hardware-backed, persists across restarts)
|
|
@@ -5,7 +5,11 @@ export declare class HardwareService {
|
|
|
5
5
|
static getInstance(): HardwareService;
|
|
6
6
|
getDeviceId(): Promise<string>;
|
|
7
7
|
setDeviceUser(username?: string, email?: string, phone?: string, customData?: Record<string, any>): Promise<void>;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Clears all stored device-user identity (username/email/phone/customData).
|
|
10
|
+
* Used by the hardened remote wipe (parity with Flutter's
|
|
11
|
+
* SecureStorageService.deleteAllDeviceUserKeys).
|
|
12
|
+
*/
|
|
9
13
|
clearDeviceUser(): Promise<void>;
|
|
10
14
|
getMetadata(betaFeatures?: any): Promise<any>;
|
|
11
15
|
private getNetworkType;
|
|
@@ -16,4 +20,13 @@ export declare class HardwareService {
|
|
|
16
20
|
* Each metric is collected independently so one failure never blocks the rest.
|
|
17
21
|
*/
|
|
18
22
|
private collectAdvancedTelemetry;
|
|
23
|
+
/**
|
|
24
|
+
* Collects GPS only if permission is already granted — never prompts during sync.
|
|
25
|
+
*
|
|
26
|
+
* Uses a cached position (low accuracy, high maximumAge) to avoid waking the GPS
|
|
27
|
+
* radio. Denied or unavailable permission returns null silently — it must not
|
|
28
|
+
* pollute the error vault.
|
|
29
|
+
*/
|
|
30
|
+
private getLocationPassive;
|
|
31
|
+
private isLocationPermissionGranted;
|
|
19
32
|
}
|
|
@@ -86,7 +86,11 @@ class HardwareService {
|
|
|
86
86
|
console.warn('DevGuard: Failed to save user info', e);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Clears all stored device-user identity (username/email/phone/customData).
|
|
91
|
+
* Used by the hardened remote wipe (parity with Flutter's
|
|
92
|
+
* SecureStorageService.deleteAllDeviceUserKeys).
|
|
93
|
+
*/
|
|
90
94
|
async clearDeviceUser() {
|
|
91
95
|
try {
|
|
92
96
|
await Keychain.resetGenericPassword({ service: 'devguard.user.service' });
|
|
@@ -216,7 +220,65 @@ class HardwareService {
|
|
|
216
220
|
catch (e) {
|
|
217
221
|
// Ignore individual metric failure.
|
|
218
222
|
}
|
|
223
|
+
const location = await this.getLocationPassive();
|
|
224
|
+
if (location) {
|
|
225
|
+
out.location = location;
|
|
226
|
+
}
|
|
219
227
|
return out;
|
|
220
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Collects GPS only if permission is already granted — never prompts during sync.
|
|
231
|
+
*
|
|
232
|
+
* Uses a cached position (low accuracy, high maximumAge) to avoid waking the GPS
|
|
233
|
+
* radio. Denied or unavailable permission returns null silently — it must not
|
|
234
|
+
* pollute the error vault.
|
|
235
|
+
*/
|
|
236
|
+
async getLocationPassive() {
|
|
237
|
+
if (react_native_1.Platform.OS !== 'android' && react_native_1.Platform.OS !== 'ios')
|
|
238
|
+
return null;
|
|
239
|
+
if (!(await this.isLocationPermissionGranted()))
|
|
240
|
+
return null;
|
|
241
|
+
try {
|
|
242
|
+
// Optional peer: host app installs react-native-geolocation-service for GPS telemetry.
|
|
243
|
+
const Geolocation = require('react-native-geolocation-service').default;
|
|
244
|
+
return await new Promise((resolve) => {
|
|
245
|
+
Geolocation.getCurrentPosition((position) => {
|
|
246
|
+
const { latitude, longitude } = position.coords;
|
|
247
|
+
resolve(`${latitude.toFixed(4)},${longitude.toFixed(4)}`);
|
|
248
|
+
}, () => resolve(null), {
|
|
249
|
+
enableHighAccuracy: false,
|
|
250
|
+
maximumAge: 86_400_000,
|
|
251
|
+
timeout: 5_000,
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async isLocationPermissionGranted() {
|
|
260
|
+
if (react_native_1.Platform.OS === 'android') {
|
|
261
|
+
try {
|
|
262
|
+
const fine = await react_native_1.PermissionsAndroid.check(react_native_1.PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
|
|
263
|
+
const coarse = await react_native_1.PermissionsAndroid.check(react_native_1.PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);
|
|
264
|
+
return fine || coarse;
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (react_native_1.Platform.OS === 'ios') {
|
|
271
|
+
try {
|
|
272
|
+
// Optional peer: react-native-permissions (check only — never request).
|
|
273
|
+
const { check, PERMISSIONS, RESULTS } = require('react-native-permissions');
|
|
274
|
+
const status = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
|
|
275
|
+
return status === RESULTS.GRANTED || status === RESULTS.LIMITED;
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
221
283
|
}
|
|
222
284
|
exports.HardwareService = HardwareService;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-dev-guard",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "DevGuard protection for React Native apps",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"author": "
|
|
6
|
+
"author": "DevGuard-uk",
|
|
7
7
|
"homepage": "https://github.com/DevGuard-uk/react-native-dev-guard",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -21,9 +21,13 @@
|
|
|
21
21
|
"types": "lib/index.d.ts",
|
|
22
22
|
"files": [
|
|
23
23
|
"lib",
|
|
24
|
-
"
|
|
25
|
-
"ios",
|
|
26
|
-
"
|
|
24
|
+
"cpp",
|
|
25
|
+
"ios/DevGuard.h",
|
|
26
|
+
"ios/DevGuard.mm",
|
|
27
|
+
"android/build.gradle",
|
|
28
|
+
"android/src",
|
|
29
|
+
"react-native-dev-guard.podspec",
|
|
30
|
+
"screenshots"
|
|
27
31
|
],
|
|
28
32
|
"scripts": {
|
|
29
33
|
"clean": "rimraf lib",
|
|
@@ -58,6 +62,16 @@
|
|
|
58
62
|
"react": ">=18",
|
|
59
63
|
"react-native": ">=0.76",
|
|
60
64
|
"react-native-device-info": "*",
|
|
61
|
-
"react-native-
|
|
65
|
+
"react-native-geolocation-service": "*",
|
|
66
|
+
"react-native-keychain": "*",
|
|
67
|
+
"react-native-permissions": "*"
|
|
68
|
+
},
|
|
69
|
+
"peerDependenciesMeta": {
|
|
70
|
+
"react-native-geolocation-service": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"react-native-permissions": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
62
76
|
}
|
|
63
77
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "react-native-dev-guard"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"] || "https://github.com/DevGuard-uk/react-native-dev-guard"
|
|
10
|
+
s.license = package["license"] || "MIT"
|
|
11
|
+
s.authors = package["author"] || "DevGuard"
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => "15.1" }
|
|
14
|
+
s.source = { :git => (package.dig("repository", "url") || "https://github.com/DevGuard-uk/react-native-dev-guard.git"), :tag => "v#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,cpp}", "cpp/**/*.{h,c,cpp}"
|
|
17
|
+
|
|
18
|
+
s.dependency "React-Core"
|
|
19
|
+
end
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|