mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-07-01 17:53:36 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
0d74f6f561 | |||
efeb7f09a3 | |||
104199cf53 | |||
f214da98a4 | |||
95cf88d3ca | |||
04835fa437 | |||
31dfba8265 | |||
df8eedebd0 | |||
0a9ecb039e | |||
2e9a3eb90d | |||
df599fbe62 | |||
7c60e9b04b | |||
f7f182ec77 | |||
a0052e8395 | |||
10d3fa150c | |||
c5abca4099 | |||
f674d47507 | |||
1e3ece600d | |||
7481498c5b | |||
a6fbcdbe55 | |||
36e655e527 | |||
dd3acf5ae1 | |||
2257e1e190 |
BIN
.github/readme/notification.png
vendored
BIN
.github/readme/notification.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.6 MiB |
19
Brief/Brief.h
Normal file
19
Brief/Brief.h
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// Brief.h
|
||||
// Brief
|
||||
//
|
||||
// Created by Max Goedjen on 3/21/20.
|
||||
// Copyright © 2020 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! 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 <Brief/PublicHeader.h>
|
||||
|
||||
|
24
Brief/Info.plist
Normal file
24
Brief/Info.plist
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Max Goedjen. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
updateSink = updater.$update.sink { release in
|
||||
guard let release = release else { return }
|
||||
self.notifier.notify(update: release)
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// Insert code here to tear down your application
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Max Goedjen. All rights reserved.</string>
|
||||
<string>$(PRODUCT_NAME) is MIT Licensed.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
@ -1,10 +1,21 @@
|
||||
import Foundation
|
||||
import UserNotifications
|
||||
import AppKit
|
||||
import SecretKit
|
||||
import SecretAgentKit
|
||||
import UserNotifications
|
||||
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
|
||||
@ -14,12 +25,48 @@ class Notifier {
|
||||
func notify(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) {
|
||||
let notificationCenter = UNUserNotificationCenter.current()
|
||||
let notificationContent = UNMutableNotificationContent()
|
||||
notificationContent.title = "Signed Request"
|
||||
notificationContent.body = "\(secret.name) was used to sign a request from \(provenance.origin.name)."
|
||||
notificationContent.title = "Signed Request from \(provenance.origin.name)"
|
||||
notificationContent.subtitle = "Using secret \"\(secret.name)\""
|
||||
if let iconURL = iconURL(for: provenance), let attachment = try? UNNotificationAttachment(identifier: "icon", url: iconURL, options: nil) {
|
||||
notificationContent.attachments = [attachment]
|
||||
}
|
||||
let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil)
|
||||
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 {
|
||||
|
||||
func iconURL(for provenance: SigningRequestProvenance) -> URL? {
|
||||
do {
|
||||
if let app = NSRunningApplication(processIdentifier: provenance.origin.pid), let icon = app.icon?.tiffRepresentation {
|
||||
let temporaryURL = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("\(UUID().uuidString).png"))
|
||||
let bitmap = NSBitmapImageRep(data: icon)
|
||||
try bitmap?.representation(using: .png, properties: [:])?.write(to: temporaryURL)
|
||||
return temporaryURL
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Notifier: SigningWitness {
|
||||
@ -32,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)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.smartcard</key>
|
||||
<true/>
|
||||
<key>keychain-access-groups</key>
|
||||
|
@ -2,7 +2,6 @@ import Foundation
|
||||
import CryptoKit
|
||||
import OSLog
|
||||
import SecretKit
|
||||
import SecretAgentKit
|
||||
import AppKit
|
||||
|
||||
public class Agent {
|
||||
@ -79,7 +78,7 @@ extension Agent {
|
||||
|
||||
func sign(data: Data, from pid: Int32) throws -> Data {
|
||||
let reader = OpenSSHReader(data: data)
|
||||
let hash = try reader.readNextChunk()
|
||||
let hash = reader.readNextChunk()
|
||||
guard let (store, secret) = secret(matching: hash) else {
|
||||
os_log(.debug, "Agent did not have a key matching %@", hash as NSData)
|
||||
throw AgentError.noMatchingKey
|
||||
@ -90,7 +89,7 @@ extension Agent {
|
||||
try witness.speakNowOrForeverHoldYourPeace(forAccessTo: secret, by: provenance)
|
||||
}
|
||||
|
||||
let dataToSign = try reader.readNextChunk()
|
||||
let dataToSign = reader.readNextChunk()
|
||||
let derSignature = try store.sign(data: dataToSign, with: secret)
|
||||
|
||||
let curveData = writer.curveType(for: secret.algorithm, length: secret.keySize).data(using: .utf8)!
|
||||
|
@ -19,6 +19,6 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Max Goedjen. All rights reserved.</string>
|
||||
<string>$(PRODUCT_NAME) is MIT Licensed.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -1,11 +1,3 @@
|
||||
//
|
||||
// SecretAgentKit.h
|
||||
// SecretAgentKit
|
||||
//
|
||||
// Created by Max Goedjen on 2/22/20.
|
||||
// Copyright © 2020 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
|
@ -1,11 +1,3 @@
|
||||
//
|
||||
// SecretAgentKitTests.swift
|
||||
// SecretAgentKitTests
|
||||
//
|
||||
// Created by Max Goedjen on 2/22/20.
|
||||
// Copyright © 2020 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SecretAgentKit
|
||||
|
||||
|
@ -8,7 +8,7 @@ public class OpenSSHReader {
|
||||
remaining = Data(data)
|
||||
}
|
||||
|
||||
public func readNextChunk() throws -> Data {
|
||||
public func readNextChunk() -> Data {
|
||||
let lengthRange = 0..<(UInt32.bitWidth/8)
|
||||
let lengthChunk = remaining[lengthRange]
|
||||
remaining.removeSubrange(lengthRange)
|
||||
|
@ -20,6 +20,10 @@ public class SecretStoreList: ObservableObject {
|
||||
addInternal(store: modifiable)
|
||||
}
|
||||
|
||||
public var anyAvailable: Bool {
|
||||
stores.reduce(false, { $0 || $1.isAvailable })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SecretStoreList {
|
||||
|
@ -19,6 +19,6 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Max Goedjen. All rights reserved.</string>
|
||||
<string>$(PRODUCT_NAME) is MIT Licensed.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -1,11 +1,3 @@
|
||||
//
|
||||
// SecretKit.h
|
||||
// SecretKit
|
||||
//
|
||||
// Created by Max Goedjen on 2/18/20.
|
||||
// Copyright © 2020 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for SecretKit.
|
||||
|
17
SecretKitTests/AnySecretTests.swift
Normal file
17
SecretKitTests/AnySecretTests.swift
Normal file
@ -0,0 +1,17 @@
|
||||
import Foundation
|
||||
import XCTest
|
||||
@testable import SecretKit
|
||||
|
||||
class AnySecretTests: XCTestCase {
|
||||
|
||||
func testEraser() {
|
||||
let secret = SmartCard.Secret(id: UUID().uuidString.data(using: .utf8)!, name: "Name", algorithm: .ellipticCurve, keySize: 256, publicKey: UUID().uuidString.data(using: .utf8)!)
|
||||
let erased = AnySecret(secret)
|
||||
XCTAssert(erased.id == secret.id as AnyHashable)
|
||||
XCTAssert(erased.name == secret.name)
|
||||
XCTAssert(erased.algorithm == secret.algorithm)
|
||||
XCTAssert(erased.keySize == secret.keySize)
|
||||
XCTAssert(erased.publicKey == secret.publicKey)
|
||||
}
|
||||
|
||||
}
|
25
SecretKitTests/OpenSSHReaderTests.swift
Normal file
25
SecretKitTests/OpenSSHReaderTests.swift
Normal file
@ -0,0 +1,25 @@
|
||||
import Foundation
|
||||
import XCTest
|
||||
@testable import SecretKit
|
||||
|
||||
class OpenSSHReaderTests: XCTestCase {
|
||||
|
||||
func testSignatureRequest() {
|
||||
let reader = OpenSSHReader(data: Constants.signatureRequest)
|
||||
let hash = reader.readNextChunk()
|
||||
XCTAssert(hash == Data(base64Encoded: "AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBEqCbkJbOHy5S1wVCaJoKPmpS0egM4frMqllgnlRRQ/Uvnn6EVS8oV03cPA2Bz0EdESyRKA/sbmn0aBtgjIwGELxu45UXEW1TEz6TxyS0u3vuIqR3Wo1CrQWRDnkrG/pBQ=="))
|
||||
let dataToSign = reader.readNextChunk()
|
||||
XCTAssert(dataToSign == Data(base64Encoded: "AAAAICi5xf1ixOestUlxdjvt/BDcM+rzhwy7Vo8cW5YcxA8+MgAAAANnaXQAAAAOc3NoLWNvbm5lY3Rpb24AAAAJcHVibGlja2V5AQAAABNlY2RzYS1zaGEyLW5pc3RwMzg0AAAAiAAAABNlY2RzYS1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQRKgm5CWzh8uUtcFQmiaCj5qUtHoDOH6zKpZYJ5UUUP1L55+hFUvKFdN3DwNgc9BHREskSgP7G5p9GgbYIyMBhC8buOVFxFtUxM+k8cktLt77iKkd1qNQq0FkQ55Kxv6QU="))
|
||||
let empty = reader.readNextChunk()
|
||||
XCTAssert(empty.isEmpty)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OpenSSHReaderTests {
|
||||
|
||||
enum Constants {
|
||||
static let signatureRequest = Data(base64Encoded: "AAAAiAAAABNlY2RzYS1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQRKgm5CWzh8uUtcFQmiaCj5qUtHoDOH6zKpZYJ5UUUP1L55+hFUvKFdN3DwNgc9BHREskSgP7G5p9GgbYIyMBhC8buOVFxFtUxM+k8cktLt77iKkd1qNQq0FkQ55Kxv6QUAAADvAAAAICi5xf1ixOestUlxdjvt/BDcM+rzhwy7Vo8cW5YcxA8+MgAAAANnaXQAAAAOc3NoLWNvbm5lY3Rpb24AAAAJcHVibGlja2V5AQAAABNlY2RzYS1zaGEyLW5pc3RwMzg0AAAAiAAAABNlY2RzYS1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQRKgm5CWzh8uUtcFQmiaCj5qUtHoDOH6zKpZYJ5UUUP1L55+hFUvKFdN3DwNgc9BHREskSgP7G5p9GgbYIyMBhC8buOVFxFtUxM+k8cktLt77iKkd1qNQq0FkQ55Kxv6QUAAAAA")!
|
||||
}
|
||||
|
||||
}
|
@ -27,11 +27,18 @@
|
||||
50617DD023FCED2C0099B055 /* SecureEnclave.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DCF23FCED2C0099B055 /* SecureEnclave.swift */; };
|
||||
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DD123FCEFA90099B055 /* PreviewStore.swift */; };
|
||||
506772C72424784600034DED /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 506772C62424784600034DED /* Credits.rtf */; };
|
||||
506772C92425BB8500034DED /* NoStoresView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506772C82425BB8500034DED /* NoStoresView.swift */; };
|
||||
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, ); }; };
|
||||
5067730E242701BA00034DED /* OpenSSHReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5067730D242701BA00034DED /* OpenSSHReaderTests.swift */; };
|
||||
506773102427057600034DED /* AnySecretTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5067730F2427057600034DED /* AnySecretTests.swift */; };
|
||||
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 */; };
|
||||
@ -102,6 +109,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 */;
|
||||
@ -126,6 +147,7 @@
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
50617DBE23FCE4AB0099B055 /* SecretKit.framework in Embed Frameworks */,
|
||||
506773032426F3F400034DED /* Brief.framework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -156,6 +178,7 @@
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
5067730C2426F40E00034DED /* Brief.framework in Embed Frameworks */,
|
||||
50A5C18D240E4B4B00E2996C /* SecretAgentKit.framework in Embed Frameworks */,
|
||||
50A5C190240E4B4C00E2996C /* SecretKit.framework in Embed Frameworks */,
|
||||
);
|
||||
@ -201,10 +224,16 @@
|
||||
50617DCF23FCED2C0099B055 /* SecureEnclave.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureEnclave.swift; sourceTree = "<group>"; };
|
||||
50617DD123FCEFA90099B055 /* PreviewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewStore.swift; sourceTree = "<group>"; };
|
||||
506772C62424784600034DED /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||
506772C82425BB8500034DED /* NoStoresView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoStoresView.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
506772FE2426F3F400034DED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
506773082426F3FD00034DED /* Updater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = "<group>"; };
|
||||
5067730D242701BA00034DED /* OpenSSHReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSSHReaderTests.swift; sourceTree = "<group>"; };
|
||||
5067730F2427057600034DED /* AnySecretTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretTests.swift; sourceTree = "<group>"; };
|
||||
5068389D241471CD00F55094 /* SecretStoreList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStoreList.swift; sourceTree = "<group>"; };
|
||||
506838A02415EA5600F55094 /* AnySecret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecret.swift; sourceTree = "<group>"; };
|
||||
506838A22415EA5D00F55094 /* AnySecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretStore.swift; sourceTree = "<group>"; };
|
||||
50731665241DF8660023809E /* Updater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = "<group>"; };
|
||||
50731668241E00C20023809E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = "<group>"; };
|
||||
507CE4EF2420A4C50029F750 /* SigningWitness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningWitness.swift; sourceTree = "<group>"; };
|
||||
507CE4F32420A8C10029F750 /* SigningRequestProvenance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigningRequestProvenance.swift; sourceTree = "<group>"; };
|
||||
@ -247,6 +276,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
50617DBD23FCE4AB0099B055 /* SecretKit.framework in Frameworks */,
|
||||
506773022426F3F400034DED /* Brief.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -272,6 +302,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
506772F82426F3F400034DED /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
5099A069240242BA0062B6F2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -310,6 +347,7 @@
|
||||
5099A06D240242BA0062B6F2 /* SecretAgentKit */,
|
||||
5099A07A240242BA0062B6F2 /* SecretAgentKitTests */,
|
||||
508A58AF241E144C0069DC07 /* Config */,
|
||||
506772FC2426F3F400034DED /* Brief */,
|
||||
50617D8023FCE48E0099B055 /* Products */,
|
||||
5099A08B240243730062B6F2 /* Frameworks */,
|
||||
);
|
||||
@ -325,6 +363,7 @@
|
||||
5099A06C240242BA0062B6F2 /* SecretAgentKit.framework */,
|
||||
5099A074240242BA0062B6F2 /* SecretAgentKitTests.xctest */,
|
||||
50A3B78A24026B7500D209EA /* SecretAgent.app */,
|
||||
506772FB2426F3F400034DED /* Brief.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -383,6 +422,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
50524B432420969D008DBD97 /* OpenSSHWriterTests.swift */,
|
||||
5067730D242701BA00034DED /* OpenSSHReaderTests.swift */,
|
||||
5067730F2427057600034DED /* AnySecretTests.swift */,
|
||||
50617DB923FCE4AB0099B055 /* Info.plist */,
|
||||
);
|
||||
path = SecretKitTests;
|
||||
@ -398,6 +439,16 @@
|
||||
path = SecureEnclave;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
506772FC2426F3F400034DED /* Brief */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
506773082426F3FD00034DED /* Updater.swift */,
|
||||
506772FD2426F3F400034DED /* Brief.h */,
|
||||
506772FE2426F3F400034DED /* Info.plist */,
|
||||
);
|
||||
path = Brief;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5068389F2415EA4F00F55094 /* Erasers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -434,6 +485,7 @@
|
||||
5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */,
|
||||
50B8550C24138C4F009958AC /* DeleteSecretView.swift */,
|
||||
50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */,
|
||||
506772C82425BB8500034DED /* NoStoresView.swift */,
|
||||
50C385A8240B636500AF2719 /* SetupView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
@ -442,7 +494,6 @@
|
||||
508A58B1241ED1EA0069DC07 /* Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
50731665241DF8660023809E /* Updater.swift */,
|
||||
508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */,
|
||||
);
|
||||
path = Controllers;
|
||||
@ -532,6 +583,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
506772F62426F3F400034DED /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
506772FF2426F3F400034DED /* Brief.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
5099A067240242BA0062B6F2 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -557,6 +616,7 @@
|
||||
);
|
||||
dependencies = (
|
||||
50617DBC23FCE4AB0099B055 /* PBXTargetDependency */,
|
||||
506773012426F3F400034DED /* PBXTargetDependency */,
|
||||
);
|
||||
name = Secretive;
|
||||
productName = Secretive;
|
||||
@ -618,6 +678,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" */;
|
||||
@ -670,6 +748,7 @@
|
||||
dependencies = (
|
||||
5018F5492402736A002EB505 /* PBXTargetDependency */,
|
||||
5018F54B2402736A002EB505 /* PBXTargetDependency */,
|
||||
5067730B2426F40A00034DED /* PBXTargetDependency */,
|
||||
);
|
||||
name = SecretAgent;
|
||||
productName = SecretAgent;
|
||||
@ -700,6 +779,10 @@
|
||||
50617DAF23FCE4AB0099B055 = {
|
||||
CreatedOnToolsVersion = 11.3;
|
||||
};
|
||||
506772FA2426F3F400034DED = {
|
||||
CreatedOnToolsVersion = 11.4;
|
||||
LastSwiftMigration = 1140;
|
||||
};
|
||||
5099A06B240242BA0062B6F2 = {
|
||||
CreatedOnToolsVersion = 11.4;
|
||||
LastSwiftMigration = 1140;
|
||||
@ -732,6 +815,7 @@
|
||||
50617DAF23FCE4AB0099B055 /* SecretKitTests */,
|
||||
5099A06B240242BA0062B6F2 /* SecretAgentKit */,
|
||||
5099A073240242BA0062B6F2 /* SecretAgentKitTests */,
|
||||
506772FA2426F3F400034DED /* Brief */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -769,6 +853,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
506772F92426F3F400034DED /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
5099A06A240242BA0062B6F2 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -806,11 +897,11 @@
|
||||
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 */,
|
||||
50617D8323FCE48E0099B055 /* AppDelegate.swift in Sources */,
|
||||
506772C92425BB8500034DED /* NoStoresView.swift in Sources */,
|
||||
508A58B5241ED48F0069DC07 /* PreviewAgentStatusChecker.swift in Sources */,
|
||||
508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */,
|
||||
);
|
||||
@ -849,6 +940,16 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
50524B442420969E008DBD97 /* OpenSSHWriterTests.swift in Sources */,
|
||||
506773102427057600034DED /* AnySecretTests.swift in Sources */,
|
||||
5067730E242701BA00034DED /* OpenSSHReaderTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
506772F72426F3F400034DED /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
506773092426F3FD00034DED /* Updater.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -910,6 +1011,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 */;
|
||||
@ -1254,6 +1365,95 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
506773052426F3F400034DED /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
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 = "-";
|
||||
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 = "-";
|
||||
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 */;
|
||||
@ -1690,6 +1890,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 = (
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Cocoa
|
||||
import SwiftUI
|
||||
import SecretKit
|
||||
import Brief
|
||||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
@ -66,7 +67,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
@IBAction func runSetup(sender: AnyObject?) {
|
||||
let setupWindow = NSWindow(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
|
||||
contentRect: NSRect(x: 0, y: 0, width: 0, height: 0),
|
||||
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
|
||||
backing: .buffered, defer: false)
|
||||
let setupView = SetupView() { success in
|
||||
|
@ -5,19 +5,19 @@
|
||||
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6119\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/maxgoedjen/secretive"}}{\fldrslt
|
||||
\f0\fs24 \cf0 https://github.com/maxgoedjen/secretive}}
|
||||
\f0\fs24 \cf0 GitHub Repository}}
|
||||
\f0\fs24 \
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
\cf0 \
|
||||
GITHUB_BUILD_URL\
|
||||
{\field{\*\fldinst{HYPERLINK "GITHUB_BUILD_URL"}}{\fldrslt Build Log}}\
|
||||
\
|
||||
Special Thanks To:\
|
||||
https://github.com/bdash\
|
||||
https://github.com/danielctull\
|
||||
https://github.com/davedelong\
|
||||
https://github.com/esttorhe\
|
||||
https://github.com/joeblau\
|
||||
https://github.com/marksands\
|
||||
https://github.com/mergesort\
|
||||
https://github.com/phillco\
|
||||
https://github.com/zackdotcomputer}
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/bdash"}}{\fldrslt Mark Rowe}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/danielctull"}}{\fldrslt Daniel Tull}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/davedelong"}}{\fldrslt Dave DeLong}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/esttorhe"}}{\fldrslt Esteban Torres}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/joeblau"}}{\fldrslt Joe Blau}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/marksands"}}{\fldrslt Mark Sands}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/mergesort"}}{\fldrslt Joe Fabisevich}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/phillco"}}{\fldrslt Phil Cohen}}\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/zackdotcomputer"}}{\fldrslt Zack Sheppard}}}
|
@ -19,11 +19,11 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(CI_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CI_VERSION)</string>
|
||||
<string>$(CI_BUILD_NUMBER)</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 Max Goedjen. All rights reserved.</string>
|
||||
<string>$(PRODUCT_NAME) is MIT Licensed.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
import Brief
|
||||
|
||||
class PreviewUpdater: UpdaterProtocol {
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import SwiftUI
|
||||
import SecretKit
|
||||
import Brief
|
||||
|
||||
struct ContentView<UpdaterType: UpdaterProtocol, AgentStatusCheckerType: AgentStatusCheckerProtocol>: View {
|
||||
|
||||
@ -20,6 +21,7 @@ struct ContentView<UpdaterType: UpdaterProtocol, AgentStatusCheckerType: AgentSt
|
||||
if !agentStatusChecker.running {
|
||||
agentNotice()
|
||||
}
|
||||
if storeList.anyAvailable {
|
||||
NavigationView {
|
||||
List(selection: $active) {
|
||||
ForEach(storeList.stores) { store in
|
||||
@ -68,7 +70,10 @@ struct ContentView<UpdaterType: UpdaterProtocol, AgentStatusCheckerType: AgentSt
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NoStoresView()
|
||||
}
|
||||
}.frame(minWidth: 640, minHeight: 320)
|
||||
}
|
||||
|
||||
func updateNotice() -> some View {
|
||||
|
29
Secretive/Views/NoStoresView.swift
Normal file
29
Secretive/Views/NoStoresView.swift
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// NoStoresView.swift
|
||||
// Secretive
|
||||
//
|
||||
// Created by Max Goedjen on 3/20/20.
|
||||
// Copyright © 2020 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct NoStoresView: View {
|
||||
var body: some View {
|
||||
VStack {
|
||||
Text("No Secure Storage Available").bold()
|
||||
Text("Your Mac doesn't have a Secure Enclave, and there's not a compatible Smart Card inserted.")
|
||||
Button(action: {
|
||||
NSWorkspace.shared.open(URL(string: "https://www.yubico.com/products/compare-yubikey-5-series/")!)
|
||||
}) {
|
||||
Text("If you're looking to add one to your Mac, the YubiKey 5 Series are great.")
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
}
|
||||
|
||||
struct NoStoresView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NoStoresView()
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ struct SetupView: View {
|
||||
actionText: "Install") {
|
||||
self.installLaunchAgent()
|
||||
}
|
||||
SetupStepView(text: "You need to add a line to your shell config (.bashrc or .zshrc) telling SSH to talk to SecretAgent when it wants to authenticate. Drag this into your config file.",
|
||||
SetupStepView(text: "Add this line to your shell config (.bashrc or .zshrc) telling SSH to talk to SecretAgent when it wants to authenticate. Drag this into your config file.",
|
||||
index: 2,
|
||||
nestedView: SetupStepCommandView(text: Constants.socketPrompt),
|
||||
actionText: "Added") {
|
||||
@ -27,7 +27,7 @@ struct SetupView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}.frame(minWidth: 640, minHeight: 400)
|
||||
}
|
||||
|
||||
}
|
||||
@ -64,10 +64,8 @@ struct SetupStepView<NestedViewType: View>: View {
|
||||
Text(text)
|
||||
.opacity(completed ? 0.5 : 1)
|
||||
.lineLimit(nil)
|
||||
.frame(idealHeight: 0, maxHeight: .infinity)
|
||||
if nestedView != nil {
|
||||
Spacer()
|
||||
nestedView!
|
||||
nestedView!.padding()
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
@ -87,18 +85,33 @@ struct SetupStepCommandView: View {
|
||||
let text: String
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Text(text)
|
||||
.font(.system(.caption, design: .monospaced))
|
||||
.lineLimit(nil)
|
||||
.frame(idealHeight: 0, maxHeight: .infinity)
|
||||
.font(.system(.caption, design: .monospaced))
|
||||
.multilineTextAlignment(.leading)
|
||||
.frame(minHeight: 50)
|
||||
HStack {
|
||||
Spacer()
|
||||
Button(action: copy) {
|
||||
Text("Copy")
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(Color(white: 0, opacity: 0.10))
|
||||
.cornerRadius(10)
|
||||
.onDrag {
|
||||
return NSItemProvider(item: NSData(data: self.text.data(using: .utf8)!), typeIdentifier: kUTTypeUTF8PlainText as String)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func copy() {
|
||||
NSPasteboard.general.declareTypes([.string], owner: nil)
|
||||
NSPasteboard.general.setString(text, forType: .string)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SetupView {
|
||||
|
@ -1,11 +1,3 @@
|
||||
//
|
||||
// SecretiveTests.swift
|
||||
// SecretiveTests
|
||||
//
|
||||
// Created by Max Goedjen on 2/18/20.
|
||||
// Copyright © 2020 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Secretive
|
||||
|
||||
|
Reference in New Issue
Block a user