diff --git a/CHANGELOG.md b/CHANGELOG.md
index 45d57f5b..bd5b01b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2.0.7] - 2024-08-08
+Requires macOS 12.0 and higher.
+
+### Added
+- If using `utilizeSOFAFeed`, you can now set the `aboutUpdateURL` to `sofa`
+ - If a URL is found in the relevant `SecurityInfo` key for the corresponding update, this value will be used.
+ - If no URL is found, the aboutUpdateURL button will not be shown to the user
+ - [Feature Request 629](https://github.com/macadmins/nudge/issues/629)
+
+### Changed
+- The `SMAppService` logic logs have been moved to debug logs
+- When an updated Managed Preference is sent for `com.github.macadmins.Nudge`, if the values are different, [Nudge will exit](https://github.com/macadmins/nudge/commit/f13a697dd61400f7f0d73dc38226f7769ed8e4f4)
+ - This is a workaround for issue [602](https://github.com/macadmins/nudge/issues/602)
+ - The LaunchAgent will ensure the application is successfully restarted at a future time.
+
+### Fixed
+- The Jamf JSON schema file had an [item missing](https://github.com/macadmins/nudge/pull/632) and a [key incorrectly set](https://github.com/macadmins/nudge/pull/634)
+
## [2.0.6] - 2024-08-01
Requires macOS 12.0 and higher.
diff --git a/Example Assets/com.github.macadmins.Nudge.tester.json b/Example Assets/com.github.macadmins.Nudge.tester.json
index 8ea8d003..b6fd09b5 100644
--- a/Example Assets/com.github.macadmins.Nudge.tester.json
+++ b/Example Assets/com.github.macadmins.Nudge.tester.json
@@ -5,7 +5,7 @@
},
"osVersionRequirements": [
{
- "aboutUpdateURL": "https://apple.com",
+ "aboutUpdateURL": "sofa",
"requiredMinimumOSVersion": "latest",
"unsupportedURL": "https://google.com"
}
diff --git a/Nudge.xcodeproj/project.pbxproj b/Nudge.xcodeproj/project.pbxproj
index 278be3c2..de99b846 100644
--- a/Nudge.xcodeproj/project.pbxproj
+++ b/Nudge.xcodeproj/project.pbxproj
@@ -698,7 +698,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
- MARKETING_VERSION = 2.0.6;
+ MARKETING_VERSION = 2.0.7;
PRODUCT_BUNDLE_IDENTIFIER = com.github.macadmins.Nudge;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -729,7 +729,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
- MARKETING_VERSION = 2.0.6;
+ MARKETING_VERSION = 2.0.7;
PRODUCT_BUNDLE_IDENTIFIER = com.github.macadmins.Nudge;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/Nudge/Info.plist b/Nudge/Info.plist
index 34cd4143..607a5905 100644
--- a/Nudge/Info.plist
+++ b/Nudge/Info.plist
@@ -15,9 +15,9 @@
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 2.0.6
+ 2.0.7
CFBundleVersion
- 2.0.6
+ 2.0.7
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
diff --git a/Nudge/UI/Common/InformationButton.swift b/Nudge/UI/Common/InformationButton.swift
index 37384ada..3c9ca48b 100644
--- a/Nudge/UI/Common/InformationButton.swift
+++ b/Nudge/UI/Common/InformationButton.swift
@@ -20,9 +20,19 @@ struct InformationButton: View {
private var informationButton: some View {
guard OSVersionRequirementVariables.aboutUpdateURL != "" else { return AnyView(EmptyView()) }
+ var selectedURL = OSVersionRequirementVariables.aboutUpdateURL
+ if OSVersionRequirementVariables.aboutUpdateURL == "sofa" && OptionalFeatureVariables.utilizeSOFAFeed {
+ if nudgePrimaryState.sofaAboutUpdateURL.hasPrefix("https://") {
+ selectedURL = nudgePrimaryState.sofaAboutUpdateURL
+ } else {
+ return AnyView(EmptyView())
+ }
+ }
return AnyView(
- Button(action: UIUtilities().openMoreInfo) {
+ Button(action: {
+ UIUtilities().openMoreInfo(infoURL: selectedURL)
+ }) {
Text(.init(UserInterfaceVariables.informationButtonText.localized(desiredLanguage: getDesiredLanguage(locale: appState.locale))))
.foregroundColor(dynamicTextColor)
}
diff --git a/Nudge/UI/Defaults.swift b/Nudge/UI/Defaults.swift
index b06e221d..42d912c2 100644
--- a/Nudge/UI/Defaults.swift
+++ b/Nudge/UI/Defaults.swift
@@ -23,7 +23,7 @@ struct Globals {
static let snc = NSWorkspace.shared.notificationCenter
// Preferences
static let configJSON = ConfigurationManager().getConfigurationAsJSON()
- static var configProfile = ConfigurationManager().getConfigurationAsProfile()
+ static let configProfile = ConfigurationManager().getConfigurationAsProfile()
static let nudgeDefaults = UserDefaults.standard
static let nudgeJSONPreferences = NetworkFileManager().getNudgeJSONPreferences()
// Device Properties
@@ -83,6 +83,7 @@ class AppState: ObservableObject {
@Published var requireDualQuitButtons = false
@Published var requiredMinimumOSVersion = OSVersionRequirementVariables.requiredMinimumOSVersion
@Published var shouldExit = false
+ @Published var sofaAboutUpdateURL: String = ""
@Published var timerCycle = 0
@Published var userDeferrals = Globals.nudgeDefaults.object(forKey: "userDeferrals") as? Int ?? 0
@Published var userQuitDeferrals = Globals.nudgeDefaults.object(forKey: "userQuitDeferrals") as? Int ?? 0
diff --git a/Nudge/UI/Main.swift b/Nudge/UI/Main.swift
index 47c0f827..c941e0c9 100644
--- a/Nudge/UI/Main.swift
+++ b/Nudge/UI/Main.swift
@@ -282,6 +282,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// Start setting UI fields
nudgePrimaryState.requiredMinimumOSVersion = selectedOS!.productVersion
+ nudgePrimaryState.sofaAboutUpdateURL = selectedOS!.securityInfo
nudgePrimaryState.activelyExploitedCVEs = activelyExploitedCVEs
releaseDate = selectedOS!.releaseDate ?? Date()
if requiredInstallationDate == Date(timeIntervalSince1970: 0) {
@@ -650,7 +651,22 @@ class AppDelegate: NSObject, NSApplicationDelegate {
private func handleSMAppService() {
if #available(macOS 13, *) {
let appService = SMAppService.agent(plistName: "com.github.macadmins.Nudge.SMAppService.plist")
+ let mainAppServce = SMAppService.mainApp
let appServiceStatus = appService.status
+ let mainAppServiceStatus = mainAppServce.status
+// print("")
+// print("com.github.macadmins.Nudge.SMAppService")
+// print("notRegistered: \(appServiceStatus == SMAppService.Status.notRegistered)")
+// print("enabled: \(appServiceStatus == SMAppService.Status.enabled)")
+// print("requiresApproval: \(appServiceStatus == SMAppService.Status.requiresApproval)")
+// print("notFound: \(appServiceStatus == SMAppService.Status.notFound)")
+// print("")
+// print("mainAppService")
+// print("notRegistered: \(mainAppServiceStatus == SMAppService.Status.notRegistered)")
+// print("enabled: \(mainAppServiceStatus == SMAppService.Status.enabled)")
+// print("requiresApproval: \(mainAppServiceStatus == SMAppService.Status.requiresApproval)")
+// print("notFound: \(mainAppServiceStatus == SMAppService.Status.notFound)")
+// print("")
if CommandLine.arguments.contains("--register") || UserExperienceVariables.loadLaunchAgent {
SMAppManager().loadSMAppLaunchAgent(appService: appService, appServiceStatus: appServiceStatus)
@@ -724,8 +740,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
Globals.nc.addObserver(
forName: UserDefaults.didChangeNotification,
object: nil,
- queue: .main) { [weak self] _ in
- Globals.configProfile = ConfigurationManager().getConfigurationAsProfile()
+ queue: .main) { _ in
+ if ConfigurationManager().getConfigurationAsProfile() == Globals.configProfile {
+ LogManager.debug("MDM Profile has been re-installed or updated but configuration is identical, no need to quit Nudge.", logger: sofaLog)
+ } else {
+ LogManager.info("MDM Profile has been re-installed or updated. Quitting Nudge to allow LaunchAgent to re-initalize with new settings.", logger: sofaLog)
+ nudgePrimaryState.shouldExit = true
+ exit(2)
+ }
}
}
diff --git a/Nudge/Utilities/Utils.swift b/Nudge/Utilities/Utils.swift
index d0892d00..6b4e2ebc 100644
--- a/Nudge/Utilities/Utils.swift
+++ b/Nudge/Utilities/Utils.swift
@@ -1283,7 +1283,7 @@ struct SubProcessUtilities {
struct SMAppManager {
private func handleLegacyLaunchAgent(passedThroughCLI: Bool, action: String) {
- logOrPrint("Legacy Nudge LaunchAgent currently loaded. Please disable this agent before attempting to \(action) modern agent.", passedThroughCLI: passedThroughCLI, exitCode: 1)
+ logOrPrint("Legacy Nudge LaunchAgent currently loaded. Please disable this agent before attempting to \(action) modern agent.", error: false, passedThroughCLI: passedThroughCLI, exitCode: 1)
}
@available(macOS 13.0, *)
@@ -1299,29 +1299,34 @@ struct SMAppManager {
switch appServiceStatus {
case .enabled:
- logOrPrint("Nudge LaunchAgent is currently registered and enabled", passedThroughCLI: passedThroughCLI, exitCode: 0)
+ logOrPrint("Nudge LaunchAgent is currently registered and enabled", error: false, passedThroughCLI: passedThroughCLI, exitCode: 0)
default:
registerOrUnregister(appService: appService, passedThroughCLI: passedThroughCLI, action: "register")
}
}
- private func logOrPrint(_ message: String, passedThroughCLI: Bool, exitCode: Int? = nil) {
+ private func logOrPrint(_ message: String, error: Bool, passedThroughCLI: Bool, exitCode: Int? = nil) {
if passedThroughCLI {
print(message)
if let code = exitCode { exit(Int32(code)) }
} else {
- LogManager.info("\(message)", logger: uiLog)
+ if error {
+ LogManager.error("\(message)", logger: uiLog)
+ } else {
+ LogManager.debug("\(message)", logger: uiLog)
+ }
+
}
}
@available(macOS 13.0, *)
private func registerOrUnregister(appService: SMAppService, passedThroughCLI: Bool, action: String) {
do {
- logOrPrint("\(action.capitalized)ing Nudge LaunchAgent", passedThroughCLI: passedThroughCLI)
+ logOrPrint("\(action.capitalized)ing Nudge LaunchAgent", error: false, passedThroughCLI: passedThroughCLI)
try action == "register" ? appService.register() : appService.unregister()
- logOrPrint("Successfully \(action)ed Nudge LaunchAgent", passedThroughCLI: passedThroughCLI, exitCode: 0)
+ logOrPrint("Successfully \(action)ed Nudge LaunchAgent", error: false, passedThroughCLI: passedThroughCLI, exitCode: 0)
} catch {
- logOrPrint("Failed to \(action) Nudge LaunchAgent", passedThroughCLI: passedThroughCLI, exitCode: 1)
+ logOrPrint("Failed to \(action) Nudge LaunchAgent", error: true, passedThroughCLI: passedThroughCLI, exitCode: 1)
}
}
@@ -1331,7 +1336,7 @@ struct SMAppManager {
switch appServiceStatus {
case .notFound, .notRegistered:
- logOrPrint("Nudge LaunchAgent has never been registered or is not currently registered", passedThroughCLI: passedThroughCLI, exitCode: 0)
+ logOrPrint("Nudge LaunchAgent has never been registered or is not currently registered", error: false, passedThroughCLI: passedThroughCLI, exitCode: 0)
default:
registerOrUnregister(appService: appService, passedThroughCLI: passedThroughCLI, action: "unregister")
}
@@ -1418,8 +1423,8 @@ struct UIUtilities {
return shellCommands.contains(where: path.hasPrefix)
}
- func openMoreInfo() {
- guard let url = URL(string: OSVersionRequirementVariables.aboutUpdateURL) else {
+ func openMoreInfo(infoURL: String) {
+ guard let url = URL(string: infoURL) else {
return
}
LogManager.notice("User clicked moreInfo button", logger: uiLog)