react-native-ssl-manager 1.0.0 → 1.0.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/README.md +319 -58
- package/android/build.gradle +23 -1
- package/android/src/main/java/com/usesslpinning/SslPinningFactory.kt +94 -0
- package/android/src/main/java/com/usesslpinning/UseSslPinningModuleImpl.kt +34 -0
- package/android/src/newarch/com/usesslpinning/UseSslPinningModule.kt +26 -0
- package/android/src/newarch/com/usesslpinning/UseSslPinningPackage.kt +36 -0
- package/android/src/oldarch/com/usesslpinning/UseSslPinningModule.kt +32 -0
- package/android/src/{main/java → oldarch}/com/usesslpinning/UseSslPinningPackage.kt +0 -1
- package/android/ssl-pinning-setup.gradle +148 -0
- package/expo-module.config.json +10 -0
- package/ios/SharedLogic.swift +247 -0
- package/ios/UseSslPinning.h +5 -0
- package/ios/{UseSslPinning.mm → UseSslPinningModule.mm} +9 -6
- package/ios/UseSslPinningModule.swift +65 -0
- package/lib/NativeUseSslPinning.d.ts +8 -0
- package/lib/NativeUseSslPinning.d.ts.map +1 -0
- package/lib/NativeUseSslPinning.js +4 -0
- package/lib/UseSslPinning.types.d.ts +17 -0
- package/lib/UseSslPinning.types.d.ts.map +1 -0
- package/lib/UseSslPinning.types.js +2 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +58 -0
- package/package.json +82 -39
- package/react-native-ssl-manager.podspec +87 -38
- package/react-native.config.js +34 -0
- package/scripts/build.sh +52 -0
- package/src/NativeUseSslPinning.ts +9 -0
- package/src/UseSslPinning.types.ts +17 -0
- package/src/index.tsx +53 -33
- package/android/src/main/java/com/usesslpinning/UseSslPinningFactory.kt +0 -50
- package/android/src/main/java/com/usesslpinning/UseSslPinningModule.kt +0 -45
- package/ios/UseSslPinning-Bridging-Header.h +0 -2
- package/ios/UseSslPinning.swift +0 -169
package/package.json
CHANGED
|
@@ -1,51 +1,88 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-ssl-manager",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "React Native SSL Pinning provides seamless SSL certificate pinning integration for enhanced network security in React Native apps. This module enables developers to easily implement and manage certificate pinning, protecting applications against man-in-the-middle (MITM) attacks. With dynamic configuration options and the ability to toggle SSL pinning, it's particularly useful for development and testing scenarios.",
|
|
5
|
-
"main": "lib/
|
|
6
|
-
"module": "lib/
|
|
7
|
-
"types": "lib/
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"module": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"source": "src/index.tsx",
|
|
9
|
+
"expo": {
|
|
10
|
+
"plugin": "./app.plugin.js"
|
|
11
|
+
},
|
|
8
12
|
"react-native": {
|
|
9
13
|
"android": {
|
|
10
|
-
"
|
|
14
|
+
"sourceDir": "android/src/main/java",
|
|
15
|
+
"packageImportPath": "import com.usesslpinning.UseSslPinningPackage;"
|
|
11
16
|
},
|
|
12
17
|
"ios": {
|
|
13
|
-
"
|
|
18
|
+
"podspecPath": "react-native-ssl-manager.podspec"
|
|
14
19
|
}
|
|
15
20
|
},
|
|
16
|
-
"
|
|
21
|
+
"codegenConfig": {
|
|
22
|
+
"name": "RNUseSslPinningSpec",
|
|
23
|
+
"type": "modules",
|
|
24
|
+
"jsSrcsDir": "src"
|
|
25
|
+
},
|
|
17
26
|
"files": [
|
|
18
|
-
"src",
|
|
19
27
|
"lib",
|
|
20
|
-
"
|
|
21
|
-
"!**/__fixtures__",
|
|
22
|
-
"!**/__mocks__",
|
|
28
|
+
"src",
|
|
23
29
|
"android",
|
|
24
30
|
"ios",
|
|
25
|
-
"
|
|
31
|
+
"plugin",
|
|
26
32
|
"*.podspec",
|
|
27
|
-
"
|
|
33
|
+
"react-native-ssl-manager.podspec",
|
|
34
|
+
"expo-module.config.json",
|
|
35
|
+
"react-native.config.js",
|
|
36
|
+
"scripts/build.sh",
|
|
37
|
+
"!**/__tests__",
|
|
38
|
+
"!**/__fixtures__",
|
|
39
|
+
"!**/__mocks__",
|
|
28
40
|
"!ios/build",
|
|
29
41
|
"!android/build",
|
|
42
|
+
"!android/.gradle",
|
|
30
43
|
"!android/gradle",
|
|
31
44
|
"!android/gradlew",
|
|
32
45
|
"!android/gradlew.bat",
|
|
33
46
|
"!android/local.properties",
|
|
47
|
+
"!example",
|
|
48
|
+
"!example-expo",
|
|
34
49
|
"!**/.*"
|
|
35
50
|
],
|
|
36
51
|
"scripts": {
|
|
37
|
-
"
|
|
38
|
-
"
|
|
52
|
+
"build": "tsc",
|
|
53
|
+
"clean": "expo-module clean",
|
|
54
|
+
"lint": "expo-module lint",
|
|
55
|
+
"test": "expo-module test",
|
|
56
|
+
"prepare": "echo 'Skipping prepare script'",
|
|
39
57
|
"typecheck": "tsc --noEmit",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
58
|
+
"release": "release-it",
|
|
59
|
+
"build:all": "./scripts/build.sh",
|
|
60
|
+
"build:examples": "./scripts/build.sh --with-examples",
|
|
61
|
+
"example:install": "cd example && yarn install",
|
|
62
|
+
"postinstall": "node scripts/postinstall.js",
|
|
63
|
+
"postinstall:bun": "bun scripts/bun-postinstall.js",
|
|
64
|
+
"example:ios": "cd example && npx react-native run-ios",
|
|
65
|
+
"example:android": "cd example && npx react-native run-android",
|
|
66
|
+
"example-expo:install": "cd example-expo && yarn install",
|
|
67
|
+
"example-expo:ios": "cd example-expo && npx expo run:ios",
|
|
68
|
+
"example-expo:android": "cd example-expo && npx expo run:android",
|
|
69
|
+
"example-expo:start": "cd example-expo && npx expo start",
|
|
70
|
+
"bun:install": "bun install",
|
|
71
|
+
"bun:build": "bun run build",
|
|
72
|
+
"bun:test": "bun test",
|
|
73
|
+
"bun:example:install": "cd example && bun install",
|
|
74
|
+
"bun:example-expo:install": "cd example-expo && bun install",
|
|
75
|
+
"bun:test-compatibility": "bun scripts/test-bun.js"
|
|
44
76
|
},
|
|
45
77
|
"keywords": [
|
|
46
78
|
"react-native",
|
|
47
79
|
"ios",
|
|
48
|
-
"android"
|
|
80
|
+
"android",
|
|
81
|
+
"expo",
|
|
82
|
+
"bun",
|
|
83
|
+
"ssl-pinning",
|
|
84
|
+
"security",
|
|
85
|
+
"certificate-pinning"
|
|
49
86
|
],
|
|
50
87
|
"repository": {
|
|
51
88
|
"type": "git",
|
|
@@ -63,7 +100,6 @@
|
|
|
63
100
|
},
|
|
64
101
|
"devDependencies": {
|
|
65
102
|
"@commitlint/config-conventional": "^17.0.2",
|
|
66
|
-
"@evilmartians/lefthook": "^1.5.0",
|
|
67
103
|
"@react-native/eslint-config": "^0.73.1",
|
|
68
104
|
"@release-it/conventional-changelog": "^5.0.0",
|
|
69
105
|
"@types/jest": "^29.5.5",
|
|
@@ -73,13 +109,13 @@
|
|
|
73
109
|
"eslint": "^8.51.0",
|
|
74
110
|
"eslint-config-prettier": "^9.0.0",
|
|
75
111
|
"eslint-plugin-prettier": "^5.0.1",
|
|
112
|
+
"expo-module-scripts": "^3.4.0",
|
|
76
113
|
"jest": "^29.7.0",
|
|
77
114
|
"prettier": "^3.0.3",
|
|
78
115
|
"react": "18.2.0",
|
|
79
116
|
"react-native": "0.73.6",
|
|
80
117
|
"react-native-builder-bob": "^0.20.0",
|
|
81
118
|
"release-it": "^15.0.0",
|
|
82
|
-
"turbo": "^1.10.7",
|
|
83
119
|
"typescript": "5.1.x"
|
|
84
120
|
},
|
|
85
121
|
"resolutions": {
|
|
@@ -89,14 +125,27 @@
|
|
|
89
125
|
"react": "*",
|
|
90
126
|
"react-native": "*"
|
|
91
127
|
},
|
|
92
|
-
"workspaces": [
|
|
93
|
-
"example"
|
|
94
|
-
],
|
|
95
128
|
"packageManager": "yarn@3.6.1",
|
|
129
|
+
"engines": {
|
|
130
|
+
"node": ">=16.0.0",
|
|
131
|
+
"bun": ">=1.0.0"
|
|
132
|
+
},
|
|
133
|
+
"overrides": {
|
|
134
|
+
"bun": {
|
|
135
|
+
"react": "*",
|
|
136
|
+
"react-native": "*"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"codegenConfig": {
|
|
140
|
+
"name": "RNUseSslPinningSpec",
|
|
141
|
+
"type": "modules",
|
|
142
|
+
"jsSrcsDir": "src"
|
|
143
|
+
},
|
|
96
144
|
"jest": {
|
|
97
145
|
"preset": "react-native",
|
|
98
146
|
"modulePathIgnorePatterns": [
|
|
99
147
|
"<rootDir>/example/node_modules",
|
|
148
|
+
"<rootDir>/example-expo/node_modules",
|
|
100
149
|
"<rootDir>/lib/"
|
|
101
150
|
]
|
|
102
151
|
},
|
|
@@ -143,7 +192,9 @@
|
|
|
143
192
|
},
|
|
144
193
|
"eslintIgnore": [
|
|
145
194
|
"node_modules/",
|
|
146
|
-
"lib/"
|
|
195
|
+
"lib/",
|
|
196
|
+
"example/",
|
|
197
|
+
"example-expo/"
|
|
147
198
|
],
|
|
148
199
|
"prettier": {
|
|
149
200
|
"quoteProps": "consistent",
|
|
@@ -152,21 +203,13 @@
|
|
|
152
203
|
"trailingComma": "es5",
|
|
153
204
|
"useTabs": false
|
|
154
205
|
},
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"commonjs",
|
|
160
|
-
"module",
|
|
161
|
-
[
|
|
162
|
-
"typescript",
|
|
163
|
-
{
|
|
164
|
-
"project": "tsconfig.build.json"
|
|
165
|
-
}
|
|
166
|
-
]
|
|
167
|
-
]
|
|
206
|
+
"codegenConfig": {
|
|
207
|
+
"name": "RNUseSslPinningSpec",
|
|
208
|
+
"type": "modules",
|
|
209
|
+
"jsSrcsDir": "src"
|
|
168
210
|
},
|
|
169
211
|
"dependencies": {
|
|
212
|
+
"@babel/runtime": "^7.23.0",
|
|
170
213
|
"postinstall": "^0.10.3"
|
|
171
214
|
}
|
|
172
215
|
}
|
|
@@ -1,43 +1,92 @@
|
|
|
1
|
-
require "json"
|
|
2
|
-
|
|
3
|
-
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
-
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
|
5
|
-
|
|
6
1
|
Pod::Spec.new do |s|
|
|
7
|
-
s.name
|
|
8
|
-
s.version
|
|
9
|
-
s.summary
|
|
10
|
-
s.
|
|
11
|
-
s.
|
|
12
|
-
s.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
s.source = { :git => "https://github.com/huytdps13400/react-native-ssl-manager.git", :tag => "#{s.version}" }
|
|
2
|
+
s.name = 'react-native-ssl-manager'
|
|
3
|
+
s.version = '1.0.1'
|
|
4
|
+
s.summary = 'SSL Pinning Module for React Native and Expo'
|
|
5
|
+
s.author = 'Huy Tran'
|
|
6
|
+
s.homepage = 'https://github.com/huytdps13400/react-native-ssl-manager'
|
|
7
|
+
s.platforms = { :ios => '13.0' }
|
|
8
|
+
s.source = { :git => 'https://github.com/huytdps13400/react-native-ssl-manager', :tag => s.version.to_s }
|
|
9
|
+
|
|
16
10
|
|
|
11
|
+
|
|
12
|
+
# RNBootSplash pattern - single implementation for all architectures
|
|
17
13
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if respond_to?(:install_modules_dependencies, true)
|
|
22
|
-
install_modules_dependencies(s)
|
|
23
|
-
else
|
|
24
|
-
s.dependency "React-Core"
|
|
25
|
-
|
|
26
|
-
# Don't install the dependencies when we run `pod install` in the old architecture.
|
|
14
|
+
|
|
15
|
+
s.pod_target_xcconfig = { "DEFINES_MODULE" => "YES" }
|
|
16
|
+
|
|
27
17
|
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
|
|
28
|
-
|
|
29
|
-
s.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
# New Architecture dependencies would go here if needed
|
|
19
|
+
s.dependency "React-Core"
|
|
20
|
+
else
|
|
21
|
+
s.dependency "React-Core"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Use script phase to copy ssl_config.json during app build
|
|
25
|
+
s.script_phases = [
|
|
26
|
+
{
|
|
27
|
+
:name => 'Copy SSL Config to App Bundle',
|
|
28
|
+
:script => '
|
|
29
|
+
echo "🔧 SSL Manager: Copying ssl_config.json to app bundle..."
|
|
30
|
+
|
|
31
|
+
# Look for ssl_config.json in parent directories of SRCROOT
|
|
32
|
+
SSL_CONFIG_SOURCE=""
|
|
33
|
+
|
|
34
|
+
# Check common locations and verify content is not empty
|
|
35
|
+
if [ -f "${SRCROOT}/../ssl_config.json" ]; then
|
|
36
|
+
CONTENT=$(cat "${SRCROOT}/../ssl_config.json" | tr -d " \\n\\r")
|
|
37
|
+
if [ "$CONTENT" != "{}" ]; then
|
|
38
|
+
SSL_CONFIG_SOURCE="${SRCROOT}/../ssl_config.json"
|
|
39
|
+
echo "📄 Found ssl_config.json at: $SSL_CONFIG_SOURCE"
|
|
40
|
+
fi
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if [ -z "$SSL_CONFIG_SOURCE" ] && [ -f "${SRCROOT}/../../ssl_config.json" ]; then
|
|
44
|
+
CONTENT=$(cat "${SRCROOT}/../../ssl_config.json" | tr -d " \\n\\r")
|
|
45
|
+
if [ "$CONTENT" != "{}" ]; then
|
|
46
|
+
SSL_CONFIG_SOURCE="${SRCROOT}/../../ssl_config.json"
|
|
47
|
+
echo "📄 Found ssl_config.json at: $SSL_CONFIG_SOURCE"
|
|
48
|
+
fi
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if [ -z "$SSL_CONFIG_SOURCE" ] && [ -f "${SRCROOT}/../../../ssl_config.json" ]; then
|
|
52
|
+
CONTENT=$(cat "${SRCROOT}/../../../ssl_config.json" | tr -d " \\n\\r")
|
|
53
|
+
if [ "$CONTENT" != "{}" ]; then
|
|
54
|
+
SSL_CONFIG_SOURCE="${SRCROOT}/../../../ssl_config.json"
|
|
55
|
+
echo "📄 Found ssl_config.json at: $SSL_CONFIG_SOURCE"
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [ -n "$SSL_CONFIG_SOURCE" ]; then
|
|
60
|
+
# Copy to app bundle resources
|
|
61
|
+
cp "$SSL_CONFIG_SOURCE" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/"
|
|
62
|
+
echo "✅ SSL config copied to app bundle"
|
|
63
|
+
else
|
|
64
|
+
echo "⚠️ ssl_config.json not found in common locations"
|
|
65
|
+
echo "🔍 Searching for ssl_config.json with content..."
|
|
66
|
+
|
|
67
|
+
# Search for any ssl_config.json with content
|
|
68
|
+
for path in $(find "${SRCROOT}/../.." -name "ssl_config.json" -type f 2>/dev/null); do
|
|
69
|
+
CONTENT=$(cat "$path" | tr -d " \\n\\r")
|
|
70
|
+
if [ "$CONTENT" != "{}" ]; then
|
|
71
|
+
SSL_CONFIG_SOURCE="$path"
|
|
72
|
+
echo "📄 Found ssl_config.json with content at: $SSL_CONFIG_SOURCE"
|
|
73
|
+
cp "$SSL_CONFIG_SOURCE" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/"
|
|
74
|
+
echo "✅ SSL config copied to app bundle"
|
|
75
|
+
break
|
|
76
|
+
fi
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
if [ -z "$SSL_CONFIG_SOURCE" ]; then
|
|
80
|
+
echo "💡 SRCROOT: $SRCROOT"
|
|
81
|
+
echo "💡 Create ssl_config.json at project root for SSL pinning to work"
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
',
|
|
86
|
+
:execution_position => :before_compile
|
|
33
87
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
s.dependency "TrustKit"
|
|
43
|
-
end
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
s.dependency 'TrustKit'
|
|
91
|
+
s.dependency 'React-Core'
|
|
92
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// React Native SSL Manager Auto-linking Configuration
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
dependencies: {
|
|
5
|
+
'react-native-ssl-manager': {
|
|
6
|
+
platforms: {
|
|
7
|
+
android: {
|
|
8
|
+
sourceDir: '../android',
|
|
9
|
+
packageImportPath: 'import com.usesslpinning.UseSslPinningPackage;',
|
|
10
|
+
packageInstance: 'new UseSslPinningPackage()',
|
|
11
|
+
// Auto-setup SSL config copy script
|
|
12
|
+
buildTypes: [],
|
|
13
|
+
componentDescriptors: [],
|
|
14
|
+
cmakeListsPath: null,
|
|
15
|
+
},
|
|
16
|
+
ios: {
|
|
17
|
+
podspecPath: '../react-native-ssl-manager.podspec',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
hooks: {
|
|
21
|
+
postlink: () => {
|
|
22
|
+
console.log('🔗 React Native SSL Manager linked successfully');
|
|
23
|
+
console.log('📋 SSL config auto-copy script is now available');
|
|
24
|
+
console.log(
|
|
25
|
+
'💡 Android: Run "cd android && ./gradlew checkSslConfig" to verify setup'
|
|
26
|
+
);
|
|
27
|
+
console.log(
|
|
28
|
+
'💡 iOS: ssl_config.json will be auto-copied during build'
|
|
29
|
+
);
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
package/scripts/build.sh
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Build script for react-native-ssl-manager
|
|
4
|
+
# This script helps build and test the library
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🚀 Building react-native-ssl-manager..."
|
|
9
|
+
|
|
10
|
+
# Clean previous builds
|
|
11
|
+
echo "🧹 Cleaning previous builds..."
|
|
12
|
+
rm -rf lib/
|
|
13
|
+
rm -rf build/
|
|
14
|
+
|
|
15
|
+
# Install dependencies
|
|
16
|
+
echo "📦 Installing dependencies..."
|
|
17
|
+
yarn install
|
|
18
|
+
|
|
19
|
+
# Type check
|
|
20
|
+
echo "🔍 Running type check..."
|
|
21
|
+
yarn typecheck
|
|
22
|
+
|
|
23
|
+
# Build TypeScript
|
|
24
|
+
echo "🔨 Building TypeScript..."
|
|
25
|
+
yarn build
|
|
26
|
+
|
|
27
|
+
# Run tests
|
|
28
|
+
echo "🧪 Running tests..."
|
|
29
|
+
yarn test
|
|
30
|
+
|
|
31
|
+
echo "✅ Build completed successfully!"
|
|
32
|
+
|
|
33
|
+
# Optional: Build examples
|
|
34
|
+
if [ "$1" = "--with-examples" ]; then
|
|
35
|
+
echo "📱 Building examples..."
|
|
36
|
+
|
|
37
|
+
# Build React Native CLI example
|
|
38
|
+
echo "Building React Native CLI example..."
|
|
39
|
+
cd example
|
|
40
|
+
yarn install
|
|
41
|
+
cd ..
|
|
42
|
+
|
|
43
|
+
# Build Expo example
|
|
44
|
+
echo "Building Expo example..."
|
|
45
|
+
cd example-expo
|
|
46
|
+
yarn install
|
|
47
|
+
cd ..
|
|
48
|
+
|
|
49
|
+
echo "✅ Examples built successfully!"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo "🎉 All done! The library is ready for use."
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface Spec extends TurboModule {
|
|
5
|
+
readonly setUseSSLPinning: (usePinning: boolean) => Promise<void>;
|
|
6
|
+
readonly getUseSSLPinning: () => Promise<boolean>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('UseSslPinning');
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSL Pinning Configuration Interface
|
|
3
|
+
* Defines the structure for SSL pinning configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface SslPinningConfig {
|
|
6
|
+
sha256Keys: {
|
|
7
|
+
[domain: string]: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* SSL Pinning Error Interface
|
|
13
|
+
*/
|
|
14
|
+
export interface SslPinningError extends Error {
|
|
15
|
+
code?: string;
|
|
16
|
+
message: string;
|
|
17
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,43 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
// Remove unused Platform import since we no longer check OS
|
|
2
|
+
|
|
3
|
+
// Export types from the library
|
|
4
|
+
export type { SslPinningConfig, SslPinningError } from './UseSslPinning.types';
|
|
5
|
+
|
|
6
|
+
// New Architecture and Legacy Architecture support
|
|
7
|
+
let UseSslPinning: any;
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
// Try Legacy NativeModules first (more reliable)
|
|
11
|
+
const { NativeModules } = require('react-native');
|
|
12
|
+
|
|
13
|
+
// Look for our universal module (works in both CLI and Expo)
|
|
14
|
+
UseSslPinning = NativeModules.UseSslPinning;
|
|
15
|
+
|
|
16
|
+
if (UseSslPinning) {
|
|
17
|
+
} else {
|
|
18
|
+
// Fallback to TurboModule if available
|
|
19
|
+
try {
|
|
20
|
+
UseSslPinning = require('./NativeUseSslPinning').default;
|
|
21
|
+
} catch (turboModuleError) {
|
|
22
|
+
console.log(
|
|
23
|
+
'❌ TurboModule failed:',
|
|
24
|
+
(turboModuleError as Error).message
|
|
25
|
+
);
|
|
26
|
+
UseSslPinning = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.log('❌ Overall module loading failed:', (error as Error).message);
|
|
31
|
+
UseSslPinning = null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Fallback implementation if native module is not available
|
|
35
|
+
if (!UseSslPinning) {
|
|
36
|
+
UseSslPinning = {
|
|
37
|
+
setUseSSLPinning: (_usePinning: boolean) => {
|
|
38
|
+
return Promise.resolve();
|
|
39
|
+
},
|
|
40
|
+
getUseSSLPinning: () => {
|
|
41
|
+
return Promise.resolve(true);
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
23
45
|
|
|
24
46
|
/**
|
|
25
|
-
*
|
|
47
|
+
* Sets whether SSL pinning should be used.
|
|
26
48
|
*
|
|
27
|
-
* @
|
|
49
|
+
* @param {boolean} usePinning - Whether to enable SSL pinning
|
|
50
|
+
* @returns {Promise<void>} A promise that resolves when the setting is saved
|
|
28
51
|
*/
|
|
29
|
-
export const
|
|
30
|
-
return
|
|
52
|
+
export const setUseSSLPinning = (usePinning: boolean): Promise<void> => {
|
|
53
|
+
return UseSslPinning.setUseSSLPinning(usePinning);
|
|
31
54
|
};
|
|
32
55
|
|
|
33
56
|
/**
|
|
34
|
-
*
|
|
57
|
+
* Retrieves the current state of SSL pinning usage.
|
|
35
58
|
*
|
|
36
|
-
* @
|
|
37
|
-
* @returns {Promise<any>} A promise that resolves when the SSL pinning is initialized.
|
|
59
|
+
* @returns A promise that resolves to a boolean indicating whether SSL pinning is being used.
|
|
38
60
|
*/
|
|
39
|
-
export const
|
|
40
|
-
|
|
41
|
-
): Promise<any> => {
|
|
42
|
-
return await UseSslPinning.initializeSslPinning(configJsonString);
|
|
61
|
+
export const getUseSSLPinning = async (): Promise<boolean> => {
|
|
62
|
+
return await UseSslPinning.getUseSSLPinning();
|
|
43
63
|
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
package com.usesslpinning
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.util.Log
|
|
5
|
-
import com.facebook.react.modules.network.OkHttpClientFactory
|
|
6
|
-
import com.facebook.react.modules.network.ReactCookieJarContainer
|
|
7
|
-
import okhttp3.CertificatePinner
|
|
8
|
-
import okhttp3.OkHttpClient
|
|
9
|
-
import org.json.JSONObject
|
|
10
|
-
|
|
11
|
-
class UseSslPinningFactory(
|
|
12
|
-
private val context: Context,
|
|
13
|
-
private val configJsonString: String
|
|
14
|
-
) : OkHttpClientFactory {
|
|
15
|
-
|
|
16
|
-
override fun createNewNetworkModuleClient(): OkHttpClient {
|
|
17
|
-
val sharedPreferences = context.getSharedPreferences("AppSettings", Context.MODE_PRIVATE)
|
|
18
|
-
val useSSLPinning = sharedPreferences.getBoolean("useSSLPinning", true)
|
|
19
|
-
|
|
20
|
-
val clientBuilder = OkHttpClient.Builder().cookieJar(ReactCookieJarContainer()).apply {
|
|
21
|
-
if (useSSLPinning) {
|
|
22
|
-
val certificatePinnerBuilder = CertificatePinner.Builder()
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
val configJson = JSONObject(configJsonString)
|
|
26
|
-
addCertificatesToPinner(certificatePinnerBuilder, configJson)
|
|
27
|
-
val certificatePinner = certificatePinnerBuilder.build()
|
|
28
|
-
certificatePinner(certificatePinner)
|
|
29
|
-
} catch (e: Exception) {
|
|
30
|
-
e.printStackTrace()
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}.cache(null).build()
|
|
34
|
-
|
|
35
|
-
return clientBuilder
|
|
36
|
-
}
|
|
37
|
-
private fun addCertificatesToPinner(certificatePinnerBuilder: CertificatePinner.Builder, configJson: JSONObject) {
|
|
38
|
-
val sha256Keys = configJson.getJSONObject("sha256Keys")
|
|
39
|
-
val hostnames = sha256Keys.keys()
|
|
40
|
-
while (hostnames.hasNext()) {
|
|
41
|
-
val hostname = hostnames.next()
|
|
42
|
-
val keysArray = sha256Keys.getJSONArray(hostname)
|
|
43
|
-
for (i in 0 until keysArray.length()) {
|
|
44
|
-
val sha256Key = keysArray.getString(i)
|
|
45
|
-
certificatePinnerBuilder.add(hostname, sha256Key)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
package com.usesslpinning
|
|
2
|
-
|
|
3
|
-
import android.content.Context // Thêm dòng này
|
|
4
|
-
import android.util.Log
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
-
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
7
|
-
import com.facebook.react.bridge.ReactMethod
|
|
8
|
-
import com.facebook.react.bridge.Promise
|
|
9
|
-
import com.facebook.react.modules.network.OkHttpClientProvider
|
|
10
|
-
|
|
11
|
-
class UseSslPinningModule(reactContext: ReactApplicationContext) :
|
|
12
|
-
ReactContextBaseJavaModule(reactContext) {
|
|
13
|
-
|
|
14
|
-
override fun getName(): String {
|
|
15
|
-
return NAME
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@ReactMethod
|
|
19
|
-
fun setUseSSLPinning(usePinning: Boolean) {
|
|
20
|
-
val sharedPreferences = reactApplicationContext.getSharedPreferences("AppSettings", Context.MODE_PRIVATE)
|
|
21
|
-
sharedPreferences.edit().putBoolean("useSSLPinning", usePinning).apply()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@ReactMethod
|
|
25
|
-
fun getUseSSLPinning(promise: Promise) {
|
|
26
|
-
val sharedPreferences = reactApplicationContext.getSharedPreferences("AppSettings", Context.MODE_PRIVATE)
|
|
27
|
-
val usePinning = sharedPreferences.getBoolean("useSSLPinning", true)
|
|
28
|
-
promise.resolve(usePinning)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@ReactMethod
|
|
32
|
-
fun initializeSslPinning(configJsonString: String, promise: Promise) {
|
|
33
|
-
try {
|
|
34
|
-
OkHttpClientProvider.setOkHttpClientFactory(UseSslPinningFactory(reactApplicationContext, configJsonString))
|
|
35
|
-
Log.d("MyLibrary", "SSL Pinning initialized successfully")
|
|
36
|
-
promise.resolve("SSL Pinning initialized successfully")
|
|
37
|
-
} catch (e: Exception) {
|
|
38
|
-
promise.reject("SSL_PINNING_ERROR", "Failed to initialize SSL Pinning", e)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
companion object {
|
|
43
|
-
const val NAME = "UseSslPinning"
|
|
44
|
-
}
|
|
45
|
-
}
|