diff --git a/Pareto/AppHandlers.swift b/Pareto/AppHandlers.swift
index 54eceda..9a1c8fb 100644
--- a/Pareto/AppHandlers.swift
+++ b/Pareto/AppHandlers.swift
@@ -284,6 +284,18 @@ class AppHandlers: NSObject, NetworkHandlerObserver {
welcomeWindow!.makeKeyAndOrderFront(nil)
}
+ func copyLogs() {
+ NSPasteboard.general.clearContents()
+ if let data = try? AppInfo.logEntries().joined(separator: "\n") {
+ NSPasteboard.general.setString(data, forType: .string)
+ }
+ let alert = NSAlert()
+ alert.messageText = "Logs have been copied to the clipboard."
+ alert.alertStyle = NSAlert.Style.informational
+ alert.addButton(withTitle: "OK")
+ alert.runModal()
+ }
+
func copyDebug(_ onlyCheck: String) {
var data = ""
for claim in Claims.sorted {
@@ -457,6 +469,8 @@ class AppHandlers: NSObject, NetworkHandlerObserver {
case "debug":
let check = url.queryParams()["check"] ?? ""
copyDebug(check)
+ case "logs":
+ copyLogs()
case "runChecks":
NSApp.sendAction(#selector(runChecks), to: nil, from: nil)
NSApp.activate(ignoringOtherApps: true)
diff --git a/Pareto/AppInfo.swift b/Pareto/AppInfo.swift
index 17b873a..fabec44 100644
--- a/Pareto/AppInfo.swift
+++ b/Pareto/AppInfo.swift
@@ -103,7 +103,7 @@ enum AppInfo {
static let bugReportURL = { () -> URL in
let baseURL = "https://paretosecurity.com/report-bug?"
- let logs = logEntries().joined(separator: "\n").addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
+ let logs = try? logEntries().joined(separator: "\n").addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
let versions = getVersions().addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
if let url = URL(string: baseURL + "&logs=" + logs! + "&version=" + versions!) {
return url
@@ -119,7 +119,28 @@ enum AppInfo {
logs.append("Build: \(AppInfo.utmSource)")
logs.append("\nLogs:")
- logs.append("Please copy the logs from the Console app by searching for the ParetoSecurity.")
+
+ if #available(macOS 12.0, *) {
+ let logStore = try OSLogStore(scope: .currentProcessIdentifier)
+ // Get all the logs from the last hour.
+ let oneHourAgo = logStore.position(date: Date().addingTimeInterval(-3600))
+
+ // Fetch log objects.
+ let allEntries = try logStore.getEntries(at: oneHourAgo)
+
+ // Filter the log to be relevant for our specific subsystem
+ // and remove other elements (signposts, etc).
+ for log in allEntries
+ .compactMap({ $0 as? OSLogEntryLog })
+ .filter({ entry in
+ entry.subsystem == "niteo.co.Pareto"
+ }) {
+ logs.append("\(log.subsystem): \(log.composedMessage)")
+ }
+ } else {
+ logs.append("Please copy the logs from the Console app by searching for the ParetoSecurity.")
+ }
+
return logs
}
diff --git a/Pareto/Checks/Access Security/SSHKeysStrength.swift b/Pareto/Checks/Access Security/SSHKeysStrength.swift
index 761dc37..6b832aa 100644
--- a/Pareto/Checks/Access Security/SSHKeysStrength.swift
+++ b/Pareto/Checks/Access Security/SSHKeysStrength.swift
@@ -92,7 +92,7 @@ class SSHKeysStrengthCheck: ParetoCheck {
func isKeyStrong(withKey path: String) -> Bool {
let output = runCMD(app: "/usr/bin/ssh-keygen", args: ["-l", "-f", path])
let info = KeyInfo(stringLiteral: output.strip())
- os_log("%s has %d", log: Log.check, path, info.strength)
+ os_log("%{public}s has %d", log: Log.check, path, info.strength)
// https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-57pt3r1.pdf
switch info.cipher {
case .RSA:
diff --git a/Pareto/Info.plist b/Pareto/Info.plist
index 7918bdb..8f58e96 100644
--- a/Pareto/Info.plist
+++ b/Pareto/Info.plist
@@ -26,7 +26,7 @@
CFBundleVersion
- 4863
+ 4870
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
diff --git a/Pareto/StatusBar/StatusBarController.swift b/Pareto/StatusBar/StatusBarController.swift
index 7fba7eb..9c5b449 100644
--- a/Pareto/StatusBar/StatusBarController.swift
+++ b/Pareto/StatusBar/StatusBarController.swift
@@ -157,9 +157,9 @@ class StatusBarController: NSObject, NSMenuDelegate {
Team.update(withReport: report).response { response in
switch response.result {
case .success:
- os_log("Check status was updated", log: Log.app)
+ os_log("Team status was updated", log: Log.app)
case let .failure(err):
- os_log("Check status update failed: %s", log: Log.app, err.localizedDescription)
+ os_log("Team status update failed: %s", log: Log.app, err.localizedDescription)
}
}
}
diff --git a/Pareto/Teams.swift b/Pareto/Teams.swift
index ab61b0f..311dddf 100644
--- a/Pareto/Teams.swift
+++ b/Pareto/Teams.swift
@@ -147,8 +147,10 @@ enum Team {
let headers: HTTPHeaders = [
"X-Device-Auth": Defaults[.teamAuth]
]
+ let url = base + "/\(Defaults[.teamID])/device"
+ os_log("Requesting %{public}s", url)
return AF.request(
- base + "/\(Defaults[.teamID])/device",
+ url,
method: .put,
parameters: device,
encoder: JSONParameterEncoder.default,
@@ -156,7 +158,7 @@ enum Team {
).validate().cURLDescription { cmd in
debugPrint(cmd)
}.response(queue: queue) { data in
- os_log("%s", log: Log.api, data.debugDescription)
+ os_log("%{public}s", log: Log.api, data.debugDescription)
}
}
@@ -164,8 +166,10 @@ enum Team {
let headers: HTTPHeaders = [
"X-Device-Auth": Defaults[.teamAuth]
]
+ let url = base + "/\(Defaults[.teamID])/device"
+ os_log("Requesting %{public}s", url)
return AF.request(
- base + "/\(Defaults[.teamID])/device",
+ url,
method: .patch,
parameters: report,
encoder: JSONParameterEncoder.default,
@@ -188,7 +192,7 @@ enum Team {
os_log("Move detected, ticket parsing failed", log: Log.api)
}
} else {
- os_log("%s", log: Log.api, data.debugDescription)
+ os_log("%{public}s", log: Log.api, data.debugDescription)
}
}
}