Skip to content

Commit

Permalink
Add strings catalog and update strings to be keyed (#500)
Browse files Browse the repository at this point in the history
* Set up and start main content view

* Continue

* Setup flow

* No secure storage view

* Delete

* Detail

* Rename

* More create

* Empty.

* List

* Main app

* Agent and bump

* .
  • Loading branch information
maxgoedjen authored Jan 5, 2024
1 parent 8c67ea7 commit c80a6f1
Show file tree
Hide file tree
Showing 18 changed files with 875 additions and 134 deletions.
2 changes: 1 addition & 1 deletion Sources/Packages/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "SecretivePackages",
platforms: [
.macOS(.v11)
.macOS(.v12)
],
products: [
.library(
Expand Down
16 changes: 3 additions & 13 deletions Sources/Packages/Sources/SmartCardSecretKit/SmartCardStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,10 @@ extension SmartCard.Store {
guard let tokenID = tokenID else { return }

let fallbackName = NSLocalizedString("Smart Card", comment: "Smart Card")
if #available(macOS 12.0, *) {
if let driverName = watcher.tokenInfo(forTokenID: tokenID)?.driverName {
name = driverName
} else {
name = fallbackName
}
if let driverName = watcher.tokenInfo(forTokenID: tokenID)?.driverName {
name = driverName
} else {
// Hack to read name if there's only one smart card
let slotNames = TKSmartCardSlotManager().slotNames
if watcher.nonSecureEnclaveTokens.count == 1 && slotNames.count == 1 {
name = slotNames.first!
} else {
name = fallbackName
}
name = fallbackName
}

let attributes = KeychainDictionary([
Expand Down
105 changes: 105 additions & 0 deletions Sources/SecretAgent/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -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"
}
26 changes: 11 additions & 15 deletions Sources/SecretAgent/Notifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class Notifier {
private let notificationDelegate = NotificationDelegate()

init() {
let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: "Update", options: [])
let ignoreAction = UNNotificationAction(identifier: Constants.ignoreActionIdentitifier, title: "Ignore", options: [])
let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: String(localized: "update_notification_update_button"), 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 criticalUpdateCategory = UNNotificationCategory(identifier: Constants.criticalUpdateCategoryIdentitifier, actions: [updateAction], intentIdentifiers: [], options: [])

Expand All @@ -22,7 +22,7 @@ class Notifier {
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]

let formatter = DateComponentsFormatter()
Expand All @@ -40,7 +40,7 @@ class Notifier {

let persistAuthenticationCategory = UNNotificationCategory(identifier: Constants.persistAuthenticationCategoryIdentitifier, actions: allPersistenceActions, intentIdentifiers: [], options: [])
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().delegate = notificationDelegate
Expand All @@ -62,13 +62,11 @@ class Notifier {
notificationDelegate.pendingPersistableStores[store.id.description] = store
let notificationCenter = UNUserNotificationCenter.current()
let notificationContent = UNMutableNotificationContent()
notificationContent.title = "Signed Request from \(provenance.origin.displayName)"
notificationContent.subtitle = "Using secret \"\(secret.name)\""
notificationContent.title = String(localized: "signed_notification_title_\(provenance.origin.displayName)")
notificationContent.subtitle = String(localized: "signed_notification_description_\(secret.name)")
notificationContent.userInfo[Constants.persistSecretIDKey] = secret.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 {
notificationContent.categoryIdentifier = Constants.persistAuthenticationCategoryIdentitifier
}
Expand All @@ -85,14 +83,12 @@ class Notifier {
let notificationCenter = UNUserNotificationCenter.current()
let notificationContent = UNMutableNotificationContent()
if update.critical {
if #available(macOS 12.0, *) {
notificationContent.interruptionLevel = .critical
}
notificationContent.title = "Critical Security Update - \(update.name)"
notificationContent.interruptionLevel = .critical
notificationContent.title = String(localized: "update_notification_update_critical_title_\(update.name)")
} 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.categoryIdentifier = update.critical ? Constants.criticalUpdateCategoryIdentitifier : Constants.updateCategoryIdentitifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil)
Expand Down
17 changes: 17 additions & 0 deletions Sources/Secretive.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
5003EF612780081600DF2006 /* SmartCardSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF602780081600DF2006 /* SmartCardSecretKit */; };
5003EF632780081B00DF2006 /* SecureEnclaveSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF622780081B00DF2006 /* SecureEnclaveSecretKit */; };
5003EF652780081B00DF2006 /* SmartCardSecretKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5003EF642780081B00DF2006 /* SmartCardSecretKit */; };
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 */; };
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 */; };
Expand Down Expand Up @@ -108,6 +110,8 @@
50020BAF24064869003D4025 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.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>"; };
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>"; };
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>"; };
Expand Down Expand Up @@ -228,6 +232,7 @@
508BF28D25B4F005009EFB7E /* InternetAccessPolicy.plist */,
50617D8F23FCE48E0099B055 /* Secretive.entitlements */,
506772C62424784600034DED /* Credits.rtf */,
500B93C22B478D8400E157DE /* Localizable.xcstrings */,
50617D8823FCE48E0099B055 /* Preview Content */,
);
path = Secretive;
Expand Down Expand Up @@ -311,6 +316,7 @@
50A3B79824026B7600D209EA /* Info.plist */,
508BF29425B4F140009EFB7E /* InternetAccessPolicy.plist */,
50A3B79924026B7600D209EA /* SecretAgent.entitlements */,
500B93C62B479E2E00E157DE /* Localizable.xcstrings */,
50A3B79224026B7600D209EA /* Preview Content */,
);
path = SecretAgent;
Expand Down Expand Up @@ -444,6 +450,7 @@
buildActionMask = 2147483647;
files = (
50617D8A23FCE48E0099B055 /* Preview Assets.xcassets in Resources */,
500B93C32B478D8400E157DE /* Localizable.xcstrings in Resources */,
50617D8723FCE48E0099B055 /* Assets.xcassets in Resources */,
506772C72424784600034DED /* Credits.rtf in Resources */,
508BF28E25B4F005009EFB7E /* InternetAccessPolicy.plist in Resources */,
Expand All @@ -462,6 +469,7 @@
buildActionMask = 2147483647;
files = (
50A3B79724026B7600D209EA /* Main.storyboard in Resources */,
500B93C72B479E2E00E157DE /* Localizable.xcstrings in Resources */,
50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */,
50A3B79124026B7600D209EA /* Assets.xcassets in Resources */,
508BF2AA25B4F1CB009EFB7E /* InternetAccessPolicy.plist in Resources */,
Expand Down Expand Up @@ -606,6 +614,7 @@
STRIP_INSTALLED_PRODUCT = NO;
STRIP_SWIFT_SYMBOLS = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
Expand Down Expand Up @@ -664,6 +673,7 @@
STRIP_INSTALLED_PRODUCT = NO;
STRIP_SWIFT_SYMBOLS = NO;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
Expand All @@ -687,6 +697,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -715,6 +726,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -827,6 +839,7 @@
STRIP_INSTALLED_PRODUCT = NO;
STRIP_SWIFT_SYMBOLS = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Test;
Expand All @@ -847,6 +860,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -891,6 +905,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -915,6 +930,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -940,6 +956,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
6 changes: 3 additions & 3 deletions Sources/Secretive/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ struct Secretive: App {
}
.commands {
CommandGroup(after: CommandGroupPlacement.newItem) {
Button("New Secret") {
Button("app_menu_new_secret_button") {
showingCreation = true
}
.keyboardShortcut(KeyboardShortcut(KeyEquivalent("N"), modifiers: [.command, .shift]))
}
CommandGroup(replacing: .help) {
Button("Help") {
Button("app_menu_help_button") {
NSWorkspace.shared.open(Constants.helpURL)
}
}
CommandGroup(after: .help) {
Button("Setup Secretive") {
Button("app_menu_setup_button") {
showingSetup = true
}
}
Expand Down
Loading

0 comments on commit c80a6f1

Please sign in to comment.