Skip to content

Commit

Permalink
re-assess gracePeriod logic with SOFA
Browse files Browse the repository at this point in the history
  • Loading branch information
erikng committed Jul 22, 2024
1 parent 16f3276 commit 733d664
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 38 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ 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.4] - 2024-07-22
Requires macOS 12.0 and higher.

### Fixed
- Logic introduced in v2.0.1 for `requiredInstallatonDate` when using the new `gracePeriodInstallDelay` was still incorrect and has been rewritten a second time.

## [2.0.3] - 2024-07-22
Requires macOS 12.0 and higher.

Expand Down
5 changes: 1 addition & 4 deletions Example Assets/com.github.macadmins.Nudge.tester.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@
"optionalFeatures": {
"customSOFAFeedURL": "https://sofafeed.macadmins.io/v1/macos_data_feed.json",
"_customSOFAFeedURL": "https://sofafeed.macadmins.io/beta/v1/macos_data_feed.json",
"utilizeSOFAFeed": true,
},
"osVersionRequirements": [
{
"aboutUpdateURL": "https://apple.com",
"requiredMinimumOSVersion": "14.5",
"requiredInstallationDate": "2025-01-01T00:00:00",
"requiredMinimumOSVersion": "latest",
"unsupportedURL": "https://google.com"
}
],
"userExperience": {
"elapsedRefreshCycle": 10,
"initialRefreshCycle": 10,
"loadLaunchAgent": false,
"nudgeRefreshCycle": 5,
"randomDelay": false
},
Expand Down
4 changes: 2 additions & 2 deletions Nudge.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 2.0.3;
MARKETING_VERSION = 2.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.github.macadmins.Nudge;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -729,7 +729,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 2.0.3;
MARKETING_VERSION = 2.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.github.macadmins.Nudge;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-simulate-os-version &quot;14.5&quot;"
argument = "-simulate-os-version &quot;14.4.1&quot;"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
Expand Down
4 changes: 2 additions & 2 deletions Nudge/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>2.0.3</string>
<string>2.0.4</string>
<key>CFBundleVersion</key>
<string>2.0.3</string>
<string>2.0.4</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
Expand Down
1 change: 0 additions & 1 deletion Nudge/UI/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class AppState: ObservableObject {
@Published var deferViewIsPresented = false
@Published var additionalInfoViewIsPresented = false
@Published var differentiateWithoutColor = NSWorkspace.shared.accessibilityDisplayShouldDifferentiateWithoutColor
@Published var hasUpdatedDueToDracePeriodInstallDelay = false
}

class DNDConfig {
Expand Down
8 changes: 2 additions & 6 deletions Nudge/UI/Main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
releaseDate = selectedOS!.releaseDate ?? Date()
if requiredInstallationDate == Date(timeIntervalSince1970: 0) {
requiredInstallationDate = selectedOS!.releaseDate?.addingTimeInterval(slaExtension) ?? DateManager().getCurrentDate().addingTimeInterval(TimeInterval(90 * 86400))
LogManager.notice("Extending requiredInstallationDate to \(requiredInstallationDate)", logger: sofaLog)
}
if nudgePrimaryState.hasUpdatedDueToDracePeriodInstallDelay {
requiredInstallationDate = requiredInstallationDate.addingTimeInterval(slaExtension)
LogManager.notice("Extending requiredInstallationDate to \(requiredInstallationDate)", logger: sofaLog)
LogManager.notice("Setting requiredInstallationDate via SOFA to \(requiredInstallationDate)", logger: sofaLog)
}
LogManager.notice("SOFA Matched OS Version: \(selectedOS!.productVersion)", logger: sofaLog)
LogManager.notice("SOFA Assets: \(selectedOS!.supportedDevices)", logger: sofaLog)
Expand Down Expand Up @@ -287,8 +283,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
checkForBadProfilePath()
handleCommandLineArguments()
applyRandomDelayIfNecessary()
applyGracePeriodLogic()
sofaPreLaunchLogic()
applyGracePeriodLogic()
applydelayNudgeEventLogic()
updateNudgeState()
handleSoftwareUpdateRequirements()
Expand Down
63 changes: 42 additions & 21 deletions Nudge/Utilities/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,45 +87,65 @@ struct AppStateManager {
}

private func calculateNewRequiredInstallationDateIfNeeded(currentDate: Date, gracePeriodPathCreationDate: Date) -> Date {
let gracePeriodInstallDelay = UserExperienceVariables.gracePeriodInstallDelay
let gracePeriodLaunchDelay = UserExperienceVariables.gracePeriodLaunchDelay
let gracePeriodPath = UserExperienceVariables.gracePeriodPath
let gracePeriodPathCreationTimeInHours = Int(currentDate.timeIntervalSince(gracePeriodPathCreationDate) / 3600)
let combinedGracePeriod = UserExperienceVariables.gracePeriodInstallDelay + UserExperienceVariables.gracePeriodLaunchDelay
let gracePeriodsDelay = gracePeriodInstallDelay + gracePeriodLaunchDelay
let originalRequiredInstallationDate = requiredInstallationDate

if currentDate > PrefsWrapper.requiredInstallationDate || combinedGracePeriod > DateManager().getNumberOfHoursRemaining(currentDate: currentDate) {
if UserExperienceVariables.gracePeriodLaunchDelay > gracePeriodPathCreationTimeInHours {
LogManager.info("Device within gracePeriodLaunchDelay, exiting Nudge", logger: uiLog)
nudgePrimaryState.shouldExit = true
return currentDate
} else {
LogManager.info("gracePeriodPath (\(UserExperienceVariables.gracePeriodPath)) outside of gracePeriodLaunchDelay (\(UserExperienceVariables.gracePeriodLaunchDelay)) - File age is \(gracePeriodPathCreationTimeInHours) hours", logger: uiLog)
}
// Bail Nudge if within gracePeriodLaunchDelay
if gracePeriodLaunchDelay > gracePeriodPathCreationTimeInHours {
LogManager.info("gracePeriodPath (\(gracePeriodPath)) within gracePeriodLaunchDelay (\(gracePeriodLaunchDelay)) - File age is \(gracePeriodPathCreationTimeInHours) hours", logger: uiLog)
nudgePrimaryState.shouldExit = true
return currentDate
} else {
LogManager.info("gracePeriodPath (\(gracePeriodPath)) outside of gracePeriodLaunchDelay (\(gracePeriodLaunchDelay)) - File age is \(gracePeriodPathCreationTimeInHours) hours", logger: uiLog)
}

if UserExperienceVariables.gracePeriodInstallDelay > gracePeriodPathCreationTimeInHours {
requiredInstallationDate = gracePeriodPathCreationDate.addingTimeInterval(Double(combinedGracePeriod) * 3600)
LogManager.notice("Device permitted for gracePeriods - setting date to: \(requiredInstallationDate)", logger: uiLog)
nudgePrimaryState.hasUpdatedDueToDracePeriodInstallDelay = true
if gracePeriodInstallDelay > gracePeriodPathCreationTimeInHours {
if currentDate > originalRequiredInstallationDate {
requiredInstallationDate = currentDate.addingTimeInterval(Double(gracePeriodsDelay) * 3600)
LogManager.info("Device permitted for gracePeriodInstallDelay - setting date from: \(originalRequiredInstallationDate) to: \(requiredInstallationDate)", logger: uiLog)
return requiredInstallationDate
}
} else {
LogManager.info("gracePeriodPath (\(gracePeriodPath)) outside of gracePeriodInstallDelay (\(gracePeriodInstallDelay)) - File age is \(gracePeriodPathCreationTimeInHours) hours", logger: uiLog)
}

return PrefsWrapper.requiredInstallationDate
}


func exitNudge() {
LogManager.notice("Nudge is terminating due to condition met", logger: uiLog)
nudgePrimaryState.shouldExit = true
exit(0)
}

func getCreationDateForPath(_ path: String, testFileDate: Date?) -> Date? {
let attributes = try? FileManager.default.attributesOfItem(atPath: path)
if attributes?[.size] as? Int == 0 && testFileDate == nil {
do {
let attributes = try FileManager.default.attributesOfItem(atPath: path)

// Check if the file size is 0
if let fileSize = attributes[.size] as? Int, fileSize == 0 {
// If file size is 0 and testFileDate is provided, use testFileDate
if let testDate = testFileDate {
return testDate
} else {
// Fallback to the creation date from the file attributes if testFileDate is nil
return attributes[.creationDate] as? Date ?? DateManager().coerceStringToDate(dateString: "2020-08-06T00:00:00Z")
}
}

// Return the creation date from the file attributes if the file size is not 0
return attributes[.creationDate] as? Date ?? DateManager().coerceStringToDate(dateString: "2020-08-06T00:00:00Z")

} catch {
print("Error retrieving file attributes: \(error)")
return DateManager().coerceStringToDate(dateString: "2020-08-06T00:00:00Z")
}
let creationDate = attributes?[.creationDate] as? Date
return testFileDate ?? creationDate
}


func getModifiedDateForPath(_ path: String, testFileDate: Date?) -> Date? {
let attributes = try? FileManager.default.attributesOfItem(atPath: path)
if attributes?[.size] as? Int == 0 && testFileDate == nil {
Expand Down Expand Up @@ -169,7 +189,8 @@ struct AppStateManager {
return signingCertificateSummary
}

func gracePeriodLogic(currentDate: Date = DateManager().getCurrentDate(), testFileDate: Date? = nil) -> Date {
func gracePeriodLogic(currentDate: Date? = nil, testFileDate: Date? = nil) -> Date {
let computedCurrentDate = currentDate == nil ? Date() : currentDate!
guard UserExperienceVariables.allowGracePeriods || PrefsWrapper.allowGracePeriods,
!CommandLineUtilities().demoModeEnabled() else {
return PrefsWrapper.requiredInstallationDate
Expand All @@ -182,7 +203,7 @@ struct AppStateManager {
return PrefsWrapper.requiredInstallationDate
}

return calculateNewRequiredInstallationDateIfNeeded(currentDate: currentDate, gracePeriodPathCreationDate: gracePeriodPathCreationDate)
return calculateNewRequiredInstallationDateIfNeeded(currentDate: computedCurrentDate, gracePeriodPathCreationDate: gracePeriodPathCreationDate)
}

func delayNudgeEventLogic(currentDate: Date = DateManager().getCurrentDate(), testFileDate: Date? = nil) -> Date {
Expand Down
2 changes: 1 addition & 1 deletion Schema/jamf/com.github.macadmins.Nudge.json
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@
"type": "integer",
"options": {
"inputAttributes": {
"placeholder": "24"
"placeholder": "23"
}
}
}
Expand Down

0 comments on commit 733d664

Please sign in to comment.