react-native-wireguard-vpn-patched 1.0.22-patch.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.
@@ -0,0 +1,5 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ @interface WireGuardVpn : RCTEventEmitter <RCTBridgeModule>
5
+ @end
@@ -0,0 +1,294 @@
1
+ #import "WireGuardVpn.h"
2
+ #import <NetworkExtension/NetworkExtension.h>
3
+
4
+ @implementation WireGuardVpn {
5
+ id _neStatusObserver;
6
+ }
7
+
8
+ RCT_EXPORT_MODULE(WireGuardVpnModule)
9
+
10
+ - (NSArray<NSString *> *)supportedEvents
11
+ {
12
+ return @[@"vpnStateChanged"];
13
+ }
14
+
15
+ // RN will call these when JS starts/stops listening to events.
16
+ - (void)startObserving
17
+ {
18
+ if (_neStatusObserver != nil) return;
19
+
20
+ __weak typeof(self) weakSelf = self;
21
+ _neStatusObserver = [[NSNotificationCenter defaultCenter]
22
+ addObserverForName:NEVPNStatusDidChangeNotification
23
+ object:nil
24
+ queue:[NSOperationQueue mainQueue]
25
+ usingBlock:^(NSNotification * _Nonnull note) {
26
+ [weakSelf emitVpnStateChanged];
27
+ }];
28
+ }
29
+
30
+ - (void)stopObserving
31
+ {
32
+ if (_neStatusObserver == nil) return;
33
+ [[NSNotificationCenter defaultCenter] removeObserver:_neStatusObserver];
34
+ _neStatusObserver = nil;
35
+ }
36
+
37
+ - (void)emitVpnStateChanged
38
+ {
39
+ if (![self hasListeners]) return;
40
+
41
+ NSString *providerBundleIdentifier = @"com.wireguardvpn.tunnel";
42
+ [NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
43
+ if (error || managers == nil) return;
44
+
45
+ NETunnelProviderManager *manager = nil;
46
+ for (NETunnelProviderManager *m in managers) {
47
+ if (![m.protocolConfiguration isKindOfClass:[NETunnelProviderProtocol class]]) continue;
48
+ NETunnelProviderProtocol *p = (NETunnelProviderProtocol *)m.protocolConfiguration;
49
+ if ([p.providerBundleIdentifier isEqualToString:providerBundleIdentifier]) {
50
+ manager = m;
51
+ break;
52
+ }
53
+ }
54
+
55
+ if (!manager) return;
56
+
57
+ NEVPNStatus status = manager.connection.status;
58
+ NSString *tunnelState = [self stringFromVPNStatus:status];
59
+
60
+ NSString *simpleStatus = nil;
61
+ if (status == NEVPNStatusConnected) simpleStatus = @"CONNECTED";
62
+ else if (status == NEVPNStatusDisconnected) simpleStatus = @"DISCONNECTED";
63
+ else if (status == NEVPNStatusConnecting) simpleStatus = @"CONNECTING";
64
+ else if (status == NEVPNStatusDisconnecting) simpleStatus = @"DISCONNECTING";
65
+ else if (status == NEVPNStatusInvalid) simpleStatus = @"ERROR";
66
+ else simpleStatus = @"UNKNOWN";
67
+
68
+ NSDictionary *body = @{
69
+ @"isConnected": @((status == NEVPNStatusConnected) ? YES : NO),
70
+ @"tunnelState": tunnelState ?: @"UNKNOWN",
71
+ @"status": simpleStatus ?: @"UNKNOWN"
72
+ };
73
+
74
+ [self sendEventWithName:@"vpnStateChanged" body:body];
75
+ }];
76
+ }
77
+
78
+ RCT_EXPORT_METHOD(initialize:(RCTPromiseResolveBlock)resolve
79
+ rejecter:(RCTPromiseRejectBlock)reject)
80
+ {
81
+ [NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
82
+ if (error) {
83
+ reject(@"INIT_ERROR", error.localizedDescription, error);
84
+ return;
85
+ }
86
+
87
+ NETunnelProviderManager *manager = managers.firstObject ?: [[NETunnelProviderManager alloc] init];
88
+ manager.localizedDescription = @"WireGuard VPN";
89
+ manager.protocolConfiguration = [[NETunnelProviderProtocol alloc] init];
90
+
91
+ [manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
92
+ if (error) {
93
+ reject(@"INIT_ERROR", error.localizedDescription, error);
94
+ return;
95
+ }
96
+ resolve(nil);
97
+ }];
98
+ }];
99
+ }
100
+
101
+ RCT_EXPORT_METHOD(connect:(NSDictionary *)config
102
+ resolver:(RCTPromiseResolveBlock)resolve
103
+ rejecter:(RCTPromiseRejectBlock)reject)
104
+ {
105
+ // Validate required config early for clearer errors.
106
+ NSString *serverAddress = config[@"serverAddress"];
107
+ id serverPort = config[@"serverPort"];
108
+ NSString *privateKey = config[@"privateKey"];
109
+ NSString *publicKey = config[@"publicKey"];
110
+ id allowedIPs = config[@"allowedIPs"];
111
+
112
+ BOOL hasRequired =
113
+ (serverAddress && ![serverAddress isKindOfClass:[NSNull class]]) &&
114
+ (privateKey && ![privateKey isKindOfClass:[NSNull class]]) &&
115
+ (publicKey && ![publicKey isKindOfClass:[NSNull class]]) &&
116
+ serverPort &&
117
+ (allowedIPs && [allowedIPs isKindOfClass:[NSArray class]] && [(NSArray *)allowedIPs count] > 0);
118
+
119
+ if (!hasRequired) {
120
+ reject(@"CONNECT_ERROR",
121
+ @"Missing required config: serverAddress, serverPort, privateKey, publicKey, allowedIPs (non-empty array)",
122
+ nil);
123
+ return;
124
+ }
125
+
126
+ [NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
127
+ if (error) {
128
+ reject(@"CONNECT_ERROR", error.localizedDescription, error);
129
+ return;
130
+ }
131
+
132
+ NSString *providerBundleIdentifier = @"com.wireguardvpn.tunnel";
133
+
134
+ // Pick the correct NETunnelProviderManager (do not assume firstObject).
135
+ NETunnelProviderManager *manager = nil;
136
+ for (NETunnelProviderManager *m in managers) {
137
+ if (![m.protocolConfiguration isKindOfClass:[NETunnelProviderProtocol class]]) {
138
+ continue;
139
+ }
140
+ NETunnelProviderProtocol *p = (NETunnelProviderProtocol *)m.protocolConfiguration;
141
+ if ([p.providerBundleIdentifier isEqualToString:providerBundleIdentifier]) {
142
+ manager = m;
143
+ break;
144
+ }
145
+ }
146
+ if (!manager) {
147
+ manager = [[NETunnelProviderManager alloc] init];
148
+ }
149
+
150
+ manager.enabled = YES;
151
+
152
+ NETunnelProviderProtocol *protocol = nil;
153
+ if ([manager.protocolConfiguration isKindOfClass:[NETunnelProviderProtocol class]]) {
154
+ protocol = (NETunnelProviderProtocol *)manager.protocolConfiguration;
155
+ } else {
156
+ protocol = [[NETunnelProviderProtocol alloc] init];
157
+ }
158
+
159
+ protocol.serverAddress = config[@"serverAddress"];
160
+ protocol.providerBundleIdentifier = providerBundleIdentifier;
161
+
162
+ NSMutableDictionary *tunnelConfig = [NSMutableDictionary dictionary];
163
+ tunnelConfig[@"privateKey"] = config[@"privateKey"];
164
+ tunnelConfig[@"publicKey"] = config[@"publicKey"];
165
+ tunnelConfig[@"serverPort"] = config[@"serverPort"];
166
+ tunnelConfig[@"allowedIPs"] = config[@"allowedIPs"];
167
+ tunnelConfig[@"dns"] = config[@"dns"];
168
+ tunnelConfig[@"mtu"] = config[@"mtu"];
169
+
170
+ protocol.providerConfiguration = tunnelConfig;
171
+
172
+ manager.protocolConfiguration = protocol;
173
+
174
+ [manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
175
+ if (error) {
176
+ reject(@"CONNECT_ERROR", error.localizedDescription, error);
177
+ return;
178
+ }
179
+
180
+ NSError *startError;
181
+ [manager.connection startVPNTunnelAndReturnError:&startError];
182
+
183
+ if (startError) {
184
+ reject(@"CONNECT_ERROR", startError.localizedDescription, startError);
185
+ return;
186
+ }
187
+
188
+ resolve(nil);
189
+ }];
190
+ }];
191
+ }
192
+
193
+ RCT_EXPORT_METHOD(disconnect:(RCTPromiseResolveBlock)resolve
194
+ rejecter:(RCTPromiseRejectBlock)reject)
195
+ {
196
+ [NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
197
+ if (error) {
198
+ reject(@"DISCONNECT_ERROR", error.localizedDescription, error);
199
+ return;
200
+ }
201
+
202
+ NSString *providerBundleIdentifier = @"com.wireguardvpn.tunnel";
203
+ NETunnelProviderManager *manager = nil;
204
+ for (NETunnelProviderManager *m in managers) {
205
+ if (![m.protocolConfiguration isKindOfClass:[NETunnelProviderProtocol class]]) continue;
206
+ NETunnelProviderProtocol *p = (NETunnelProviderProtocol *)m.protocolConfiguration;
207
+ if ([p.providerBundleIdentifier isEqualToString:providerBundleIdentifier]) {
208
+ manager = m;
209
+ break;
210
+ }
211
+ }
212
+
213
+ if (!manager) {
214
+ resolve(nil);
215
+ return;
216
+ }
217
+
218
+ [manager.connection stopVPNTunnel];
219
+ resolve(nil);
220
+ }];
221
+ }
222
+
223
+ RCT_EXPORT_METHOD(getStatus:(RCTPromiseResolveBlock)resolve
224
+ rejecter:(RCTPromiseRejectBlock)reject)
225
+ {
226
+ [NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
227
+ if (error) {
228
+ reject(@"STATUS_ERROR", error.localizedDescription, error);
229
+ return;
230
+ }
231
+
232
+ NSString *providerBundleIdentifier = @"com.wireguardvpn.tunnel";
233
+ NETunnelProviderManager *manager = nil;
234
+ for (NETunnelProviderManager *m in managers) {
235
+ if (![m.protocolConfiguration isKindOfClass:[NETunnelProviderProtocol class]]) continue;
236
+ NETunnelProviderProtocol *p = (NETunnelProviderProtocol *)m.protocolConfiguration;
237
+ if ([p.providerBundleIdentifier isEqualToString:providerBundleIdentifier]) {
238
+ manager = m;
239
+ break;
240
+ }
241
+ }
242
+
243
+ if (!manager) {
244
+ resolve(@{
245
+ @"isConnected": @NO,
246
+ @"tunnelState": @"INACTIVE",
247
+ @"status": @"DISCONNECTED",
248
+ });
249
+ return;
250
+ }
251
+
252
+ NEVPNStatus status = manager.connection.status;
253
+ NSString *tunnelState = [self stringFromVPNStatus:status];
254
+ NSString *simpleStatus = nil;
255
+ if (status == NEVPNStatusConnected) simpleStatus = @"CONNECTED";
256
+ else if (status == NEVPNStatusDisconnected) simpleStatus = @"DISCONNECTED";
257
+ else if (status == NEVPNStatusConnecting) simpleStatus = @"CONNECTING";
258
+ else if (status == NEVPNStatusDisconnecting) simpleStatus = @"DISCONNECTING";
259
+ else if (status == NEVPNStatusInvalid) simpleStatus = @"ERROR";
260
+ else simpleStatus = @"UNKNOWN";
261
+
262
+ resolve(@{
263
+ @"isConnected": @(status == NEVPNStatusConnected),
264
+ @"tunnelState": tunnelState,
265
+ @"status": simpleStatus
266
+ });
267
+ }];
268
+ }
269
+
270
+ RCT_EXPORT_METHOD(isSupported:(RCTPromiseResolveBlock)resolve
271
+ rejecter:(RCTPromiseRejectBlock)reject)
272
+ {
273
+ resolve(@YES);
274
+ }
275
+
276
+ - (NSString *)stringFromVPNStatus:(NEVPNStatus)status
277
+ {
278
+ switch (status) {
279
+ case NEVPNStatusConnected:
280
+ return @"ACTIVE";
281
+ case NEVPNStatusConnecting:
282
+ return @"CONNECTING";
283
+ case NEVPNStatusDisconnecting:
284
+ return @"DISCONNECTING";
285
+ case NEVPNStatusDisconnected:
286
+ return @"INACTIVE";
287
+ case NEVPNStatusInvalid:
288
+ return @"ERROR";
289
+ default:
290
+ return @"UNKNOWN";
291
+ }
292
+ }
293
+
294
+ @end
package/lib/index.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ export interface WireGuardConfig {
2
+ privateKey: string;
3
+ publicKey: string;
4
+ serverAddress: string;
5
+ serverPort: number;
6
+ /** Interface address(es), e.g. "10.64.0.1/32". If omitted, defaults to 10.64.0.1/32. Do not use 0.0.0.0/0 or ::/0 here (use allowedIPs for routing). */
7
+ address?: string | string[];
8
+ allowedIPs: string[];
9
+ dns?: string[];
10
+ mtu?: number;
11
+ presharedKey?: string;
12
+ /**
13
+ * Split tunneling — Android only.
14
+ * Package names of apps whose traffic should bypass the VPN tunnel.
15
+ * Example: ["com.google.android.apps.maps", "com.example.bankingapp"]
16
+ */
17
+ excludedApps?: string[];
18
+ }
19
+ export interface WireGuardStatus {
20
+ isConnected: boolean;
21
+ tunnelState: 'ACTIVE' | 'INACTIVE' | 'CONNECTING' | 'DISCONNECTING' | 'ERROR' | 'UNKNOWN';
22
+ /**
23
+ * Connection status as a simpler string for app UI logic.
24
+ * - CONNECTED when tunnel is up
25
+ * - DISCONNECTED when tunnel is down
26
+ * - CONNECTING/DISCONNECTING/ERROR/UNKNOWN for intermediate states
27
+ */
28
+ status: 'CONNECTED' | 'DISCONNECTED' | 'CONNECTING' | 'DISCONNECTING' | 'ERROR' | 'UNKNOWN';
29
+ error?: string;
30
+ }
31
+ declare const _default: {
32
+ /**
33
+ * Initialize the VPN service
34
+ */
35
+ initialize(): Promise<void>;
36
+ /**
37
+ * Connect to VPN using provided configuration
38
+ */
39
+ connect(config: WireGuardConfig): Promise<void>;
40
+ /**
41
+ * Disconnect from VPN
42
+ */
43
+ disconnect(): Promise<void>;
44
+ /**
45
+ * Get current VPN status
46
+ */
47
+ getStatus(): Promise<WireGuardStatus>;
48
+ /**
49
+ * Check if VPN is supported on the device
50
+ */
51
+ isSupported(): Promise<boolean>;
52
+ };
53
+ export default _default;
package/lib/index.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const react_native_1 = require("react-native");
4
+ const LINKING_ERROR = `The package 'react-native-wireguard-vpn-patched' doesn't seem to be linked. Make sure: \n\n` +
5
+ react_native_1.Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
6
+ '- You rebuilt the app after installing the package\n' +
7
+ '- You are not using Expo Go\n';
8
+ const WireGuardVpnModule = react_native_1.NativeModules.WireGuardVpnModule
9
+ ? react_native_1.NativeModules.WireGuardVpnModule
10
+ : new Proxy({}, {
11
+ get() {
12
+ throw new Error(LINKING_ERROR);
13
+ },
14
+ });
15
+ exports.default = {
16
+ /**
17
+ * Initialize the VPN service
18
+ */
19
+ initialize() {
20
+ return WireGuardVpnModule.initialize();
21
+ },
22
+ /**
23
+ * Connect to VPN using provided configuration
24
+ */
25
+ connect(config) {
26
+ return WireGuardVpnModule.connect(config);
27
+ },
28
+ /**
29
+ * Disconnect from VPN
30
+ */
31
+ disconnect() {
32
+ return WireGuardVpnModule.disconnect();
33
+ },
34
+ /**
35
+ * Get current VPN status
36
+ */
37
+ getStatus() {
38
+ return WireGuardVpnModule.getStatus();
39
+ },
40
+ /**
41
+ * Check if VPN is supported on the device
42
+ */
43
+ isSupported() {
44
+ return WireGuardVpnModule.isSupported();
45
+ },
46
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,+CAAuD;AAEvD,MAAM,aAAa,GACjB,qFAAqF;IACrF,uBAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,gCAAgC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvE,sDAAsD;IACtD,+BAA+B,CAAC;AAElC,MAAM,kBAAkB,GAAG,4BAAa,CAAC,kBAAkB;IACzD,CAAC,CAAC,4BAAa,CAAC,kBAAkB;IAClC,CAAC,CAAC,IAAI,KAAK,CACP,EAAE,EACF;QACE,GAAG;YACD,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;QACjC,CAAC;KACF,CACF,CAAC;AAwCN,kBAAe;IACb;;OAEG;IACH,UAAU;QACR,OAAO,kBAAkB,CAAC,UAAU,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,MAAuB;QAC7B,OAAO,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,kBAAkB,CAAC,UAAU,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,kBAAkB,CAAC,SAAS,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,kBAAkB,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;CACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "react-native-wireguard-vpn-patched",
3
+ "version": "1.0.22-patch.2",
4
+ "description": "Production-ready React Native WireGuard VPN module with Android VPN permission handling and split tunneling support. Forked from react-native-wireguard-vpn v1.0.22.",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "files": [
8
+ "src",
9
+ "lib",
10
+ "android/build.gradle",
11
+ "android/src",
12
+ "ios",
13
+ "plugin",
14
+ "app.plugin.js",
15
+ "react-native-wireguard-vpn-patched.podspec"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "prepare": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "react-native",
23
+ "wireguard",
24
+ "vpn",
25
+ "android",
26
+ "ios",
27
+ "split-tunneling",
28
+ "kill-switch",
29
+ "tunnel",
30
+ "wireguard-vpn"
31
+ ],
32
+ "author": {
33
+ "name": "Abdul Ahad",
34
+ "email": "ahad06074@gmail.com",
35
+ "url": "https://github.com/AbdulAHAD968"
36
+ },
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/AbdulAHAD968/react-native-wireguard-vpn-patched.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/AbdulAHAD968/react-native-wireguard-vpn-patched/issues"
44
+ },
45
+ "homepage": "https://github.com/AbdulAHAD968/react-native-wireguard-vpn-patched#readme",
46
+ "peerDependencies": {
47
+ "react": ">=18.2.0",
48
+ "react-native": ">=0.72.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/react": "^18.0.0",
52
+ "react": "18.2.0",
53
+ "react-native": "0.72.17",
54
+ "typescript": "^5.0.0"
55
+ }
56
+ }
@@ -0,0 +1,105 @@
1
+ // Expo config plugin that updates iOS Info.plist + entitlements for Network Extension.
2
+ // This does NOT create the Packet Tunnel extension target; that still must be created in Xcode.
3
+
4
+ const getConfigPlugins = () => {
5
+ // Prefer expo's re-export first, but support older setups.
6
+ try {
7
+ return require('expo/config-plugins');
8
+ } catch (e) {
9
+ return require('@expo/config-plugins');
10
+ }
11
+ };
12
+
13
+ const configPlugins = getConfigPlugins();
14
+ const { withInfoPlist, withEntitlementsPlist, withAndroidManifest } = configPlugins;
15
+
16
+ /**
17
+ * @type {(config: import('@expo/config-plugins').ConfigPluginProps) => any}
18
+ */
19
+ function withWireGuardVpn(config) {
20
+ // 1) iOS Info.plist
21
+ config = withInfoPlist(config, (cfg) => {
22
+ cfg.modResults.NSLocalNetworkUsageDescription =
23
+ cfg.modResults.NSLocalNetworkUsageDescription ||
24
+ 'This app requires access to network features for VPN functionality';
25
+
26
+ const existingModes = cfg.modResults.UIBackgroundModes;
27
+ const modes = Array.isArray(existingModes) ? existingModes.slice() : [];
28
+
29
+ if (!modes.includes('network-authentication')) modes.push('network-authentication');
30
+ if (!modes.includes('network')) modes.push('network');
31
+
32
+ cfg.modResults.UIBackgroundModes = modes;
33
+ return cfg;
34
+ });
35
+
36
+ // 2) iOS entitlements (.entitlements plist)
37
+ config = withEntitlementsPlist(config, (cfg) => {
38
+ const entitlements = cfg.modResults || {};
39
+ const key = 'com.apple.developer.networking.networkextension';
40
+
41
+ const current = entitlements[key];
42
+ const values = Array.isArray(current)
43
+ ? current.slice()
44
+ : current
45
+ ? [current]
46
+ : [];
47
+
48
+ // This entitlement is required for NEPacketTunnelProvider.
49
+ // If your app/provisioning already contains it, this won't duplicate values.
50
+ if (!values.includes('packet-tunnel-provider')) values.push('packet-tunnel-provider');
51
+
52
+ entitlements[key] = values;
53
+ cfg.modResults = entitlements;
54
+ return cfg;
55
+ });
56
+
57
+ // 3) Android: ensure required VPN permissions exist in the app manifest.
58
+ // RN autolinking usually merges the library manifest automatically, but for Expo/prebuild
59
+ // we add them defensively to prevent "missing permission" issues.
60
+ config = withAndroidManifest(config, (cfg) => {
61
+ const manifest = cfg.modResults.manifest;
62
+ if (!manifest) return cfg;
63
+
64
+ const perms = Array.isArray(manifest['uses-permission'])
65
+ ? manifest['uses-permission']
66
+ : [];
67
+
68
+ const ensurePermission = (name) => {
69
+ const exists = perms.some(
70
+ (p) => p && p.$ && p.$['android:name'] && p.$['android:name'] === name
71
+ );
72
+ if (!exists) {
73
+ perms.push({ $: { 'android:name': name } });
74
+ }
75
+ };
76
+
77
+ ensurePermission('android.permission.INTERNET');
78
+ ensurePermission('android.permission.FOREGROUND_SERVICE');
79
+ ensurePermission('android.permission.BIND_VPN_SERVICE');
80
+
81
+ manifest['uses-permission'] = perms;
82
+
83
+ // networkSecurityConfig reference: only set if it doesn't exist yet.
84
+ try {
85
+ const application = Array.isArray(manifest.application)
86
+ ? manifest.application[0]
87
+ : manifest.application;
88
+ if (application && application.$) {
89
+ const existing = application.$['android:networkSecurityConfig'];
90
+ if (!existing) {
91
+ application.$['android:networkSecurityConfig'] = '@xml/network_security_config';
92
+ }
93
+ }
94
+ } catch (e) {
95
+ // ignore; manifest structure can vary across Expo/RN versions
96
+ }
97
+
98
+ return cfg;
99
+ });
100
+
101
+ return config;
102
+ }
103
+
104
+ module.exports = withWireGuardVpn;
105
+
@@ -0,0 +1,21 @@
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-wireguard-vpn-patched"
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.description = package['description']
10
+ s.homepage = package['homepage']
11
+ s.license = package['license']
12
+ s.authors = package['author']
13
+ s.platforms = { :ios => "12.0" }
14
+ git_url = package['repository']['url'].to_s.gsub(/^git\+/, '').gsub(/\.git$/, '')
15
+ s.source = { :git => git_url, :tag => "v#{s.version}" }
16
+ s.source_files = "ios/**/*.{h,m,mm}"
17
+ s.requires_arc = true
18
+ s.dependency "React-Core"
19
+ s.frameworks = "NetworkExtension"
20
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
21
+ end
package/src/index.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ declare module 'react-native-wireguard-vpn' {
2
+ export interface WireGuardConfig {
3
+ privateKey: string;
4
+ publicKey: string;
5
+ serverAddress: string;
6
+ serverPort: number;
7
+ /** Interface address(es), e.g. "10.64.0.1/32". Optional; defaults to 10.64.0.1/32. Do not use 0.0.0.0/0 or ::/0 here. */
8
+ address?: string | string[];
9
+ allowedIPs: string[];
10
+ dns?: string[];
11
+ mtu?: number;
12
+ presharedKey?: string;
13
+ }
14
+
15
+ export interface WireGuardStatus {
16
+ isConnected: boolean;
17
+ tunnelState:
18
+ | 'ACTIVE'
19
+ | 'INACTIVE'
20
+ | 'CONNECTING'
21
+ | 'DISCONNECTING'
22
+ | 'ERROR'
23
+ | 'UNKNOWN';
24
+ status:
25
+ | 'CONNECTED'
26
+ | 'DISCONNECTED'
27
+ | 'CONNECTING'
28
+ | 'DISCONNECTING'
29
+ | 'ERROR'
30
+ | 'UNKNOWN';
31
+ error?: string;
32
+ }
33
+
34
+ export const WireGuardVpnModule: {
35
+ initialize(): Promise<void>;
36
+ connect(config: WireGuardConfig): Promise<void>;
37
+ disconnect(): Promise<void>;
38
+ getStatus(): Promise<WireGuardStatus>;
39
+ isSupported(): Promise<boolean>;
40
+ };
41
+ }