made more funcitons throw errors instead of just return, more informative

added name to host
removed hostkey from connectionview as its in keys now
fix crash on force unrap in keypair navigatoin labels
added hostinvalid() to check if the host is invalid
added case notconnected for keyerror
openshell is throwing
moved stuff round
This commit is contained in:
neon443
2025-06-25 17:17:47 +01:00
parent 2548dde85b
commit 76601e0470
12 changed files with 91 additions and 39 deletions

View File

@@ -0,0 +1,160 @@
//
// ConnectionView.swift
// ShhShell
//
// Created by neon443 on 20/06/2025.
//
import SwiftUI
struct ConnectionView: View {
@ObservedObject var handler: SSHHandler
@ObservedObject var hostsManager: HostsManager
@ObservedObject var keyManager: KeyManager
@State var passphrase: String = ""
@State var pubkeyStr: String = ""
@State var privkeyStr: String = ""
@State var showTerminal: Bool = false
@State var hostKeyChangedAlert: Bool = false
var body: some View {
NavigationStack {
List {
Section {
HStack {
Text(handler.connected ? "connected" : "not connected")
.modifier(foregroundColorStyle(handler.connected ? .green : .red))
Text(checkAuth(handler.state) ? "authorized" : "unauthorized")
.modifier(foregroundColorStyle(checkAuth(handler.state) ? .green : .red))
Text("\(handler.state)")
}
TextField("address", text: $handler.host.address)
.textFieldStyle(.roundedBorder)
TextField(
"port",
text: Binding(
get: { String(handler.host.port) },
set: {
if let input = Int($0) {
handler.host.port = input
}
}
)
)
.keyboardType(.numberPad)
.textFieldStyle(.roundedBorder)
}
Section {
TextField("Username", text: $handler.host.username)
.textFieldStyle(.roundedBorder)
SecureField("Password", text: $handler.host.password)
.textFieldStyle(.roundedBorder)
HStack {
TextField("", text: $pubkeyStr, prompt: Text("Public Key"))
.onSubmit {
let newStr = pubkeyStr.replacingOccurrences(of: "\r\n", with: "")
handler.host.publicKey = Data(newStr.utf8)
}
}
HStack {
SecureField("", text: $privkeyStr, prompt: Text("Private Key"))
.onSubmit {
let newStr = privkeyStr.replacingOccurrences(of: "\r\n", with: "")
handler.host.privateKey = Data(newStr.utf8)
}
}
TextField("", text: $passphrase, prompt: Text("Passphrase (Optional)"))
}
Button() {
showTerminal.toggle()
} label: {
Label("Show Terminal", systemImage: "apple.terminal")
}
.disabled(!checkShell(handler.state))
Button() {
handler.testExec()
} label: {
if let testResult = handler.testSuceeded {
Image(systemName: testResult ? "checkmark.circle" : "xmark.circle")
.modifier(foregroundColorStyle(testResult ? .green : .red))
} else {
Label("Test Connection", systemImage: "checkmark")
}
}
}
.alert("Hostkey changed", isPresented: $hostKeyChangedAlert) {
Button("Accept New Hostkey", role: .destructive) {
hostsManager.updateHost(handler.host)
handler.go()
}
Button("Disconnect", role: .cancel) {
handler.disconnect()
handler.host.key = hostsManager.getHostMatching(handler.host)?.key
}
} message: {
Text("Expected \(handler.host.key ?? "nil")\nbut recieved \(handler.getHostkey() ?? "nil") from the server")
}
.transition(.opacity)
.toolbar {
ToolbarItem() {
Button() {
handler.go()
showTerminal = checkShell(handler.state)
} label: {
Label(
handler.connected ? "Disconnect" : "Connect",
systemImage: handler.connected ? "xmark.app.fill" : "power"
)
}
.disabled(handler.hostInvalid())
}
}
}
.fullScreenCover(isPresented: $showTerminal) {
ShellView(handler: handler)
}
.onChange(of: handler.host.key) { _ in
guard let previousKnownHost = hostsManager.getHostMatching(handler.host) else { return }
guard handler.host.key == previousKnownHost.key else {
hostKeyChangedAlert = true
return
}
}
.onDisappear {
guard hostsManager.getHostMatching(handler.host) == handler.host else {
hostsManager.updateHost(handler.host)
return
}
}
.task {
if let publicKeyData = handler.host.publicKey {
pubkeyStr = String(data: publicKeyData, encoding: .utf8) ?? ""
}
if let privateKeyData = handler.host.privateKey {
privkeyStr = String(data: privateKeyData, encoding: .utf8) ?? ""
}
}
}
}
#Preview {
ConnectionView(
handler: SSHHandler(host: Host.debug),
hostsManager: HostsManager(),
keyManager: KeyManager()
)
}