Agent and bump

This commit is contained in:
Max Goedjen 2024-01-04 18:34:24 -08:00
parent 6d87dbd9e4
commit d999f5530e
No known key found for this signature in database
8 changed files with 170 additions and 82 deletions

View File

@ -6,7 +6,7 @@ import PackageDescription
let package = Package( let package = Package(
name: "SecretivePackages", name: "SecretivePackages",
platforms: [ platforms: [
.macOS(.v11) .macOS(.v12)
], ],
products: [ products: [
.library( .library(

View File

@ -139,20 +139,10 @@ extension SmartCard.Store {
guard let tokenID = tokenID else { return } guard let tokenID = tokenID else { return }
let fallbackName = NSLocalizedString("Smart Card", comment: "Smart Card") let fallbackName = NSLocalizedString("Smart Card", comment: "Smart Card")
if #available(macOS 12.0, *) { if let driverName = watcher.tokenInfo(forTokenID: tokenID)?.driverName {
if let driverName = watcher.tokenInfo(forTokenID: tokenID)?.driverName { name = driverName
name = driverName
} else {
name = fallbackName
}
} else { } else {
// Hack to read name if there's only one smart card name = fallbackName
let slotNames = TKSmartCardSlotManager().slotNames
if watcher.nonSecureEnclaveTokens.count == 1 && slotNames.count == 1 {
name = slotNames.first!
} else {
name = fallbackName
}
} }
let attributes = KeychainDictionary([ let attributes = KeychainDictionary([

View File

@ -0,0 +1,105 @@
{
"sourceLanguage" : "en",
"strings" : {
"persist_authentication_accept_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Leave Unlocked"
}
}
}
},
"persist_authentication_decline_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Do Not Unlock"
}
}
}
},
"signed_notification_description_%@" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Using secret %1$@"
}
}
}
},
"signed_notification_title_%@" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Signed Request from %1$@"
}
}
}
},
"update_notification_ignore_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ignore"
}
}
}
},
"update_notification_update_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Update"
}
}
}
},
"update_notification_update_critical_title_%@" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Critical Security Update - %1$@"
}
}
}
},
"update_notification_update_description" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Click to Update"
}
}
}
},
"update_notification_update_normal_title_%@" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Update Available - %1$@"
}
}
}
}
},
"version" : "1.0"
}

View File

@ -10,8 +10,8 @@ class Notifier {
private let notificationDelegate = NotificationDelegate() private let notificationDelegate = NotificationDelegate()
init() { init() {
let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: "Update", options: []) let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: String(localized: "update_notification_update_button"), options: [])
let ignoreAction = UNNotificationAction(identifier: Constants.ignoreActionIdentitifier, title: "Ignore", options: []) let ignoreAction = UNNotificationAction(identifier: Constants.ignoreActionIdentitifier, title: String(localized: "update_notification_ignore_button"), options: [])
let updateCategory = UNNotificationCategory(identifier: Constants.updateCategoryIdentitifier, actions: [updateAction, ignoreAction], intentIdentifiers: [], options: []) let updateCategory = UNNotificationCategory(identifier: Constants.updateCategoryIdentitifier, actions: [updateAction, ignoreAction], intentIdentifiers: [], options: [])
let criticalUpdateCategory = UNNotificationCategory(identifier: Constants.criticalUpdateCategoryIdentitifier, actions: [updateAction], intentIdentifiers: [], options: []) let criticalUpdateCategory = UNNotificationCategory(identifier: Constants.criticalUpdateCategoryIdentitifier, actions: [updateAction], intentIdentifiers: [], options: [])
@ -22,7 +22,7 @@ class Notifier {
Measurement(value: 24, unit: UnitDuration.hours) Measurement(value: 24, unit: UnitDuration.hours)
] ]
let doNotPersistAction = UNNotificationAction(identifier: Constants.doNotPersistActionIdentitifier, title: "Do Not Unlock", options: []) let doNotPersistAction = UNNotificationAction(identifier: Constants.doNotPersistActionIdentitifier, title: String(localized: "persist_authentication_decline_button"), options: [])
var allPersistenceActions = [doNotPersistAction] var allPersistenceActions = [doNotPersistAction]
let formatter = DateComponentsFormatter() let formatter = DateComponentsFormatter()
@ -40,7 +40,7 @@ class Notifier {
let persistAuthenticationCategory = UNNotificationCategory(identifier: Constants.persistAuthenticationCategoryIdentitifier, actions: allPersistenceActions, intentIdentifiers: [], options: []) let persistAuthenticationCategory = UNNotificationCategory(identifier: Constants.persistAuthenticationCategoryIdentitifier, actions: allPersistenceActions, intentIdentifiers: [], options: [])
if persistAuthenticationCategory.responds(to: Selector(("actionsMenuTitle"))) { if persistAuthenticationCategory.responds(to: Selector(("actionsMenuTitle"))) {
persistAuthenticationCategory.setValue("Leave Unlocked", forKey: "_actionsMenuTitle") persistAuthenticationCategory.setValue(String(localized: "persist_authentication_accept_button"), forKey: "_actionsMenuTitle")
} }
UNUserNotificationCenter.current().setNotificationCategories([updateCategory, criticalUpdateCategory, persistAuthenticationCategory]) UNUserNotificationCenter.current().setNotificationCategories([updateCategory, criticalUpdateCategory, persistAuthenticationCategory])
UNUserNotificationCenter.current().delegate = notificationDelegate UNUserNotificationCenter.current().delegate = notificationDelegate
@ -62,13 +62,11 @@ class Notifier {
notificationDelegate.pendingPersistableStores[store.id.description] = store notificationDelegate.pendingPersistableStores[store.id.description] = store
let notificationCenter = UNUserNotificationCenter.current() let notificationCenter = UNUserNotificationCenter.current()
let notificationContent = UNMutableNotificationContent() let notificationContent = UNMutableNotificationContent()
notificationContent.title = "Signed Request from \(provenance.origin.displayName)" notificationContent.title = String(localized: "signed_notification_title_\(provenance.origin.displayName)")
notificationContent.subtitle = "Using secret \"\(secret.name)\"" notificationContent.subtitle = String(localized: "signed_notification_description_\(secret.name)")
notificationContent.userInfo[Constants.persistSecretIDKey] = secret.id.description notificationContent.userInfo[Constants.persistSecretIDKey] = secret.id.description
notificationContent.userInfo[Constants.persistStoreIDKey] = store.id.description notificationContent.userInfo[Constants.persistStoreIDKey] = store.id.description
if #available(macOS 12.0, *) { notificationContent.interruptionLevel = .timeSensitive
notificationContent.interruptionLevel = .timeSensitive
}
if secret.requiresAuthentication && store.existingPersistedAuthenticationContext(secret: secret) == nil { if secret.requiresAuthentication && store.existingPersistedAuthenticationContext(secret: secret) == nil {
notificationContent.categoryIdentifier = Constants.persistAuthenticationCategoryIdentitifier notificationContent.categoryIdentifier = Constants.persistAuthenticationCategoryIdentitifier
} }
@ -85,14 +83,12 @@ class Notifier {
let notificationCenter = UNUserNotificationCenter.current() let notificationCenter = UNUserNotificationCenter.current()
let notificationContent = UNMutableNotificationContent() let notificationContent = UNMutableNotificationContent()
if update.critical { if update.critical {
if #available(macOS 12.0, *) { notificationContent.interruptionLevel = .critical
notificationContent.interruptionLevel = .critical notificationContent.title = String(localized: "update_notification_update_critical_title_\(update.name)")
}
notificationContent.title = "Critical Security Update - \(update.name)"
} else { } else {
notificationContent.title = "Update Available - \(update.name)" notificationContent.title = String(localized: "update_notification_update_normal_title_\(update.name)")
} }
notificationContent.subtitle = "Click to Update" notificationContent.subtitle = String(localized: "update_notification_update_description")
notificationContent.body = update.body notificationContent.body = update.body
notificationContent.categoryIdentifier = update.critical ? Constants.criticalUpdateCategoryIdentitifier : Constants.updateCategoryIdentitifier notificationContent.categoryIdentifier = update.critical ? Constants.criticalUpdateCategoryIdentitifier : Constants.updateCategoryIdentitifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil) let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil)

View File

@ -19,6 +19,7 @@
5003EF632780081B00DF2006 /* SecureEnclaveSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF622780081B00DF2006 /* SecureEnclaveSecretKit */; }; 5003EF632780081B00DF2006 /* SecureEnclaveSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF622780081B00DF2006 /* SecureEnclaveSecretKit */; };
5003EF652780081B00DF2006 /* SmartCardSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF642780081B00DF2006 /* SmartCardSecretKit */; }; 5003EF652780081B00DF2006 /* SmartCardSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF642780081B00DF2006 /* SmartCardSecretKit */; };
500B93C32B478D8400E157DE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 500B93C22B478D8400E157DE /* Localizable.xcstrings */; }; 500B93C32B478D8400E157DE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 500B93C22B478D8400E157DE /* Localizable.xcstrings */; };
500B93C72B479E2E00E157DE /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 500B93C62B479E2E00E157DE /* Localizable.xcstrings */; };
501421622781262300BBAA70 /* Brief in Frameworks */ = {isa = PBXBuildFile; productRef = 501421612781262300BBAA70 /* Brief */; }; 501421622781262300BBAA70 /* Brief in Frameworks */ = {isa = PBXBuildFile; productRef = 501421612781262300BBAA70 /* Brief */; };
501421652781268000BBAA70 /* SecretAgent.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 50A3B78A24026B7500D209EA /* SecretAgent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 501421652781268000BBAA70 /* SecretAgent.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 50A3B78A24026B7500D209EA /* SecretAgent.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
50153E20250AFCB200525160 /* UpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E1F250AFCB200525160 /* UpdateView.swift */; }; 50153E20250AFCB200525160 /* UpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50153E1F250AFCB200525160 /* UpdateView.swift */; };
@ -110,6 +111,7 @@
50033AC227813F1700253856 /* BundleIDs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleIDs.swift; sourceTree = "<group>"; }; 50033AC227813F1700253856 /* BundleIDs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleIDs.swift; sourceTree = "<group>"; };
5003EF39278005C800DF2006 /* Packages */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Packages; sourceTree = "<group>"; }; 5003EF39278005C800DF2006 /* Packages */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Packages; sourceTree = "<group>"; };
500B93C22B478D8400E157DE /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; }; 500B93C22B478D8400E157DE /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
500B93C62B479E2E00E157DE /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
50153E1F250AFCB200525160 /* UpdateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateView.swift; sourceTree = "<group>"; }; 50153E1F250AFCB200525160 /* UpdateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateView.swift; sourceTree = "<group>"; };
50153E21250DECA300525160 /* SecretListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretListItemView.swift; sourceTree = "<group>"; }; 50153E21250DECA300525160 /* SecretListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretListItemView.swift; sourceTree = "<group>"; };
5018F54E24064786002EB505 /* Notifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifier.swift; sourceTree = "<group>"; }; 5018F54E24064786002EB505 /* Notifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifier.swift; sourceTree = "<group>"; };
@ -314,6 +316,7 @@
50A3B79824026B7600D209EA /* Info.plist */, 50A3B79824026B7600D209EA /* Info.plist */,
508BF29425B4F140009EFB7E /* InternetAccessPolicy.plist */, 508BF29425B4F140009EFB7E /* InternetAccessPolicy.plist */,
50A3B79924026B7600D209EA /* SecretAgent.entitlements */, 50A3B79924026B7600D209EA /* SecretAgent.entitlements */,
500B93C62B479E2E00E157DE /* Localizable.xcstrings */,
50A3B79224026B7600D209EA /* Preview Content */, 50A3B79224026B7600D209EA /* Preview Content */,
); );
path = SecretAgent; path = SecretAgent;
@ -466,6 +469,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
50A3B79724026B7600D209EA /* Main.storyboard in Resources */, 50A3B79724026B7600D209EA /* Main.storyboard in Resources */,
500B93C72B479E2E00E157DE /* Localizable.xcstrings in Resources */,
50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */, 50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */,
50A3B79124026B7600D209EA /* Assets.xcassets in Resources */, 50A3B79124026B7600D209EA /* Assets.xcassets in Resources */,
508BF2AA25B4F1CB009EFB7E /* InternetAccessPolicy.plist in Resources */, 508BF2AA25B4F1CB009EFB7E /* InternetAccessPolicy.plist in Resources */,
@ -693,6 +697,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1; MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host; PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -721,6 +726,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1; MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host; PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -854,6 +860,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1; MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host; PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -898,6 +905,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1; MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent; PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -922,6 +930,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1; MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent; PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -947,6 +956,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1; MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent; PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@ -1,9 +1,6 @@
{ {
"sourceLanguage" : "en", "sourceLanguage" : "en",
"strings" : { "strings" : {
"" : {
},
"\n" : { "\n" : {
}, },
@ -130,26 +127,6 @@
} }
} }
}, },
"create_secret_legacy_notify_description" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Authentication not required when Mac is unlocked"
}
}
}
},
"create_secret_legacy_require_authentication_description" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Requires Authentication (Biometrics or Password) before each use"
}
}
}
},
"create_secret_name_label" : { "create_secret_name_label" : {
"localizations" : { "localizations" : {
"en" : { "en" : {
@ -614,6 +591,16 @@
} }
} }
}, },
"update_critical_notice_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Critical Security Update Required"
}
}
}
},
"update_ignore_button" : { "update_ignore_button" : {
"localizations" : { "localizations" : {
"en" : { "en" : {
@ -624,6 +611,16 @@
} }
} }
}, },
"update_normal_notice_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Update Available"
}
}
}
},
"update_release_notes_title" : { "update_release_notes_title" : {
"localizations" : { "localizations" : {
"en" : { "en" : {
@ -634,6 +631,16 @@
} }
} }
}, },
"update_test_notice_title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Test Build"
}
}
}
},
"update_update_button" : { "update_update_button" : {
"localizations" : { "localizations" : {
"en" : { "en" : {

View File

@ -64,15 +64,15 @@ extension ContentView {
} }
} }
var updateNoticeContent: (String, Color)? { var updateNoticeContent: (LocalizedStringKey, Color)? {
guard let update = updater.update else { return nil } guard let update = updater.update else { return nil }
if update.critical { if update.critical {
return ("Critical Security Update Required", .red) return ("update_critical_notice_title", .red)
} else { } else {
if updater.testBuild { if updater.testBuild {
return ("Test Build", .blue) return ("update_test_notice_title", .blue)
} else { } else {
return ("Update Available", .orange) return ("update_normal_notice_title", .orange)
} }
} }
} }

View File

@ -23,25 +23,12 @@ struct CreateSecretView<StoreType: SecretStoreModifiable>: View {
TextField("create_secret_name_placeholder", text: $name) TextField("create_secret_name_placeholder", text: $name)
.focusable() .focusable()
} }
if #available(macOS 12.0, *) { ThumbnailPickerView(items: [
ThumbnailPickerView(items: [ ThumbnailPickerView.Item(value: true, name: "create_secret_require_authentication_title", description: "create_secret_require_authentication_description", thumbnail: AuthenticationView()),
ThumbnailPickerView.Item(value: true, name: "create_secret_require_authentication_title", description: "create_secret_require_authentication_description", thumbnail: AuthenticationView()), ThumbnailPickerView.Item(value: false, name: "create_secret_notify_title",
ThumbnailPickerView.Item(value: false, name: "create_secret_notify_title", description: "create_secret_notify_description",
description: "create_secret_notify_description", thumbnail: NotificationView())
thumbnail: NotificationView()) ], selection: $requiresAuthentication)
], selection: $requiresAuthentication)
} else {
HStack {
VStack(spacing: 20) {
Picker("", selection: $requiresAuthentication) {
Text("create_secret_legacy_require_authentication_description").tag(true)
Text("create_secret_legacy_notify_description").tag(false)
}
.pickerStyle(RadioGroupPickerStyle())
Spacer(minLength: 10)
}
}
}
} }
} }
HStack { HStack {
@ -138,7 +125,6 @@ extension ThumbnailPickerView {
} }
@available(macOS 12.0, *)
struct SystemBackgroundView: View { struct SystemBackgroundView: View {
let anchor: UnitPoint let anchor: UnitPoint
@ -157,7 +143,6 @@ struct SystemBackgroundView: View {
} }
} }
@available(macOS 12.0, *)
struct AuthenticationView: View { struct AuthenticationView: View {
var body: some View { var body: some View {
@ -203,7 +188,6 @@ struct AuthenticationView: View {
} }
@available(macOS 12.0, *)
struct NotificationView: View { struct NotificationView: View {
var body: some View { var body: some View {
@ -253,14 +237,10 @@ struct CreateSecretView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
Group { Group {
CreateSecretView(store: Preview.StoreModifiable(), showing: .constant(true)) CreateSecretView(store: Preview.StoreModifiable(), showing: .constant(true))
if #available(macOS 12.0, *) {
AuthenticationView().environment(\.colorScheme, .dark) AuthenticationView().environment(\.colorScheme, .dark)
AuthenticationView().environment(\.colorScheme, .light) AuthenticationView().environment(\.colorScheme, .light)
NotificationView().environment(\.colorScheme, .dark) NotificationView().environment(\.colorScheme, .dark)
NotificationView().environment(\.colorScheme, .light) NotificationView().environment(\.colorScheme, .light)
} else {
// Fallback on earlier versions
}
} }
} }
} }