101 lines
3.6 KiB
Swift
101 lines
3.6 KiB
Swift
import Foundation
|
|
|
|
@MainActor
|
|
final class ProfileStore: ObservableObject {
|
|
@Published var profiles: [ConnectionProfile] = []
|
|
@Published var sshKeys: [StoredSSHKey] = []
|
|
@Published var searchText: String = ""
|
|
@Published var selectedGroup: String = "Alle"
|
|
|
|
private var profilesURL: URL {
|
|
let base = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
|
|
.appendingPathComponent("RemminaMac", isDirectory: true)
|
|
try? FileManager.default.createDirectory(at: base, withIntermediateDirectories: true)
|
|
return base.appendingPathComponent("profiles.json")
|
|
}
|
|
|
|
private var keysURL: URL {
|
|
let base = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
|
|
.appendingPathComponent("RemminaMac", isDirectory: true)
|
|
try? FileManager.default.createDirectory(at: base, withIntermediateDirectories: true)
|
|
return base.appendingPathComponent("sshkeys.json")
|
|
}
|
|
|
|
var groups: [String] {
|
|
let g = Set(profiles.map { $0.group.isEmpty ? "Allgemein" : $0.group })
|
|
return ["Alle"] + g.sorted()
|
|
}
|
|
|
|
var filteredProfiles: [ConnectionProfile] {
|
|
profiles.filter { p in
|
|
let matchGroup = selectedGroup == "Alle" || p.group == selectedGroup
|
|
let matchSearch = searchText.isEmpty ||
|
|
p.name.localizedCaseInsensitiveContains(searchText) ||
|
|
p.host.localizedCaseInsensitiveContains(searchText) ||
|
|
p.username.localizedCaseInsensitiveContains(searchText)
|
|
return matchGroup && matchSearch
|
|
}.sorted { $0.name.localizedCompare($1.name) == .orderedAscending }
|
|
}
|
|
|
|
func load() {
|
|
if let data = try? Data(contentsOf: profilesURL),
|
|
let decoded = try? JSONDecoder().decode([ConnectionProfile].self, from: data) {
|
|
profiles = decoded
|
|
}
|
|
if let data = try? Data(contentsOf: keysURL),
|
|
let decoded = try? JSONDecoder().decode([StoredSSHKey].self, from: data) {
|
|
sshKeys = decoded
|
|
}
|
|
if profiles.isEmpty {
|
|
profiles = Self.sampleProfiles
|
|
}
|
|
}
|
|
|
|
func save() {
|
|
if let data = try? JSONEncoder().encode(profiles) {
|
|
try? data.write(to: profilesURL)
|
|
}
|
|
if let data = try? JSONEncoder().encode(sshKeys) {
|
|
try? data.write(to: keysURL)
|
|
}
|
|
}
|
|
|
|
func add(_ profile: ConnectionProfile) {
|
|
profiles.append(profile)
|
|
save()
|
|
}
|
|
|
|
func update(_ profile: ConnectionProfile) {
|
|
if let i = profiles.firstIndex(where: { $0.id == profile.id }) {
|
|
profiles[i] = profile
|
|
save()
|
|
}
|
|
}
|
|
|
|
func delete(_ profile: ConnectionProfile) {
|
|
profiles.removeAll { $0.id == profile.id }
|
|
save()
|
|
}
|
|
|
|
func duplicate(_ profile: ConnectionProfile) {
|
|
var copy = profile
|
|
copy.id = UUID()
|
|
copy.name += " (Kopie)"
|
|
copy.passwordAccount = nil
|
|
add(copy)
|
|
}
|
|
|
|
func key(for profile: ConnectionProfile) -> StoredSSHKey? {
|
|
guard let id = profile.sshKeyID else { return nil }
|
|
return sshKeys.first { $0.id == id }
|
|
}
|
|
|
|
static var sampleProfiles: [ConnectionProfile] {
|
|
[
|
|
ConnectionProfile(name: "Webserver", proto: .ssh, host: "192.168.1.10", port: 22, username: "admin", group: "Server"),
|
|
ConnectionProfile(name: "Büro-PC", proto: .rdp, host: "192.168.1.50", port: 3389, username: "user", group: "Windows"),
|
|
ConnectionProfile(name: "Dateiserver", proto: .sftp, host: "nas.local", port: 22, username: "nas", group: "Server")
|
|
]
|
|
}
|
|
}
|