Skip to content

Commit 0dcb389

Browse files
Merge branch 'dev' into release
# Conflicts: # pubspec.yaml
2 parents 94b7215 + 21e1f5c commit 0dcb389

59 files changed

Lines changed: 2397 additions & 2459 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

android/app/src/main/kotlin/com/defyx/defyx/MainActivity.kt

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.flutter.embedding.engine.FlutterEngine
1616
import io.flutter.plugin.common.EventChannel
1717
import io.flutter.plugin.common.MethodCall
1818
import io.flutter.plugin.common.MethodChannel
19+
import java.io.File
1920
import java.net.*
2021
import kotlinx.coroutines.*
2122

@@ -94,6 +95,9 @@ class MainActivity : FlutterActivity() {
9495
"setTimezone" -> setTimezone(call.arguments as? Map<String, Any>, result)
9596
"getFlowLine" -> getFlowLine(call.arguments as? Map<String, Any>, result)
9697
"getCachedFlowLine" -> getCachedFlowLine(result)
98+
"decodeAndVerifyFlowline" -> decodeAndVerifyFlowline(call.arguments as? Map<String, Any>, result)
99+
"setCacheDir" -> setCacheDir(call.arguments as? Map<String, Any>, result)
100+
"getSharedDirectory" -> result.success("${cacheDir.absolutePath}/defyx")
97101
"setConnectionMethod" ->
98102
setConnectionMethod(call.arguments as? Map<String, Any>, result)
99103
else -> result.notImplemented()
@@ -236,8 +240,13 @@ class MainActivity : FlutterActivity() {
236240
}
237241
return@launch
238242
}
243+
val vpnCacheDir = "${cacheDir.absolutePath}/defyx"
244+
val cacheDirectory = File(vpnCacheDir)
245+
if (!cacheDirectory.exists()) {
246+
cacheDirectory.mkdirs()
247+
}
239248
DefyxVpnService.getInstance()
240-
.connectVPN(cacheDir.absolutePath, flowLine, pattern, boolDeepScan)
249+
.connectVPN(vpnCacheDir, flowLine, pattern, boolDeepScan)
241250
result.success(true)
242251
} catch (e: Exception) {
243252
Log.e("Start VPN", "Start VPN failed: ${e.message}", e)
@@ -348,6 +357,32 @@ class MainActivity : FlutterActivity() {
348357
}
349358
}
350359
}
360+
361+
private fun decodeAndVerifyFlowline(args: Map<String, Any>?, result: MethodChannel.Result) {
362+
CoroutineScope(Dispatchers.IO).launch {
363+
try {
364+
val flowLine = args?.get("flowLine") as? String
365+
if (flowLine.isNullOrEmpty()) {
366+
withContext(Dispatchers.Main) {
367+
result.error("INVALID_ARGUMENT", "flowLine is missing or empty", null)
368+
}
369+
return@launch
370+
}
371+
val decodedFlowLine = DefyxVpnService.getInstance().decodeAndVerifyFlowline(flowLine)
372+
result.success(decodedFlowLine)
373+
} catch (e: Exception) {
374+
Log.e("Decode And Verify Flowline", "Decode And Verify Flowline failed: ${e.message}", e)
375+
withContext(Dispatchers.Main) {
376+
result.error(
377+
"DECODE_VERIFY_FLOWLINE_ERROR",
378+
"Failed to decode and verify flowline",
379+
e.localizedMessage
380+
)
381+
}
382+
}
383+
}
384+
}
385+
351386
private fun setConnectionMethod(args: Map<String, Any>?, result: MethodChannel.Result) {
352387
CoroutineScope(Dispatchers.IO).launch {
353388
try {
@@ -372,6 +407,31 @@ class MainActivity : FlutterActivity() {
372407
}
373408
}
374409
}
410+
411+
private fun setCacheDir(args: Map<String, Any>?, result: MethodChannel.Result) {
412+
CoroutineScope(Dispatchers.IO).launch {
413+
try {
414+
val cacheDir = args?.get("cacheDir") as? String
415+
if (cacheDir.isNullOrEmpty()) {
416+
withContext(Dispatchers.Main) {
417+
result.error("INVALID_ARGUMENT", "cacheDir is missing or empty", null)
418+
}
419+
return@launch
420+
}
421+
DefyxVpnService.getInstance().setCacheDir(cacheDir)
422+
result.success(true)
423+
} catch (e: Exception) {
424+
Log.e("Set Cache Dir", "Set Cache Dir failed: ${e.message}", e)
425+
withContext(Dispatchers.Main) {
426+
result.error(
427+
"SET_CACHE_DIR_ERROR",
428+
"Failed to Set Cache Dir",
429+
e.localizedMessage
430+
)
431+
}
432+
}
433+
}
434+
}
375435
}
376436

377437
class ProgressStreamHandler : EventChannel.StreamHandler, ProgressListener {

android/app/src/main/kotlin/com/defyx/defyx/VpnService.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import android.os.ParcelFileDescriptor
1111
import android.util.Log
1212
import androidx.core.app.NotificationCompat
1313
import androidx.core.content.edit
14+
import java.io.File
1415
import kotlinx.coroutines.*
1516

1617
class DefyxVpnService : VpnService() {
@@ -342,6 +343,15 @@ class DefyxVpnService : VpnService() {
342343
}
343344
}
344345

346+
fun decodeAndVerifyFlowline(flowLine: String): String {
347+
return try {
348+
Android.decodeAndVerifyFlowline(flowLine)
349+
} catch (e: Exception) {
350+
log("Decode and Verify Flowline failed: ${e.message}")
351+
""
352+
}
353+
}
354+
345355
fun log(message: String) {
346356
try {
347357
Android.log(message)
@@ -372,4 +382,16 @@ class DefyxVpnService : VpnService() {
372382
fun setConnectionMethod(method: String) {
373383
connectionMethod = method
374384
}
385+
386+
fun setCacheDir(cacheDir: String) {
387+
try {
388+
val directory = File(cacheDir)
389+
if (!directory.exists()) {
390+
directory.mkdirs()
391+
}
392+
Android.setCacheDir(cacheDir)
393+
} catch (e: Exception) {
394+
log("Set Cache Dir failed: ${e.message}")
395+
}
396+
}
375397
}

assets/icons/Icon_Import_API.svg

Lines changed: 15 additions & 0 deletions
Loading

assets/icons/vpn_cloud.svg

Lines changed: 12 additions & 0 deletions
Loading

ios/PacketTunnel/PacketTunnelProvider.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,45 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
264264
completionHandler?(nil)
265265
}
266266

267+
case "DECODE_VERIFY_FLOWLINE":
268+
do {
269+
let flowLine = dict["flowLine"] ?? ""
270+
let decodedFlowLine = IosDecodeAndVerifyFlowline(flowLine)
271+
let response: String = decodedFlowLine
272+
273+
if let data = response.data(using: .utf8) {
274+
completionHandler?(data)
275+
} else {
276+
throw NSError(
277+
domain: "EncodingError",
278+
code: -1,
279+
userInfo: [NSLocalizedDescriptionKey: "Failed to encode response to UTF-8"]
280+
)
281+
}
282+
} catch {
283+
print("Error: \(error.localizedDescription)")
284+
completionHandler?(nil)
285+
}
286+
287+
case "SET_CACHE_DIR":
288+
do {
289+
let cacheDir = dict["cacheDir"] ?? ""
290+
IosSetCacheDir(cacheDir)
291+
292+
if let data = "true".data(using: .utf8) {
293+
completionHandler?(data)
294+
} else {
295+
throw NSError(
296+
domain: "EncodingError",
297+
code: -1,
298+
userInfo: [NSLocalizedDescriptionKey: "Failed to encode response to UTF-8"]
299+
)
300+
}
301+
} catch {
302+
print("Error: \(error.localizedDescription)")
303+
completionHandler?(nil)
304+
}
305+
267306
default:
268307
os_log("⚠️ Unknown command received.")
269308
completionHandler?(nil)

ios/Podfile.lock

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
PODS:
2+
- app_tracking_transparency (0.0.1):
3+
- Flutter
24
- audioplayers_darwin (0.0.1):
35
- Flutter
46
- FlutterMacOS
@@ -8,6 +10,40 @@ PODS:
810
- Flutter
911
- device_info_plus (0.0.1):
1012
- Flutter
13+
- DKImagePickerController/Core (4.3.9):
14+
- DKImagePickerController/ImageDataManager
15+
- DKImagePickerController/Resource
16+
- DKImagePickerController/ImageDataManager (4.3.9)
17+
- DKImagePickerController/PhotoGallery (4.3.9):
18+
- DKImagePickerController/Core
19+
- DKPhotoGallery
20+
- DKImagePickerController/Resource (4.3.9)
21+
- DKPhotoGallery (0.0.19):
22+
- DKPhotoGallery/Core (= 0.0.19)
23+
- DKPhotoGallery/Model (= 0.0.19)
24+
- DKPhotoGallery/Preview (= 0.0.19)
25+
- DKPhotoGallery/Resource (= 0.0.19)
26+
- SDWebImage
27+
- SwiftyGif
28+
- DKPhotoGallery/Core (0.0.19):
29+
- DKPhotoGallery/Model
30+
- DKPhotoGallery/Preview
31+
- SDWebImage
32+
- SwiftyGif
33+
- DKPhotoGallery/Model (0.0.19):
34+
- SDWebImage
35+
- SwiftyGif
36+
- DKPhotoGallery/Preview (0.0.19):
37+
- DKPhotoGallery/Model
38+
- DKPhotoGallery/Resource
39+
- SDWebImage
40+
- SwiftyGif
41+
- DKPhotoGallery/Resource (0.0.19):
42+
- SDWebImage
43+
- SwiftyGif
44+
- file_picker (0.0.1):
45+
- DKImagePickerController/PhotoGallery
46+
- Flutter
1147
- Firebase/CoreOnly (12.4.0):
1248
- FirebaseCore (~> 12.4.0)
1349
- firebase_analytics (12.0.4):
@@ -125,11 +161,15 @@ PODS:
125161
- Flutter
126162
- FlutterMacOS
127163
- PromisesObjC (2.4.0)
164+
- SDWebImage (5.21.7):
165+
- SDWebImage/Core (= 5.21.7)
166+
- SDWebImage/Core (5.21.7)
128167
- sensors_plus (0.0.1):
129168
- Flutter
130169
- shared_preferences_foundation (0.0.1):
131170
- Flutter
132171
- FlutterMacOS
172+
- SwiftyGif (5.4.5)
133173
- url_launcher_ios (0.0.1):
134174
- Flutter
135175
- vibration (3.0.0):
@@ -139,10 +179,12 @@ PODS:
139179
- FlutterMacOS
140180

141181
DEPENDENCIES:
182+
- app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`)
142183
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/darwin`)
143184
- battery_plus (from `.symlinks/plugins/battery_plus/ios`)
144185
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
145186
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
187+
- file_picker (from `.symlinks/plugins/file_picker/ios`)
146188
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
147189
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
148190
- Flutter (from `Flutter`)
@@ -161,6 +203,8 @@ DEPENDENCIES:
161203

162204
SPEC REPOS:
163205
trunk:
206+
- DKImagePickerController
207+
- DKPhotoGallery
164208
- Firebase
165209
- FirebaseAnalytics
166210
- FirebaseCore
@@ -173,8 +217,12 @@ SPEC REPOS:
173217
- GoogleUtilities
174218
- nanopb
175219
- PromisesObjC
220+
- SDWebImage
221+
- SwiftyGif
176222

177223
EXTERNAL SOURCES:
224+
app_tracking_transparency:
225+
:path: ".symlinks/plugins/app_tracking_transparency/ios"
178226
audioplayers_darwin:
179227
:path: ".symlinks/plugins/audioplayers_darwin/darwin"
180228
battery_plus:
@@ -183,6 +231,8 @@ EXTERNAL SOURCES:
183231
:path: ".symlinks/plugins/connectivity_plus/ios"
184232
device_info_plus:
185233
:path: ".symlinks/plugins/device_info_plus/ios"
234+
file_picker:
235+
:path: ".symlinks/plugins/file_picker/ios"
186236
firebase_analytics:
187237
:path: ".symlinks/plugins/firebase_analytics/ios"
188238
firebase_core:
@@ -213,10 +263,14 @@ EXTERNAL SOURCES:
213263
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
214264

215265
SPEC CHECKSUMS:
266+
app_tracking_transparency: 3d84f147f67ca82d3c15355c36b1fa6b66ca7c92
216267
audioplayers_darwin: 4f9ca89d92d3d21cec7ec580e78ca888e5fb68bd
217268
battery_plus: b42253f6d2dde71712f8c36fef456d99121c5977
218269
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
219270
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
271+
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
272+
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
273+
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
220274
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
221275
firebase_analytics: 67fbdd9f3c04e55048024f3da21cfc36f05e56cf
222276
firebase_core: f1aafb21c14f497e5498f7ffc4dc63cbb52b2594
@@ -238,8 +292,10 @@ SPEC CHECKSUMS:
238292
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
239293
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
240294
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
295+
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
241296
sensors_plus: 6a11ed0c2e1d0bd0b20b4029d3bad27d96e0c65b
242297
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
298+
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
243299
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
244300
vibration: 69774ad57825b11c951ee4c46155f455d7a592ce
245301
webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d

ios/Runner/Info.plist

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@
3131
<key>NSDocumentsFolderUsageDescription</key>
3232
<string>WARP needs access to store its configuration files</string>
3333
<key>NSVPNConfigurationUsageDescription</key>
34-
<string>Defyx needs access to VPN configurations to secure your connection.</string> <key>NSUserTrackingUsageDescription</key>
35-
<string>We show personalized ads to support this free VPN service. Your data stays private and secure.</string> <key>UIApplicationSupportsIndirectInputEvents</key>
34+
<string>Defyx needs access to VPN configurations to secure your connection.</string>
35+
<key>NSUserTrackingUsageDescription</key>
36+
<string>We show personalized ads to support this free VPN service. Your data stays private and secure.</string>
37+
<key>NSPhotoLibraryUsageDescription</key>
38+
<string>Defyx needs access to your photo library to let you select and share images, such as profile pictures or VPN connection QR codes.</string>
39+
<key>UIApplicationSupportsIndirectInputEvents</key>
3640
<true/>
3741
<key>UILaunchStoryboardName</key>
3842
<string>LaunchScreen</string>
@@ -63,6 +67,33 @@
6367
<true/>
6468
</dict>
6569
<key>UIStatusBarHidden</key>
66-
<false/>
70+
<false/>
71+
<key>LSSupportsOpeningDocumentsInPlace</key>
72+
<true/>
73+
<key>UIFileSharingEnabled</key>
74+
<true/>
75+
<key>UISupportsDocumentBrowser</key>
76+
<true/>
77+
<key>UTImportedTypeDeclarations</key>
78+
<array>
79+
<dict>
80+
<key>UTTypeConformsTo</key>
81+
<array>
82+
<string>public.data</string>
83+
<string>public.content</string>
84+
</array>
85+
<key>UTTypeDescription</key>
86+
<string>DefyX Configuration File</string>
87+
<key>UTTypeIdentifier</key>
88+
<string>de.unboundtech.defyxvpn.dfx</string>
89+
<key>UTTypeTagSpecification</key>
90+
<dict>
91+
<key>public.filename-extension</key>
92+
<array>
93+
<string>dfx</string>
94+
</array>
95+
</dict>
96+
</dict>
97+
</array>
6798
</dict>
68-
</plist>
99+
</plist>

0 commit comments

Comments
 (0)