react-native-ssl-manager 1.0.1 → 1.0.2
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/app.plugin.js +293 -0
- package/package.json +2 -1
package/app.plugin.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
const {
|
|
2
|
+
withInfoPlist,
|
|
3
|
+
withDangerousMod,
|
|
4
|
+
withXcodeProject,
|
|
5
|
+
withAndroidManifest,
|
|
6
|
+
withMainApplication,
|
|
7
|
+
} = require('@expo/config-plugins');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Expo Config Plugin for react-native-ssl-manager
|
|
13
|
+
* Automatically configures SSL pinning for Expo projects
|
|
14
|
+
*/
|
|
15
|
+
function withSslManager(config, options = {}) {
|
|
16
|
+
const {
|
|
17
|
+
enableAndroid = true,
|
|
18
|
+
enableIOS = true,
|
|
19
|
+
sslConfigPath = 'ssl_config.json',
|
|
20
|
+
} = options;
|
|
21
|
+
|
|
22
|
+
// Add Android configuration
|
|
23
|
+
if (enableAndroid) {
|
|
24
|
+
config = withAndroidSslPinning(config);
|
|
25
|
+
config = withAndroidMainApplication(config);
|
|
26
|
+
config = withAndroidAssets(config, { sslConfigPath });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Add iOS configuration
|
|
30
|
+
if (enableIOS) {
|
|
31
|
+
config = withIOSSslPinning(config);
|
|
32
|
+
config = withIosAssets(config, { sslConfigPath });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return config;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Configure Android SSL pinning
|
|
40
|
+
*/
|
|
41
|
+
function withAndroidSslPinning(config) {
|
|
42
|
+
return withAndroidManifest(config, (config) => {
|
|
43
|
+
const manifest = config.modResults;
|
|
44
|
+
|
|
45
|
+
// Add required permissions
|
|
46
|
+
if (!manifest.manifest['uses-permission']) {
|
|
47
|
+
manifest.manifest['uses-permission'] = [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const permissions = Array.isArray(manifest.manifest['uses-permission'])
|
|
51
|
+
? manifest.manifest['uses-permission']
|
|
52
|
+
: [manifest.manifest['uses-permission']];
|
|
53
|
+
|
|
54
|
+
// Add INTERNET permission if not exists
|
|
55
|
+
if (
|
|
56
|
+
!permissions.find(
|
|
57
|
+
(p) => p.$['android:name'] === 'android.permission.INTERNET'
|
|
58
|
+
)
|
|
59
|
+
) {
|
|
60
|
+
permissions.push({
|
|
61
|
+
$: {
|
|
62
|
+
'android:name': 'android.permission.INTERNET',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
manifest.manifest['uses-permission'] = permissions;
|
|
68
|
+
return config;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Configure Android MainApplication - No longer needed as autolinking handles package registration
|
|
74
|
+
* Keeping function for backward compatibility but removing auto-registration to avoid duplicates
|
|
75
|
+
*/
|
|
76
|
+
function withAndroidMainApplication(config) {
|
|
77
|
+
// No longer auto-register package - let autolinking handle it
|
|
78
|
+
// This prevents duplicate module registration errors
|
|
79
|
+
return config;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Auto-copy SSL config to Android assets
|
|
84
|
+
*/
|
|
85
|
+
function withAndroidAssets(config, options) {
|
|
86
|
+
return withDangerousMod(config, [
|
|
87
|
+
'android',
|
|
88
|
+
async (config) => {
|
|
89
|
+
const { sslConfigPath = 'ssl_config.json' } = options;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
93
|
+
const sourceConfigPath = path.resolve(projectRoot, sslConfigPath);
|
|
94
|
+
|
|
95
|
+
if (fs.existsSync(sourceConfigPath)) {
|
|
96
|
+
const assetsDir = path.join(
|
|
97
|
+
config.modRequest.platformProjectRoot,
|
|
98
|
+
'app/src/main/assets'
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Create assets directory if it doesn't exist
|
|
102
|
+
if (!fs.existsSync(assetsDir)) {
|
|
103
|
+
fs.mkdirSync(assetsDir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Copy SSL config to assets
|
|
107
|
+
const targetPath = path.join(assetsDir, 'ssl_config.json');
|
|
108
|
+
fs.copyFileSync(sourceConfigPath, targetPath);
|
|
109
|
+
} else {
|
|
110
|
+
console.warn(`⚠️ SSL config file not found at: ${sourceConfigPath}`);
|
|
111
|
+
console.warn(
|
|
112
|
+
'💡 Place ssl_config.json in your project root for auto-setup'
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.warn('⚠️ Failed to auto-copy SSL config to assets:', error);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return config;
|
|
120
|
+
},
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Configure iOS SSL pinning - No Info.plist modification needed
|
|
126
|
+
* SSL pinning is handled by SharedLogic.swift at runtime
|
|
127
|
+
*/
|
|
128
|
+
function withIOSSslPinning(config) {
|
|
129
|
+
// No Info.plist modifications needed
|
|
130
|
+
// SSL pinning is initialized at runtime by SharedLogic.swift
|
|
131
|
+
|
|
132
|
+
return config;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Auto-copy SSL config to iOS bundle resources and add to Xcode project
|
|
137
|
+
*/
|
|
138
|
+
function withIosAssets(config, options) {
|
|
139
|
+
// First copy the file
|
|
140
|
+
config = withDangerousMod(config, [
|
|
141
|
+
'ios',
|
|
142
|
+
async (config) => {
|
|
143
|
+
const { sslConfigPath = 'ssl_config.json' } = options;
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
147
|
+
const sourceConfigPath = path.resolve(projectRoot, sslConfigPath);
|
|
148
|
+
|
|
149
|
+
if (fs.existsSync(sourceConfigPath)) {
|
|
150
|
+
// Create ios directory if it doesn't exist
|
|
151
|
+
const iosDir = path.join(projectRoot, 'ios');
|
|
152
|
+
if (!fs.existsSync(iosDir)) {
|
|
153
|
+
fs.mkdirSync(iosDir, { recursive: true });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Copy ssl_config.json to ios directory
|
|
157
|
+
const targetConfigPath = path.join(iosDir, 'ssl_config.json');
|
|
158
|
+
fs.copyFileSync(sourceConfigPath, targetConfigPath);
|
|
159
|
+
|
|
160
|
+
// Also copy to app bundle directory for Xcode project
|
|
161
|
+
const appBundleDir = path.join(iosDir, config.modRequest.projectName);
|
|
162
|
+
const appBundleConfigPath = path.join(
|
|
163
|
+
appBundleDir,
|
|
164
|
+
'ssl_config.json'
|
|
165
|
+
);
|
|
166
|
+
if (fs.existsSync(appBundleDir)) {
|
|
167
|
+
fs.copyFileSync(sourceConfigPath, appBundleConfigPath);
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
console.warn(`⚠️ SSL config file not found at: ${sourceConfigPath}`);
|
|
171
|
+
console.warn(
|
|
172
|
+
'💡 Place ssl_config.json in your project root for auto-setup'
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.warn('⚠️ Failed to copy SSL config:', error);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return config;
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
182
|
+
|
|
183
|
+
// Add to Xcode project programmatically - run in same withDangerousMod as file copy
|
|
184
|
+
config = withDangerousMod(config, [
|
|
185
|
+
'ios',
|
|
186
|
+
async (config) => {
|
|
187
|
+
// First ensure file is copied to app bundle directory
|
|
188
|
+
const projectName = config.modRequest.projectName || 'exampleexpo';
|
|
189
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
190
|
+
const sourceConfigPath = path.resolve(projectRoot, 'ssl_config.json');
|
|
191
|
+
const appBundleDir = path.join(
|
|
192
|
+
config.modRequest.platformProjectRoot,
|
|
193
|
+
projectName
|
|
194
|
+
);
|
|
195
|
+
const appBundleConfigPath = path.join(appBundleDir, 'ssl_config.json');
|
|
196
|
+
|
|
197
|
+
// Ensure SSL config is copied to app bundle directory
|
|
198
|
+
if (fs.existsSync(sourceConfigPath) && fs.existsSync(appBundleDir)) {
|
|
199
|
+
fs.copyFileSync(sourceConfigPath, appBundleConfigPath);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
const projectPath = path.join(
|
|
204
|
+
config.modRequest.platformProjectRoot,
|
|
205
|
+
`${projectName}.xcodeproj/project.pbxproj`
|
|
206
|
+
);
|
|
207
|
+
const sslConfigPath = appBundleConfigPath;
|
|
208
|
+
|
|
209
|
+
if (!fs.existsSync(projectPath) || !fs.existsSync(sslConfigPath)) {
|
|
210
|
+
console.warn(
|
|
211
|
+
'⚠️ Xcode project or SSL config not found, skipping automatic addition'
|
|
212
|
+
);
|
|
213
|
+
return config;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let projectContent = fs.readFileSync(projectPath, 'utf8');
|
|
217
|
+
|
|
218
|
+
// Check if already added
|
|
219
|
+
if (projectContent.includes('ssl_config.json')) {
|
|
220
|
+
return config;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Generate unique IDs for the file
|
|
224
|
+
const fileRefId =
|
|
225
|
+
'SSL' + Math.random().toString(36).substr(2, 24).toUpperCase();
|
|
226
|
+
const buildFileId =
|
|
227
|
+
'SSL' + Math.random().toString(36).substr(2, 24).toUpperCase();
|
|
228
|
+
|
|
229
|
+
// Add file reference
|
|
230
|
+
const fileRefEntry = `\t\t${fileRefId} /* ssl_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ssl_config.json; sourceTree = "<group>"; };`;
|
|
231
|
+
projectContent = projectContent.replace(
|
|
232
|
+
'/* End PBXFileReference section */',
|
|
233
|
+
fileRefEntry + '\n\t\t/* End PBXFileReference section */'
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
// Add build file
|
|
237
|
+
const buildFileEntry = `\t\t${buildFileId} /* ssl_config.json in Resources */ = {isa = PBXBuildFile; fileRef = ${fileRefId} /* ssl_config.json */; };`;
|
|
238
|
+
projectContent = projectContent.replace(
|
|
239
|
+
'/* End PBXBuildFile section */',
|
|
240
|
+
buildFileEntry + '\n\t\t/* End PBXBuildFile section */'
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
// Add to resources build phase
|
|
244
|
+
const resourcesPhaseMatch = projectContent.match(
|
|
245
|
+
/(\w+) \/\* Resources \*\/ = \{[^}]*files = \(([^)]*)\)/
|
|
246
|
+
);
|
|
247
|
+
if (resourcesPhaseMatch) {
|
|
248
|
+
const filesSection = resourcesPhaseMatch[2];
|
|
249
|
+
const newFilesSection =
|
|
250
|
+
filesSection +
|
|
251
|
+
`\t\t\t\t${buildFileId} /* ssl_config.json in Resources */,\n`;
|
|
252
|
+
projectContent = projectContent.replace(
|
|
253
|
+
`files = (${filesSection})`,
|
|
254
|
+
`files = (\n${newFilesSection}\t\t\t)`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Add to main group
|
|
259
|
+
const mainGroupMatch = projectContent.match(
|
|
260
|
+
new RegExp(
|
|
261
|
+
`(\\w+) /\\* ${projectName} \\*/ = \\{[^}]*children = \\(([^)]*)\\)`
|
|
262
|
+
)
|
|
263
|
+
);
|
|
264
|
+
if (mainGroupMatch) {
|
|
265
|
+
const childrenSection = mainGroupMatch[2];
|
|
266
|
+
const newChildrenSection =
|
|
267
|
+
childrenSection + `\t\t\t\t${fileRefId} /* ssl_config.json */,\n`;
|
|
268
|
+
projectContent = projectContent.replace(
|
|
269
|
+
`children = (${childrenSection})`,
|
|
270
|
+
`children = (\n${newChildrenSection}\t\t\t)`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Write back to file
|
|
275
|
+
fs.writeFileSync(projectPath, projectContent);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.warn(
|
|
278
|
+
'⚠️ Failed to add SSL config to Xcode project:',
|
|
279
|
+
error.message
|
|
280
|
+
);
|
|
281
|
+
console.warn(
|
|
282
|
+
'💡 File copied to ios/ directory, manual Xcode setup may be needed'
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return config;
|
|
287
|
+
},
|
|
288
|
+
]);
|
|
289
|
+
|
|
290
|
+
return config;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
module.exports = withSslManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-ssl-manager",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
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
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"android",
|
|
30
30
|
"ios",
|
|
31
31
|
"plugin",
|
|
32
|
+
"app.plugin.js",
|
|
32
33
|
"*.podspec",
|
|
33
34
|
"react-native-ssl-manager.podspec",
|
|
34
35
|
"expo-module.config.json",
|