Files
ShhShell/ShhShell/Views/Hosts/ConnectionView.swift
neon443 76601e0470 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
2025-06-25 17:17:47 +01:00

161 lines
4.2 KiB
Swift

//
// 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()
)
}