2026-03-03 02:54:58 +05:30
|
|
|
//
|
|
|
|
|
// VPNConfiguration.swift
|
|
|
|
|
// AltStore
|
|
|
|
|
//
|
|
|
|
|
// Created by Magesh K on 02/03/26.
|
|
|
|
|
// Copyright © 2026 SideStore. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
|
import Combine
|
|
|
|
|
|
|
|
|
|
private typealias SButton = SwiftUI.Button
|
|
|
|
|
|
|
|
|
|
struct VPNConfigurationView: View {
|
|
|
|
|
@Environment(\.presentationMode) var presentationMode
|
|
|
|
|
@StateObject private var config = TunnelConfig.shared
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
List {
|
|
|
|
|
Section(header: Text("Discovered from network")) {
|
|
|
|
|
Group {
|
|
|
|
|
networkConfigRow(label: "Tunnel IP", text: $config.deviceIP, editable: false)
|
|
|
|
|
networkConfigRow(label: "Device IP", text: $config.fakeIP, editable: false)
|
|
|
|
|
networkConfigRow(label: "Subnet Mask", text: $config.subnetMask, editable: false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Section {
|
|
|
|
|
networkConfigRow(
|
|
|
|
|
label: "Device IP",
|
2026-03-03 04:02:07 +05:30
|
|
|
text: Binding<String?>(get: { config.overrideFakeIP }, set: { config.overrideFakeIP = $0 ?? "" }),
|
2026-03-03 02:54:58 +05:30
|
|
|
editable: true
|
|
|
|
|
)
|
2026-03-03 04:02:07 +05:30
|
|
|
networkConfigRow(
|
|
|
|
|
label: "Active",
|
|
|
|
|
text: Binding<String?>(get: { config.overrideActive }, set: { _ in }),
|
|
|
|
|
editable: false
|
|
|
|
|
)
|
2026-03-03 02:54:58 +05:30
|
|
|
} header: {
|
|
|
|
|
Text("Override Configuration")
|
|
|
|
|
} footer: {
|
|
|
|
|
HStack(alignment: .top, spacing: 0) {
|
|
|
|
|
Text("Note: ")
|
2026-03-03 04:02:07 +05:30
|
|
|
Text("if override configuration is invalid or unusable SideStore may use auto-discovered config as fallback.")
|
2026-03-03 02:54:58 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.navigationTitle("VPN Configuration")
|
|
|
|
|
.toolbar {
|
|
|
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
|
|
|
SButton("Confirm") {
|
|
|
|
|
commitChanges()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func commitChanges() {
|
|
|
|
|
TunnelConfig.shared.commitFakeIP()
|
|
|
|
|
bindTunnelConfig()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func dismiss() {
|
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func networkConfigRow(
|
|
|
|
|
label: LocalizedStringKey,
|
|
|
|
|
text: Binding<String?>,
|
|
|
|
|
editable: Bool
|
|
|
|
|
) -> some View {
|
|
|
|
|
|
|
|
|
|
let proxy = Binding<String>(
|
|
|
|
|
get: { text.wrappedValue ?? "N/A" },
|
|
|
|
|
set: { text.wrappedValue = $0.isEmpty || $0 == "N/A" ? nil : $0 }
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return HStack {
|
|
|
|
|
Text(label)
|
|
|
|
|
.foregroundColor(editable ? .primary : .gray)
|
|
|
|
|
Spacer()
|
|
|
|
|
TextField(label, text: proxy)
|
|
|
|
|
.multilineTextAlignment(.trailing)
|
|
|
|
|
.foregroundColor(editable ? .secondary : .gray)
|
|
|
|
|
.disabled(!editable)
|
|
|
|
|
.keyboardType(.numbersAndPunctuation)
|
|
|
|
|
.onChange(of: proxy.wrappedValue) { newValue in
|
|
|
|
|
guard editable else { return }
|
|
|
|
|
proxy.wrappedValue =
|
|
|
|
|
newValue.filter { "0123456789.".contains($0) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final class TunnelConfig: ObservableObject {
|
|
|
|
|
|
|
|
|
|
static let shared = TunnelConfig()
|
|
|
|
|
|
2026-03-03 03:23:00 +05:30
|
|
|
private static let defaultOverrideIP: String = {
|
|
|
|
|
if #available(iOS 26.4, *) { return "192.168.1.50" }
|
|
|
|
|
return "10.7.0.1"
|
|
|
|
|
}()
|
|
|
|
|
|
2026-03-03 02:54:58 +05:30
|
|
|
@Published var deviceIP: String?
|
|
|
|
|
@Published var subnetMask: String?
|
|
|
|
|
@Published var fakeIP: String?
|
2026-03-03 03:23:00 +05:30
|
|
|
@Published var overrideFakeIP: String = overrideIPStorage {
|
|
|
|
|
didSet { Self.overrideIPStorage = overrideFakeIP }
|
2026-03-03 02:54:58 +05:30
|
|
|
}
|
|
|
|
|
@Published var overrideEffective: Bool = false
|
2026-03-03 03:23:00 +05:30
|
|
|
|
|
|
|
|
private static var overrideIPStorage: String {
|
|
|
|
|
get { UserDefaults.standard.string(forKey: "TunnelOverrideFakeIP") ?? defaultOverrideIP }
|
|
|
|
|
set { UserDefaults.standard.set(newValue, forKey: "TunnelOverrideFakeIP") }
|
2026-03-03 02:54:58 +05:30
|
|
|
}
|
|
|
|
|
|
2026-03-03 03:23:00 +05:30
|
|
|
var overrideActive: String { overrideEffective ? "Yes" : "No" }
|
2026-03-03 02:54:58 +05:30
|
|
|
|
|
|
|
|
func commitFakeIP() {
|
|
|
|
|
fakeIP = overrideFakeIP
|
|
|
|
|
}
|
|
|
|
|
}
|