diff --git a/AppIcon.icon/icon.json b/AppIcon.icon/icon.json index e5b6368..6049cc2 100644 --- a/AppIcon.icon/icon.json +++ b/AppIcon.icon/icon.json @@ -1,13 +1,36 @@ { "fill" : { - "automatic-gradient" : "display-p3:0.23889,0.54053,0.96826,1.00000" + "linear-gradient" : [ + "display-p3:0.72718,1.00000,0.56150,1.00000", + "display-p3:0.23889,0.54053,0.96826,1.00000" + ], + "orientation" : { + "start" : { + "x" : 0.5, + "y" : 0 + }, + "stop" : { + "x" : 0.5, + "y" : 0.7 + } + } }, "groups" : [ { "layers" : [ { + "blend-mode" : "normal", + "hidden" : false, "image-name" : "StosPlug.svg", - "name" : "StosPlug" + "name" : "StosPlug", + "opacity" : 0.5, + "position" : { + "scale" : 1, + "translation-in-points" : [ + 0, + 0 + ] + } } ], "shadow" : { diff --git a/Build.xcconfig b/Build.xcconfig index fff8a9d..86b1886 100644 --- a/Build.xcconfig +++ b/Build.xcconfig @@ -5,15 +5,15 @@ MARKETING_VERSION = 1.2.1 CURRENT_PROJECT_VERSION = 1 // Vars to be overwritten by `CodeSigning.xcconfig` if exists -DEVELOPMENT_TEAM = 95J8WZ4TN8 -ORG_IDENTIFIER = com.stossy11 +DEVELOPMENT_TEAM = 42Q7QX86GV +ORG_IDENTIFIER = com.jkcoxson // Codesigning settings defined optionally, see `CodeSigning.xcconfig.example` #include? "CodeSigning.xcconfig" ORG_PREFIX = $(ORG_IDENTIFIER) -PRODUCT_BUNDLE_IDENTIFIER = $(ORG_PREFIX).StosVPN +PRODUCT_BUNDLE_IDENTIFIER = $(ORG_PREFIX).LocalDevVPN TUNNEL_NAME = TunnelProv diff --git a/StosVPN.xcodeproj/project.pbxproj b/LocalDevVPN.xcodeproj/project.pbxproj similarity index 88% rename from StosVPN.xcodeproj/project.pbxproj rename to LocalDevVPN.xcodeproj/project.pbxproj index 11c7272..33557c4 100644 --- a/StosVPN.xcodeproj/project.pbxproj +++ b/LocalDevVPN.xcodeproj/project.pbxproj @@ -41,13 +41,20 @@ 0E6351B62E18DF53002AF750 /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; 0E6351B72E18DF53002AF750 /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = ""; }; 0E6351B82E18DF53002AF750 /* CodeSigning.xcconfig.sample */ = {isa = PBXFileReference; lastKnownFileType = text; path = CodeSigning.xcconfig.sample; sourceTree = ""; }; - 4EB3C7582D96631A00C1B22C /* StosVPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StosVPN.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4EB3C7582D96631A00C1B22C /* LocalDevVPN.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LocalDevVPN.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4EB3C76E2D96715400C1B22C /* TunnelProv.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TunnelProv.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 4EB3C7702D96715400C1B22C /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; 4EE6B99A2E8F756700E30694 /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 190996C92ED0FC91006411F1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 4EB3C7572D96631A00C1B22C /* LocalDevVPN */; + }; 4EB3C77A2D96715400C1B22C /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( @@ -55,17 +62,10 @@ ); target = 4EB3C76D2D96715400C1B22C /* TunnelProv */; }; - 4EB3C7802D9672DE00C1B22C /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - ); - target = 4EB3C7572D96631A00C1B22C /* StosVPN */; - }; /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ - 4EB3C75A2D96631A00C1B22C /* StosVPN */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (4EB3C7802D9672DE00C1B22C /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = StosVPN; sourceTree = ""; }; + 4EB3C75A2D96631A00C1B22C /* LocalDevVPN */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (190996C92ED0FC91006411F1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = LocalDevVPN; sourceTree = ""; }; 4EB3C7722D96715400C1B22C /* TunnelProv */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (4EB3C77A2D96715400C1B22C /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = TunnelProv; sourceTree = ""; }; /* End PBXFileSystemSynchronizedRootGroup section */ @@ -96,7 +96,7 @@ 0E6351B62E18DF53002AF750 /* Build.xcconfig */, 0E6351B72E18DF53002AF750 /* CodeSigning.xcconfig */, 0E6351B82E18DF53002AF750 /* CodeSigning.xcconfig.sample */, - 4EB3C75A2D96631A00C1B22C /* StosVPN */, + 4EB3C75A2D96631A00C1B22C /* LocalDevVPN */, 4EB3C7722D96715400C1B22C /* TunnelProv */, 4EB3C76F2D96715400C1B22C /* Frameworks */, 4EB3C7592D96631A00C1B22C /* Products */, @@ -106,7 +106,7 @@ 4EB3C7592D96631A00C1B22C /* Products */ = { isa = PBXGroup; children = ( - 4EB3C7582D96631A00C1B22C /* StosVPN.app */, + 4EB3C7582D96631A00C1B22C /* LocalDevVPN.app */, 4EB3C76E2D96715400C1B22C /* TunnelProv.appex */, ); name = Products; @@ -123,9 +123,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 4EB3C7572D96631A00C1B22C /* StosVPN */ = { + 4EB3C7572D96631A00C1B22C /* LocalDevVPN */ = { isa = PBXNativeTarget; - buildConfigurationList = 4EB3C7662D96631B00C1B22C /* Build configuration list for PBXNativeTarget "StosVPN" */; + buildConfigurationList = 4EB3C7662D96631B00C1B22C /* Build configuration list for PBXNativeTarget "LocalDevVPN" */; buildPhases = ( 4EB3C7542D96631A00C1B22C /* Sources */, 4EB3C7552D96631A00C1B22C /* Frameworks */, @@ -138,14 +138,14 @@ 4EB3C7782D96715400C1B22C /* PBXTargetDependency */, ); fileSystemSynchronizedGroups = ( - 4EB3C75A2D96631A00C1B22C /* StosVPN */, + 4EB3C75A2D96631A00C1B22C /* LocalDevVPN */, ); - name = StosVPN; + name = LocalDevVPN; packageProductDependencies = ( 0E6351BD2E18EABA002AF750 /* NavigationBackport */, ); - productName = StosVPN; - productReference = 4EB3C7582D96631A00C1B22C /* StosVPN.app */; + productName = LocalDevVPN; + productReference = 4EB3C7582D96631A00C1B22C /* LocalDevVPN.app */; productType = "com.apple.product-type.application"; }; 4EB3C76D2D96715400C1B22C /* TunnelProv */ = { @@ -190,7 +190,7 @@ }; }; }; - buildConfigurationList = 4EB3C7532D96631A00C1B22C /* Build configuration list for PBXProject "StosVPN" */; + buildConfigurationList = 4EB3C7532D96631A00C1B22C /* Build configuration list for PBXProject "LocalDevVPN" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; @@ -210,7 +210,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 4EB3C7572D96631A00C1B22C /* StosVPN */, + 4EB3C7572D96631A00C1B22C /* LocalDevVPN */, 4EB3C76D2D96715400C1B22C /* TunnelProv */, ); }; @@ -414,8 +414,13 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; - DEVELOPMENT_ASSET_PATHS = "\"StosVPN/Preview Content\""; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"LocalDevVPN/Preview Content\""; + DEVELOPMENT_TEAM = 42Q7QX86GV; ENABLE_PREVIEWS = YES; + INFOPLIST_KEY_CFBundleDisplayName = LocalDevVPN; + INFOPLIST_KEY_NSHumanReadableCopyright = Stossy11; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -425,9 +430,11 @@ "$(inherited)", "@executable_path/Frameworks", ); + PRODUCT_BUNDLE_IDENTIFIER = com.jkcoxson.LocalDevVPN; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; - SWIFT_OBJC_BRIDGING_HEADER = "StosVPN/StosVPN-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "LocalDevVPN/LocalDevVPN-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3"; @@ -442,8 +449,13 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; - DEVELOPMENT_ASSET_PATHS = "\"StosVPN/Preview Content\""; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"LocalDevVPN/Preview Content\""; + DEVELOPMENT_TEAM = 42Q7QX86GV; ENABLE_PREVIEWS = YES; + INFOPLIST_KEY_CFBundleDisplayName = LocalDevVPN; + INFOPLIST_KEY_NSHumanReadableCopyright = Stossy11; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -453,9 +465,11 @@ "$(inherited)", "@executable_path/Frameworks", ); + PRODUCT_BUNDLE_IDENTIFIER = com.jkcoxson.LocalDevVPN; + PROVISIONING_PROFILE_SPECIFIER = ""; SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; - SWIFT_OBJC_BRIDGING_HEADER = "StosVPN/StosVPN-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "LocalDevVPN/LocalDevVPN-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3"; TVOS_DEPLOYMENT_TARGET = 17.0; @@ -465,6 +479,7 @@ 4EB3C77C2D96715400C1B22C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + DEVELOPMENT_TEAM = 42Q7QX86GV; INFOPLIST_KEY_CFBundleDisplayName = TunnelProv; INFOPLIST_KEY_NSHumanReadableCopyright = Stossy11; INFOPLIST_KEY_UIRequiredDeviceCapabilities = arm64; @@ -474,10 +489,12 @@ "@executable_path/../../Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = "$(TUNNEL_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=appletvos*]" = com.jkcoxson.LocalDevVPN.TunnelProv; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = com.jkcoxson.LocalDevVPN.TunnelProv; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; - SWIFT_OBJC_BRIDGING_HEADER = "StosVPN/StosVPN-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "LocalDevVPN/LocalDevVPN-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3"; TVOS_DEPLOYMENT_TARGET = 17.0; @@ -487,6 +504,7 @@ 4EB3C77D2D96715400C1B22C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + DEVELOPMENT_TEAM = 42Q7QX86GV; INFOPLIST_KEY_CFBundleDisplayName = TunnelProv; INFOPLIST_KEY_NSHumanReadableCopyright = Stossy11; INFOPLIST_KEY_UIRequiredDeviceCapabilities = arm64; @@ -496,10 +514,12 @@ "@executable_path/../../Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = "$(TUNNEL_BUNDLE_IDENTIFIER)"; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=appletvos*]" = com.jkcoxson.LocalDevVPN.TunnelProv; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = com.jkcoxson.LocalDevVPN.TunnelProv; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; - SWIFT_OBJC_BRIDGING_HEADER = "StosVPN/StosVPN-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "LocalDevVPN/LocalDevVPN-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3"; TVOS_DEPLOYMENT_TARGET = 17.0; @@ -509,7 +529,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 4EB3C7532D96631A00C1B22C /* Build configuration list for PBXProject "StosVPN" */ = { + 4EB3C7532D96631A00C1B22C /* Build configuration list for PBXProject "LocalDevVPN" */ = { isa = XCConfigurationList; buildConfigurations = ( 4EB3C7642D96631B00C1B22C /* Debug */, @@ -518,7 +538,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4EB3C7662D96631B00C1B22C /* Build configuration list for PBXNativeTarget "StosVPN" */ = { + 4EB3C7662D96631B00C1B22C /* Build configuration list for PBXNativeTarget "LocalDevVPN" */ = { isa = XCConfigurationList; buildConfigurations = ( 4EB3C7672D96631B00C1B22C /* Debug */, diff --git a/StosVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LocalDevVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from StosVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to LocalDevVPN.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/StosVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LocalDevVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved similarity index 100% rename from StosVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved rename to LocalDevVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/LocalDevVPN.xcodeproj/project.xcworkspace/xcuserdata/jacksoncoxson.xcuserdatad/UserInterfaceState.xcuserstate b/LocalDevVPN.xcodeproj/project.xcworkspace/xcuserdata/jacksoncoxson.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..f8ab713 Binary files /dev/null and b/LocalDevVPN.xcodeproj/project.xcworkspace/xcuserdata/jacksoncoxson.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/StosVPN.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate b/LocalDevVPN.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate similarity index 100% rename from StosVPN.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate rename to LocalDevVPN.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/StosVPN.xcodeproj/xcshareddata/xcschemes/StosVPN.xcscheme b/LocalDevVPN.xcodeproj/xcshareddata/xcschemes/StosVPN.xcscheme similarity index 83% rename from StosVPN.xcodeproj/xcshareddata/xcschemes/StosVPN.xcscheme rename to LocalDevVPN.xcodeproj/xcshareddata/xcschemes/StosVPN.xcscheme index 41fa216..49a5837 100644 --- a/StosVPN.xcodeproj/xcshareddata/xcschemes/StosVPN.xcscheme +++ b/LocalDevVPN.xcodeproj/xcshareddata/xcschemes/StosVPN.xcscheme @@ -16,9 +16,9 @@ + BuildableName = "LocalDevVPN.app" + BlueprintName = "LocalDevVPN" + ReferencedContainer = "container:LocalDevVPN.xcodeproj"> @@ -45,9 +45,9 @@ + BuildableName = "LocalDevVPN.app" + BlueprintName = "LocalDevVPN" + ReferencedContainer = "container:LocalDevVPN.xcodeproj"> @@ -62,9 +62,9 @@ + BuildableName = "LocalDevVPN.app" + BlueprintName = "LocalDevVPN" + ReferencedContainer = "container:LocalDevVPN.xcodeproj"> diff --git a/StosVPN.xcodeproj/xcshareddata/xcschemes/TunnelProv.xcscheme b/LocalDevVPN.xcodeproj/xcshareddata/xcschemes/TunnelProv.xcscheme similarity index 92% rename from StosVPN.xcodeproj/xcshareddata/xcschemes/TunnelProv.xcscheme rename to LocalDevVPN.xcodeproj/xcshareddata/xcschemes/TunnelProv.xcscheme index 31c9da5..d892b55 100644 --- a/StosVPN.xcodeproj/xcshareddata/xcschemes/TunnelProv.xcscheme +++ b/LocalDevVPN.xcodeproj/xcshareddata/xcschemes/TunnelProv.xcscheme @@ -31,8 +31,8 @@ @@ -62,8 +62,8 @@ @@ -81,8 +81,8 @@ diff --git a/StosVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/LocalDevVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist similarity index 100% rename from StosVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist rename to LocalDevVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist diff --git a/StosVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist b/LocalDevVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist similarity index 100% rename from StosVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist rename to LocalDevVPN.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/StosVPN/Assets.xcassets/AccentColor.colorset/Contents.json b/LocalDevVPN/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AccentColor.colorset/Contents.json rename to LocalDevVPN/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.appiconset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.appiconset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.appiconset/StosVPN-icon.jpg b/LocalDevVPN/Assets.xcassets/AppIcon.appiconset/StosVPN-icon.jpg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.appiconset/StosVPN-icon.jpg rename to LocalDevVPN/Assets.xcassets/AppIcon.appiconset/StosVPN-icon.jpg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/1280x768.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/1280x768.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/1280x768.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/1280x768.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/1280x768 copy 3.jpeg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content@2x.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content@2x.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content@2x.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Content@2x.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Back.imagestacklayer/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool 1.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool 1.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool 1.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool 1.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/cool.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Front.imagestacklayer/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content@2x.png b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content@2x.png similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content@2x.png rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Content@2x.png diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4 2.jpeg b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4 2.jpeg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4 2.jpeg rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4 2.jpeg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4.jpeg b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4.jpeg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4.jpeg rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/1280x768 copy 4.jpeg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image Wide.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 4.jpeg b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 4.jpeg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 4.jpeg rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 4.jpeg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 5.jpeg b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 5.jpeg similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 5.jpeg rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/1280x768 copy 5.jpeg diff --git a/StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/Contents.json b/LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/Contents.json rename to LocalDevVPN/Assets.xcassets/AppIcon.brandassets/Top Shelf Image.imageset/Contents.json diff --git a/StosVPN/Assets.xcassets/Contents.json b/LocalDevVPN/Assets.xcassets/Contents.json similarity index 100% rename from StosVPN/Assets.xcassets/Contents.json rename to LocalDevVPN/Assets.xcassets/Contents.json diff --git a/StosVPN/ContentView.swift b/LocalDevVPN/ContentView.swift similarity index 88% rename from StosVPN/ContentView.swift rename to LocalDevVPN/ContentView.swift index 327233e..7cddc56 100644 --- a/StosVPN/ContentView.swift +++ b/LocalDevVPN/ContentView.swift @@ -1,13 +1,13 @@ // // ContentView.swift -// StosVPN +// LocalDevVPN // // Created by Stossy11 on 28/03/2025. // -import SwiftUI import Foundation import NetworkExtension +import SwiftUI import NavigationBackport @@ -17,58 +17,60 @@ extension Bundle { } // MARK: - Logging Utility + class VPNLogger: ObservableObject { @Published var logs: [String] = [] - + static var shared = VPNLogger() - + private init() {} - + func log(_ message: Any, file: String = #file, function: String = #function, line: Int = #line) { #if DEBUG - let fileName = (file as NSString).lastPathComponent - print("[\(fileName):\(line)] \(function): \(message)") + let fileName = (file as NSString).lastPathComponent + print("[\(fileName):\(line)] \(function): \(message)") #endif - + logs.append("\(message)") } } // MARK: - Tunnel Manager + class TunnelManager: ObservableObject { @Published var hasLocalDeviceSupport = false @Published var tunnelStatus: TunnelStatus = .disconnected - + static var shared = TunnelManager() - + @Published var waitingOnSettings: Bool = false @Published var vpnManager: NETunnelProviderManager? private var vpnObserver: NSObjectProtocol? private var isProcessingStatusChange = false - + private var tunnelDeviceIp: String { UserDefaults.standard.string(forKey: "TunnelDeviceIP") ?? "10.7.0.0" } - + private var tunnelFakeIp: String { UserDefaults.standard.string(forKey: "TunnelFakeIP") ?? "10.7.0.1" } - + private var tunnelSubnetMask: String { UserDefaults.standard.string(forKey: "TunnelSubnetMask") ?? "255.255.255.0" } - + private var tunnelBundleId: String { Bundle.main.bundleIdentifier!.appending(".TunnelProv") } - + enum TunnelStatus { case disconnected case connecting case connected case disconnecting case error - + var color: Color { switch self { case .disconnected: return .gray @@ -78,7 +80,7 @@ class TunnelManager: ObservableObject { case .error: return .red } } - + var systemImage: String { switch self { case .disconnected: return "network.slash" @@ -88,7 +90,7 @@ class TunnelManager: ObservableObject { case .error: return "exclamationmark.shield.fill" } } - + var localizedTitle: LocalizedStringKey { switch self { case .disconnected: @@ -104,17 +106,18 @@ class TunnelManager: ObservableObject { } } } - + private init() { setupStatusObserver() loadTunnelPreferences() } - + // MARK: - Private Methods + private func loadTunnelPreferences() { - NETunnelProviderManager.loadAllFromPreferences { [weak self] (managers, error) in + NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in guard let self = self else { return } - + DispatchQueue.main.async { if let error = error { VPNLogger.shared.log("Error loading preferences: \(error.localizedDescription)") @@ -122,10 +125,10 @@ class TunnelManager: ObservableObject { self.waitingOnSettings = true return } - + self.hasLocalDeviceSupport = true self.waitingOnSettings = true - + if let managers = managers, !managers.isEmpty { let stosManagers = managers.filter { manager in guard let proto = manager.protocolConfiguration as? NETunnelProviderProtocol else { @@ -133,18 +136,18 @@ class TunnelManager: ObservableObject { } return proto.providerBundleIdentifier == self.tunnelBundleId } - + if !stosManagers.isEmpty { if stosManagers.count > 1 { self.cleanupDuplicateManagers(stosManagers) } else if let manager = stosManagers.first { self.vpnManager = manager let currentStatus = manager.connection.status - VPNLogger.shared.log("Loaded existing StosVPN tunnel configuration with status: \(currentStatus.rawValue)") + VPNLogger.shared.log("Loaded existing LocalDevVPN tunnel configuration with status: \(currentStatus.rawValue)") self.updateTunnelStatus(from: currentStatus) } } else { - VPNLogger.shared.log("No StosVPN tunnel configuration found") + VPNLogger.shared.log("No LocalDevVPN tunnel configuration found") } } else { VPNLogger.shared.log("No existing tunnel configurations found") @@ -152,21 +155,21 @@ class TunnelManager: ObservableObject { } } } - + private func cleanupDuplicateManagers(_ managers: [NETunnelProviderManager]) { - VPNLogger.shared.log("Found \(managers.count) StosVPN configurations. Cleaning up duplicates...") - + VPNLogger.shared.log("Found \(managers.count) LocalDevVPN configurations. Cleaning up duplicates...") + let activeManager = managers.first { $0.connection.status == .connected || $0.connection.status == .connecting } - + let managerToKeep = activeManager ?? managers.first! - + DispatchQueue.main.async { [weak self] in self?.vpnManager = managerToKeep self?.updateTunnelStatus(from: managerToKeep.connection.status) } - + for manager in managers where manager != managerToKeep { manager.removeFromPreferences { error in if let error = error { @@ -177,7 +180,7 @@ class TunnelManager: ObservableObject { } } } - + private func setupStatusObserver() { vpnObserver = NotificationCenter.default.addObserver( forName: .NEVPNStatusDidChange, @@ -186,18 +189,18 @@ class TunnelManager: ObservableObject { ) { [weak self] notification in guard let self = self else { return } guard let connection = notification.object as? NEVPNConnection else { return } - + VPNLogger.shared.log("VPN Status notification received: \(connection.status.rawValue)") - + // Update status immediately if it's our manager if let manager = self.vpnManager, connection == manager.connection { self.updateTunnelStatus(from: connection.status) } - + self.handleVPNStatusChange(notification: notification) } } - + private func updateTunnelStatus(from connectionStatus: NEVPNStatus) { let newStatus: TunnelStatus switch connectionStatus { @@ -214,29 +217,29 @@ class TunnelManager: ObservableObject { @unknown default: newStatus = .error } - + DispatchQueue.main.async { [weak self] in guard let self = self else { return } if self.tunnelStatus != newStatus { - VPNLogger.shared.log("StosVPN status updated from \(self.tunnelStatus) to \(newStatus)") + VPNLogger.shared.log("LocalDevVPN status updated from \(self.tunnelStatus) to \(newStatus)") } self.tunnelStatus = newStatus } } - - private func createStosVPNConfiguration(completion: @escaping (NETunnelProviderManager?) -> Void) { - NETunnelProviderManager.loadAllFromPreferences { [weak self] (managers, error) in + + private func createLocalDevVPNConfiguration(completion: @escaping (NETunnelProviderManager?) -> Void) { + NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in guard let self = self else { completion(nil) return } - + if let error = error { VPNLogger.shared.log("Error checking existing VPN configurations: \(error.localizedDescription)") completion(nil) return } - + if let managers = managers { let stosManagers = managers.filter { manager in guard let proto = manager.protocolConfiguration as? NETunnelProviderProtocol else { @@ -244,48 +247,48 @@ class TunnelManager: ObservableObject { } return proto.providerBundleIdentifier == self.tunnelBundleId } - + if let existingManager = stosManagers.first { - VPNLogger.shared.log("Found existing StosVPN configuration, using it instead of creating new one") + VPNLogger.shared.log("Found existing LocalDevVPN configuration, using it instead of creating new one") completion(existingManager) return } } - + let manager = NETunnelProviderManager() - manager.localizedDescription = "StosVPN" - + manager.localizedDescription = "LocalDevVPN" + let proto = NETunnelProviderProtocol() proto.providerBundleIdentifier = self.tunnelBundleId - proto.serverAddress = "StosVPN's Local Network Tunnel" + proto.serverAddress = "LocalDevVPN's Local Network Tunnel" manager.protocolConfiguration = proto - + let onDemandRule = NEOnDemandRuleEvaluateConnection() onDemandRule.interfaceTypeMatch = .any onDemandRule.connectionRules = [NEEvaluateConnectionRule( matchDomains: ["10.7.0.0", "10.7.0.1"], andAction: .connectIfNeeded )] - + manager.onDemandRules = [onDemandRule] manager.isOnDemandEnabled = true manager.isEnabled = true - + manager.saveToPreferences { error in DispatchQueue.main.async { if let error = error { - VPNLogger.shared.log("Error creating StosVPN configuration: \(error.localizedDescription)") + VPNLogger.shared.log("Error creating LocalDevVPN configuration: \(error.localizedDescription)") completion(nil) return } - - VPNLogger.shared.log("StosVPN configuration created successfully") + + VPNLogger.shared.log("LocalDevVPN configuration created successfully") completion(manager) } } } } - + private func getActiveVPNManager(completion: @escaping (NETunnelProviderManager?) -> Void) { NETunnelProviderManager.loadAllFromPreferences { managers, error in if let error = error { @@ -293,22 +296,22 @@ class TunnelManager: ObservableObject { completion(nil) return } - + guard let managers = managers else { completion(nil) return } - + let activeManager = managers.first { manager in manager.connection.status == .connected || manager.connection.status == .connecting } - + completion(activeManager) } } - + // MARK: - Public Methods - + func toggleVPNConnection() { if tunnelStatus == .connected || tunnelStatus == .connecting { stopVPN() @@ -316,12 +319,12 @@ class TunnelManager: ObservableObject { startVPN() } } - + func startVPN() { if let manager = vpnManager { let currentStatus = manager.connection.status VPNLogger.shared.log("Current manager status: \(currentStatus.rawValue)") - + if currentStatus == .connected { VPNLogger.shared.log("VPN already connected, updating UI") DispatchQueue.main.async { [weak self] in @@ -329,7 +332,7 @@ class TunnelManager: ObservableObject { } return } - + if currentStatus == .connecting { VPNLogger.shared.log("VPN already connecting, updating UI") DispatchQueue.main.async { [weak self] in @@ -338,49 +341,50 @@ class TunnelManager: ObservableObject { return } } - + getActiveVPNManager { [weak self] activeManager in guard let self = self else { return } - + if let activeManager = activeManager, - (activeManager.protocolConfiguration as? NETunnelProviderProtocol)?.providerBundleIdentifier != self.tunnelBundleId { - VPNLogger.shared.log("Disconnecting existing VPN connection before starting StosVPN") - - UserDefaults.standard.set(true, forKey: "ShouldStartStosVPNAfterDisconnect") + (activeManager.protocolConfiguration as? NETunnelProviderProtocol)?.providerBundleIdentifier != self.tunnelBundleId + { + VPNLogger.shared.log("Disconnecting existing VPN connection before starting LocalDevVPN") + + UserDefaults.standard.set(true, forKey: "ShouldStartLocalDevVPNAfterDisconnect") activeManager.connection.stopVPNTunnel() return } - - self.initializeAndStartStosVPN() + + self.initializeAndStartLocalDevVPN() } } - - private func initializeAndStartStosVPN() { + + private func initializeAndStartLocalDevVPN() { if let manager = vpnManager { manager.loadFromPreferences { [weak self] error in guard let self = self else { return } - + if let error = error { VPNLogger.shared.log("Error reloading manager: \(error.localizedDescription)") self.createAndStartVPN() return } - + self.startExistingVPN(manager: manager) } } else { createAndStartVPN() } } - + private func createAndStartVPN() { NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in guard let self = self else { return } - + if let error = error { VPNLogger.shared.log("Error reloading VPN configurations: \(error.localizedDescription)") } - + if let managers = managers { let stosManagers = managers.filter { manager in guard let proto = manager.protocolConfiguration as? NETunnelProviderProtocol else { @@ -388,24 +392,24 @@ class TunnelManager: ObservableObject { } return proto.providerBundleIdentifier == self.tunnelBundleId } - + if !stosManagers.isEmpty { DispatchQueue.main.async { [weak self] in self?.vpnManager = stosManagers.first } - + if stosManagers.count > 1 { self.cleanupDuplicateManagers(stosManagers) } - + if let manager = stosManagers.first { self.startExistingVPN(manager: manager) } return } } - - self.createStosVPNConfiguration { [weak self] manager in + + self.createLocalDevVPNConfiguration { [weak self] manager in guard let self = self, let manager = manager else { return } DispatchQueue.main.async { [weak self] in self?.vpnManager = manager @@ -414,32 +418,32 @@ class TunnelManager: ObservableObject { } } } - + private func startExistingVPN(manager: NETunnelProviderManager) { // First check the actual current status let currentStatus = manager.connection.status VPNLogger.shared.log("Current VPN status before start attempt: \(currentStatus.rawValue)") - + if currentStatus == .connected { - VPNLogger.shared.log("StosVPN tunnel is already connected") + VPNLogger.shared.log("LocalDevVPN tunnel is already connected") DispatchQueue.main.async { [weak self] in self?.tunnelStatus = .connected } return } - + if currentStatus == .connecting { - VPNLogger.shared.log("StosVPN tunnel is already connecting") + VPNLogger.shared.log("LocalDevVPN tunnel is already connecting") DispatchQueue.main.async { [weak self] in self?.tunnelStatus = .connecting } return } - + manager.isEnabled = true manager.saveToPreferences { [weak self] error in guard let self = self else { return } - + if let error = error { VPNLogger.shared.log("Error saving preferences: \(error.localizedDescription)") DispatchQueue.main.async { [weak self] in @@ -447,10 +451,10 @@ class TunnelManager: ObservableObject { } return } - + manager.loadFromPreferences { [weak self] error in guard let self = self else { return } - + if let error = error { VPNLogger.shared.log("Error reloading preferences: \(error.localizedDescription)") DispatchQueue.main.async { [weak self] in @@ -458,11 +462,11 @@ class TunnelManager: ObservableObject { } return } - + // Check status again after reload let statusAfterReload = manager.connection.status VPNLogger.shared.log("VPN status after reload: \(statusAfterReload.rawValue)") - + if statusAfterReload == .connected { VPNLogger.shared.log("VPN is already connected after reload") DispatchQueue.main.async { [weak self] in @@ -470,126 +474,128 @@ class TunnelManager: ObservableObject { } return } - + DispatchQueue.main.async { [weak self] in self?.tunnelStatus = .connecting } - + let options: [String: NSObject] = [ "TunnelDeviceIP": self.tunnelDeviceIp as NSObject, "TunnelFakeIP": self.tunnelFakeIp as NSObject, - "TunnelSubnetMask": self.tunnelSubnetMask as NSObject + "TunnelSubnetMask": self.tunnelSubnetMask as NSObject, ] - + do { try manager.connection.startVPNTunnel(options: options) - VPNLogger.shared.log("StosVPN tunnel start initiated") + VPNLogger.shared.log("LocalDevVPN tunnel start initiated") } catch { DispatchQueue.main.async { [weak self] in self?.tunnelStatus = .error } - VPNLogger.shared.log("Failed to start StosVPN tunnel: \(error.localizedDescription)") + VPNLogger.shared.log("Failed to start LocalDevVPN tunnel: \(error.localizedDescription)") } } } } - + func stopVPN() { guard let manager = vpnManager else { VPNLogger.shared.log("No VPN manager available to stop") return } - + DispatchQueue.main.async { [weak self] in self?.tunnelStatus = .disconnecting } - + manager.connection.stopVPNTunnel() - VPNLogger.shared.log("StosVPN tunnel stop initiated") - - UserDefaults.standard.removeObject(forKey: "ShouldStartStosVPNAfterDisconnect") + VPNLogger.shared.log("LocalDevVPN tunnel stop initiated") + + UserDefaults.standard.removeObject(forKey: "ShouldStartLocalDevVPNAfterDisconnect") } - + func handleVPNStatusChange(notification: Notification) { guard let connection = notification.object as? NEVPNConnection else { return } - + VPNLogger.shared.log("Handling VPN status change: \(connection.status.rawValue)") - + // Always update status if it's our manager's connection if let manager = vpnManager, connection == manager.connection { - VPNLogger.shared.log("Status change is for our StosVPN manager") + VPNLogger.shared.log("Status change is for our LocalDevVPN manager") updateTunnelStatus(from: connection.status) } - + if connection.status == .disconnected && - UserDefaults.standard.bool(forKey: "ShouldStartStosVPNAfterDisconnect") { - UserDefaults.standard.removeObject(forKey: "ShouldStartStosVPNAfterDisconnect") - + UserDefaults.standard.bool(forKey: "ShouldStartLocalDevVPNAfterDisconnect") + { + UserDefaults.standard.removeObject(forKey: "ShouldStartLocalDevVPNAfterDisconnect") + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in - self?.initializeAndStartStosVPN() + self?.initializeAndStartLocalDevVPN() } return } - + // Prevent recursive calls when checking for duplicates guard !isProcessingStatusChange else { return } isProcessingStatusChange = true - + // Check for duplicates asynchronously without blocking DispatchQueue.global(qos: .utility).async { [weak self] in guard let self = self else { return } - - NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in + + NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, _ in guard let self = self, let managers = managers, !managers.isEmpty else { DispatchQueue.main.async { [weak self] in self?.isProcessingStatusChange = false } return } - + let stosManagers = managers.filter { manager in guard let proto = manager.protocolConfiguration as? NETunnelProviderProtocol else { return false } return proto.providerBundleIdentifier == self.tunnelBundleId } - + if stosManagers.count > 1 { DispatchQueue.main.async { [weak self] in self?.cleanupDuplicateManagers(stosManagers) } } - + DispatchQueue.main.async { [weak self] in self?.isProcessingStatusChange = false } } } } - + // MARK: - Cleanup Utilities - + func cleanupAllVPNConfigurations() { NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in guard let self = self else { return } - + if let error = error { VPNLogger.shared.log("Error loading VPN configurations for cleanup: \(error.localizedDescription)") return } - + guard let managers = managers else { return } - + for manager in managers { guard let proto = manager.protocolConfiguration as? NETunnelProviderProtocol, - proto.providerBundleIdentifier == self.tunnelBundleId else { + proto.providerBundleIdentifier == self.tunnelBundleId + else { continue } - + if manager.connection.status == .connected || manager.connection.status == .connecting { manager.connection.stopVPNTunnel() } - + manager.removeFromPreferences { error in if let error = error { VPNLogger.shared.log("Error removing VPN configuration: \(error.localizedDescription)") @@ -598,14 +604,14 @@ class TunnelManager: ObservableObject { } } } - + DispatchQueue.main.async { [weak self] in self?.vpnManager = nil self?.tunnelStatus = .disconnected } } } - + deinit { if let observer = vpnObserver { NotificationCenter.default.removeObserver(observer) @@ -621,28 +627,28 @@ struct ContentView: View { @State var tunnel = false @AppStorage("autoConnect") private var autoConnect = false @AppStorage("hasNotCompletedSetup") private var hasNotCompletedSetup = true - + var body: some View { NBNavigationStack { VStack(spacing: 30) { Spacer() - + StatusIndicatorView() - + ConnectionButton( action: { tunnelManager.tunnelStatus == .connected ? tunnelManager.stopVPN() : tunnelManager.startVPN() } ) - + Spacer() - + if tunnelManager.tunnelStatus == .connected { ConnectionStatsView() } } .padding() - .navigationTitle("StosVPN") + .navigationTitle("LocalDevVPN") .tvOSNavigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .topBarTrailing) { @@ -673,38 +679,37 @@ extension View { @ViewBuilder func tvOSNavigationBarTitleDisplayMode(_ displayMode: NavigationBarItem.TitleDisplayMode) -> some View { #if os(iOS) - self.navigationBarTitleDisplayMode(displayMode) + navigationBarTitleDisplayMode(displayMode) #else - self + self #endif } } - struct StatusIndicatorView: View { @StateObject private var tunnelManager = TunnelManager.shared @State private var animationAmount = 1.0 @State private var isAnimating = false - + var body: some View { VStack(spacing: 20) { ZStack { Circle() .stroke(tunnelManager.tunnelStatus.color.opacity(0.2), lineWidth: 20) .frame(width: 200, height: 200) - + Circle() .stroke(tunnelManager.tunnelStatus.color, lineWidth: 10) .frame(width: 200, height: 200) .scaleEffect(animationAmount) .opacity(2 - animationAmount) .animation(isAnimating ? Animation.easeOut(duration: 1.5).repeatForever(autoreverses: false) : .default, value: animationAmount) - + VStack(spacing: 10) { Image(systemName: tunnelManager.tunnelStatus.systemImage) .font(.system(size: 50)) .foregroundColor(tunnelManager.tunnelStatus.color) - + Text(tunnelManager.tunnelStatus.localizedTitle) .font(.headline) .foregroundColor(.primary) @@ -716,14 +721,14 @@ struct StatusIndicatorView: View { .onChange(of: tunnelManager.tunnelStatus) { _ in updateAnimation() } - Text(tunnelManager.tunnelStatus == .connected ? - NSLocalizedString("local_tunnel_active", comment: "") : + Text(tunnelManager.tunnelStatus == .connected ? + NSLocalizedString("local_tunnel_active", comment: "") : NSLocalizedString("local_tunnel_inactive", comment: "")) .font(.subheadline) .foregroundColor(tunnelManager.tunnelStatus == .connected ? .green : .secondary) } } - + private func updateAnimation() { switch tunnelManager.tunnelStatus { case .disconnecting: @@ -746,18 +751,17 @@ struct StatusIndicatorView: View { } } - struct ConnectionButton: View { @StateObject private var tunnelManager = TunnelManager.shared let action: () -> Void - + var body: some View { Button(action: action) { HStack { Text(buttonText) .font(.headline) .fontWeight(.semibold) - + if tunnelManager.tunnelStatus == .connecting || tunnelManager.tunnelStatus == .disconnecting { ProgressView() .progressViewStyle(CircularProgressViewStyle()) @@ -772,7 +776,7 @@ struct ConnectionButton: View { } .disabled(tunnelManager.tunnelStatus == .connecting || tunnelManager.tunnelStatus == .disconnecting) } - + private var buttonText: String { switch tunnelManager.tunnelStatus { case .connected: @@ -785,7 +789,7 @@ struct ConnectionButton: View { return NSLocalizedString("connect", comment: "") } } - + private var buttonBackground: some View { Group { if tunnelManager.tunnelStatus == .connected { @@ -808,7 +812,7 @@ struct ConnectionButton: View { struct ConnectionStatsView: View { @State private var time = 0 let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() - + var body: some View { VStack(spacing: 25) { Text("local_tunnel_details") @@ -849,12 +853,12 @@ struct ConnectionStatsView: View { time += 1 } } - + var formattedTime: String { let minutes = (time / 60) % 60 let hours = time / 3600 let seconds = time % 60 - + if hours > 0 { return String(format: "%02d:%02d:%02d", hours, minutes, seconds) } else { @@ -867,18 +871,18 @@ struct StatItemView: View { let title: LocalizedStringKey let value: String let icon: String - + var body: some View { VStack(alignment: .leading, spacing: 10) { HStack { Image(systemName: icon) .foregroundColor(.blue) - + Text(title) .font(.caption) .foregroundColor(.secondary) } - + Text(value) .font(.system(size: 16, weight: .semibold)) .foregroundColor(.primary) @@ -888,6 +892,7 @@ struct StatItemView: View { } // MARK: - Updated SettingsView + struct SettingsView: View { @Environment(\.presentationMode) var presentationMode @AppStorage("selectedLanguage") private var selectedLanguage = Locale.current.languageCode ?? "en" @@ -901,7 +906,7 @@ struct SettingsView: View { @State private var showNetworkWarning = false @State private var showRestartPopUp = false - + var body: some View { NBNavigationStack { List { @@ -952,15 +957,15 @@ struct SettingsView: View { LanguageManager.shared.updateLanguage(to: languageCode) showRestartPopUp = true } - .alert(isPresented: $showRestartPopUp){ - Alert( - title: Text("restart_title"), - message: Text("restart_message"), - dismissButton: .cancel(Text("understand_button")) { - showRestartPopUp = true - } - ) - } + .alert(isPresented: $showRestartPopUp) { + Alert( + title: Text("restart_title"), + message: Text("restart_message"), + dismissButton: .cancel(Text("understand_button")) { + showRestartPopUp = true + } + ) + } } } .alert(isPresented: $showNetworkWarning) { @@ -969,7 +974,7 @@ struct SettingsView: View { message: Text("warning_message"), dismissButton: .cancel(Text("understand_button")) { shownTunnelAlert = true - + deviceIP = "10.7.0.0" fakeIP = "10.7.0.1" subnetMask = "255.255.255.0" @@ -991,7 +996,7 @@ struct SettingsView: View { private func dismiss() { presentationMode.wrappedValue.dismiss() } - + private func networkConfigRow(label: LocalizedStringKey, text: Binding) -> some View { HStack { Text(label) @@ -1000,11 +1005,11 @@ struct SettingsView: View { .multilineTextAlignment(.trailing) .foregroundColor(.secondary) .keyboardType(.numbersAndPunctuation) - .onChange(of: text.wrappedValue) { newValue in + .onChange(of: text.wrappedValue) { _ in if !shownTunnelAlert { showNetworkWarning = true } - + tunnelManager.vpnManager?.saveToPreferences { error in if let error = error { VPNLogger.shared.log(error.localizedDescription) @@ -1016,6 +1021,7 @@ struct SettingsView: View { } // MARK: - New Data Collection Info View + struct DataCollectionInfoView: View { var body: some View { ScrollView { @@ -1024,27 +1030,27 @@ struct DataCollectionInfoView: View { .font(.title) .fontWeight(.bold) .padding(.bottom, 10) - + GroupBox(label: Label("no_data_collection", systemImage: "hand.raised.slash").font(.headline)) { Text("no_data_collection_description") .padding(.vertical) } - + GroupBox(label: Label("local_processing_only", systemImage: "iphone").font(.headline)) { Text("local_processing_only_description") .padding(.vertical) } - + GroupBox(label: Label("no_third_party_sharing", systemImage: "person.2.slash").font(.headline)) { Text("no_third_party_sharing_description") .padding(.vertical) } - + GroupBox(label: Label("why_use_network_permissions", systemImage: "network").font(.headline)) { Text("why_use_network_permissions_description") .padding(.vertical) } - + GroupBox(label: Label("our_promise", systemImage: "checkmark.seal").font(.headline)) { Text("our_promise_description") .padding(.vertical) @@ -1188,13 +1194,13 @@ struct SetupView: View { description: "setup_privacy_description", imageName: "lock.shield.fill", details: "setup_privacy_details" - ) + ), ] var body: some View { NBNavigationStack { VStack { TabView(selection: $currentPage) { - ForEach(0..( - label: some View, - @ViewBuilder content: @escaping () -> Content -) -> some View { - #if os(tvOS) - tvOSGroupBox(label: { - label - }, content: content) - #else - SwiftUI.GroupBox(label: label, content: content) - #endif -} - -struct tvOSGroupBox: View { - @ViewBuilder let label: () -> Label - @ViewBuilder let content: () -> Content - - init( - @ViewBuilder label: @escaping () -> Label, + @ViewBuilder + func GroupBox( + label: some View, @ViewBuilder content: @escaping () -> Content - ) { - self.label = label - self.content = content + ) -> some View { + #if os(tvOS) + tvOSGroupBox(label: { + label + }, content: content) + #else + SwiftUI.GroupBox(label: label, content: content) + #endif } - var body: some View { - VStack(alignment: .leading, spacing: 8) { - label() - .font(.headline) - - content() - .padding(.top, 4) + struct tvOSGroupBox: View { + @ViewBuilder let label: () -> Label + @ViewBuilder let content: () -> Content + + init( + @ViewBuilder label: @escaping () -> Label, + @ViewBuilder content: @escaping () -> Content + ) { + self.label = label + self.content = content + } + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + label() + .font(.headline) + + content() + .padding(.top, 4) + } + .padding() + .background( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .fill(.secondary) + ) + .overlay( + RoundedRectangle(cornerRadius: 12, style: .continuous) + .stroke(.separator, lineWidth: 0.5) + ) } - .padding() - .background( - RoundedRectangle(cornerRadius: 12, style: .continuous) - .fill(.secondary) - ) - .overlay( - RoundedRectangle(cornerRadius: 12, style: .continuous) - .stroke(.separator, lineWidth: 0.5) - ) } -} #endif #Preview { diff --git a/StosVPN/Info.plist b/LocalDevVPN/Info.plist similarity index 100% rename from StosVPN/Info.plist rename to LocalDevVPN/Info.plist diff --git a/StosVPN/StosVPN-Bridging-Header.h b/LocalDevVPN/LocalDevVPN-Bridging-Header.h similarity index 100% rename from StosVPN/StosVPN-Bridging-Header.h rename to LocalDevVPN/LocalDevVPN-Bridging-Header.h diff --git a/StosVPN/StosVPN.entitlements b/LocalDevVPN/LocalDevVPN.entitlements similarity index 100% rename from StosVPN/StosVPN.entitlements rename to LocalDevVPN/LocalDevVPN.entitlements diff --git a/StosVPN/Localization/en.lproj/Localizable.strings b/LocalDevVPN/Localization/en.lproj/Localizable.strings similarity index 76% rename from StosVPN/Localization/en.lproj/Localizable.strings rename to LocalDevVPN/Localization/en.lproj/Localizable.strings index def42cb..4fed88a 100644 --- a/StosVPN/Localization/en.lproj/Localizable.strings +++ b/LocalDevVPN/Localization/en.lproj/Localizable.strings @@ -13,7 +13,7 @@ "disconnect" = "Disconnect"; "connecting_ellipsis" = "Connecting..."; "disconnecting_ellipsis" = "Disconnecting..."; -"server_address_name" = "StosVPN Local Tunnel"; +"server_address_name" = "LocalDevVPN Local Tunnel"; "local_tunnel_details" = "Tunnel Details"; "time_connected" = "Time Connected"; @@ -53,32 +53,32 @@ "data_collection_policy_title" = "Data Collection Policy"; "no_data_collection" = "No Data Collection"; -"no_data_collection_description" = "StosVPN DOES NOT collect user data, traffic information, or browsing activity. This app creates a local network tunnel that stays entirely on your device."; +"no_data_collection_description" = "LocalDevVPN DOES NOT collect user data, traffic information, or browsing activity. This app creates a local network tunnel that stays entirely on your device."; "local_processing_only" = "Local Processing Only"; "local_processing_only_description" = "All network traffic and configurations are processed locally on your device. No information ever leaves the device or is transmitted over the Internet."; "no_third_party_sharing" = "No Third Party Sharing"; "no_third_party_sharing_description" = "Since we do not collect data, there is no sharing with third parties. We do not have analytics, tracking, or data collection mechanisms in this app."; "why_use_network_permissions" = "Why Use Network Permissions?"; -"why_use_network_permissions_description" = "StosVPN requires network extension permissions to create a local network interface on your device. This is used exclusively for local development and testing."; +"why_use_network_permissions_description" = "LocalDevVPN requires network extension permissions to create a local network interface on your device. This is used exclusively for local development and testing."; "our_promise" = "Our Promise"; "our_promise_description" = "We are committed to privacy and transparency. This app is designed for developers to test and connect to local servers with no privacy concerns."; "data_collection_policy_nav" = "Data Collection"; "logs_nav" = "Logs"; "faq_header" = "Frequently Asked Questions"; "faq_q1" = "What does this app do?"; -"faq_q1_a1" = "StosVPN creates a local network interface for development and testing. It does not route traffic through external servers: everything stays on the device."; +"faq_q1_a1" = "LocalDevVPN creates a local network interface for development and testing. It does not route traffic through external servers: everything stays on the device."; "faq_common_use_cases" = "Common use cases include:"; "faq_case1" = "• Web app testing with local servers"; "faq_case2" = "• Development and debugging of network features"; "faq_case3" = "• Accessing hosted local development environments"; "faq_case4" = "• Testing apps that require specific network configurations"; "faq_q2" = "Is it a traditional VPN?"; -"faq_q2_a1" = "No, StosVPN is NOT a traditional VPN service. It does NOT:"; +"faq_q2_a1" = "No, LocalDevVPN is NOT a traditional VPN service. It does NOT:"; "faq_q2_point1" = "• Route your traffic through external servers"; "faq_q2_point2" = "• Provide privacy or anonymity for browsing"; "faq_q2_point3" = "• Connect to remote VPN servers"; "faq_q2_point4" = "• Encrypt or route your internet traffic"; -"faq_q2_a2" = "StosVPN only creates a local network interface to help developers connect to local services for development and testing."; +"faq_q2_a2" = "LocalDevVPN only creates a local network interface to help developers connect to local services for development and testing."; "faq_q3" = "Why does the connection fail?"; "faq_q3_a1" = "Connection failures may be due to system permissions, configuration errors, or iOS restrictions."; "faq_troubleshoot_header" = "Troubleshooting steps:"; @@ -87,15 +87,15 @@ "faq_troubleshoot3" = "• Check if the IP configuration is valid"; "faq_troubleshoot4" = "• Restart the device if problems persist"; "faq_q4" = "Who is this app for?"; -"faq_q4_intro" = "StosVPN is primarily designed for:"; +"faq_q4_intro" = "LocalDevVPN is primarily designed for:"; "faq_q4_case1" = "• Developers testing local web servers"; "faq_q4_case2" = "• App developers testing network features"; "faq_q4_case3" = "• QA engineers testing apps in isolated environments"; "faq_q4_case4" = "• Anyone needing access to local services on iOS"; "faq_q4_conclusion" = "This app is publicly available and useful for developers who need to test apps with network features on iOS."; "business_model_header" = "Business Model"; -"biz_q1" = "How does StosVPN work?"; -"biz_q1_a1" = "StosVPN is a completely free app available to the public. There are no paid features, subscriptions, or in-app purchases."; +"biz_q1" = "How does LocalDevVPN work?"; +"biz_q1_a1" = "LocalDevVPN is a completely free app available to the public. There are no paid features, subscriptions, or in-app purchases."; "biz_key_points_header" = "Key points of our model:"; "biz_point1" = "• The app is not tied to any company or group"; "biz_point2" = "• Anyone can download and use the app from the App Store"; @@ -106,18 +106,18 @@ "requires_ios" = "Requires iOS 14.0 or later"; "uses_network_extension" = "Uses Apple Network Extension APIs"; "help_and_support_nav" = "Help & Support"; -"setup_welcome_title" = "Welcome to StosVPN"; +"setup_welcome_title" = "Welcome to LocalDevVPN"; "setup_welcome_description" = "A simple local network tunnel for developers"; -"setup_welcome_details" = "StosVPN creates a local network interface for development, testing, and access to local servers. This app DOES NOT collect user data or route traffic through external servers."; -"setup_why_title" = "Why Use StosVPN?"; +"setup_welcome_details" = "LocalDevVPN creates a local network interface for development, testing, and access to local servers. This app DOES NOT collect user data or route traffic through external servers."; +"setup_why_title" = "Why Use LocalDevVPN?"; "setup_why_description" = "Perfect for iOS developers"; "setup_why_details" = "• Access local web servers and development environments\n• Test apps requiring specific network configurations\n• Connect to local network services without complex setup\n• Create isolated testing environments"; "setup_easy_title" = "Easy to Use"; "setup_easy_description" = "Just one tap to connect"; -"setup_easy_details" = "StosVPN is designed to be simple. Just tap the connect button to establish a local tunnel with preconfigured settings."; +"setup_easy_details" = "LocalDevVPN is designed to be simple. Just tap the connect button to establish a local tunnel with preconfigured settings."; "setup_privacy_title" = "Privacy Focused"; "setup_privacy_description" = "Your data stays on the device"; -"setup_privacy_details" = "StosVPN creates a local tunnel that does not route traffic through external servers. All traffic stays on your device, ensuring privacy and security. No data is collected or shared with third parties."; +"setup_privacy_details" = "LocalDevVPN creates a local tunnel that does not route traffic through external servers. All traffic stays on your device, ensuring privacy and security. No data is collected or shared with third parties."; "setup_nav" = "Setup"; "setup_get_started" = "Get Started"; "setup_next" = "Next"; diff --git a/StosVPN/Localization/es.lproj/Localizable.strings b/LocalDevVPN/Localization/es.lproj/Localizable.strings similarity index 75% rename from StosVPN/Localization/es.lproj/Localizable.strings rename to LocalDevVPN/Localization/es.lproj/Localizable.strings index 29ab1a9..758f150 100644 --- a/StosVPN/Localization/es.lproj/Localizable.strings +++ b/LocalDevVPN/Localization/es.lproj/Localizable.strings @@ -13,7 +13,7 @@ "disconnect" = "Desconectar"; "connecting_ellipsis" = "Conectando..."; "disconnecting_ellipsis" = "Desconectando..."; -"server_address_name" = "Túnel Local de StosVPN"; +"server_address_name" = "Túnel Local de LocalDevVPN"; "local_tunnel_details" = "Detalles del Túnel"; "time_connected" = "Tiempo Conectado"; @@ -53,32 +53,32 @@ "data_collection_policy_title" = "Política de Recopilación de Datos"; "no_data_collection" = "No Recopilación de Datos"; -"no_data_collection_description" = "StosVPN NO recopila datos de usuarios, información sobre el tráfico o actividad de navegación. Esta app crea un túnel de red local que permanece completamente en tu dispositivo."; +"no_data_collection_description" = "LocalDevVPN NO recopila datos de usuarios, información sobre el tráfico o actividad de navegación. Esta app crea un túnel de red local que permanece completamente en tu dispositivo."; "local_processing_only" = "Solo Procesamiento Local"; "local_processing_only_description" = "Todo el tráfico de red y configuraciones se procesan localmente en tu dispositivo. Ninguna información deja el dispositivo ni se transmite a Internet."; "no_third_party_sharing" = "No Compartir con Terceros"; "no_third_party_sharing_description" = "Dado que no recopilamos datos, no compartimos con terceros. No tenemos análisis, rastreo ni mecanismos de recopilación de datos en esta app."; "why_use_network_permissions" = "¿Por Qué Usar Permisos de Red?"; -"why_use_network_permissions_description" = "StosVPN requiere permisos de extensión de red para crear una interfaz de red local en tu dispositivo. Esto se utiliza exclusivamente para desarrollo y pruebas locales."; +"why_use_network_permissions_description" = "LocalDevVPN requiere permisos de extensión de red para crear una interfaz de red local en tu dispositivo. Esto se utiliza exclusivamente para desarrollo y pruebas locales."; "our_promise" = "Nuestra Promesa"; "our_promise_description" = "Estamos comprometidos con la privacidad y la transparencia. Esta app está diseñada para desarrolladores para probar y conectarse a servidores locales sin preocupaciones sobre la privacidad."; "data_collection_policy_nav" = "Recopilación de Datos"; "logs_nav" = "Registros"; "faq_header" = "Preguntas Frecuentes"; "faq_q1" = "¿Qué hace esta app?"; -"faq_q1_a1" = "StosVPN crea una interfaz de red local útil para el desarrollo y las pruebas. No enruta el tráfico a través de servidores externos: todo permanece en el dispositivo."; +"faq_q1_a1" = "LocalDevVPN crea una interfaz de red local útil para el desarrollo y las pruebas. No enruta el tráfico a través de servidores externos: todo permanece en el dispositivo."; "faq_common_use_cases" = "Los casos de uso comunes incluyen:"; "faq_case1" = "• Pruebas de aplicaciones web con servidores locales"; "faq_case2" = "• Desarrollo y depuración de funcionalidades de red"; "faq_case3" = "• Acceso a entornos de desarrollo locales alojados"; "faq_case4" = "• Pruebas de apps que requieren configuraciones de red específicas"; "faq_q2" = "¿Es una VPN tradicional?"; -"faq_q2_a1" = "No, StosVPN NO es un servicio de VPN tradicional. No:"; +"faq_q2_a1" = "No, LocalDevVPN NO es un servicio de VPN tradicional. No:"; "faq_q2_point1" = "• Enruta tu tráfico a través de servidores externos"; "faq_q2_point2" = "• Proporciona privacidad o anonimato para la navegación"; "faq_q2_point3" = "• Se conecta a servidores VPN remotos"; "faq_q2_point4" = "• Cifra o enruta tu tráfico de internet"; -"faq_q2_a2" = "StosVPN solo crea una interfaz de red local para ayudar a los desarrolladores a conectarse a servicios locales para el desarrollo y las pruebas."; +"faq_q2_a2" = "LocalDevVPN solo crea una interfaz de red local para ayudar a los desarrolladores a conectarse a servicios locales para el desarrollo y las pruebas."; "faq_q3" = "¿Por qué falla la conexión?"; "faq_q3_a1" = "Las fallas en la conexión pueden deberse a permisos del sistema, errores de configuración o restricciones de iOS."; "faq_troubleshoot_header" = "Pasos para solucionar problemas:"; @@ -87,15 +87,15 @@ "faq_troubleshoot3" = "• Verifica si la configuración IP es válida"; "faq_troubleshoot4" = "• Reinicia el dispositivo si los problemas persisten"; "faq_q4" = "¿Para quién es esta app?"; -"faq_q4_intro" = "StosVPN está diseñado principalmente para:"; +"faq_q4_intro" = "LocalDevVPN está diseñado principalmente para:"; "faq_q4_case1" = "• Desarrolladores que prueban servidores web locales"; "faq_q4_case2" = "• Desarrolladores de apps que prueban funcionalidades de red"; "faq_q4_case3" = "• Ingenieros de QA que prueban apps en entornos aislados"; "faq_q4_case4" = "• Cualquier persona que necesite acceder a servicios locales en iOS"; "faq_q4_conclusion" = "Esta app está disponible para el público y es útil para desarrolladores que necesitan probar apps con funcionalidades de red en iOS."; "business_model_header" = "Modelo de Negocio"; -"biz_q1" = "¿Cómo funciona StosVPN?"; -"biz_q1_a1" = "StosVPN es una app completamente gratuita disponible para el público. No hay funciones de pago, suscripciones ni compras dentro de la app."; +"biz_q1" = "¿Cómo funciona LocalDevVPN?"; +"biz_q1_a1" = "LocalDevVPN es una app completamente gratuita disponible para el público. No hay funciones de pago, suscripciones ni compras dentro de la app."; "biz_key_points_header" = "Puntos clave de nuestro modelo:"; "biz_point1" = "• La app no está vinculada a ninguna empresa o grupo"; "biz_point2" = "• Cualquier persona puede descargar y usar la app desde la App Store"; @@ -106,18 +106,18 @@ "requires_ios" = "Requiere iOS 14.0 o superior"; "uses_network_extension" = "Usa la API de Extensión de Red de Apple"; "help_and_support_nav" = "Ayuda & Soporte"; -"setup_welcome_title" = "Bienvenido a StosVPN"; +"setup_welcome_title" = "Bienvenido a LocalDevVPN"; "setup_welcome_description" = "Un simple túnel de red local para desarrolladores"; -"setup_welcome_details" = "StosVPN crea una interfaz de red local para el desarrollo, pruebas y acceso a servidores locales. Esta app NO recopila datos de usuario ni enruta el tráfico a través de servidores externos."; -"setup_why_title" = "¿Por qué usar StosVPN?"; +"setup_welcome_details" = "LocalDevVPN crea una interfaz de red local para el desarrollo, pruebas y acceso a servidores locales. Esta app NO recopila datos de usuario ni enruta el tráfico a través de servidores externos."; +"setup_why_title" = "¿Por qué usar LocalDevVPN?"; "setup_why_description" = "Ideal para desarrolladores iOS"; "setup_why_details" = "• Accede a servidores web locales y entornos de desarrollo\n• Prueba apps que requieren configuraciones de red específicas\n• Conéctate a servicios de red locales sin configuraciones complejas\n• Crea entornos aislados para pruebas"; "setup_easy_title" = "Fácil de Usar"; "setup_easy_description" = "Conéctate con solo un toque"; -"setup_easy_details" = "StosVPN está diseñado para ser simple. Solo toca el botón de conexión para establecer un túnel local con configuraciones predefinidas."; +"setup_easy_details" = "LocalDevVPN está diseñado para ser simple. Solo toca el botón de conexión para establecer un túnel local con configuraciones predefinidas."; "setup_privacy_title" = "Enfocado en la Privacidad"; "setup_privacy_description" = "Tus datos permanecen en tu dispositivo"; -"setup_privacy_details" = "StosVPN crea un túnel local que no enruta el tráfico a través de servidores externos. Todo el tráfico permanece en tu dispositivo, asegurando privacidad y seguridad. Ningún dato se recopila ni se comparte con terceros."; +"setup_privacy_details" = "LocalDevVPN crea un túnel local que no enruta el tráfico a través de servidores externos. Todo el tráfico permanece en tu dispositivo, asegurando privacidad y seguridad. Ningún dato se recopila ni se comparte con terceros."; "setup_nav" = "Configuración"; "setup_get_started" = "Comenzar"; "setup_next" = "Siguiente"; diff --git a/StosVPN/Localization/it.lproj/Localizable.strings b/LocalDevVPN/Localization/it.lproj/Localizable.strings similarity index 77% rename from StosVPN/Localization/it.lproj/Localizable.strings rename to LocalDevVPN/Localization/it.lproj/Localizable.strings index ea7d7e8..98e01b6 100644 --- a/StosVPN/Localization/it.lproj/Localizable.strings +++ b/LocalDevVPN/Localization/it.lproj/Localizable.strings @@ -13,7 +13,7 @@ "disconnect" = "Disconnetti"; "connecting_ellipsis" = "Connessione in corso..."; "disconnecting_ellipsis" = "Disconnessione in corso..."; -"server_address_name" = "Tunnel Locale di StosVPN"; +"server_address_name" = "Tunnel Locale di LocalDevVPN"; "local_tunnel_details" = "Dettagli del Tunnel"; "time_connected" = "Tempo Connesso"; @@ -53,32 +53,32 @@ "data_collection_policy_title" = "Politica di Raccolta Dati"; "no_data_collection" = "Nessuna raccolta di dati"; -"no_data_collection_description" = "StosVPN NON raccoglie dati utente, informazioni sul traffico o attività di navigazione. Questa app crea un tunnel di rete locale che rimane interamente sul tuo dispositivo."; +"no_data_collection_description" = "LocalDevVPN NON raccoglie dati utente, informazioni sul traffico o attività di navigazione. Questa app crea un tunnel di rete locale che rimane interamente sul tuo dispositivo."; "local_processing_only" = "Elaborazione solo sul tuo smartphone"; "local_processing_only_description" = "Tutto il traffico di rete e le configurazioni vengono elaborate localmente sul tuo dispositivo. Nessuna informazione lascia mai il dispositivo o viene trasmessa su Internet."; "no_third_party_sharing" = "Nessuna condivisione con servizi di terze parti"; "no_third_party_sharing_description" = "Poiché non raccogliamo dati, non c'è alcuna condivisione con terze parti. Non abbiamo analisi, tracciamento o meccanismi di raccolta dati in questa app."; "why_use_network_permissions" = "Perché concedere i permessi di Rete?"; -"why_use_network_permissions_description" = "StosVPN richiede permessi di estensione di rete per creare un'interfaccia di rete locale sul tuo dispositivo. Questo è utilizzato esclusivamente per sviluppo e test locali sul tuo dispositivo."; +"why_use_network_permissions_description" = "LocalDevVPN richiede permessi di estensione di rete per creare un'interfaccia di rete locale sul tuo dispositivo. Questo è utilizzato esclusivamente per sviluppo e test locali sul tuo dispositivo."; "our_promise" = "La nostra promessa"; "our_promise_description" = "Ci impegniamo per la privacy e la trasparenza. Questa app è progettata per sviluppatori per testare e connettersi a server locali senza preoccupazioni sulla privacy."; "data_collection_policy_nav" = "Raccolta Dati"; "logs_nav" = "Log di connessione"; "faq_header" = "Domande Frequenti"; "faq_q1" = "Cosa fa questa app?"; -"faq_q1_a1" = "StosVPN crea un'interfaccia di rete locale utilizzabile per sviluppo e test. Non instrada il traffico attraverso server esterni, tutto rimane sul dispositivo."; +"faq_q1_a1" = "LocalDevVPN crea un'interfaccia di rete locale utilizzabile per sviluppo e test. Non instrada il traffico attraverso server esterni, tutto rimane sul dispositivo."; "faq_common_use_cases" = "I casi d'uso comuni includono:"; "faq_case1" = "• Test di applicazioni web con server locali."; "faq_case2" = "• Sviluppo e Debug di funzionalità di rete."; "faq_case3" = "• Accesso ad ambienti di sviluppo locali ospitati."; "faq_case4" = "• Test di applicazioni che richiedono configurazioni di rete specifiche."; "faq_q2" = "È un VPN tradizionale?"; -"faq_q2_a1" = "No, StosVPN NON è un servizio VPN tradizionale. Non:"; +"faq_q2_a1" = "No, LocalDevVPN NON è un servizio VPN tradizionale. Non:"; "faq_q2_point1" = "• Instrada il tuo traffico attraverso server esterni."; "faq_q2_point2" = "• Garantisce privacy e la navigazione in incognito."; "faq_q2_point3" = "• Esegue connessioni a server VPN remoti."; "faq_q2_point4" = "• Cripta o instrada il tuo traffico internet."; -"faq_q2_a2" = "StosVPN crea solo un'interfaccia di rete locale per aiutare gli sviluppatori a connettersi a servizi locali per lo sviluppo e test."; +"faq_q2_a2" = "LocalDevVPN crea solo un'interfaccia di rete locale per aiutare gli sviluppatori a connettersi a servizi locali per lo sviluppo e test."; "faq_q3" = "Perché non si connette?"; "faq_q3_a1" = "Un errore durante la connessione può essere dovuto a permessi di sistema, errori di configurazione o restrizioni di iOS."; "faq_troubleshoot_header" = "Passaggi per risolvere:"; @@ -87,15 +87,15 @@ "faq_troubleshoot3" = "• Verifica se la configurazione IP è valida."; "faq_troubleshoot4" = "• Riavvia il dispositivo se i problemi persistono."; "faq_q4" = "Per chi è questa app?"; -"faq_q4_intro" = "StosVPN è progettato principalmente per:"; +"faq_q4_intro" = "LocalDevVPN è progettato principalmente per:"; "faq_q4_case1" = "• Sviluppatori che testano server web locali."; "faq_q4_case2" = "• Sviluppatori app che testano funzionalità di rete."; "faq_q4_case3" = "• Ingegneri QA che testano app in ambienti isolati."; "faq_q4_case4" = "• Chiunque necessiti di accedere a servizi locali sull'iOS."; "faq_q4_conclusion" = "Questa app è disponibile al pubblico ed è utile per sviluppatori che devono testare app con funzionalità di rete su iOS."; "business_model_header" = "Modello di Business"; -"biz_q1" = "Come funziona StosVPN?"; -"biz_q1_a1" = "StosVPN è un'app completamente gratuita disponibile al pubblico. Non ci sono funzionalità a pagamento, abbonamenti o acquisti in‑app."; +"biz_q1" = "Come funziona LocalDevVPN?"; +"biz_q1_a1" = "LocalDevVPN è un'app completamente gratuita disponibile al pubblico. Non ci sono funzionalità a pagamento, abbonamenti o acquisti in‑app."; "biz_key_points_header" = "Punti chiave del nostro modello:"; "biz_point1" = "• L'app non è vincolata a nessuna azienda o gruppo."; "biz_point2" = "• Chiunque può scaricare e usare l'app dall'App Store."; @@ -106,18 +106,18 @@ "requires_ios" = "Richiede iOS 14.0 o superiore"; "uses_network_extension" = "Usa le Network Extension API di Apple"; "help_and_support_nav" = "Guida & Supporto"; -"setup_welcome_title" = "Benvenuto in StosVPN"; +"setup_welcome_title" = "Benvenuto in LocalDevVPN"; "setup_welcome_description" = "Un semplice tunnel di rete locale per sviluppatori"; -"setup_welcome_details" = "StosVPN crea un'interfaccia di rete locale per sviluppo, test e accesso a server locali. Questa app NON raccoglie dati utente né instrada il traffico attraverso server esterni."; -"setup_why_title" = "Perché Usare StosVPN?"; +"setup_welcome_details" = "LocalDevVPN crea un'interfaccia di rete locale per sviluppo, test e accesso a server locali. Questa app NON raccoglie dati utente né instrada il traffico attraverso server esterni."; +"setup_why_title" = "Perché Usare LocalDevVPN?"; "setup_why_description" = "Perfetto per sviluppatori iOS"; "setup_why_details" = "• Accedi a server web locali e ambienti di sviluppo\n• Testa app che richiedono configurazioni di rete specifiche\n• Connettiti a servizi di rete locali senza setup complessi\n• Crea ambienti isolati per test"; "setup_easy_title" = "Facile da Usare"; "setup_easy_description" = "Basta un tap per connettersi"; -"setup_easy_details" = "StosVPN è progettato per essere semplice. Basta toccare il pulsante di connessione per stabilire un tunnel locale con impostazioni preconfigurate."; +"setup_easy_details" = "LocalDevVPN è progettato per essere semplice. Basta toccare il pulsante di connessione per stabilire un tunnel locale con impostazioni preconfigurate."; "setup_privacy_title" = "Focalizzato sulla Privacy"; "setup_privacy_description" = "I tuoi dati restano sul dispositivo"; -"setup_privacy_details" = "StosVPN crea un tunnel locale che non instrada il traffico attraverso server esterni. Tutto il traffico rimane sul tuo dispositivo, garantendo privacy e sicurezza. Nessun dato viene raccolto o condiviso con terze parti."; +"setup_privacy_details" = "LocalDevVPN crea un tunnel locale che non instrada il traffico attraverso server esterni. Tutto il traffico rimane sul tuo dispositivo, garantendo privacy e sicurezza. Nessun dato viene raccolto o condiviso con terze parti."; "setup_nav" = "Setup"; "setup_get_started" = "Inizia"; "setup_next" = "Avanti"; diff --git a/StosVPN/Localization/pl.lproj/Localizable.strings b/LocalDevVPN/Localization/pl.lproj/Localizable.strings similarity index 76% rename from StosVPN/Localization/pl.lproj/Localizable.strings rename to LocalDevVPN/Localization/pl.lproj/Localizable.strings index 4a78895..74a0f00 100644 --- a/StosVPN/Localization/pl.lproj/Localizable.strings +++ b/LocalDevVPN/Localization/pl.lproj/Localizable.strings @@ -13,7 +13,7 @@ "disconnect" = "Rozłącz"; "connecting_ellipsis" = "Łączenie..."; "disconnecting_ellipsis" = "Rozłączanie..."; -"server_address_name" = "Lokalny tunel StosVPN"; +"server_address_name" = "Lokalny tunel LocalDevVPN"; "local_tunnel_details" = "Szczegóły tunelu"; "time_connected" = "Czas połączenia"; @@ -54,32 +54,32 @@ "understand_button" = "Rozumiem"; "data_collection_policy_title" = "Polityka zbierania danych"; "no_data_collection" = "Brak zbierania danych"; -"no_data_collection_description" = "StosVPN NIE zbiera danych użytkownika, informacji o ruchu ani aktywności w przeglądarce. Aplikacja tworzy lokalny tunel sieciowy, który działa wyłącznie na Twoim urządzeniu."; +"no_data_collection_description" = "LocalDevVPN NIE zbiera danych użytkownika, informacji o ruchu ani aktywności w przeglądarce. Aplikacja tworzy lokalny tunel sieciowy, który działa wyłącznie na Twoim urządzeniu."; "local_processing_only" = "Tylko lokalne przetwarzanie"; "local_processing_only_description" = "Cały ruch sieciowy i konfiguracje są przetwarzane lokalnie na Twoim urządzeniu. Żadne informacje nie opuszczają urządzenia ani nie są przesyłane przez Internet."; "no_third_party_sharing" = "Brak udostępniania osobom trzecim"; "no_third_party_sharing_description" = "Ponieważ nie zbieramy danych, nie ma żadnego udostępniania osobom trzecim. Aplikacja nie zawiera analityki, śledzenia ani mechanizmów zbierania danych."; "why_use_network_permissions" = "Dlaczego wymagane są uprawnienia sieciowe"; -"why_use_network_permissions_description" = "StosVPN wymaga uprawnień rozszerzenia sieciowego, aby utworzyć lokalny interfejs sieciowy na Twoim urządzeniu. Jest on używany wyłącznie do lokalnego rozwoju i testowania."; +"why_use_network_permissions_description" = "LocalDevVPN wymaga uprawnień rozszerzenia sieciowego, aby utworzyć lokalny interfejs sieciowy na Twoim urządzeniu. Jest on używany wyłącznie do lokalnego rozwoju i testowania."; "our_promise" = "Nasza obietnica"; "our_promise_description" = "Zobowiązujemy się do ochrony prywatności i przejrzystości. Ta aplikacja została zaprojektowana z myślą o programistach do testowania i łączenia się z lokalnymi serwerami bez obaw o prywatność."; "data_collection_policy_nav" = "Zbieranie danych"; "logs_nav" = "Logi"; "faq_header" = "Najczęściej zadawane pytania"; "faq_q1" = "Do czego służy ta aplikacja?"; -"faq_q1_a1" = "StosVPN tworzy lokalny interfejs sieciowy do celów rozwojowych i testowych. Nie przekierowuje ruchu przez zewnętrzne serwery – wszystko pozostaje na urządzeniu."; +"faq_q1_a1" = "LocalDevVPN tworzy lokalny interfejs sieciowy do celów rozwojowych i testowych. Nie przekierowuje ruchu przez zewnętrzne serwery – wszystko pozostaje na urządzeniu."; "faq_common_use_cases" = "Typowe przypadki użycia:"; "faq_case1" = "• Testowanie aplikacji webowych z lokalnymi serwerami"; "faq_case2" = "• Tworzenie i debugowanie funkcji sieciowych"; "faq_case3" = "• Dostęp do lokalnych środowisk deweloperskich"; "faq_case4" = "• Testowanie aplikacji wymagających określonych konfiguracji sieciowych"; "faq_q2" = "Czy to tradycyjna sieć VPN?"; -"faq_q2_a1" = "Nie, StosVPN NIE jest tradycyjną usługą VPN. NIE robi:"; +"faq_q2_a1" = "Nie, LocalDevVPN NIE jest tradycyjną usługą VPN. NIE robi:"; "faq_q2_point1" = "• Przekierowywania ruchu przez zewnętrzne serwery"; "faq_q2_point2" = "• Zapewnienia prywatności lub anonimowości przeglądania"; "faq_q2_point3" = "• Łączenia z zewnętrznymi serwerami VPN"; "faq_q2_point4" = "• Szyfrowania lub przekierowywania Twojego ruchu internetowego"; -"faq_q2_a2" = "StosVPN jedynie tworzy lokalny interfejs sieciowy, aby pomóc programistom łączyć się z lokalnymi usługami w celu rozwoju i testowania."; +"faq_q2_a2" = "LocalDevVPN jedynie tworzy lokalny interfejs sieciowy, aby pomóc programistom łączyć się z lokalnymi usługami w celu rozwoju i testowania."; "faq_q3" = "Dlaczego połączenie się nie udaje?"; "faq_q3_a1" = "Nieudane połączenia mogą wynikać z braku uprawnień systemowych, błędów konfiguracji lub ograniczeń iOS."; "faq_troubleshoot_header" = "Kroki rozwiązywania problemów:"; @@ -88,15 +88,15 @@ "faq_troubleshoot3" = "• Sprawdź, czy konfiguracja IP jest prawidłowa"; "faq_troubleshoot4" = "• Uruchom ponownie urządzenie, jeśli problemy będą się powtarzać"; "faq_q4" = "Dla kogo jest ta aplikacja?"; -"faq_q4_intro" = "StosVPN został zaprojektowany głównie dla:"; +"faq_q4_intro" = "LocalDevVPN został zaprojektowany głównie dla:"; "faq_q4_case1" = "• Programistów testujących lokalne serwery webowe"; "faq_q4_case2" = "• Twórców aplikacji testujących funkcje sieciowe"; "faq_q4_case3" = "• Inżynierów QA testujących aplikacje w izolowanych środowiskach"; "faq_q4_case4" = "• Każdego, kto potrzebuje dostępu do lokalnych usług na iOS"; "faq_q4_conclusion" = "Aplikacja jest publicznie dostępna i przydatna dla deweloperów testujących aplikacje z funkcjami sieciowymi na iOS."; "business_model_header" = "Model biznesowy"; -"biz_q1" = "Jak działa StosVPN?"; -"biz_q1_a1" = "StosVPN to całkowicie darmowa aplikacja dostępna publicznie. Nie ma żadnych płatnych funkcji, subskrypcji ani zakupów w aplikacji."; +"biz_q1" = "Jak działa LocalDevVPN?"; +"biz_q1_a1" = "LocalDevVPN to całkowicie darmowa aplikacja dostępna publicznie. Nie ma żadnych płatnych funkcji, subskrypcji ani zakupów w aplikacji."; "biz_key_points_header" = "Kluczowe cechy naszego modelu:"; "biz_point1" = "• Aplikacja nie jest powiązana z żadną firmą ani organizacją"; "biz_point2" = "• Każdy może pobrać i używać aplikacji z App Store"; @@ -107,18 +107,18 @@ "requires_ios" = "Wymaga iOS 14.0 lub nowszego"; "uses_network_extension" = "Wykorzystuje API Apple Network Extension"; "help_and_support_nav" = "Pomoc i wsparcie"; -"setup_welcome_title" = "Witamy w StosVPN"; +"setup_welcome_title" = "Witamy w LocalDevVPN"; "setup_welcome_description" = "Prosty lokalny tunel sieciowy dla programistów"; -"setup_welcome_details" = "StosVPN tworzy lokalny interfejs sieciowy do rozwoju, testowania i dostępu do lokalnych serwerów. Aplikacja NIE zbiera danych użytkownika ani nie przekierowuje ruchu przez zewnętrzne serwery."; -"setup_why_title" = "Dlaczego warto używać StosVPN?"; +"setup_welcome_details" = "LocalDevVPN tworzy lokalny interfejs sieciowy do rozwoju, testowania i dostępu do lokalnych serwerów. Aplikacja NIE zbiera danych użytkownika ani nie przekierowuje ruchu przez zewnętrzne serwery."; +"setup_why_title" = "Dlaczego warto używać LocalDevVPN?"; "setup_why_description" = "Idealny dla programistów iOS"; "setup_why_details" = "• Dostęp do lokalnych serwerów webowych i środowisk deweloperskich\n• Testowanie aplikacji wymagających określonych konfiguracji sieci\n• Łączenie z lokalnymi usługami sieciowymi bez skomplikowanej konfiguracji\n• Tworzenie izolowanych środowisk testowych"; "setup_easy_title" = "Łatwy w użyciu"; "setup_easy_description" = "Połączenie za pomocą jednego kliknięcia"; -"setup_easy_details" = "StosVPN został zaprojektowany z myślą o prostocie. Wystarczy kliknąć przycisk połączenia, aby ustanowić lokalny tunel z gotową konfiguracją."; +"setup_easy_details" = "LocalDevVPN został zaprojektowany z myślą o prostocie. Wystarczy kliknąć przycisk połączenia, aby ustanowić lokalny tunel z gotową konfiguracją."; "setup_privacy_title" = "Skoncentrowany na prywatności"; "setup_privacy_description" = "Twoje dane pozostają na urządzeniu"; -"setup_privacy_details" = "StosVPN tworzy lokalny tunel, który nie przekierowuje ruchu przez zewnętrzne serwery. Cały ruch pozostaje na Twoim urządzeniu, zapewniając prywatność i bezpieczeństwo. Żadne dane nie są zbierane ani udostępniane osobom trzecim."; +"setup_privacy_details" = "LocalDevVPN tworzy lokalny tunel, który nie przekierowuje ruchu przez zewnętrzne serwery. Cały ruch pozostaje na Twoim urządzeniu, zapewniając prywatność i bezpieczeństwo. Żadne dane nie są zbierane ani udostępniane osobom trzecim."; "setup_nav" = "Konfiguracja"; "setup_get_started" = "Zaczynamy"; "setup_next" = "Dalej"; diff --git a/StosVPN/Preview Content/Preview Assets.xcassets/Contents.json b/LocalDevVPN/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from StosVPN/Preview Content/Preview Assets.xcassets/Contents.json rename to LocalDevVPN/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/StosVPN/StosVPNApp.swift b/LocalDevVPN/StosVPNApp.swift similarity index 80% rename from StosVPN/StosVPNApp.swift rename to LocalDevVPN/StosVPNApp.swift index 507cc9c..31d1986 100644 --- a/StosVPN/StosVPNApp.swift +++ b/LocalDevVPN/StosVPNApp.swift @@ -1,6 +1,6 @@ // // StosVPNApp.swift -// StosVPN +// LocalDevVPN // // Created by Stossy11 on 28/03/2025. // @@ -8,7 +8,7 @@ import SwiftUI @main -struct StosVPNApp: App { +struct LocalDevVPNApp: App { var body: some Scene { WindowGroup { ContentView() diff --git a/StosVPN/Assets.xcassets/.DS_Store b/StosVPN/Assets.xcassets/.DS_Store deleted file mode 100644 index f1e7878..0000000 Binary files a/StosVPN/Assets.xcassets/.DS_Store and /dev/null differ