diff --git a/.gitignore b/.gitignore
index 102ee0d..8a623ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ xcuserdata
# Rust
target/
+
+# DS Store
+**/.DS_Store
diff --git a/Apple/App/App-macOS.entitlements b/Apple/App/App-macOS.entitlements
index 02ee960..1c1e0ea 100644
--- a/Apple/App/App-macOS.entitlements
+++ b/Apple/App/App-macOS.entitlements
@@ -8,7 +8,7 @@
com.apple.security.application-groups
- $(APP_GROUP_IDENTIFIER)
+ group.com.hackclub.burrow
diff --git a/Apple/App/Assets.xcassets/OnboardingBackground.imageset/Contents.json b/Apple/App/Assets.xcassets/OnboardingBackground.imageset/Contents.json
new file mode 100644
index 0000000..dac90f3
--- /dev/null
+++ b/Apple/App/Assets.xcassets/OnboardingBackground.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "background.jpeg",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Apple/App/Assets.xcassets/OnboardingBackground.imageset/background.jpeg b/Apple/App/Assets.xcassets/OnboardingBackground.imageset/background.jpeg
new file mode 100644
index 0000000..dba511b
Binary files /dev/null and b/Apple/App/Assets.xcassets/OnboardingBackground.imageset/background.jpeg differ
diff --git a/Apple/App/BurrowApp.swift b/Apple/App/BurrowApp.swift
index 50a7231..9689c35 100644
--- a/Apple/App/BurrowApp.swift
+++ b/Apple/App/BurrowApp.swift
@@ -1,17 +1,62 @@
import NetworkExtension
import SwiftUI
+@available(macOS 13.0, *)
@main
@MainActor
struct BurrowApp: App {
+ // To connect to the App Delegate
+ @NSApplicationDelegateAdaptor(AppDelegate.self)
+ var delegate
+ var body: some Scene {
+ WindowGroup(id: "onboarding", content: {
+ OnboardingView().frame(width: 1000, height: 600.0).scaledToFill().fixedSize()
+ }).windowStyle(.hiddenTitleBar).windowResizability(.contentSize)
+ }
+}
+
+@available(macOS 13.0, *)
+@MainActor
+class AppDelegate: NSObject, NSApplicationDelegate {
static let tunnel = Tunnel { manager, proto in
proto.serverAddress = "hackclub.com"
manager.localizedDescription = "Burrow"
}
- var body: some Scene {
- WindowGroup {
- TunnelView(tunnel: Self.tunnel)
+ // Verifies app status
+ func checkFirstTime() {
+ let launchedBefore = UserDefaults.standard.bool(forKey: "launchedBefore")
+ if launchedBefore {
+ print("Not first launch.")
+ closeApp()
+ } else {
+ print("First launch, setting UserDefault.")
+ setVisited()
+ }
+ }
+
+ var statusItem: NSStatusItem?
+ var popOver = NSPopover()
+ func applicationDidFinishLaunching(_ notification: Notification) {
+ checkFirstTime()
+ let menuView = MenuView(tunnel: AppDelegate.tunnel)
+ // Creating apopOver
+ popOver.behavior = .transient
+ popOver.animates = true
+ popOver.contentViewController = NSViewController()
+ popOver.contentViewController?.view = NSHostingView(rootView: menuView)
+ statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
+ // Safe Check if status Button is Available or not...
+ if let menuButton = statusItem?.button {
+ let icon = "network.badge.shield.half.filled"
+ menuButton.image = NSImage(systemSymbolName: icon, accessibilityDescription: nil)
+ menuButton.action = #selector(menuButtonToggle)
+ }
+ }
+ @objc func
+ menuButtonToggle() {
+ if let menuButton = statusItem?.button {
+ self.popOver.show(relativeTo: menuButton.bounds, of: menuButton, preferredEdge: NSRectEdge.minY)
}
}
}
diff --git a/Apple/App/Menu/MenuView.swift b/Apple/App/Menu/MenuView.swift
new file mode 100644
index 0000000..7db9d7c
--- /dev/null
+++ b/Apple/App/Menu/MenuView.swift
@@ -0,0 +1,68 @@
+//
+// MenuView.swift
+// App
+//
+// Created by Thomas Stubblefield on 5/13/23.
+//
+
+import SwiftUI
+
+struct MenuView: View {
+ @State private var isToggled = false
+ @ObservedObject var tunnel: Tunnel
+
+ private func start() {
+ do {
+ try tunnel.start()
+ } catch {
+ print(error)
+ }
+ }
+
+ private func stop() {
+ tunnel.stop()
+ }
+
+ private func configure() {
+ Task { try await tunnel.configure() }
+ }
+
+ var body: some View {
+ VStack {
+ HStack {
+ Text("Burrow")
+ .fontWeight(.bold)
+
+ Spacer()
+ Toggle("", isOn: $isToggled)
+ .toggleStyle(SwitchToggleStyle(tint: .blue))
+ .onChange(of: isToggled) { value in
+ if value {
+ start()
+ } else {
+ stop()
+ }
+ print("Toggle value: \(value)")
+ }
+ }
+ Divider()
+ switch tunnel.status {
+ case .permissionRequired:
+ VStack(alignment: .leading) {
+ Text("Burrow requires additional permissions to function optimally on your machine. Please grant the necessary permissions to ensure smooth operation.")
+ .font(.caption)
+ .truncationMode(.tail)
+
+ Button("Grant Permissions", action: configure)
+ }
+ default:
+
+ Text("Burrow is equipped with the necessary permissions to operate seamlessly on your device.")
+ .font(.caption)
+ }
+ }
+ .frame(width: 250)
+ .padding(16)
+ .task { await tunnel.update() }
+ }
+}
diff --git a/Apple/App/Menu/OnboardingView.swift b/Apple/App/Menu/OnboardingView.swift
new file mode 100644
index 0000000..48694fb
--- /dev/null
+++ b/Apple/App/Menu/OnboardingView.swift
@@ -0,0 +1,54 @@
+//
+// OnboardingView.swift
+// App
+//
+// Created by Juan Pablo Gutierrez on 25/05/23.
+//
+// Represents the onboarding screen
+
+import SwiftUI
+
+//Sets burrow visited status
+func setVisited() {
+ UserDefaults.standard.set(true, forKey: "launchedBefore")
+}
+
+func closeApp() {
+ setVisited()
+ NSApp.windows.first?.close()
+}
+
+@available(macOS 13.0, *)
+struct OnboardingView: View {
+ var body: some View {
+ ZStack(alignment: .center) {
+ Image("OnboardingBackground")
+ .resizable(resizingMode: .stretch)
+ .aspectRatio(contentMode: .fit)
+ .scaledToFill()
+ Color.black
+ .opacity(0.6)
+ .cornerRadius(15)
+ .blur(radius: 0.2)
+ .edgesIgnoringSafeArea(.all)
+ .frame(width: 450, height: 300)
+ VStack(alignment: .center) {
+ Text("Welcome to burrow").font(.system(size: 24, weight: .bold, design: .rounded))
+ Spacer().frame(height: /*@START_MENU_TOKEN@*/20.0/*@END_MENU_TOKEN@*/)
+ Text("It is a best-in-class tool for burrowing through firewalls.").font(.system(size: 14))
+ Spacer().frame(height: 10.0)
+ Text("Built by teenagers at HackClub").font(.system(size: 14))
+ Button(action: closeApp, label: {
+ Text("Start burrowing")
+ .font(
+ .system(
+ size : 14,
+ weight: .regular,
+ design: .rounded))
+ .padding(.all, 30.0)
+ .foregroundColor(.white)
+ }).buttonBorderShape(.roundedRectangle).buttonStyle(.borderless)
+ }.padding(20.0)
+ }
+ }
+}
diff --git a/Apple/App/Tunnel.swift b/Apple/App/Tunnel.swift
index ae185a4..e8bff22 100644
--- a/Apple/App/Tunnel.swift
+++ b/Apple/App/Tunnel.swift
@@ -92,7 +92,7 @@ class Tunnel: ObservableObject {
let proto = NETunnelProviderProtocol()
proto.providerBundleIdentifier = bundleIdentifier
configure(manager, proto)
-
+
manager.protocolConfiguration = proto
try await manager.save()
}
diff --git a/Apple/App/TunnelView.swift b/Apple/App/TunnelView.swift
index 6692a04..e3b9e28 100644
--- a/Apple/App/TunnelView.swift
+++ b/Apple/App/TunnelView.swift
@@ -1,35 +1,36 @@
import SwiftUI
struct TunnelView: View {
- @ObservedObject var tunnel: Tunnel
+// @ObservedObject var tunnel: Tunnel
var body: some View {
- VStack {
- Text(verbatim: tunnel.status.description)
- switch tunnel.status {
- case .connected:
- Button("Disconnect", action: stop)
- case .permissionRequired:
- Button("Allow", action: configure)
- case .disconnected:
- Button("Start", action: start)
- default:
- EmptyView()
- }
- }
- .task { await tunnel.update() }
- .padding()
+ EmptyView()
+// VStack {
+// Text(verbatim: tunnel.status.description)
+// switch tunnel.status {
+// case .connected:
+// Button("Disconnect", action: stop)
+// case .permissionRequired:
+// Button("Allow", action: configure)
+// case .disconnected:
+// Button("Start", action: start)
+// default:
+// EmptyView()
+// }
+// }
+// .task { await tunnel.update() }
+// .padding()
}
- private func start() {
- try? tunnel.start()
- }
-
- private func stop() {
- tunnel.stop()
- }
-
- private func configure() {
- Task { try await tunnel.configure() }
- }
+// private func start() {
+// try? tunnel.start()
+// }
+//
+// private func stop() {
+// tunnel.stop()
+// }
+//
+// private func configure() {
+// Task { try await tunnel.configure() }
+// }
}
diff --git a/Apple/Burrow.xcodeproj/project.pbxproj b/Apple/Burrow.xcodeproj/project.pbxproj
index 56b64e4..40d3cc2 100644
--- a/Apple/Burrow.xcodeproj/project.pbxproj
+++ b/Apple/Burrow.xcodeproj/project.pbxproj
@@ -7,10 +7,11 @@
objects = {
/* Begin PBXBuildFile section */
+ 43AA26D82A10004900F14CE6 /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AA26D72A10004900F14CE6 /* MenuView.swift */; };
+ 91D80FC72A20615500952E28 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91D80FC62A20615500952E28 /* OnboardingView.swift */; };
D020F65829E4A697002790F6 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D020F65729E4A697002790F6 /* PacketTunnelProvider.swift */; };
D020F65D29E4A697002790F6 /* BurrowNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D020F65329E4A697002790F6 /* BurrowNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
D05B9F7629E39EEC008CB1F9 /* BurrowApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */; };
- D05B9F7829E39EEC008CB1F9 /* TunnelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7729E39EEC008CB1F9 /* TunnelView.swift */; };
D05B9F7A29E39EED008CB1F9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D05B9F7929E39EED008CB1F9 /* Assets.xcassets */; };
D0BCC5FD2A086D4700AD070D /* NetworkExtension+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BCC5FC2A086D4700AD070D /* NetworkExtension+Async.swift */; };
D0BCC5FF2A086E1C00AD070D /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BCC5FE2A086E1C00AD070D /* Status.swift */; };
@@ -44,6 +45,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 43AA26D72A10004900F14CE6 /* MenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = ""; };
+ 91D80FC62A20615500952E28 /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; wrapsLines = 0; };
D020F63D29E4A1FF002790F6 /* Identity.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Identity.xcconfig; sourceTree = ""; };
D020F64029E4A1FF002790F6 /* Compiler.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Compiler.xcconfig; sourceTree = ""; };
D020F64229E4A1FF002790F6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
@@ -60,7 +63,6 @@
D020F66929E4AA74002790F6 /* App-macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "App-macOS.entitlements"; sourceTree = ""; };
D05B9F7229E39EEC008CB1F9 /* Burrow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Burrow.app; sourceTree = BUILT_PRODUCTS_DIR; };
D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurrowApp.swift; sourceTree = ""; };
- D05B9F7729E39EEC008CB1F9 /* TunnelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelView.swift; sourceTree = ""; };
D05B9F7929E39EED008CB1F9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
D0B98FBF29FD8072004E7149 /* build-rust.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-rust.sh"; sourceTree = ""; };
D0B98FC629FDC5B5004E7149 /* Tunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tunnel.swift; sourceTree = ""; };
@@ -90,6 +92,15 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 43AA26D62A0FFFD000F14CE6 /* Menu */ = {
+ isa = PBXGroup;
+ children = (
+ 43AA26D72A10004900F14CE6 /* MenuView.swift */,
+ 91D80FC62A20615500952E28 /* OnboardingView.swift */,
+ );
+ path = Menu;
+ sourceTree = "";
+ };
D020F63C29E4A1FF002790F6 /* Configuration */ = {
isa = PBXGroup;
children = (
@@ -137,8 +148,8 @@
D05B9F7429E39EEC008CB1F9 /* App */ = {
isa = PBXGroup;
children = (
+ 43AA26D62A0FFFD000F14CE6 /* Menu */,
D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */,
- D05B9F7729E39EEC008CB1F9 /* TunnelView.swift */,
D0B98FC629FDC5B5004E7149 /* Tunnel.swift */,
D0BCC5FE2A086E1C00AD070D /* Status.swift */,
D0BCC5FC2A086D4700AD070D /* NetworkExtension+Async.swift */,
@@ -299,10 +310,11 @@
buildActionMask = 2147483647;
files = (
D0BCC6082A0981FE00AD070D /* Tunnel.swift in Sources */,
- D05B9F7829E39EEC008CB1F9 /* TunnelView.swift in Sources */,
+ 43AA26D82A10004900F14CE6 /* MenuView.swift in Sources */,
D0BCC5FF2A086E1C00AD070D /* Status.swift in Sources */,
D05B9F7629E39EEC008CB1F9 /* BurrowApp.swift in Sources */,
D0BCC5FD2A086D4700AD070D /* NetworkExtension+Async.swift in Sources */,
+ 91D80FC72A20615500952E28 /* OnboardingView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -329,6 +341,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = D020F66229E4A6E5002790F6 /* NetworkExtension.xcconfig */;
buildSettings = {
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ INFOPLIST_KEY_CFBundleDisplayName = Burrow;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Hack Club";
+ "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = com.hackclub.burrow.network;
};
name = Debug;
};
@@ -336,6 +352,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = D020F66229E4A6E5002790F6 /* NetworkExtension.xcconfig */;
buildSettings = {
+ DEVELOPMENT_TEAM = P6PV2R9443;
+ INFOPLIST_KEY_CFBundleDisplayName = Burrow;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Hack Club";
+ "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = com.hackclub.burrow.network;
};
name = Release;
};
@@ -357,6 +377,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = D020F64929E4A34B002790F6 /* App.xcconfig */;
buildSettings = {
+ INFOPLIST_KEY_CFBundleDisplayName = Burrow;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
+ INFOPLIST_KEY_LSUIElement = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Hack Club";
};
name = Debug;
};
@@ -364,6 +388,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = D020F64929E4A34B002790F6 /* App.xcconfig */;
buildSettings = {
+ INFOPLIST_KEY_CFBundleDisplayName = Burrow;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
+ INFOPLIST_KEY_LSUIElement = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Hack Club";
};
name = Release;
};
diff --git a/Apple/Configuration/Info.plist b/Apple/Configuration/Info.plist
index 7632dad..0c67376 100644
--- a/Apple/Configuration/Info.plist
+++ b/Apple/Configuration/Info.plist
@@ -1,8 +1,5 @@
-
- CFBundleName
- $(INFOPLIST_KEY_CFBundleDisplayName)
-
+
diff --git a/Apple/NetworkExtension/Info.plist b/Apple/NetworkExtension/Info.plist
index e2cf604..3059459 100644
--- a/Apple/NetworkExtension/Info.plist
+++ b/Apple/NetworkExtension/Info.plist
@@ -2,8 +2,6 @@
- CFBundleName
- $(INFOPLIST_KEY_CFBundleDisplayName)
NSExtension
NSExtensionPointIdentifier
diff --git a/Apple/NetworkExtension/NetworkExtension-macOS.entitlements b/Apple/NetworkExtension/NetworkExtension-macOS.entitlements
index 02ee960..1c1e0ea 100644
--- a/Apple/NetworkExtension/NetworkExtension-macOS.entitlements
+++ b/Apple/NetworkExtension/NetworkExtension-macOS.entitlements
@@ -8,7 +8,7 @@
com.apple.security.application-groups
- $(APP_GROUP_IDENTIFIER)
+ group.com.hackclub.burrow