Skip to content

Commit

Permalink
Add fallback handler for macOS 14 and xcode15
Browse files Browse the repository at this point in the history
  • Loading branch information
dz0ny committed Jan 14, 2024
1 parent f61133c commit 74c4d1a
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 100 deletions.
38 changes: 30 additions & 8 deletions Pareto Security.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@
4FEBA2F6269CD48F009B2469 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4FEBA2F5269CD48F009B2469 /* Assets.xcassets */; };
4FEBA2F9269CD48F009B2469 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4FEBA2F8269CD48F009B2469 /* Preview Assets.xcassets */; };
4FEBA304269CD4E0009B2469 /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FEBA303269CD4E0009B2469 /* StatusBarController.swift */; };
4FED33D32B54442700B153F7 /* SettingsAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 4FED33D22B54442700B153F7 /* SettingsAccess */; };
4FED33D52B54443000B153F7 /* SettingsAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 4FED33D42B54443000B153F7 /* SettingsAccess */; };
4FF13D9726DCCB9900E4084E /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF13D9626DCCB9900E4084E /* Utils.swift */; };
4FF13D9D26DE235700E4084E /* UpdaterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF13D9C26DE235700E4084E /* UpdaterTest.swift */; };
4FF22A6526F0CFA500500213 /* Flags.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF22A6426F0CFA500500213 /* Flags.swift */; };
Expand Down Expand Up @@ -408,6 +410,7 @@
4F37E7382718122E00A2B254 /* Version in Frameworks */,
4F37E7392718122E00A2B254 /* Path in Frameworks */,
4F37E73A2718122E00A2B254 /* Alamofire in Frameworks */,
4FED33D52B54443000B153F7 /* SettingsAccess in Frameworks */,
4F37E73B2718122E00A2B254 /* Defaults in Frameworks */,
4F37E73C2718122E00A2B254 /* SwiftSocket in Frameworks */,
4F37E73D2718122E00A2B254 /* LaunchAtLogin in Frameworks */,
Expand Down Expand Up @@ -444,6 +447,7 @@
4F1AE88B26F9FC150084A381 /* SwiftSocket in Frameworks */,
4F103012269F1C65008C1E86 /* LaunchAtLogin in Frameworks */,
4F196CD62714B51900A2A7B8 /* JWTDecode in Frameworks */,
4FED33D32B54442700B153F7 /* SettingsAccess in Frameworks */,
4F3EF0A528AEA05F00D83F4E /* Yams in Frameworks */,
4F923CED2756918E00070551 /* Cache in Frameworks */,
);
Expand Down Expand Up @@ -757,6 +761,7 @@
4F1E6DDA2760081300FD3F01 /* Regex */,
4FAF5BC12895583A004E9615 /* Setapp */,
4F3EF0A628AEA07400D83F4E /* Yams */,
4FED33D42B54443000B153F7 /* SettingsAccess */,
);
productName = Pareto;
productReference = 4F37E7472718122E00A2B254 /* Pareto Security SetApp.app */;
Expand Down Expand Up @@ -826,6 +831,7 @@
4F923CEC2756918E00070551 /* Cache */,
4F6EF891275FEE6C00752559 /* Regex */,
4F3EF0A428AEA05F00D83F4E /* Yams */,
4FED33D22B54442700B153F7 /* SettingsAccess */,
);
productName = Pareto;
productReference = 4FEBA2EE269CD48F009B2469 /* Pareto Security.app */;
Expand Down Expand Up @@ -876,6 +882,7 @@
4FAF5BC02895583A004E9615 /* XCRemoteSwiftPackageReference "Setapp-framework" */,
4F3EF0A328AEA05F00D83F4E /* XCRemoteSwiftPackageReference "Yams" */,
4FC0F2EC2A4C47FD004E7359 /* XCRemoteSwiftPackageReference "ViewInspector" */,
4FED33D12B54437800B153F7 /* XCRemoteSwiftPackageReference "SettingsAccess" */,
);
productRefGroup = 4FEBA2EF269CD48F009B2469 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -1279,7 +1286,7 @@
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Pareto/Preview Content\"";
DEVELOPMENT_TEAM = PM784W7B8X;
DEVELOPMENT_TEAM = JND55328G8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
Expand Down Expand Up @@ -1320,7 +1327,7 @@
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Pareto/Preview Content\"";
DEVELOPMENT_TEAM = PM784W7B8X;
DEVELOPMENT_TEAM = JND55328G8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "SETAPP_ENABLED=1";
Expand Down Expand Up @@ -1599,18 +1606,15 @@
DEVELOPMENT_TEAM = JND55328G8;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"SETAPP_ENABLED=0",
"DEBUG=1",
);
GCC_PREPROCESSOR_DEFINITIONS = "SETAPP_ENABLED=0";
INFOPLIST_FILE = Pareto/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 0.0.17;
MARKETING_VERSION = 1.7.72;
PRODUCT_BUNDLE_IDENTIFIER = niteo.co.Pareto;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -1643,7 +1647,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 0.0.17;
MARKETING_VERSION = 1.7.72;
PRODUCT_BUNDLE_IDENTIFIER = niteo.co.Pareto;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -1847,6 +1851,14 @@
minimumVersion = 0.9.7;
};
};
4FED33D12B54437800B153F7 /* XCRemoteSwiftPackageReference "SettingsAccess" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/orchetect/SettingsAccess";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.4.0;
};
};
4FF515BF26F7B362008D135E /* XCRemoteSwiftPackageReference "Alamofire" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Alamofire/Alamofire";
Expand Down Expand Up @@ -1958,6 +1970,16 @@
package = 4FAF5BC02895583A004E9615 /* XCRemoteSwiftPackageReference "Setapp-framework" */;
productName = Setapp;
};
4FED33D22B54442700B153F7 /* SettingsAccess */ = {
isa = XCSwiftPackageProductDependency;
package = 4FED33D12B54437800B153F7 /* XCRemoteSwiftPackageReference "SettingsAccess" */;
productName = SettingsAccess;
};
4FED33D42B54443000B153F7 /* SettingsAccess */ = {
isa = XCSwiftPackageProductDependency;
package = 4FED33D12B54437800B153F7 /* XCRemoteSwiftPackageReference "SettingsAccess" */;
productName = SettingsAccess;
};
4FF515C026F7B362008D135E /* Alamofire */ = {
isa = XCSwiftPackageProductDependency;
package = 4FF515BF26F7B362008D135E /* XCRemoteSwiftPackageReference "Alamofire" */;
Expand Down
102 changes: 68 additions & 34 deletions Pareto/AppHandlers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Alamofire
import Combine
import CoreGraphics
import Defaults
import Foundation
import LaunchAtLogin
Expand Down Expand Up @@ -166,6 +167,7 @@ class AppHandlers: NSObject, NetworkHandlerObserver {
}
completion(.finished)
}

NSBackgroundActivityScheduler.repeating(withName: "TeamsRunner", withInterval: 60 * 59) { (completion: NSBackgroundActivityScheduler.CompletionHandler) in
DispatchQueue.global(qos: .userInteractive).async {
if self.networkHandler.currentStatus == .satisfied {
Expand Down Expand Up @@ -227,7 +229,7 @@ class AppHandlers: NSObject, NetworkHandlerObserver {

@objc func doUpdate() {
if #available(macOS 14.0, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
showSettingsFallback()
} else if #available(macOS 13.0, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
} else {
Expand All @@ -239,7 +241,7 @@ class AppHandlers: NSObject, NetworkHandlerObserver {
@objc func showPrefs() {
Defaults[.updateNag] = false
if #available(macOS 14.0, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
showSettingsFallback()
} else if #available(macOS 13.0, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
} else {
Expand All @@ -265,20 +267,22 @@ class AppHandlers: NSObject, NetworkHandlerObserver {
@objc func runChecks() {
if !Defaults.firstLaunch(), !AppInfo.Licensed, !enrolledHandler, Defaults.shouldShowNag() {
Defaults.shownNag()
let alert = NSAlert()
alert.messageText = "You are running the free version of the app. Please consider purchasing the Personal lifetime license for unlimited devices."
alert.alertStyle = NSAlert.Style.informational
alert.addButton(withTitle: "Purchase")
alert.addButton(withTitle: "Later")
switch alert.runModal() {
case NSApplication.ModalResponse.alertFirstButtonReturn:
NSWorkspace.shared.open(URL(string: "https://paretosecurity.com/pricing")!)
case NSApplication.ModalResponse.alertSecondButtonReturn:
DispatchQueue.global(qos: .userInteractive).async {
self.statusBar?.runChecks()
DispatchQueue.main.async {
let alert = NSAlert()
alert.messageText = "You are running the free version of the app. Please consider purchasing the Personal lifetime license for unlimited devices."
alert.alertStyle = NSAlert.Style.informational
alert.addButton(withTitle: "Purchase")
alert.addButton(withTitle: "Later")
switch alert.runModal() {
case NSApplication.ModalResponse.alertFirstButtonReturn:
NSWorkspace.shared.open(URL(string: "https://paretosecurity.com/pricing")!)
case NSApplication.ModalResponse.alertSecondButtonReturn:
DispatchQueue.global(qos: .userInteractive).async {
self.statusBar?.runChecks()
}
default:
os_log("Unknown")
}
default:
os_log("Unknown")
}
} else {
DispatchQueue.global(qos: .userInteractive).async {
Expand All @@ -300,27 +304,57 @@ class AppHandlers: NSObject, NetworkHandlerObserver {
}

@objc func showWelcome() {
if welcomeWindow == nil {
let welcome = WelcomeView()
// Create the preferences window and set content
welcomeWindow = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 640, height: 480),
styleMask: [.closable, .titled],
backing: .buffered,
defer: false
)
welcomeWindow!.titlebarAppearsTransparent = true
welcomeWindow!.center()
welcomeWindow!.setFrameAutosaveName("welcomeView")
welcomeWindow!.isReleasedWhenClosed = true
welcomeWindow?.level = .floating

let hosting = NSHostingView(rootView: welcome)
hosting.autoresizingMask = [NSView.AutoresizingMask.width, NSView.AutoresizingMask.height]
welcomeWindow!.contentView = hosting
DispatchQueue.main.async { [self] in
if welcomeWindow == nil {
let welcome = WelcomeView()
// Create the preferences window and set content
welcomeWindow = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 640, height: 480),
styleMask: [.closable, .titled],
backing: .buffered,
defer: false
)
welcomeWindow!.titlebarAppearsTransparent = true
welcomeWindow!.center()
welcomeWindow!.setFrameAutosaveName("welcomeView")
welcomeWindow!.isReleasedWhenClosed = true
welcomeWindow?.level = .floating

let hosting = NSHostingView(rootView: welcome)
hosting.autoresizingMask = [NSView.AutoresizingMask.width, NSView.AutoresizingMask.height]
welcomeWindow!.contentView = hosting
}

welcomeWindow!.makeKeyAndOrderFront(nil)
}
}

welcomeWindow!.makeKeyAndOrderFront(nil)
@objc func showSettingsFallback() {
DispatchQueue.main.async { [self] in
if welcomeWindow == nil {
let settings = SettingsView(selected: SettingsView.Tabs.general)
// Create the preferences window and set content
welcomeWindow = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 420, height: 280),
styleMask: [.closable, .titled],
backing: .buffered,
defer: false
)

welcomeWindow!.titlebarAppearsTransparent = false
welcomeWindow!.center()
welcomeWindow!.setFrameAutosaveName("settingsView")
welcomeWindow!.isReleasedWhenClosed = false
welcomeWindow?.level = .floating

let hosting = NSHostingView(rootView: settings)
hosting.autoresizingMask = [NSView.AutoresizingMask.width, NSView.AutoresizingMask.height]
welcomeWindow!.contentView = hosting
welcomeWindow!.contentView?.translatesAutoresizingMaskIntoConstraints = true
}

welcomeWindow!.makeKeyAndOrderFront(nil)
}
}

func copyLogs() {
Expand Down
15 changes: 9 additions & 6 deletions Pareto/Checks/Access Security/NoUnusedUsers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ class NoUnusedUsers: ParetoCheck {
}

var accounts: [String] {
let adminUsers = runCMD(app: "/usr/bin/dscl", args: [".", "-read", "/Groups/admin", "GroupMembership"]).components(separatedBy: " ")
let adminUsers = runCMD(app: "/usr/bin/dscl", args: [".", "-read", "/Groups/admin", "GroupMembership"]).replacingAllMatches(of: "\n", with: "").components(separatedBy: " ")
let output = runCMD(app: "/usr/bin/dscl", args: [".", "-list", "/Users"]).components(separatedBy: "\n")
let local = output.filter { u in
!u.hasPrefix("_") && u.count > 1 && u != "root" && u != "nobody" && u != "daemon" && !adminUsers.contains(u)
!u.hasPrefix("_") && u.count > 1 && u != "root" && u != "nobody" && u != "daemon"
}
return local
let users = local.filter { u in
!adminUsers.contains(u)
}
return users
}

var isAdmin: Bool {
return runCMD(app: "/usr/bin/id", args: ["-Gn"]).components(separatedBy: " ").contains("admin")
}
Expand Down Expand Up @@ -70,8 +73,8 @@ class NoUnusedUsers: ParetoCheck {
}

override func checkPasses() -> Bool {
if !isAdmin{
return true
if !isAdmin {
return accounts.count == 1
}
return accounts.allSatisfy { u in
lastLoginRecent(user: u)
Expand Down
2 changes: 1 addition & 1 deletion Pareto/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>5326</string>
<string>5384</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
Expand Down
15 changes: 2 additions & 13 deletions Pareto/ParetoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Foundation
import LaunchAtLogin
import os.log
import OSLog
import SettingsAccess
import SwiftUI
import UserNotifications

Expand Down Expand Up @@ -133,19 +134,6 @@ class AppDelegate: AppHandlers, NSApplicationDelegate {
exit(1)
}
}

#if !DEBUG
#if !SETAPP_ENABLED
if !Bundle.main.path.string.hasPrefix("/Applications/") {
let alert = NSAlert()
alert.messageText = "Please install application by moving it into the Applications folder."
alert.alertStyle = NSAlert.Style.critical
alert.addButton(withTitle: "Close")
alert.runModal()
NSApplication.shared.terminate(self)
}
#endif
#endif
}

func application(_: NSApplication, open urls: [URL]) {
Expand Down Expand Up @@ -217,6 +205,7 @@ class AppDelegate: AppHandlers, NSApplicationDelegate {
@main
struct Pareto: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@Environment(\.openSettings) private var openSettings

var body: some Scene {
Settings {
Expand Down
26 changes: 14 additions & 12 deletions Pareto/StatusBar/StatusBarController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,20 @@ class StatusBarController: NSObject, NSMenuDelegate {
if Defaults.shouldDoTeamUpdate() || interactive {
let report = Report.now()
if !Defaults[.sendHWInfo], AppInfo.TeamSettings.forceSerialPush, Defaults.shouldAskForHWAllow() {
let alert = NSAlert()
alert.messageText = "Send device model and serial"
alert.informativeText = "Your team policy enables collection of serial number and hardware model name from this device. Do you allow it?"
alert.alertStyle = NSAlert.Style.warning
alert.addButton(withTitle: "OK")
alert.addButton(withTitle: "Don't Allow")
if alert.runModal() == .alertFirstButtonReturn {
Defaults[.sendHWInfo] = true
Defaults[.lastHWAsk] = Date().currentTimeMs()
} else {
Defaults[.sendHWInfo] = false
Defaults[.lastHWAsk] = Date().currentTimeMs()
DispatchQueue.main.async {
let alert = NSAlert()
alert.messageText = "Send device model and serial"
alert.informativeText = "Your team policy enables collection of serial number and hardware model name from this device. Do you allow it?"
alert.alertStyle = NSAlert.Style.warning
alert.addButton(withTitle: "OK")
alert.addButton(withTitle: "Don't Allow")
if alert.runModal() == .alertFirstButtonReturn {
Defaults[.sendHWInfo] = true
Defaults[.lastHWAsk] = Date().currentTimeMs()
} else {
Defaults[.sendHWInfo] = false
Defaults[.lastHWAsk] = Date().currentTimeMs()
}
}
}

Expand Down
6 changes: 2 additions & 4 deletions Pareto/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ func runShell(args: [String]) -> String {
}

func runOSA(appleScript: String) -> String? {

let out = runCMD(app: "/usr/bin/osascript", args: ["-e", appleScript])
return out

let out = runCMD(app: "/usr/bin/osascript", args: ["-e", appleScript])
return out
}

func lsof(withCommand cmd: String, withPort port: Int) -> Bool {
Expand Down
Loading

0 comments on commit 74c4d1a

Please sign in to comment.