Compare commits
5 Commits
3ecda77f86
...
aa6c20e1c9
Author | SHA1 | Date |
---|---|---|
Paul Heidekrüger | aa6c20e1c9 | |
Yoshimasa Niwa | fc21018eb4 | |
Paul Heidekrüger | fabd1a0cff | |
Paul Heidekrüger | a1424d3663 | |
Paul Heidekrüger | 53c3ba83b9 |
|
@ -53,6 +53,8 @@
|
|||
50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */; };
|
||||
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C385A42407A76D00AF2719 /* SecretDetailView.swift */; };
|
||||
50E9CF422B51D596004AB36D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 500B93C22B478D8400E157DE /* Localizable.xcstrings */; };
|
||||
DA140C502B8DF70500948F81 /* SettingsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA140C4F2B8DF70500948F81 /* SettingsHelper.swift */; };
|
||||
DA22A3402B712A57004D45DD /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA22A33F2B712A57004D45DD /* SettingsView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -152,6 +154,9 @@
|
|||
50B8550C24138C4F009958AC /* DeleteSecretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeleteSecretView.swift; sourceTree = "<group>"; };
|
||||
50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStoreView.swift; sourceTree = "<group>"; };
|
||||
50C385A42407A76D00AF2719 /* SecretDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretDetailView.swift; sourceTree = "<group>"; };
|
||||
DA140C4F2B8DF70500948F81 /* SettingsHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHelper.swift; sourceTree = "<group>"; };
|
||||
DA22A33C2B6EB835004D45DD /* SecretiveRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SecretiveRelease.entitlements; sourceTree = "<group>"; };
|
||||
DA22A33F2B712A57004D45DD /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -192,6 +197,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
50033AC227813F1700253856 /* BundleIDs.swift */,
|
||||
DA140C4F2B8DF70500948F81 /* SettingsHelper.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
@ -282,6 +288,7 @@
|
|||
50153E1F250AFCB200525160 /* UpdateView.swift */,
|
||||
5066A6C12516F303004B5A36 /* SetupView.swift */,
|
||||
5066A6C72516FE6E004B5A36 /* CopyableView.swift */,
|
||||
DA22A33F2B712A57004D45DD /* SettingsView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -496,6 +503,7 @@
|
|||
5079BA0F250F29BF00EA86F4 /* StoreListView.swift in Sources */,
|
||||
50617DD223FCEFA90099B055 /* PreviewStore.swift in Sources */,
|
||||
5066A6F7251829B1004B5A36 /* ShellConfigurationController.swift in Sources */,
|
||||
DA22A3402B712A57004D45DD /* SettingsView.swift in Sources */,
|
||||
50033AC327813F1700253856 /* BundleIDs.swift in Sources */,
|
||||
508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */,
|
||||
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */,
|
||||
|
@ -507,6 +515,7 @@
|
|||
50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */,
|
||||
50617D8323FCE48E0099B055 /* App.swift in Sources */,
|
||||
506772C92425BB8500034DED /* NoStoresView.swift in Sources */,
|
||||
DA140C502B8DF70500948F81 /* SettingsHelper.swift in Sources */,
|
||||
50153E22250DECA300525160 /* SecretListItemView.swift in Sources */,
|
||||
508A58B5241ED48F0069DC07 /* PreviewAgentStatusChecker.swift in Sources */,
|
||||
508A58AA241E06B40069DC07 /* PreviewUpdater.swift in Sources */,
|
||||
|
|
|
@ -62,6 +62,9 @@ struct Secretive: App {
|
|||
}
|
||||
SidebarCommands()
|
||||
}
|
||||
Settings {
|
||||
SettingsView()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,14 +15,11 @@ class JustUpdatedChecker: ObservableObject, JustUpdatedCheckerProtocol {
|
|||
}
|
||||
|
||||
func check() {
|
||||
let lastBuild = UserDefaults.standard.object(forKey: Constants.previousVersionUserDefaultsKey) as? String ?? "None"
|
||||
let lastBuild = SettingsStore.get(key: Constants.previousVersionUserDefaultsKey) ?? "None"
|
||||
let currentBuild = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
|
||||
UserDefaults.standard.set(currentBuild, forKey: Constants.previousVersionUserDefaultsKey)
|
||||
SettingsStore.set(key: Constants.previousVersionUserDefaultsKey, value: currentBuild)
|
||||
justUpdated = lastBuild != currentBuild
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension JustUpdatedChecker {
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// SettingsHelper.swift
|
||||
// Secretive
|
||||
//
|
||||
// Created by Paul Heidekrüger on 27.02.24.
|
||||
// Copyright © 2024 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class SettingsStore {
|
||||
static let service = "com.maxgoedjen.Secretive"
|
||||
}
|
||||
|
||||
extension SettingsStore {
|
||||
static func set(key: String, value: String) -> Bool {
|
||||
let valueData = value.data(using: String.Encoding.utf8)!
|
||||
|
||||
if let keyVal = get(key: key) {
|
||||
if keyVal == value {
|
||||
return true
|
||||
}
|
||||
|
||||
let updateQuery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrServer as String: service]
|
||||
let attributes: [String: Any] = [kSecAttrAccount as String: key,
|
||||
kSecValueData as String: valueData]
|
||||
// FIXME: Make this non-blocking as described here: https://developer.apple.com/documentation/security/1393617-secitemupdate
|
||||
let status = SecItemUpdate(updateQuery as CFDictionary, attributes as CFDictionary)
|
||||
guard status == errSecSuccess else {
|
||||
print("Couldn't update item in keychain. " + status.description)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
let addquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrAccount as String: key,
|
||||
kSecAttrServer as String: service,
|
||||
kSecValueData as String: valueData]
|
||||
// FIXME: Make this non-blocking as described here: https://developer.apple.com/documentation/security/1401659-secitemadd
|
||||
let status = SecItemAdd(addquery as CFDictionary, nil)
|
||||
guard status == errSecSuccess else {
|
||||
print("Couldn't add item to keychain. " + status.description)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
static func get(key: String) -> String? {
|
||||
let getquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrAccount as String: key,
|
||||
kSecAttrServer as String: service,
|
||||
kSecMatchLimit as String: kSecMatchLimitOne,
|
||||
kSecReturnData as String: true]
|
||||
var item: CFTypeRef?
|
||||
let status = SecItemCopyMatching(getquery as CFDictionary, &item)
|
||||
|
||||
return status == errSecSuccess ? String(decoding: item as! Data, as: UTF8.self) : nil
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@ import SecretKit
|
|||
struct SecretDetailView<SecretType: Secret>: View {
|
||||
|
||||
@State var secret: SecretType
|
||||
@AppStorage("com.maxgoedjen.Secretive.commentStyle") var style: CommentStyle = .keyAndHost
|
||||
|
||||
private let keyWriter = OpenSSHKeyWriter()
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: NSHomeDirectory().replacingOccurrences(of: Bundle.main.hostBundleID, with: Bundle.main.agentBundleID))
|
||||
|
@ -42,9 +43,13 @@ struct SecretDetailView<SecretType: Secret>: View {
|
|||
}
|
||||
|
||||
var keyString: String {
|
||||
keyWriter.openSSHString(secret: secret, comment: "\(dashedKeyName)@\(dashedHostName)")
|
||||
switch style {
|
||||
case CommentStyle.none:
|
||||
keyWriter.openSSHString(secret: secret, comment: "")
|
||||
default:
|
||||
keyWriter.openSSHString(secret: secret, comment: "\(dashedKeyName)@\(dashedHostName)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// SettingsView.swift
|
||||
// Secretive
|
||||
//
|
||||
// Created by Paul Heidekrüger on 05.02.24.
|
||||
// Copyright © 2024 Max Goedjen. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum CommentStyle: String, CaseIterable, Identifiable {
|
||||
case keyAndHost, none
|
||||
var id: Self { self }
|
||||
}
|
||||
|
||||
struct GeneralSettingsView: View {
|
||||
@AppStorage("com.maxgoedjen.Secretive.commentStyle") var selectedCommentStyle: CommentStyle = .keyAndHost
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Section(footer: Text("SSH public keys can be extended with an arbitrary comment string without changing the meaning of the key.")
|
||||
.font(.caption)
|
||||
.fontWeight(.light)) {
|
||||
Picker("SSH Public Key Comment", selection: $selectedCommentStyle) {
|
||||
Text("Default").tag(CommentStyle.keyAndHost)
|
||||
Text("None").tag(CommentStyle.none)
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
}
|
||||
}
|
||||
.padding(20)
|
||||
.frame(width: 350, height: 100)
|
||||
.navigationTitle("Settings")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct SettingsView: View {
|
||||
private enum Tabs: Hashable {
|
||||
case general
|
||||
}
|
||||
var body: some View {
|
||||
TabView {
|
||||
GeneralSettingsView()
|
||||
.tabItem {
|
||||
Label("General", systemImage: "gear")
|
||||
}
|
||||
.tag(Tabs.general)
|
||||
}
|
||||
.padding(20)
|
||||
.frame(width: 500, height: 200)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
SettingsView()
|
||||
}
|
Loading…
Reference in New Issue