diff --git a/Brief/Brief.h b/Brief/Brief.h new file mode 100644 index 0000000..acf94a4 --- /dev/null +++ b/Brief/Brief.h @@ -0,0 +1,19 @@ +// +// Brief.h +// Brief +// +// Created by Max Goedjen on 3/21/20. +// Copyright © 2020 Max Goedjen. All rights reserved. +// + +#import + +//! Project version number for Brief. +FOUNDATION_EXPORT double BriefVersionNumber; + +//! Project version string for Brief. +FOUNDATION_EXPORT const unsigned char BriefVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Brief/Info.plist b/Brief/Info.plist new file mode 100644 index 0000000..d5ff04c --- /dev/null +++ b/Brief/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2020 Max Goedjen. All rights reserved. + + diff --git a/Secretive/Controllers/Updater.swift b/Brief/Updater.swift similarity index 76% rename from Secretive/Controllers/Updater.swift rename to Brief/Updater.swift index 25e361b..378ba18 100644 --- a/Secretive/Controllers/Updater.swift +++ b/Brief/Updater.swift @@ -1,17 +1,17 @@ import Foundation import Combine -protocol UpdaterProtocol: ObservableObject { +public protocol UpdaterProtocol: ObservableObject { var update: Release? { get } } -class Updater: ObservableObject, UpdaterProtocol { +public class Updater: ObservableObject, UpdaterProtocol { - @Published var update: Release? + @Published public var update: Release? - init() { + public init() { checkForUpdates() let timer = Timer.scheduledTimer(withTimeInterval: 60*60*24, repeats: true) { _ in self.checkForUpdates() @@ -19,7 +19,7 @@ class Updater: ObservableObject, UpdaterProtocol { timer.tolerance = 60*60 } - func checkForUpdates() { + public func checkForUpdates() { URLSession.shared.dataTask(with: Constants.updateURL) { data, _, _ in guard let data = data else { return } guard let release = try? JSONDecoder().decode(Release.self, from: data) else { return } @@ -58,16 +58,24 @@ extension Updater { } -struct Release: Codable { - let name: String - let html_url: URL - let body: String +public struct Release: Codable { + + public let name: String + public let html_url: URL + public let body: String + + public init(name: String, html_url: URL, body: String) { + self.name = name + self.html_url = html_url + self.body = body + } + } extension Release { - var critical: Bool { + public var critical: Bool { return body.contains(Constants.securityContent) } diff --git a/SecretAgent/AppDelegate.swift b/SecretAgent/AppDelegate.swift index e022e6f..41ae78c 100644 --- a/SecretAgent/AppDelegate.swift +++ b/SecretAgent/AppDelegate.swift @@ -1,7 +1,9 @@ import Cocoa +import OSLog +import Combine import SecretKit import SecretAgentKit -import OSLog +import Brief @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @@ -12,6 +14,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { list.add(store: SmartCard.Store()) return list }() + let updater = Updater() let notifier = Notifier() lazy var agent: Agent = { Agent(storeList: storeList, witness: notifier) @@ -20,6 +23,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String return SocketController(path: path) }() + fileprivate var updateSink: AnyCancellable? func applicationDidFinishLaunching(_ aNotification: Notification) { os_log(.debug, "SecretAgent finished launching") @@ -27,10 +31,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { self.socketController.handler = self.agent.handle(fileHandle:) } notifier.prompt() - } - - func applicationWillTerminate(_ aNotification: Notification) { - // Insert code here to tear down your application + updateSink = updater.$update.sink { release in + guard let release = release else { return } + self.notifier.notify(update: release) + } } diff --git a/SecretAgent/Notifier.swift b/SecretAgent/Notifier.swift index d805066..b55d9c8 100644 --- a/SecretAgent/Notifier.swift +++ b/SecretAgent/Notifier.swift @@ -1,11 +1,21 @@ import Foundation -import SecretKit -import SecretAgentKit import UserNotifications import AppKit +import SecretKit +import SecretAgentKit +import Brief class Notifier { + fileprivate let notificationDelegate = NotificationDelegate() + + init() { + let action = UNNotificationAction(identifier: Constants.updateIdentitifier, title: "Update", options: []) + let categories = UNNotificationCategory(identifier: Constants.updateIdentitifier, actions: [action], intentIdentifiers: [], options: []) + UNUserNotificationCenter.current().setNotificationCategories([categories]) + UNUserNotificationCenter.current().delegate = notificationDelegate + } + func prompt() { let notificationCenter = UNUserNotificationCenter.current() notificationCenter.requestAuthorization(options: .alert) { _, _ in @@ -24,6 +34,22 @@ class Notifier { notificationCenter.add(request, withCompletionHandler: nil) } + func notify(update: Release) { + notificationDelegate.release = update + let notificationCenter = UNUserNotificationCenter.current() + let notificationContent = UNMutableNotificationContent() + if update.critical { + notificationContent.title = "Critical Security Update - \(update.name)" + } else { + notificationContent.title = "Update Available - \(update.name)" + } + notificationContent.subtitle = "Click to Update" + notificationContent.body = update.body + notificationContent.categoryIdentifier = Constants.updateIdentitifier + let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil) + notificationCenter.add(request, withCompletionHandler: nil) + } + } extension Notifier { @@ -53,3 +79,32 @@ extension Notifier: SigningWitness { } } + +extension Notifier { + + enum Constants { + static let updateIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update" + } + +} + +class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate { + + fileprivate var release: Release? + + func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) { + + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + guard response.notification.request.content.categoryIdentifier == Notifier.Constants.updateIdentitifier else { return } + guard let update = release else { return } + NSWorkspace.shared.open(update.html_url) + completionHandler() + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + completionHandler(.alert) + } + +} diff --git a/SecretAgent/SecretAgent.entitlements b/SecretAgent/SecretAgent.entitlements index 82ba56c..895fc77 100644 --- a/SecretAgent/SecretAgent.entitlements +++ b/SecretAgent/SecretAgent.entitlements @@ -4,6 +4,8 @@ com.apple.security.app-sandbox + com.apple.security.network.client + com.apple.security.smartcard keychain-access-groups diff --git a/Secretive.xcodeproj/project.pbxproj b/Secretive.xcodeproj/project.pbxproj index 866bef1..385d623 100644 --- a/Secretive.xcodeproj/project.pbxproj +++ b/Secretive.xcodeproj/project.pbxproj @@ -29,11 +29,15 @@ 506772C72424784600034DED /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 506772C62424784600034DED /* Credits.rtf */; }; 506772C92425BB8500034DED /* NoStoresView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506772C82425BB8500034DED /* NoStoresView.swift */; }; 506772CB2426CCC200034DED /* Untitled.png in Resources */ = {isa = PBXBuildFile; fileRef = 506772CA2426CCC200034DED /* Untitled.png */; }; + 506772FF2426F3F400034DED /* Brief.h in Headers */ = {isa = PBXBuildFile; fileRef = 506772FD2426F3F400034DED /* Brief.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 506773022426F3F400034DED /* Brief.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 506772FB2426F3F400034DED /* Brief.framework */; }; + 506773032426F3F400034DED /* Brief.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 506772FB2426F3F400034DED /* Brief.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 506773092426F3FD00034DED /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506773082426F3FD00034DED /* Updater.swift */; }; + 5067730C2426F40E00034DED /* Brief.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 506772FB2426F3F400034DED /* Brief.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5068389E241471CD00F55094 /* SecretStoreList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5068389D241471CD00F55094 /* SecretStoreList.swift */; }; 506838A12415EA5600F55094 /* AnySecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A02415EA5600F55094 /* AnySecret.swift */; }; 506838A32415EA5D00F55094 /* AnySecretStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A22415EA5D00F55094 /* AnySecretStore.swift */; }; 506AB87E2412334700335D91 /* SecretAgent.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 50A3B78A24026B7500D209EA /* SecretAgent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 50731666241DF8660023809E /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731665241DF8660023809E /* Updater.swift */; }; 50731669241E00C20023809E /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50731668241E00C20023809E /* NoticeView.swift */; }; 507CE4ED2420A3C70029F750 /* Agent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79F24026B9900D209EA /* Agent.swift */; }; 507CE4EE2420A3CA0029F750 /* SocketController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A3B79D24026B9900D209EA /* SocketController.swift */; }; @@ -104,6 +108,20 @@ remoteGlobalIDString = 50617DA723FCE4AB0099B055; remoteInfo = SecretKit; }; + 506773002426F3F400034DED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 50617D7723FCE48D0099B055 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 506772FA2426F3F400034DED; + remoteInfo = Brief; + }; + 5067730A2426F40A00034DED /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 50617D7723FCE48D0099B055 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 506772FA2426F3F400034DED; + remoteInfo = Brief; + }; 507CE4F12420A6B50029F750 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 50617D7723FCE48D0099B055 /* Project object */; @@ -128,6 +146,7 @@ dstSubfolderSpec = 10; files = ( 50617DBE23FCE4AB0099B055 /* SecretKit.framework in Embed Frameworks */, + 506773032426F3F400034DED /* Brief.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -158,6 +177,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 5067730C2426F40E00034DED /* Brief.framework in Embed Frameworks */, 50A5C18D240E4B4B00E2996C /* SecretAgentKit.framework in Embed Frameworks */, 50A5C190240E4B4C00E2996C /* SecretKit.framework in Embed Frameworks */, ); @@ -205,10 +225,13 @@ 506772C62424784600034DED /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; 506772C82425BB8500034DED /* NoStoresView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoStoresView.swift; sourceTree = ""; }; 506772CA2426CCC200034DED /* Untitled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Untitled.png; sourceTree = ""; }; + 506772FB2426F3F400034DED /* Brief.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Brief.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 506772FD2426F3F400034DED /* Brief.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Brief.h; sourceTree = ""; }; + 506772FE2426F3F400034DED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 506773082426F3FD00034DED /* Updater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = ""; }; 5068389D241471CD00F55094 /* SecretStoreList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStoreList.swift; sourceTree = ""; }; 506838A02415EA5600F55094 /* AnySecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecret.swift; sourceTree = ""; }; 506838A22415EA5D00F55094 /* AnySecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretStore.swift; sourceTree = ""; }; - 50731665241DF8660023809E /* Updater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = ""; }; 50731668241E00C20023809E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = ""; }; 507CE4EF2420A4C50029F750 /* SigningWitness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningWitness.swift; sourceTree = ""; }; 507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningRequestProvenance.swift; sourceTree = ""; }; @@ -251,6 +274,7 @@ buildActionMask = 2147483647; files = ( 50617DBD23FCE4AB0099B055 /* SecretKit.framework in Frameworks */, + 506773022426F3F400034DED /* Brief.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -276,6 +300,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 506772F82426F3F400034DED /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5099A069240242BA0062B6F2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -314,6 +345,7 @@ 5099A06D240242BA0062B6F2 /* SecretAgentKit */, 5099A07A240242BA0062B6F2 /* SecretAgentKitTests */, 508A58AF241E144C0069DC07 /* Config */, + 506772FC2426F3F400034DED /* Brief */, 50617D8023FCE48E0099B055 /* Products */, 5099A08B240243730062B6F2 /* Frameworks */, ); @@ -329,6 +361,7 @@ 5099A06C240242BA0062B6F2 /* SecretAgentKit.framework */, 5099A074240242BA0062B6F2 /* SecretAgentKitTests.xctest */, 50A3B78A24026B7500D209EA /* SecretAgent.app */, + 506772FB2426F3F400034DED /* Brief.framework */, ); name = Products; sourceTree = ""; @@ -402,6 +435,16 @@ path = SecureEnclave; sourceTree = ""; }; + 506772FC2426F3F400034DED /* Brief */ = { + isa = PBXGroup; + children = ( + 506773082426F3FD00034DED /* Updater.swift */, + 506772FD2426F3F400034DED /* Brief.h */, + 506772FE2426F3F400034DED /* Info.plist */, + ); + path = Brief; + sourceTree = ""; + }; 5068389F2415EA4F00F55094 /* Erasers */ = { isa = PBXGroup; children = ( @@ -447,7 +490,6 @@ 508A58B1241ED1EA0069DC07 /* Controllers */ = { isa = PBXGroup; children = ( - 50731665241DF8660023809E /* Updater.swift */, 508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */, ); path = Controllers; @@ -538,6 +580,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 506772F62426F3F400034DED /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 506772FF2426F3F400034DED /* Brief.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5099A067240242BA0062B6F2 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -563,6 +613,7 @@ ); dependencies = ( 50617DBC23FCE4AB0099B055 /* PBXTargetDependency */, + 506773012426F3F400034DED /* PBXTargetDependency */, ); name = Secretive; productName = Secretive; @@ -624,6 +675,24 @@ productReference = 50617DB023FCE4AB0099B055 /* SecretKitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 506772FA2426F3F400034DED /* Brief */ = { + isa = PBXNativeTarget; + buildConfigurationList = 506773042426F3F400034DED /* Build configuration list for PBXNativeTarget "Brief" */; + buildPhases = ( + 506772F62426F3F400034DED /* Headers */, + 506772F72426F3F400034DED /* Sources */, + 506772F82426F3F400034DED /* Frameworks */, + 506772F92426F3F400034DED /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Brief; + productName = Brief; + productReference = 506772FB2426F3F400034DED /* Brief.framework */; + productType = "com.apple.product-type.framework"; + }; 5099A06B240242BA0062B6F2 /* SecretAgentKit */ = { isa = PBXNativeTarget; buildConfigurationList = 5099A083240242BA0062B6F2 /* Build configuration list for PBXNativeTarget "SecretAgentKit" */; @@ -676,6 +745,7 @@ dependencies = ( 5018F5492402736A002EB505 /* PBXTargetDependency */, 5018F54B2402736A002EB505 /* PBXTargetDependency */, + 5067730B2426F40A00034DED /* PBXTargetDependency */, ); name = SecretAgent; productName = SecretAgent; @@ -706,6 +776,10 @@ 50617DAF23FCE4AB0099B055 = { CreatedOnToolsVersion = 11.3; }; + 506772FA2426F3F400034DED = { + CreatedOnToolsVersion = 11.4; + LastSwiftMigration = 1140; + }; 5099A06B240242BA0062B6F2 = { CreatedOnToolsVersion = 11.4; LastSwiftMigration = 1140; @@ -738,6 +812,7 @@ 50617DAF23FCE4AB0099B055 /* SecretKitTests */, 5099A06B240242BA0062B6F2 /* SecretAgentKit */, 5099A073240242BA0062B6F2 /* SecretAgentKitTests */, + 506772FA2426F3F400034DED /* Brief */, ); }; /* End PBXProject section */ @@ -775,6 +850,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 506772F92426F3F400034DED /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5099A06A240242BA0062B6F2 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -813,7 +895,6 @@ 508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */, 50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */, 5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */, - 50731666241DF8660023809E /* Updater.swift in Sources */, 50B8550D24138C4F009958AC /* DeleteSecretView.swift in Sources */, 50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */, 50731669241E00C20023809E /* NoticeView.swift in Sources */, @@ -860,6 +941,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 506772F72426F3F400034DED /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 506773092426F3FD00034DED /* Updater.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5099A068240242BA0062B6F2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -918,6 +1007,16 @@ target = 50617DA723FCE4AB0099B055 /* SecretKit */; targetProxy = 50617DBB23FCE4AB0099B055 /* PBXContainerItemProxy */; }; + 506773012426F3F400034DED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 506772FA2426F3F400034DED /* Brief */; + targetProxy = 506773002426F3F400034DED /* PBXContainerItemProxy */; + }; + 5067730B2426F40A00034DED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 506772FA2426F3F400034DED /* Brief */; + targetProxy = 5067730A2426F40A00034DED /* PBXContainerItemProxy */; + }; 507CE4F22420A6B50029F750 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 50617DA723FCE4AB0099B055 /* SecretKit */; @@ -1262,6 +1361,95 @@ }; name = Release; }; + 506773052426F3F400034DED /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Z72PRUAWF6; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Brief/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Brief; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 506773062426F3F400034DED /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Z72PRUAWF6; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Brief/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Brief; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Test; + }; + 506773072426F3F400034DED /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = Z72PRUAWF6; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Brief/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Brief; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; 508A5914241EF1A00069DC07 /* Test */ = { isa = XCBuildConfiguration; baseConfigurationReference = 508A58AB241E121B0069DC07 /* Config.xcconfig */; @@ -1698,6 +1886,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 506773042426F3F400034DED /* Build configuration list for PBXNativeTarget "Brief" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 506773052426F3F400034DED /* Debug */, + 506773062426F3F400034DED /* Test */, + 506773072426F3F400034DED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5099A083240242BA0062B6F2 /* Build configuration list for PBXNativeTarget "SecretAgentKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Secretive/AppDelegate.swift b/Secretive/AppDelegate.swift index 295f25e..d2e26aa 100644 --- a/Secretive/AppDelegate.swift +++ b/Secretive/AppDelegate.swift @@ -1,6 +1,7 @@ import Cocoa import SwiftUI import SecretKit +import Brief @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { diff --git a/Secretive/Preview Content/PreviewUpdater.swift b/Secretive/Preview Content/PreviewUpdater.swift index 8cbeda8..2adb988 100644 --- a/Secretive/Preview Content/PreviewUpdater.swift +++ b/Secretive/Preview Content/PreviewUpdater.swift @@ -1,5 +1,6 @@ import Foundation import Combine +import Brief class PreviewUpdater: UpdaterProtocol { diff --git a/Secretive/Views/ContentView.swift b/Secretive/Views/ContentView.swift index dbfebbf..7ce9325 100644 --- a/Secretive/Views/ContentView.swift +++ b/Secretive/Views/ContentView.swift @@ -1,5 +1,6 @@ import SwiftUI import SecretKit +import Brief struct ContentView: View {