More progress.

This commit is contained in:
Max Goedjen
2020-03-08 20:03:40 -07:00
parent a9d7e7644e
commit 376f26ef38
11 changed files with 130 additions and 65 deletions

View File

@@ -7,15 +7,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
@IBOutlet var toolbar: NSToolbar!
let secureEnclave = SecureEnclave.Store()
let smartCard = SmartCard.Store()
lazy var allStores: [AnySecretStore] = {
[AnySecretStore(secureEnclave), AnySecretStore(smartCard)]
let storeList: SecretStoreList = {
let list = SecretStoreList()
list.add(store: SecureEnclave.Store())
list.add(store: SmartCard.Store())
return list
}()
func applicationDidFinishLaunching(_ aNotification: Notification) {
let contentView = ContentView(secureEnclave: secureEnclave, smartCard: smartCard)
let contentView = ContentView(storeList: storeList)
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
@@ -27,7 +28,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
window.makeKeyAndOrderFront(nil)
window.titleVisibility = .hidden
window.toolbar = toolbar
if secureEnclave.isAvailable {
if storeList.modifiableStore?.isAvailable ?? false {
let plus = NSTitlebarAccessoryViewController()
plus.view = NSButton(image: NSImage(named: NSImage.addTemplateName)!, target: self, action: #selector(add(sender:)))
plus.layoutAttribute = .right
@@ -38,7 +39,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBAction func add(sender: AnyObject?) {
var addWindow: NSWindow!
let addView = CreateSecretView(store: secureEnclave) {
let addView = CreateSecretView(store: storeList.modifiableStore!) {
self.window.endSheet(addWindow)
}
addWindow = NSWindow(

View File

@@ -3,57 +3,53 @@ import SecretKit
struct ContentView: View {
@ObservedObject var secureEnclave: SecureEnclave.Store
@ObservedObject var smartCard: SmartCard.Store
@State var active: Data?
@ObservedObject var storeList: SecretStoreList
@State var active: AnySecret.ID?
@State var showingDeletion = false
@State var deletingSecret: SecureEnclave.Secret?
@State var deletingSecret: AnySecret?
var body: some View {
NavigationView {
List(selection: $active) {
if secureEnclave.isAvailable {
Section(header: Text(secureEnclave.name)) {
ForEach(secureEnclave.secrets) { secret in
NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: self.$active) {
Text(secret.name)
}.contextMenu {
Button(action: { self.delete(secret: secret) }) {
Text("Delete")
ForEach(storeList.stores) { store in
if store.isAvailable {
Section(header: Text(store.name)) {
ForEach(store.secrets) { secret in
NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: self.$active) {
Text(secret.name)
}.contextMenu {
if store is AnySecretStoreModifiable {
Button(action: { self.delete(secret: secret) }) {
Text("Delete")
}
}
}
}
}
}
}
if smartCard.isAvailable {
Section(header: Text(smartCard.name)) {
ForEach(smartCard.secrets) { secret in
NavigationLink(destination: SecretDetailView(secret: secret), tag: secret.id, selection: self.$active) {
Text(secret.name)
}
}
}
}
}.onAppear {
self.active = self.secureEnclave.secrets.first?.id ?? self.smartCard.secrets.first?.id
self.active = self.storeList.stores.compactMap { $0.secrets.first }.first?.id
}
.listStyle(SidebarListStyle())
.frame(minWidth: 100, idealWidth: 240)
}
.navigationViewStyle(DoubleColumnNavigationViewStyle())
.sheet(isPresented: $showingDeletion) {
DeleteSecretView(secret: self.deletingSecret!, store: self.secureEnclave) {
self.showingDeletion = false
if self.storeList.modifiableStore != nil {
DeleteSecretView(secret: self.deletingSecret!, store: self.storeList.modifiableStore!) {
self.showingDeletion = false
}
}
}
}
func delete(secret: SecureEnclave.Secret) {
deletingSecret = secret
showingDeletion = true
func delete<SecretType: Secret>(secret: SecretType) {
deletingSecret = AnySecret(secret)
self.showingDeletion = true
}
}

View File

@@ -3,7 +3,7 @@ import SecretKit
struct CreateSecretView: View {
@ObservedObject var store: SecureEnclave.Store
@ObservedObject var store: AnySecretStoreModifiable
@State var name = ""
@State var requiresAuthentication = true

View File

@@ -1,16 +1,16 @@
import SwiftUI
import SecretKit
struct DeleteSecretView: View {
struct DeleteSecretView<StoreType: SecretStoreModifiable>: View {
let secret: SecureEnclave.Secret
@ObservedObject var store: SecureEnclave.Store
let secret: StoreType.SecretType
@ObservedObject var store: StoreType
@State var confirm = ""
fileprivate var dismissalBlock: () -> ()
init(secret: SecureEnclave.Secret, store: SecureEnclave.Store, dismissalBlock: @escaping () -> ()) {
init(secret: StoreType.SecretType, store: StoreType, dismissalBlock: @escaping () -> ()) {
self.secret = secret
self.store = store
self.dismissalBlock = dismissalBlock

View File

@@ -20,6 +20,7 @@ extension Preview {
class Store: SecretStore, ObservableObject {
let isAvailable = true
let id = UUID()
let name = "Preview Store"
@Published var secrets: [Secret] = []