import SwiftUI import CryptoKit struct SingleKeyView: View { @State private var needRefresh = false @Binding var keyManager: KeyManagement @State private var showEditWindow = false @State private var keyText = "" let type: KeyManagement.KeyType private var generateText: String { hasKey ? "Regenerate" : "Generate" } var hasKey: Bool { keyManager.has(type) } var content: String { keyManager.get(type)?.displayString ?? "-" } var copyText: String { guard let key = keyManager.get(type)?.data else { return "" } guard type.usesHashing else { return key.hexEncoded } return SHA256.hash(data: key).hexEncoded } var body: some View { VStack(alignment: .leading, spacing: 8) { Text(type.displayName) .bold() Text(needRefresh ? content : content) .font(.system(.body, design: .monospaced)) .foregroundColor(.secondary) HStack() { Button(generateText) { keyManager.generate(type) needRefresh.toggle() } .padding([.horizontal, .bottom]) .padding(.top, 4) Button(type.usesHashing ? "Copy hash" : "Copy") { UIPasteboard.general.string = copyText } .disabled(!hasKey) .padding([.horizontal, .bottom]) .padding(.top, 4) Button("Edit") { keyText = keyManager.get(type)?.displayString ?? "" print("Set key text to '\(keyText)'") showEditWindow = true } .padding([.horizontal, .bottom]) .padding(.top, 4) Spacer() } } .alert("Update key", isPresented: $showEditWindow, actions: { TextField("Key data", text: $keyText) .lineLimit(4) .font(.system(.body, design: .monospaced)) .foregroundColor(.black) Button("Save", action: saveKey) Button("Cancel", role: .cancel, action: {}) }, message: { Text("Enter the hex encoded key") }) } private func saveKey() { let cleanText = keyText.replacingOccurrences(of: " ", with: "") guard let keyData = Data(fromHexEncodedString: cleanText) else { print("Invalid key string") return } let keyLength = type.keyLength.bitCount guard keyData.count * 8 == keyLength else { print("Invalid key length \(keyData.count * 8) bits, expected \(keyLength)") return } keyManager.save(type, data: keyData) print("Key \(type) saved") } } struct SingleKeyView_Previews: PreviewProvider { static var previews: some View { SingleKeyView( keyManager: .constant(KeyManagement()), type: .deviceKey) .previewLayout(.fixed(width: 350, height: 100)) } }