mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-04-18 05:22:11 +00:00
Adding better notification formatting
This commit is contained in:
parent
10d3fa150c
commit
2227a4230c
@ -2,6 +2,7 @@ import Foundation
|
|||||||
import SecretKit
|
import SecretKit
|
||||||
import SecretAgentKit
|
import SecretAgentKit
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
import AppKit
|
||||||
|
|
||||||
class Notifier {
|
class Notifier {
|
||||||
|
|
||||||
@ -14,14 +15,34 @@ class Notifier {
|
|||||||
func notify(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) {
|
func notify(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) {
|
||||||
let notificationCenter = UNUserNotificationCenter.current()
|
let notificationCenter = UNUserNotificationCenter.current()
|
||||||
let notificationContent = UNMutableNotificationContent()
|
let notificationContent = UNMutableNotificationContent()
|
||||||
notificationContent.title = "Signed Request"
|
notificationContent.title = "Signed Request from \(provenance.origin.name)"
|
||||||
notificationContent.body = "\(secret.name) was used to sign a request from \(provenance.origin.name)."
|
notificationContent.subtitle = 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)
|
let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil)
|
||||||
notificationCenter.add(request, withCompletionHandler: 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 {
|
extension Notifier: SigningWitness {
|
||||||
|
|
||||||
func speakNowOrForeverHoldYourPeace(forAccessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws {
|
func speakNowOrForeverHoldYourPeace(forAccessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws {
|
||||||
|
BIN
SecretAgent/Untitled.png
Normal file
BIN
SecretAgent/Untitled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
@ -28,6 +28,7 @@
|
|||||||
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DD123FCEFA90099B055 /* PreviewStore.swift */; };
|
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50617DD123FCEFA90099B055 /* PreviewStore.swift */; };
|
||||||
506772C72424784600034DED /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 506772C62424784600034DED /* Credits.rtf */; };
|
506772C72424784600034DED /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 506772C62424784600034DED /* Credits.rtf */; };
|
||||||
506772C92425BB8500034DED /* NoStoresView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506772C82425BB8500034DED /* NoStoresView.swift */; };
|
506772C92425BB8500034DED /* NoStoresView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506772C82425BB8500034DED /* NoStoresView.swift */; };
|
||||||
|
506772CB2426CCC200034DED /* Untitled.png in Resources */ = {isa = PBXBuildFile; fileRef = 506772CA2426CCC200034DED /* Untitled.png */; };
|
||||||
5068389E241471CD00F55094 /* SecretStoreList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5068389D241471CD00F55094 /* SecretStoreList.swift */; };
|
5068389E241471CD00F55094 /* SecretStoreList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5068389D241471CD00F55094 /* SecretStoreList.swift */; };
|
||||||
506838A12415EA5600F55094 /* AnySecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A02415EA5600F55094 /* AnySecret.swift */; };
|
506838A12415EA5600F55094 /* AnySecret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A02415EA5600F55094 /* AnySecret.swift */; };
|
||||||
506838A32415EA5D00F55094 /* AnySecretStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A22415EA5D00F55094 /* AnySecretStore.swift */; };
|
506838A32415EA5D00F55094 /* AnySecretStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506838A22415EA5D00F55094 /* AnySecretStore.swift */; };
|
||||||
@ -203,6 +204,7 @@
|
|||||||
50617DD123FCEFA90099B055 /* PreviewStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewStore.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>"; };
|
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>"; };
|
506772C82425BB8500034DED /* NoStoresView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoStoresView.swift; sourceTree = "<group>"; };
|
||||||
|
506772CA2426CCC200034DED /* Untitled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Untitled.png; sourceTree = "<group>"; };
|
||||||
5068389D241471CD00F55094 /* SecretStoreList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretStoreList.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>"; };
|
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>"; };
|
506838A22415EA5D00F55094 /* AnySecretStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnySecretStore.swift; sourceTree = "<group>"; };
|
||||||
@ -507,6 +509,7 @@
|
|||||||
children = (
|
children = (
|
||||||
50020BAF24064869003D4025 /* AppDelegate.swift */,
|
50020BAF24064869003D4025 /* AppDelegate.swift */,
|
||||||
5018F54E24064786002EB505 /* Notifier.swift */,
|
5018F54E24064786002EB505 /* Notifier.swift */,
|
||||||
|
506772CA2426CCC200034DED /* Untitled.png */,
|
||||||
50A3B79024026B7600D209EA /* Assets.xcassets */,
|
50A3B79024026B7600D209EA /* Assets.xcassets */,
|
||||||
50A3B79524026B7600D209EA /* Main.storyboard */,
|
50A3B79524026B7600D209EA /* Main.storyboard */,
|
||||||
50A3B79824026B7600D209EA /* Info.plist */,
|
50A3B79824026B7600D209EA /* Info.plist */,
|
||||||
@ -790,6 +793,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
506772CB2426CCC200034DED /* Untitled.png in Resources */,
|
||||||
50A3B79724026B7600D209EA /* Main.storyboard in Resources */,
|
50A3B79724026B7600D209EA /* Main.storyboard in Resources */,
|
||||||
50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */,
|
50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */,
|
||||||
50A3B79124026B7600D209EA /* Assets.xcassets in Resources */,
|
50A3B79124026B7600D209EA /* Assets.xcassets in Resources */,
|
||||||
|
@ -66,7 +66,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
|
|
||||||
@IBAction func runSetup(sender: AnyObject?) {
|
@IBAction func runSetup(sender: AnyObject?) {
|
||||||
let setupWindow = NSWindow(
|
let setupWindow = NSWindow(
|
||||||
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
|
contentRect: NSRect(x: 0, y: 0, width: 00, height: 00),
|
||||||
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
|
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
|
||||||
backing: .buffered, defer: false)
|
backing: .buffered, defer: false)
|
||||||
let setupView = SetupView() { success in
|
let setupView = SetupView() { success in
|
||||||
@ -74,6 +74,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
self.agentStatusChecker.check()
|
self.agentStatusChecker.check()
|
||||||
}
|
}
|
||||||
setupWindow.contentView = NSHostingView(rootView: setupView)
|
setupWindow.contentView = NSHostingView(rootView: setupView)
|
||||||
|
setupWindow.setContentSize(setupWindow.contentView!.fittingSize)
|
||||||
window.beginSheet(setupWindow, completionHandler: nil)
|
window.beginSheet(setupWindow, completionHandler: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ import SwiftUI
|
|||||||
import ServiceManagement
|
import ServiceManagement
|
||||||
|
|
||||||
struct SetupView: View {
|
struct SetupView: View {
|
||||||
|
|
||||||
var completion: ((Bool) -> Void)?
|
var completion: ((Bool) -> Void)?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
SetupStepView<Spacer>(text: "Secretive needs to install a helper app to sign requests when the main app isn't running. This app is called \"SecretAgent\" and you might see it in Activity Manager from time to time.",
|
SetupStepView<Spacer>(text: "Secretive needs to install a helper app to sign requests when the main app isn't running. This app is called \"SecretAgent\" and you might see it in Activity Manager from time to time.",
|
||||||
@ -29,18 +29,18 @@ struct SetupView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetupStepView<NestedViewType: View>: View {
|
struct SetupStepView<NestedViewType: View>: View {
|
||||||
|
|
||||||
let text: String
|
let text: String
|
||||||
let index: Int
|
let index: Int
|
||||||
let nestedView: NestedViewType?
|
let nestedView: NestedViewType?
|
||||||
@State var completed = false
|
@State var completed = false
|
||||||
let actionText: String
|
let actionText: String
|
||||||
let action: (() -> Bool)
|
let action: (() -> Bool)
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Section {
|
Section {
|
||||||
HStack {
|
HStack {
|
||||||
@ -83,9 +83,9 @@ struct SetupStepView<NestedViewType: View>: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct SetupStepCommandView: View {
|
struct SetupStepCommandView: View {
|
||||||
|
|
||||||
let text: String
|
let text: String
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text(text)
|
Text(text)
|
||||||
@ -104,36 +104,36 @@ struct SetupStepCommandView: View {
|
|||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.onDrag {
|
.onDrag {
|
||||||
return NSItemProvider(item: NSData(data: self.text.data(using: .utf8)!), typeIdentifier: kUTTypeUTF8PlainText as String)
|
return NSItemProvider(item: NSData(data: self.text.data(using: .utf8)!), typeIdentifier: kUTTypeUTF8PlainText as String)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func copy() {
|
func copy() {
|
||||||
NSPasteboard.general.declareTypes([.string], owner: nil)
|
NSPasteboard.general.declareTypes([.string], owner: nil)
|
||||||
NSPasteboard.general.setString(text, forType: .string)
|
NSPasteboard.general.setString(text, forType: .string)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SetupView {
|
extension SetupView {
|
||||||
|
|
||||||
func installLaunchAgent() -> Bool {
|
func installLaunchAgent() -> Bool {
|
||||||
SMLoginItemSetEnabled("com.maxgoedjen.Secretive.SecretAgent" as CFString, true)
|
SMLoginItemSetEnabled("com.maxgoedjen.Secretive.SecretAgent" as CFString, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func markAsDone() -> Bool {
|
func markAsDone() -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SetupView {
|
extension SetupView {
|
||||||
|
|
||||||
enum Constants {
|
enum Constants {
|
||||||
static let socketPath = (NSHomeDirectory().replacingOccurrences(of: "com.maxgoedjen.Secretive.Host", with: "com.maxgoedjen.Secretive.SecretAgent") as NSString).appendingPathComponent("socket.ssh") as String
|
static let socketPath = (NSHomeDirectory().replacingOccurrences(of: "com.maxgoedjen.Secretive.Host", with: "com.maxgoedjen.Secretive.SecretAgent") as NSString).appendingPathComponent("socket.ssh") as String
|
||||||
static let socketPrompt = "export SSH_AUTH_SOCK=\(socketPath)"
|
static let socketPrompt = "export SSH_AUTH_SOCK=\(socketPath)"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
Loading…
Reference in New Issue
Block a user