Passwort nutzen: Auto-Login via sshpass + Keychain, Editor mit Anzeige/Loeschen, Doku
This commit is contained in:
@@ -104,7 +104,7 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
.sheet(item: $editingProfile) { profile in
|
||||
ProfileEditorView(profile: profile) { saved in
|
||||
ProfileEditorView(profile: profile, isNew: !store.profiles.contains(where: { $0.id == profile.id })) { saved in
|
||||
if store.profiles.contains(where: { $0.id == saved.id }) {
|
||||
store.update(saved)
|
||||
} else {
|
||||
|
||||
@@ -164,7 +164,7 @@ struct EmbeddedTerminalView: View {
|
||||
if checking { return "Prüfe \(profile.host):\(profile.port) …" }
|
||||
switch term.state {
|
||||
case .never: return canConnect ? "Bereit — verbindet beim Öffnen." : "Host/Benutzer fehlt."
|
||||
case .running: return "Verbunden (PTY, TERM=xterm-256color)."
|
||||
case .running: return term.autoLogin ? "Verbunden (Auto-Login via Keychain)." : "Verbunden (PTY, TERM=xterm-256color)."
|
||||
case .done(_, let msg): return msg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,21 @@ struct ProfileEditorView: View {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@EnvironmentObject var store: ProfileStore
|
||||
@State var profile: ConnectionProfile
|
||||
var isNew: Bool
|
||||
var onSave: (ConnectionProfile) -> Void
|
||||
@State private var password: String = ""
|
||||
@State private var savePassword: Bool = false
|
||||
@State private var storedPasswordPresent: Bool = false
|
||||
|
||||
init(profile: ConnectionProfile, onSave: @escaping (ConnectionProfile) -> Void) {
|
||||
init(profile: ConnectionProfile, isNew: Bool, onSave: @escaping (ConnectionProfile) -> Void) {
|
||||
_profile = State(initialValue: profile)
|
||||
self.isNew = isNew
|
||||
self.onSave = onSave
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
Text(profile.id.uuidString.prefix(8) == ConnectionProfile().id.uuidString.prefix(8) ? "Profil bearbeiten" : "Profil").font(.headline).padding()
|
||||
Text(isNew ? "Neues Profil" : "Profil bearbeiten").font(.headline).padding()
|
||||
Form {
|
||||
Section("Allgemein") {
|
||||
TextField("Name", text: $profile.name)
|
||||
@@ -44,8 +47,17 @@ struct ProfileEditorView: View {
|
||||
Text("Kein Key").tag(UUID?.none)
|
||||
ForEach(store.sshKeys) { k in Text(k.name).tag(UUID?.some(k.id)) }
|
||||
}
|
||||
SecureField("Passwort (optional, Keychain)", text: $password)
|
||||
if storedPasswordPresent && password.isEmpty {
|
||||
HStack {
|
||||
Image(systemName: "checkmark.circle.fill").foregroundStyle(.green)
|
||||
Text("Passwort in Keychain gespeichert")
|
||||
Spacer()
|
||||
Button("Löschen", role: .destructive) { deleteStoredPassword() }
|
||||
}
|
||||
}
|
||||
SecureField(storedPasswordPresent ? "Neues Passwort …" : "Passwort (optional, Keychain)", text: $password)
|
||||
Toggle("Passwort in Keychain speichern", isOn: $savePassword)
|
||||
Text(sshpassHint).font(.caption).foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
@@ -68,12 +80,30 @@ struct ProfileEditorView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.frame(width: 520, height: 620)
|
||||
.frame(width: 520, height: 640)
|
||||
.onAppear {
|
||||
if let acct = profile.passwordAccount {
|
||||
password = KeychainHelper.load(account: acct) ?? ""
|
||||
savePassword = !password.isEmpty
|
||||
if let acct = profile.passwordAccount,
|
||||
let stored = KeychainHelper.load(account: acct), !stored.isEmpty {
|
||||
storedPasswordPresent = true
|
||||
savePassword = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sshpassHint: String {
|
||||
if SSHService.findSshpass() != nil {
|
||||
return "sshpass gefunden → Auto-Login mit Keychain-Passwort aktiv, kein Tippen nötig."
|
||||
} else {
|
||||
return "Ohne sshpass: Passwort wird beim Verbinden im Terminal abgefragt. Für Auto-Login: brew install sshpass."
|
||||
}
|
||||
}
|
||||
|
||||
func deleteStoredPassword() {
|
||||
if let acct = profile.passwordAccount {
|
||||
KeychainHelper.delete(account: acct)
|
||||
}
|
||||
password = ""
|
||||
savePassword = false
|
||||
storedPasswordPresent = false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user