fix: handle protected app uninstall removals#103
Merged
Conversation
Distinguish Full Disk Access failures from administrator-required uninstall artifacts and route narrow app bundle, receipt, and launch plist removals through the vetted admin cleaner.
10 tasks
momenbasel
pushed a commit
that referenced
this pull request
May 23, 2026
Supersedes #76. - Adds Brazilian Portuguese (pt-BR) localization with 227 keys at parity with en. - Localizes the post-#80 dashboard surface (DashboardView, MainWindow, CategoryDetailView, AppListView, AppFilesView, OrphanListView, OnboardingView, SettingsView, AppearancePill). - Settings → General → Language picker with System Default + every bundled language. Mutates only AppleLanguages on apply (AppleLocale preserved so number/date/currency formatting follows the host locale). - Extracts AppLanguage + AppLanguagePreferences into Models/. - Relaunch prompt after language switch (AppleLanguages is consumed at startup) via /usr/bin/open -n. - AppState gains injection points (performStartupTasks, locationsProvider, appFileScanner) so the app-file scan path is unit-testable. - New PureMacTests target with three test cases: LocalizationFilesTests (locale key-parity guard), AppLanguagePreferencesTests, AppStateTests. project.yml registers the test target + shared scheme. Rebased onto post-#103 main; AppState.swift @published additions kept side-by-side.
This was referenced May 23, 2026
Closed
Closed
momenbasel
pushed a commit
that referenced
this pull request
May 23, 2026
Stage 1 of in-app updates. Adds Sparkle as an opt-in dependency. - New `UpdateService` (singleton) wraps `SPUStandardUpdaterController` started with `startingUpdater: false` so no automatic update checks happen at launch. - `Updates → Check for Updates` command added to the main menu. - Safe fallback: when no `SUFeedURL` is configured in Info.plist, the menu item opens https://github.com/momenbasel/PureMac/releases/latest in NSWorkspace instead of starting Sparkle. - Sparkle SPM package pinned to `from: 2.0.0` in project.yml. Stage 2 (signed appcast, EdDSA key management, release-workflow integration that makes auto-update actually fire on new releases) is tracked separately. Rebased onto post-#103 main; the original PR's unrelated AppState concurrency-warning workaround was dropped during rebase. Verified: `xcodebuild build` succeeds on macOS 13 / Xcode 16. Refs #94.
momenbasel
added a commit
that referenced
this pull request
May 23, 2026
Bundles three user-facing fixes and one new feature for the next release: - #103: Protected-app uninstall now routes admin-required paths through the vetted CleaningEngine admin cleaner (fixes #93/#95/#97/#102). - #96: Orphan-file context menu uses activateFileViewerSelecting + exposes Copy Path / Move to Trash per row. - #92: AppInfoFetcher.appSize drops the broken directory-inode fast path; sums per-file allocated size so installed-app sizes match Finder's Size on disk. - #101: pt-BR localization, locale parity test guard, Settings language picker. - #99: Sparkle Stage 1 - opt-in UpdateService with Releases-page fallback. Signed-appcast work tracked in #104.
momenbasel
pushed a commit
that referenced
this pull request
May 24, 2026
Distinguishes Full Disk Access failures from administrator-required uninstall artifacts. - Routes narrow allow-listed uninstall artifacts (app bundles under /Applications and ~/Applications, package receipts under /var/db/receipts and /private/var/db/receipts, LaunchDaemons/LaunchAgents plists) through the existing administrator cleaner. - CleaningEngine re-validates each escalation path against the allow-list before invoking the privileged removal. - Hardens the AppleScript shell payload by single-quoting the temp-file path (no longer trusting NSTemporaryDirectory to be free of metacharacters). - AppState distinguishes missing-file, FDA-blocked, and admin-required failures, and the AppFilesView alert only offers the Open System Settings button when FDA is actually the blocker. Fixes #93. Closes #95, #97, #102. Supersedes #100.
momenbasel
pushed a commit
that referenced
this pull request
May 24, 2026
Supersedes #76. - Adds Brazilian Portuguese (pt-BR) localization with 227 keys at parity with en. - Localizes the post-#80 dashboard surface (DashboardView, MainWindow, CategoryDetailView, AppListView, AppFilesView, OrphanListView, OnboardingView, SettingsView, AppearancePill). - Settings → General → Language picker with System Default + every bundled language. Mutates only AppleLanguages on apply (AppleLocale preserved so number/date/currency formatting follows the host locale). - Extracts AppLanguage + AppLanguagePreferences into Models/. - Relaunch prompt after language switch (AppleLanguages is consumed at startup) via /usr/bin/open -n. - AppState gains injection points (performStartupTasks, locationsProvider, appFileScanner) so the app-file scan path is unit-testable. - New PureMacTests target with three test cases: LocalizationFilesTests (locale key-parity guard), AppLanguagePreferencesTests, AppStateTests. project.yml registers the test target + shared scheme. Rebased onto post-#103 main; AppState.swift @published additions kept side-by-side.
momenbasel
pushed a commit
that referenced
this pull request
May 24, 2026
Stage 1 of in-app updates. Adds Sparkle as an opt-in dependency. - New `UpdateService` (singleton) wraps `SPUStandardUpdaterController` started with `startingUpdater: false` so no automatic update checks happen at launch. - `Updates → Check for Updates` command added to the main menu. - Safe fallback: when no `SUFeedURL` is configured in Info.plist, the menu item opens https://github.com/momenbasel/PureMac/releases/latest in NSWorkspace instead of starting Sparkle. - Sparkle SPM package pinned to `from: 2.0.0` in project.yml. Stage 2 (signed appcast, EdDSA key management, release-workflow integration that makes auto-update actually fire on new releases) is tracked separately. Rebased onto post-#103 main; the original PR's unrelated AppState concurrency-warning workaround was dropped during rebase. Verified: `xcodebuild build` succeeds on macOS 13 / Xcode 16. Refs #94.
momenbasel
added a commit
that referenced
this pull request
May 24, 2026
Bundles three user-facing fixes and one new feature for the next release: - #103: Protected-app uninstall now routes admin-required paths through the vetted CleaningEngine admin cleaner (fixes #93/#95/#97/#102). - #96: Orphan-file context menu uses activateFileViewerSelecting + exposes Copy Path / Move to Trash per row. - #92: AppInfoFetcher.appSize drops the broken directory-inode fast path; sums per-file allocated size so installed-app sizes match Finder's Size on disk. - #101: pt-BR localization, locale parity test guard, Settings language picker. - #99: Sparkle Stage 1 - opt-in UpdateService with Releases-page fallback. Signed-appcast work tracked in #104.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes protected app-uninstaller removals by separating Full Disk Access failures from administrator-required uninstall artifacts.
Fixes #93. Related to #100.
Root Cause
The uninstaller previously treated removal failures as Full Disk Access problems. Some selected uninstall artifacts, such as root-owned app bundles, package receipts, and launch plists, can still require administrator authorization even after PureMac has Full Disk Access.
Changes
FileManager.trashItemas the first removal attempt so TCC attribution stays with PureMac.CleaningEnginebefore escalation.Security Notes
CleaningEngine; callers cannot pass arbitrary selected paths directly to privileged removal.xargs -0, preserving spaces/newlines in filenames.Validation
xcodebuild -project PureMac.xcodeproj -scheme PureMac -configuration Debug -derivedDataPath DerivedData CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO buildgit diff --check.