diff --git a/SecretKit/Secret.swift b/SecretKit/Secret.swift new file mode 100644 index 0000000..2a84f5b --- /dev/null +++ b/SecretKit/Secret.swift @@ -0,0 +1,5 @@ +import Foundation + +public protocol Secret: Identifiable, Hashable { + var id: String { get } +} diff --git a/SecretKit/SecretStore.swift b/SecretKit/SecretStore.swift new file mode 100644 index 0000000..88f2eab --- /dev/null +++ b/SecretKit/SecretStore.swift @@ -0,0 +1,9 @@ +import Foundation +import Combine + +public protocol SecretStore: ObservableObject { + + associatedtype SecretType: Secret + var secrets: [SecretType] { get } + +} diff --git a/SecretKit/SecureEnclave/SecureEnclave.swift b/SecretKit/SecureEnclave/SecureEnclave.swift new file mode 100644 index 0000000..2536bc9 --- /dev/null +++ b/SecretKit/SecureEnclave/SecureEnclave.swift @@ -0,0 +1,3 @@ +import Foundation + +public enum SecureEnclave {} diff --git a/SecretKit/SecureEnclave/SecureEnclaveSecret.swift b/SecretKit/SecureEnclave/SecureEnclaveSecret.swift new file mode 100644 index 0000000..5d60ff8 --- /dev/null +++ b/SecretKit/SecureEnclave/SecureEnclaveSecret.swift @@ -0,0 +1,12 @@ +import Foundation +import Combine + +extension SecureEnclave { + + public struct Secret: SecretKit.Secret { + + public let id: String + + } + +} diff --git a/SecretKit/SecureEnclave/SecureEnclaveStore.swift b/SecretKit/SecureEnclave/SecureEnclaveStore.swift new file mode 100644 index 0000000..b340d6c --- /dev/null +++ b/SecretKit/SecureEnclave/SecureEnclaveStore.swift @@ -0,0 +1,21 @@ +import Foundation +import Security + +extension SecureEnclave { + + public class Store: SecretStore { + + @Published public fileprivate(set) var secrets: [Secret] = [] + + public init() { + loadSecrets() + } + + fileprivate func loadSecrets() { + let secret = Secret(id: "Test") + secrets.append(secret) + } + + } + +} diff --git a/Secretive.xcodeproj/project.pbxproj b/Secretive.xcodeproj/project.pbxproj index ff2d8cd..57b1965 100644 --- a/Secretive.xcodeproj/project.pbxproj +++ b/Secretive.xcodeproj/project.pbxproj @@ -18,6 +18,12 @@ 50617DBA23FCE4AB0099B055 /* SecretKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 50617DAA23FCE4AB0099B055 /* SecretKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 50617DBD23FCE4AB0099B055 /* SecretKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; }; 50617DBE23FCE4AB0099B055 /* SecretKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 50617DC723FCE4EA0099B055 /* SecretStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DC623FCE4EA0099B055 /* SecretStore.swift */; }; + 50617DC923FCE50E0099B055 /* SecureEnclaveStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DC823FCE50E0099B055 /* SecureEnclaveStore.swift */; }; + 50617DCB23FCECA10099B055 /* Secret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCA23FCECA10099B055 /* Secret.swift */; }; + 50617DCE23FCECFA0099B055 /* SecureEnclaveSecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */; }; + 50617DD023FCED2C0099B055 /* SecureEnclave.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */; }; + 50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DD123FCEFA90099B055 /* PreviewStore.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -83,6 +89,12 @@ 50617DB023FCE4AB0099B055 /* SecretKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecretKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50617DB723FCE4AB0099B055 /* SecretKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretKitTests.swift; sourceTree = ""; }; 50617DB923FCE4AB0099B055 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 50617DC623FCE4EA0099B055 /* SecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStore.swift; sourceTree = ""; }; + 50617DC823FCE50E0099B055 /* SecureEnclaveStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclaveStore.swift; sourceTree = ""; }; + 50617DCA23FCECA10099B055 /* Secret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Secret.swift; sourceTree = ""; }; + 50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclaveSecret.swift; sourceTree = ""; }; + 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclave.swift; sourceTree = ""; }; + 50617DD123FCEFA90099B055 /* PreviewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewStore.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -159,6 +171,7 @@ isa = PBXGroup; children = ( 50617D8923FCE48E0099B055 /* Preview Assets.xcassets */, + 50617DD123FCEFA90099B055 /* PreviewStore.swift */, ); path = "Preview Content"; sourceTree = ""; @@ -176,6 +189,9 @@ isa = PBXGroup; children = ( 50617DAA23FCE4AB0099B055 /* SecretKit.h */, + 50617DCA23FCECA10099B055 /* Secret.swift */, + 50617DC623FCE4EA0099B055 /* SecretStore.swift */, + 50617DCC23FCECEE0099B055 /* SecureEnclave */, 50617DAB23FCE4AB0099B055 /* Info.plist */, ); path = SecretKit; @@ -190,6 +206,16 @@ path = SecretKitTests; sourceTree = ""; }; + 50617DCC23FCECEE0099B055 /* SecureEnclave */ = { + isa = PBXGroup; + children = ( + 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */, + 50617DCD23FCECFA0099B055 /* SecureEnclaveSecret.swift */, + 50617DC823FCE50E0099B055 /* SecureEnclaveStore.swift */, + ); + path = SecureEnclave; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -297,6 +323,7 @@ }; 50617DA723FCE4AB0099B055 = { CreatedOnToolsVersion = 11.3; + LastSwiftMigration = 1130; }; 50617DAF23FCE4AB0099B055 = { CreatedOnToolsVersion = 11.3; @@ -365,6 +392,7 @@ buildActionMask = 2147483647; files = ( 50617D8523FCE48E0099B055 /* ContentView.swift in Sources */, + 50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */, 50617D8323FCE48E0099B055 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -381,6 +409,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 50617DC723FCE4EA0099B055 /* SecretStore.swift in Sources */, + 50617DCB23FCECA10099B055 /* Secret.swift in Sources */, + 50617DC923FCE50E0099B055 /* SecureEnclaveStore.swift in Sources */, + 50617DCE23FCECFA0099B055 /* SecureEnclaveSecret.swift in Sources */, + 50617DD023FCED2C0099B055 /* SecureEnclave.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -545,6 +578,7 @@ 50617D9E23FCE48E0099B055 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Secretive/Secretive.entitlements; CODE_SIGN_STYLE = Automatic; @@ -568,6 +602,7 @@ 50617D9F23FCE48E0099B055 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = Secretive/Secretive.entitlements; CODE_SIGN_STYLE = Automatic; @@ -635,6 +670,7 @@ 50617DC023FCE4AB0099B055 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; @@ -653,6 +689,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretKit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -662,6 +699,7 @@ 50617DC123FCE4AB0099B055 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; diff --git a/Secretive/AppDelegate.swift b/Secretive/AppDelegate.swift index bac94de..f540eea 100644 --- a/Secretive/AppDelegate.swift +++ b/Secretive/AppDelegate.swift @@ -1,13 +1,6 @@ -// -// AppDelegate.swift -// Secretive -// -// Created by Max Goedjen on 2/18/20. -// Copyright © 2020 Max Goedjen. All rights reserved. -// - import Cocoa import SwiftUI +import SecretKit @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @@ -16,10 +9,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { - // Create the SwiftUI view that provides the window contents. - let contentView = ContentView() - // Create the window and set the content view. + let secureEnclave = SecureEnclave.Store() + let contentView = ContentView(store: secureEnclave) + + // Create the window and set the content view. window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], diff --git a/Secretive/ContentView.swift b/Secretive/ContentView.swift index 399a13d..51d49bf 100644 --- a/Secretive/ContentView.swift +++ b/Secretive/ContentView.swift @@ -7,17 +7,33 @@ // import SwiftUI +import SecretKit + +struct ContentView: View { + + @ObservedObject var store: StoreType + + @State var pk: String = "" -struct ContentView: View { var body: some View { - Text("Hello, World!") - .frame(maxWidth: .infinity, maxHeight: .infinity) + HSplitView { + List { + ForEach(store.secrets) { secret in + Text(secret.id) + } + }.listStyle(SidebarListStyle()) + Form { + Text("Public Key") + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { - ContentView() + ContentView(store: Preview.Store(numberOfRandomSecrets: 10)) } } + diff --git a/Secretive/Preview Content/PreviewStore.swift b/Secretive/Preview Content/PreviewStore.swift new file mode 100644 index 0000000..7173bbd --- /dev/null +++ b/Secretive/Preview Content/PreviewStore.swift @@ -0,0 +1,36 @@ +import Foundation +import SecretKit + +enum Preview {} + +extension Preview { + + struct Secret: SecretKit.Secret { + + let id = UUID().uuidString + var name: String { + return id + } + + } + +} + +extension Preview { + + class Store: SecretStore, ObservableObject { + + @Published var secrets: [Secret] = [] + + init(secrets: [Secret]) { + self.secrets.append(contentsOf: secrets) + } + + init(numberOfRandomSecrets: Int) { + let new = (0...numberOfRandomSecrets).map { _ in Secret() } + self.secrets.append(contentsOf: new) + } + + } + +}