Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
493fb1ec16 | ||
|
|
b167a69976 | ||
|
|
79b46bf210 | ||
|
|
98a26f9ae4 | ||
|
|
dbe3c5cfb9 | ||
|
|
25d7f7b2a4 | ||
|
|
b76e99ac0f |
2
.github/actions/setup-node/action.yml
vendored
2
.github/actions/setup-node/action.yml
vendored
@@ -3,6 +3,6 @@ runs:
|
||||
steps:
|
||||
-
|
||||
name: Setup node
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
|
||||
6
.github/workflows/checks.build.yaml
vendored
6
.github/workflows/checks.build.yaml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Install Docker on macOS
|
||||
if: matrix.os == 'macos' # macOS runner is missing Docker
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
2
.github/workflows/checks.external-urls.yaml
vendored
2
.github/workflows/checks.external-urls.yaml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
2
.github/workflows/checks.quality.yaml
vendored
2
.github/workflows/checks.quality.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
4
.github/workflows/checks.scripts.yaml
vendored
4
.github/workflows/checks.scripts.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
2
.github/workflows/checks.security.sast.yaml
vendored
2
.github/workflows/checks.security.sast.yaml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
|
||||
2
.github/workflows/release.desktop.yaml
vendored
2
.github/workflows/release.desktop.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
steps:
|
||||
-
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: master # otherwise it defaults to the version tag missing bump commit
|
||||
fetch-depth: 0 # fetch all history
|
||||
|
||||
6
.github/workflows/release.site.yaml
vendored
6
.github/workflows/release.site.yaml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: "Infrastructure: Checkout"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: aws
|
||||
repository: undergroundwires/aws-static-site-with-cd
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
working-directory: aws
|
||||
-
|
||||
name: "App: Checkout"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: app
|
||||
ref: master # otherwise we don't get version bump commit
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
-
|
||||
name: "App: Deploy to S3"
|
||||
shell: bash
|
||||
run: >-
|
||||
run: |-
|
||||
declare web_output_dir
|
||||
if ! web_output_dir=$(cd app && node scripts/print-dist-dir.js --web); then
|
||||
echo 'Error: Could not determine distribution directory.'
|
||||
|
||||
2
.github/workflows/tests.e2e.yaml
vendored
2
.github/workflows/tests.e2e.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
2
.github/workflows/tests.integration.yaml
vendored
2
.github/workflows/tests.integration.yaml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
2
.github/workflows/tests.unit.yaml
vendored
2
.github/workflows/tests.unit.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set-up node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## 0.12.5 (2023-10-13)
|
||||
|
||||
* Fix Docker build and improve checks #220 | [7669985](https://github.com/undergroundwires/privacy.sexy/commit/7669985f8e1446e726a95626ecf35b3ce6b60a16)
|
||||
* Add SAST security checks with SECURITY.md #178 | [3e5239f](https://github.com/undergroundwires/privacy.sexy/commit/3e5239f7d35e57749c01adf3dbbcd365aebb39c8)
|
||||
* Add Scoop download instructions #174 | [cf55ca9](https://github.com/undergroundwires/privacy.sexy/commit/cf55ca9e28b064fa7a516077a9da23e3a8e3f534)
|
||||
* win: fix and improve temp dir cleanup #176, #89 | [d457504](https://github.com/undergroundwires/privacy.sexy/commit/d45750428cca010daf2721b33a8ae3a01b28813b)
|
||||
* win, linux: improve VSCode setting robustness #196 | [e8a52f7](https://github.com/undergroundwires/privacy.sexy/commit/e8a52f717dc799b34ceeb1c27c2b8219391dff6a)
|
||||
* linux: fix obsolete Firefox DPI script #239 | [e5f6edf](https://github.com/undergroundwires/privacy.sexy/commit/e5f6edf405bcec7c29ea4d7932d1910620fa15f8)
|
||||
* win: add removal of Edge assocations #64 | [888c916](https://github.com/undergroundwires/privacy.sexy/commit/888c9166fc66a2094137fa8be739cc21bafef5f6)
|
||||
* win: improve Edge & OneDrive shortcut removal #73 | [8501495](https://github.com/undergroundwires/privacy.sexy/commit/8501495c170af61913288a63dbd369db5bbc5003)
|
||||
* win: relocate and document SecHealthUI #190 | [2862951](https://github.com/undergroundwires/privacy.sexy/commit/286295128d0179358e0c6b7b6415d752175a1aed)
|
||||
* Add developer toolkit UI component | [2147eae](https://github.com/undergroundwires/privacy.sexy/commit/2147eae687b82d05bc43bb4605d9068f148bb92a)
|
||||
* win: fix and improve network data usage reset #265 | [5e359c2](https://github.com/undergroundwires/privacy.sexy/commit/5e359c2fb82a08e6acf7159b70ca86a8234b359b)
|
||||
* win: improve app reversion and docs #260 | [a3f11df](https://github.com/undergroundwires/privacy.sexy/commit/a3f11dff187c821a00910c20dac05e285cda9073)
|
||||
* Fix working directory in CI/CD web release | [698b570](https://github.com/undergroundwires/privacy.sexy/commit/698b570ee6e300d6703015464f4345b5e706f1cb)
|
||||
* Implement new UI component for icons #230 | [48730bc](https://github.com/undergroundwires/privacy.sexy/commit/48730bca0506120bca4bf3a23545d59f2b1a9009)
|
||||
* win: fix and improve AppCompat disabling #255 | [bab6316](https://github.com/undergroundwires/privacy.sexy/commit/bab6316e7625230cf4a4cf67c3aca417347db75c)
|
||||
* win, linux, mac: fix typos and improve naming | [67c3677](https://github.com/undergroundwires/privacy.sexy/commit/67c3677621b201525a813e8a26f07d607176e89b)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.4...0.12.5)
|
||||
|
||||
## 0.12.4 (2023-09-25)
|
||||
|
||||
* win: fix Windows spotlight revert, docs, recommend | [659fea7](https://github.com/undergroundwires/privacy.sexy/commit/659fea7afcabcd0ea273cfdcc8c4bae190c126f3)
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
## Get started
|
||||
|
||||
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
|
||||
- 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.4/privacy.sexy-Setup-0.12.4.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.4/privacy.sexy-0.12.4.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.4/privacy.sexy-0.12.4.AppImage). For more options, see [here](#additional-install-options).
|
||||
- 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.5/privacy.sexy-Setup-0.12.5.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.5/privacy.sexy-0.12.5.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.5/privacy.sexy-0.12.5.AppImage). For more options, see [here](#additional-install-options).
|
||||
|
||||
Online version does not require to run any software on your computer. Offline version has more functions such as running the scripts directly.
|
||||
|
||||
|
||||
@@ -6,7 +6,10 @@ const CYPRESS_BASE_DIR = 'tests/e2e/';
|
||||
export default defineConfig({
|
||||
fixturesFolder: `${CYPRESS_BASE_DIR}/fixtures`,
|
||||
screenshotsFolder: `${CYPRESS_BASE_DIR}/screenshots`,
|
||||
|
||||
video: true,
|
||||
videosFolder: `${CYPRESS_BASE_DIR}/videos`,
|
||||
|
||||
e2e: {
|
||||
baseUrl: `http://localhost:${ViteConfig.server.port}/`,
|
||||
specPattern: `${CYPRESS_BASE_DIR}/**/*.cy.{js,jsx,ts,tsx}`, // Default: cypress/e2e/**/*.cy.{js,jsx,ts,tsx}
|
||||
|
||||
9286
package-lock.json
generated
9286
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
68
package.json
68
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "privacy.sexy",
|
||||
"version": "0.12.4",
|
||||
"version": "0.12.5",
|
||||
"private": true,
|
||||
"slogan": "Now you have the choice",
|
||||
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy 🍑🍆",
|
||||
@@ -36,18 +36,19 @@
|
||||
"dependencies": {
|
||||
"@floating-ui/vue": "^1.0.2",
|
||||
"@juggle/resize-observer": "^3.4.0",
|
||||
"ace-builds": "^1.23.4",
|
||||
"ace-builds": "^1.30.0",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"electron-log": "^4.4.8",
|
||||
"electron-progressbar": "^2.1.0",
|
||||
"electron-updater": "^6.1.4",
|
||||
"file-saver": "^2.0.5",
|
||||
"markdown-it": "^13.0.1",
|
||||
"npm": "^9.8.1",
|
||||
"markdown-it": "^13.0.2",
|
||||
"vue": "^2.7.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@modyfi/vite-plugin-yaml": "^1.0.4",
|
||||
"@rushstack/eslint-patch": "^1.3.2",
|
||||
"@types/ace": "^0.0.48",
|
||||
"@rushstack/eslint-patch": "^1.5.1",
|
||||
"@types/ace": "^0.0.49",
|
||||
"@types/file-saver": "^2.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
@@ -56,47 +57,42 @@
|
||||
"@vue/eslint-config-airbnb-with-typescript": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.3",
|
||||
"@vue/test-utils": "^1.3.6",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"cypress": "^12.17.2",
|
||||
"electron": "^25.3.2",
|
||||
"electron-builder": "^24.6.3",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"cypress": "^13.3.1",
|
||||
"electron": "^27.0.0",
|
||||
"electron-builder": "^24.6.4",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-icon-builder": "^2.0.1",
|
||||
"electron-log": "^4.4.8",
|
||||
"electron-updater": "^6.1.4",
|
||||
"electron-vite": "^1.0.27",
|
||||
"eslint": "^8.46.0",
|
||||
"eslint-plugin-cypress": "^2.14.0",
|
||||
"eslint-plugin-vue": "^9.6.0",
|
||||
"eslint-plugin-vuejs-accessibility": "^1.2.0",
|
||||
"icon-gen": "^3.0.1",
|
||||
"eslint": "^8.51.0",
|
||||
"eslint-plugin-cypress": "^2.15.1",
|
||||
"eslint-plugin-vue": "^9.17.0",
|
||||
"eslint-plugin-vuejs-accessibility": "^2.2.0",
|
||||
"icon-gen": "^4.0.0",
|
||||
"jsdom": "^22.1.0",
|
||||
"markdownlint-cli": "^0.35.0",
|
||||
"postcss": "^8.4.28",
|
||||
"remark-cli": "^11.0.0",
|
||||
"markdownlint-cli": "^0.37.0",
|
||||
"postcss": "^8.4.31",
|
||||
"remark-cli": "^12.0.0",
|
||||
"remark-lint-no-dead-urls": "^1.1.0",
|
||||
"remark-preset-lint-consistent": "^5.1.2",
|
||||
"remark-validate-links": "^12.1.1",
|
||||
"sass": "^1.64.1",
|
||||
"start-server-and-test": "^2.0.0",
|
||||
"remark-validate-links": "^13.0.0",
|
||||
"sass": "^1.69.3",
|
||||
"start-server-and-test": "^2.0.1",
|
||||
"svgexport": "^0.4.2",
|
||||
"terser": "^5.19.2",
|
||||
"tslib": "~2.4.0",
|
||||
"typescript": "~4.6.2",
|
||||
"vite": "^4.4.9",
|
||||
"vitest": "^0.34.2",
|
||||
"vue-tsc": "^1.8.8",
|
||||
"terser": "^5.21.0",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^4.4.11",
|
||||
"vitest": "^0.34.6",
|
||||
"vue-tsc": "^1.8.19",
|
||||
"yaml-lint": "^1.7.0"
|
||||
},
|
||||
"//devDependencies": {
|
||||
"terser": "Used by @vitejs/plugin-legacy for minification",
|
||||
"typescript": [
|
||||
"Cannot upgrade to 5.X.X due to unmaintained @vue/cli-plugin-typescript, https://github.com/vuejs/vue-cli/issues/7401",
|
||||
"Cannot upgrade to > 4.6.X otherwise unit tests do not work, https://github.com/evanw/node-source-map-support/issues/252"
|
||||
],
|
||||
"tslib": "Cannot upgrade to > 2.4.X otherwise unit tests do not work, https://github.com/evanw/node-source-map-support/issues/252",
|
||||
"@typescript-eslint/eslint-plugin": "Cannot upgrade to 6.X.X due to @vue/eslint-config-typescript, https://github.com/vuejs/eslint-config-typescript/pull/60",
|
||||
"@typescript-eslint/parser": "Cannot upgrade to 6.X.X due to @vue/eslint-config-typescript, https://github.com/vuejs/eslint-config-typescript/pull/60"
|
||||
"@rushstack/eslint-patch": "Needed by @vue/eslint-config-typescript",
|
||||
"@vue/eslint-config-typescript": "Cannot upgrade to 12.X.X due to @vue/eslint-config-airbnb-with-typescript, https://github.com/vuejs/eslint-config-airbnb/issues/58",
|
||||
"@typescript-eslint/eslint-plugin": "Cannot upgrade to 6.X.X due to @vue/eslint-config-airbnb-with-typescript, https://github.com/vuejs/eslint-config-airbnb/issues/58",
|
||||
"@typescript-eslint/parser": "Cannot upgrade to 6.X.X due to @vue/eslint-config-airbnb-with-typescript, https://github.com/vuejs/eslint-config-airbnb/issues/58"
|
||||
},
|
||||
"homepage": "https://privacy.sexy",
|
||||
"repository": {
|
||||
|
||||
@@ -1238,6 +1238,376 @@ actions:
|
||||
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate 'CriticalUpdateInstall' -bool true
|
||||
# Trigger background check with normal scan (critical updates only)
|
||||
sudo softwareupdate --background-critical
|
||||
-
|
||||
category: Disable OS services
|
||||
children:
|
||||
# Get active services : launchctl list | grep -v "\-\t0"
|
||||
# Find a service : sudo grep -lR [service] /System/Library/Launch* /Library/Launch* ~/Library/LaunchAgents
|
||||
# Locate a service : pgrep -fl [service]
|
||||
# TODO: https://gist.github.com/ecompayment/b1054421eb90f296bbca226683c7ff7e
|
||||
-
|
||||
category: Disable continuously data-collecting services by default
|
||||
children:
|
||||
-
|
||||
name: Disable diagnostics and usage data sender
|
||||
recommend: standard
|
||||
docs: https://apple.stackexchange.com/questions/66119/disable-submitdiaginfo
|
||||
call:
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.SubmitDiagInfo
|
||||
type: LaunchDaemons
|
||||
-
|
||||
name: Disable diagnostics and usage data sender
|
||||
recommend: standard
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.rtcreportingd.plist
|
||||
type: LaunchDaemons
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /usr/libexec/rtcreportingd
|
||||
-
|
||||
name: Disable Family Circle Daemon for Family Sharing
|
||||
docs: https://support.apple.com/en-us/HT201060
|
||||
recommend: standard
|
||||
# Connects to setup.icloud.com HTTPS (TCP 443 )
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.familycircled
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/FamilyCircle.framework/Versions/A/Resources/familycircled
|
||||
-
|
||||
name: Disable home sharing
|
||||
docs: https://discussions.apple.com/thread/7434075?answerId=29677460022#29677460022
|
||||
# Connects to apps.mzstatic.com and init.itunes.apple.com HTTPS (TCP 443 )
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.itunescloudd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /usr/libexec/rtcreportingd # TODO: SIP required?
|
||||
-
|
||||
name: Disable CommerceKit handling purchases for Apple products
|
||||
# the Mac App Store, iTunes store, and Book Store
|
||||
# Connects to init.itunes.apple.com and xp.apple.com HTTPS (TCP 443 )
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.commerce.plist
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/CommerceKit.framework/Versions/A/Resources/commerce
|
||||
-
|
||||
category: Disable Siri services # TODO: merge with other assistantd script
|
||||
children:
|
||||
-
|
||||
name: Disable Siri dictation service sending voice data
|
||||
recommend: strict
|
||||
docs: https://apple.stackexchange.com/questions/57514/what-is-assistantd
|
||||
# Connects to guzzoni.apple.com HTTPS (TCP 443 )
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.assistantd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/AssistantServices.framework/Versions/A/Support/assistantd
|
||||
-
|
||||
name: Disable Siri assistant service
|
||||
recommend: strict
|
||||
docs: https://www.howtogeek.com/354897/what-are-assistant_service-and-assistantd-and-why-are-they-running-on-my-mac/
|
||||
# Connects to radio.itunes.apple.com HTTPS (TCP 443 )
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.assistant_service.plist
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/AssistantServices.framework/Versions/A/Support/assistant_service
|
||||
-
|
||||
category: Disable Messages services
|
||||
docs: https://blog.quarkslab.com/imessage-privacy.html
|
||||
children:
|
||||
-
|
||||
name: Disable Apple Push Service Daemon used for Notification Center and Messages
|
||||
# Connects to *-courier.push.apple.com (where * is a number) using HTTPS (TCP 443) and apple-push (TCP 5223)
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.apsd
|
||||
type: LaunchDaemons
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/ApplePushService.framework/apsd
|
||||
-
|
||||
name: Disable iMessage Agent in Messages app
|
||||
# Used for e.g. FaceTime invitations
|
||||
docs:
|
||||
- https://apple.stackexchange.com/questions/86814/firewall-settings-with-imagent
|
||||
- https://blog.quarkslab.com/imessage-privacy.html
|
||||
# Connects to using HTTPS (TCP 443) and apple-push (TCP 5223)
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.imagent
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/IMCore.framework/imagent.app/Contents/MacOS/imagent
|
||||
-
|
||||
name: Disable Address Book Source Sync (breaks Contacts data sync)
|
||||
# Synchronizes data data for the “Contacts” app with iCloud, CardDAV, and Exchange servers
|
||||
docs: https://apple.stackexchange.com/questions/219774/how-to-disable-addressbooksourcesync-in-el-capitan
|
||||
# Connects to p25-contacts.icloud.com using HTTPS (TCP 443) and apple-push (TCP 5223)
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.AddressBook.SourceSync
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/Frameworks/AddressBook.framework/Versions/A/Helpers/AddressBookSourceSync.app/Contents/MacOS/AddressBookSourceSync
|
||||
-
|
||||
name: Disable usage tracking agent
|
||||
recommend: strict
|
||||
docs: https://www.unix.com/man-page/mojave/8/USAGETRACKINGAGENT/
|
||||
# Connects to itunes.apple.com using HTTPS 443 (TCP)
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.UsageTrackingAgent
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/UsageTracking.framework/Versions/A/UsageTrackingAgent
|
||||
-
|
||||
name: Disable AMPLibraryAgent for Apple Music
|
||||
# Connects to buy.itunes.apple.com, init.itunes.apple.com, play.itunes.apple.com, xp.apple.com using HTTPS 443 (TCP)
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.AMPLibraryAgent
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: System/Library/PrivateFrameworks/AMPLibrary.framework/Versions/A/Support/AMPLibraryAgent
|
||||
-
|
||||
category: Disable location services
|
||||
children:
|
||||
-
|
||||
name: Disable Maps push daemon
|
||||
docs:
|
||||
- https://www.unix.com/man-page/mojave/8/MAPSPUSHD/
|
||||
- https://discussions.apple.com/thread/7025815
|
||||
call:
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.Maps.pushdaemon
|
||||
type: LaunchAgents
|
||||
-
|
||||
name: Disable Geo Daemon / geolocation daemon used to show maps by apps e.g. Maps
|
||||
# Connects to Apple servers for loading map data on behalf of other apps and for resolving geographical coordinates to readable addresses.
|
||||
# Connects to gspe*-ssl.ls.apple.com (where * is a number from 1 to 100 ), sp-ssl.ls.apple.com, configuration.ls.apple.com using HTTPS 443 (TCP)
|
||||
call:
|
||||
function: "RenameSystemFile (TODO: Just like Windows.yaml, requires SIP)"
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/GeoServices.framework/Versions/A/XPCServices/com.apple.geod.xpc/Contents/MacOS/com.apple.geod
|
||||
-
|
||||
name: Disable Location-Based Suggestions for Siri, Spotlight and other places
|
||||
# Used for suggestions in Spotlight, Messages, Lookup, Safari, Siri, and other place
|
||||
# Connects to api-glb-euc1b.smoot.apple.com, api.smoot.apple.com using HTTPS 443 (TCP)
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.parsecd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: "RenameSystemFile (TODO: Just like Windows.yaml, requires SIP)"
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/CoreParsec.framework/parsecd
|
||||
-
|
||||
category: Disable iCloud services
|
||||
children:
|
||||
-
|
||||
name: Disable iCloud notification agent
|
||||
recommend: strict
|
||||
call:
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.iCloudNotificationAgent
|
||||
type: LaunchAgents
|
||||
-
|
||||
name: Disable Sync Defaults Daemon
|
||||
# Syncs user preferences or other configuration related data via iCloud
|
||||
docs: https://www.unix.com/man-page/mojave/8/syncdefaultsd
|
||||
# Connects to keyvalueservice.icloud.com and p*-keyvalueservice.icloud.com (where * is a number) using HTTPS 443 (TCP)
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.syncdefaultsd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: "RenameSystemFile (TODO: Just like Windows.yaml, requires SIP)"
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/SyncedDefaults.framework/Support/syncdefaultsd
|
||||
-
|
||||
name: Disable Reminder Daemon that synchronizes the reminder list in "Reminders" with iCloud
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.remindd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /usr/libexec/remindd #TODO: Mb don't require SIP
|
||||
-
|
||||
name: Disable Cloud Daemon used for iCloud syncing
|
||||
# Connects to gateway.icloud.com, metrics.icloud.com using HTTPS 443 (TCP)
|
||||
recommend: strict
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.cloudd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.cloudd
|
||||
type: LaunchDaemons
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/CloudKitDaemon.framework/Support/cloudd
|
||||
-
|
||||
name: Disable Help Daemon (breaks HelpViewer feature)
|
||||
recommend: strict
|
||||
docs: https://discussions.apple.com/thread/3930621
|
||||
# Connects to cds.apple.com, help.apple.com using HTTPS (TCP 443)
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.helpd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/HelpData.framework/Versions/A/Resources/helpd
|
||||
-
|
||||
name: Disable Rapport Daemon for communication between Apple devices
|
||||
# Rapport Daemon is a macOS system process that enables Phone Call Handoff and other communication features between Apple devices.
|
||||
# Connects to init.ess.apple.com using HTTPS (TCP 443)
|
||||
docs: https://apple.stackexchange.com/questions/308294/what-is-rapportd-and-why-does-it-want-incoming-network-connections
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.rapportd-user
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.rapportd
|
||||
type: LaunchDaemons
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /usr/libexec/rapportd #TODO: No SIP required?
|
||||
-
|
||||
name: Disable App Tracking Transparency framework
|
||||
docs:
|
||||
- https://apple.stackexchange.com/questions/409349/what-is-the-transparencyd-daemon-for
|
||||
- https://developer.apple.com/documentation/apptrackingtransparency
|
||||
# Connects to server kt-prod.apple.com using HTTPS (TCP 443 )
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.transparencyd
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /usr/libexec/transparencyd #TODO: No need for SIP?
|
||||
-
|
||||
category: Disable Calendar Agent that sync Calender App to iCloud and other servers
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.CalendarAgent
|
||||
type: LaunchAgents
|
||||
-
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /System/Library/PrivateFrameworks/CalendarAgent.framework/Executables/CalendarAgent
|
||||
-
|
||||
name: Disable advertising services daemon
|
||||
recommend: strict
|
||||
docs: https://www.unix.com/man-page/mojave/8/adservicesd
|
||||
call:
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.ap.adservicesd
|
||||
type: LaunchAgents
|
||||
-
|
||||
name: Disable NetBIOS interactions (might break Microsoft services)
|
||||
# Mostly used for mostly SMB network volumes
|
||||
docs: https://www.manpagez.com/man/8/netbiosd/
|
||||
call:
|
||||
-
|
||||
function: DisableService
|
||||
parameters:
|
||||
name: com.apple.netbiosd
|
||||
type: LaunchDaemons
|
||||
function: RenameSystemFile
|
||||
parameters:
|
||||
filePath: /usr/sbin/netbiosd
|
||||
requireSip: false # TODO: Test
|
||||
|
||||
functions:
|
||||
-
|
||||
name: PersistUserEnvironmentConfiguration
|
||||
@@ -1268,3 +1638,31 @@ functions:
|
||||
echo "[$profile_file] No need for any action, configuration does not exist"
|
||||
fi
|
||||
done
|
||||
-
|
||||
name: DisableService
|
||||
parameters:
|
||||
- name: name
|
||||
- name: type
|
||||
code: |-
|
||||
original_file='/System/Library/{{ $type }}/{{ $name }}.plist'
|
||||
backup_file="$original_file.disabled"
|
||||
if [ -f "$original_file" ]; then
|
||||
sudo launchctl unload -w "$original_file" 2> /dev/null
|
||||
mv "$original_file" "$backup_file"
|
||||
echo 'Disabled successfully'
|
||||
else
|
||||
echo 'Already disabled'
|
||||
fi
|
||||
revertCode: |-
|
||||
original_file='/System/Library/{{ $type }}/{{ $name }}.plist'
|
||||
backup_file="$original_file.disabled"
|
||||
if [ -f "$original_file" ]; then
|
||||
sudo launchctl unload -w "$original_file" 2> /dev/null
|
||||
if mv "$original_file" "$backup_file"; then
|
||||
echo 'Disabled successfully'
|
||||
else
|
||||
>&2 echo 'Failed to disable'
|
||||
fi
|
||||
else
|
||||
echo 'Already disabled'
|
||||
fi
|
||||
|
||||
@@ -5999,9 +5999,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.SecHealthUI
|
||||
packageName: Microsoft.Windows.SecHealthUI
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: UI for privacy
|
||||
children:
|
||||
@@ -7733,7 +7733,7 @@ actions:
|
||||
This category includes scripts for uninstalling default system apps in Windows.
|
||||
|
||||
System apps are pre-installed [1] [2] applications located in the `C:\Windows*` directory [1] [2].
|
||||
These apps are typically found on `C:\Windows\SystemApps\{PackageFamilyName}` or `C:\Windows\{AppName}` folders.
|
||||
These apps are typically found on `C:\Windows\SystemApps\{PackageFamilyName}` or `C:\Windows\{ShortAppName}` folders.
|
||||
|
||||
To view all system apps:
|
||||
|
||||
@@ -7758,9 +7758,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage 1527c705-839a-4832-9118-54d4Bd6a0c89
|
||||
packageName: 1527c705-839a-4832-9118-54d4Bd6a0c89
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "File Explorer" app
|
||||
docs: |
|
||||
@@ -7772,9 +7772,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage c5e2524a-ea46-4f67-841f-6a9465d9d515
|
||||
packageName: c5e2524a-ea46-4f67-841f-6a9465d9d515
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "App Resolver UX" app
|
||||
docs: |-
|
||||
@@ -7786,9 +7786,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage E2A4F912-2574-4A75-9BB0-0D023378592B
|
||||
packageName: E2A4F912-2574-4A75-9BB0-0D023378592B
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Add Suggested Folders To Library" app
|
||||
docs: |-
|
||||
@@ -7801,16 +7801,16 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE
|
||||
packageName: F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage InputApp
|
||||
packageName: InputApp
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Microsoft AAD Broker Plugin" app (breaks Night Light settings, taskbar keyboard selection and Office app authentication)
|
||||
# recommend: strict (Unrecommended due to too many side-effects)
|
||||
@@ -7843,9 +7843,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.AAD.BrokerPlugin
|
||||
packageName: Microsoft.AAD.BrokerPlugin # Offical docs point to wrong "Microsoft.AAD.Broker.Plugin"
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Microsoft Accounts Control" app
|
||||
docs: |-
|
||||
@@ -7860,9 +7860,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.AccountsControl
|
||||
packageName: Microsoft.AccountsControl
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Microsoft Async Text Service" app
|
||||
docs: |-
|
||||
@@ -7874,9 +7874,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : 8wekyb3d8bbwe
|
||||
# More info : Get-AppxPackage Microsoft.AsyncTextService
|
||||
packageName: Microsoft.AsyncTextService
|
||||
publisherId: 8wekyb3d8bbwe
|
||||
-
|
||||
category: Remove Windows Hello setup UI apps
|
||||
children:
|
||||
@@ -7894,9 +7894,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.BioEnrollment
|
||||
packageName: Microsoft.BioEnrollment
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Credentials Dialog Host" app
|
||||
docs: |-
|
||||
@@ -7909,9 +7909,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.CredDialogHost
|
||||
packageName: Microsoft.CredDialogHost
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "EC" app
|
||||
docs: |-
|
||||
@@ -7923,9 +7923,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : 8wekyb3d8bbwe
|
||||
# More info : Get-AppxPackage Microsoft.ECApp
|
||||
packageName: Microsoft.ECApp
|
||||
publisherId: 8wekyb3d8bbwe
|
||||
-
|
||||
name: Remove "Lock" app (shows lock screen)
|
||||
docs: |-
|
||||
@@ -7939,9 +7939,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.LockApp
|
||||
packageName: Microsoft.LockApp
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: Remove Edge apps
|
||||
docs: |-
|
||||
@@ -7992,9 +7992,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : 8wekyb3d8bbwe
|
||||
# More info : Get-AppxPackage Microsoft.MicrosoftEdge
|
||||
packageName: Microsoft.MicrosoftEdge
|
||||
publisherId: 8wekyb3d8bbwe
|
||||
-
|
||||
name: Remove "Microsoft Edge Dev Tools Client" app
|
||||
recommend: strict
|
||||
@@ -8018,9 +8018,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : 8wekyb3d8bbwe
|
||||
# More info : Get-AppxPackage Microsoft.MicrosoftEdgeDevToolsClient
|
||||
packageName: Microsoft.MicrosoftEdgeDevToolsClient
|
||||
publisherId: 8wekyb3d8bbwe
|
||||
-
|
||||
name: Remove Edge (legacy) file and URL associations
|
||||
recommend: strict
|
||||
@@ -8078,9 +8078,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Win32WebViewHost
|
||||
packageName: Microsoft.Win32WebViewHost
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Microsoft PPI Projection" app
|
||||
docs: |-
|
||||
@@ -8095,9 +8095,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.PPIProjection
|
||||
packageName: Microsoft.PPIProjection
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "ChxApp" app
|
||||
docs: |-
|
||||
@@ -8109,9 +8109,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.Apprep.ChxApp
|
||||
packageName: Microsoft.Windows.Apprep.ChxApp
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Assigned Access Lock App" app
|
||||
docs: |-
|
||||
@@ -8123,9 +8123,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.AssignedAccessLockApp
|
||||
packageName: Microsoft.Windows.AssignedAccessLockApp
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Capture Picker" app
|
||||
docs: |-
|
||||
@@ -8137,9 +8137,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.CapturePicker
|
||||
packageName: Microsoft.Windows.CapturePicker
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Cloud Experience Host" app (breaks Windows Hello password/PIN sign-in options, and Microsoft cloud/corporate sign in)
|
||||
# recommend: strict (Unrecommended due to too many side-effects)
|
||||
@@ -8180,9 +8180,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.CloudExperienceHost
|
||||
packageName: Microsoft.Windows.CloudExperienceHost
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Content Delivery Manager" app
|
||||
recommend: strict
|
||||
@@ -8206,9 +8206,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.ContentDeliveryManager
|
||||
packageName: Microsoft.Windows.ContentDeliveryManager
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: Remove Cortana system apps
|
||||
children:
|
||||
@@ -8238,9 +8238,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyew
|
||||
# More info : Get-AppxPackage Microsoft.Windows.Cortana
|
||||
packageName: Microsoft.Windows.Cortana # Removed since version 2004
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
function: UninstallStoreApp
|
||||
parameters:
|
||||
@@ -8265,9 +8265,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyew
|
||||
# More info : Get-AppxPackage Microsoft.Windows.Holographic.FirstRun
|
||||
packageName: Microsoft.Windows.Holographic.FirstRun
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: Remove Out-of-Box Experience (OOBE) apps
|
||||
docs: |-
|
||||
@@ -8296,9 +8296,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.OOBENetworkCaptivePortal
|
||||
packageName: Microsoft.Windows.OOBENetworkCaptivePortal # Offical docs point to wrong "Microsoft.Windows.OOBENetworkCaptivePort"
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "OOBE Network Connection Flow" app
|
||||
docs: |-
|
||||
@@ -8324,9 +8324,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.OOBENetworkConnectionFlow
|
||||
packageName: Microsoft.Windows.OOBENetworkConnectionFlow
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Microsoft Family Safety" / "Parental control" app
|
||||
recommend: standard
|
||||
@@ -8358,9 +8358,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.ParentalControls
|
||||
packageName: Microsoft.Windows.ParentalControls
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: Remove People Hub apps
|
||||
children:
|
||||
@@ -8389,9 +8389,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.PeopleExperienceHost
|
||||
packageName: Microsoft.Windows.PeopleExperienceHost
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Pinning Confirmation Dialog" app
|
||||
docs: |-
|
||||
@@ -8403,9 +8403,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.PinningConfirmationDialog
|
||||
packageName: Microsoft.Windows.PinningConfirmationDialog
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Secondary Tile Experience" app
|
||||
recommend: strict
|
||||
@@ -8427,9 +8427,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.SecondaryTileExperience
|
||||
packageName: Microsoft.Windows.SecondaryTileExperience
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Take a Test" app
|
||||
recommend: strict
|
||||
@@ -8457,9 +8457,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.Windows.SecureAssessmentBrowser
|
||||
packageName: Microsoft.Windows.SecureAssessmentBrowser
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: Remove Windows Feedback apps
|
||||
children:
|
||||
@@ -8474,9 +8474,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.WindowsFeedback
|
||||
packageName: Microsoft.WindowsFeedback
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Xbox Game Callable UI" app (breaks Xbox Live games)
|
||||
docs: |-
|
||||
@@ -8497,9 +8497,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Microsoft.XboxGameCallableUI
|
||||
packageName: Microsoft.XboxGameCallableUI
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "CBS Preview" app
|
||||
recommend: standard
|
||||
@@ -8512,9 +8512,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Windows.CBSPreview
|
||||
packageName: Windows.CBSPreview
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Contact Support" app
|
||||
docs: |-
|
||||
@@ -8525,9 +8525,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Windows.ContactSupport
|
||||
packageName: Windows.ContactSupport
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Windows Print 3D" app
|
||||
docs: |-
|
||||
@@ -8539,9 +8539,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ❌ Missing | Windows 11 (≥ 22H2): ❌ Missing
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Windows.Print3D
|
||||
packageName: Windows.Print3D
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
name: Remove "Print UI" app
|
||||
docs: |-
|
||||
@@ -8553,9 +8553,9 @@ actions:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
# Existence : Windows 10 (≥ 22H2): ✅ Exists | Windows 11 (≥ 22H2): ✅ Exists
|
||||
# Publisher ID : cw5n1h2txyewy
|
||||
# More info : Get-AppxPackage Windows.PrintDialog
|
||||
packageName: Windows.PrintDialog
|
||||
publisherId: cw5n1h2txyewy
|
||||
-
|
||||
category: Remove OneDrive
|
||||
docs: |-
|
||||
@@ -9797,50 +9797,131 @@ functions:
|
||||
name: UninstallSystemApp
|
||||
parameters:
|
||||
- name: packageName
|
||||
# It simply renames files
|
||||
- name: publisherId
|
||||
# It simply renames files in application folders.
|
||||
# Because system apps are non removable (check: (Get-AppxPackage -AllUsers 'Windows.CBSPreview').NonRemovable)
|
||||
# Otherwise they throw 0x80070032 when trying to uninstall them
|
||||
# This script all files in three application folders to make them inaccessible for the operating system:
|
||||
# 1. Installation
|
||||
# - Parent : `%WINDIR%\SystemApps\{PackageFamilyName}` or `%WINDIR%\{AppName}`
|
||||
# - Example : `C:\Windows\SystemApps\Windows.CBSPreview_cw5n1h2txyewy` or `C:\Windows\PrintDialog`
|
||||
# - Check :
|
||||
# - `(Get-AppxPackage -AllUsers 'Windows.CBSPreview').InstallLocation` or `(Get-AppxPackage -AllUsers 'Windows.PrintDialog').InstallLocation`
|
||||
# - `Get-AppxPackage -PackageTypeFilter Main | ? { $_.SignatureKind -eq "System" } | Sort Name | Format-Table Name, InstallLocation`
|
||||
# 2. User-specific data
|
||||
# - Parent : %LOCALAPPDATA%\Packages\
|
||||
# - Example : C:\Users\undergroundwires\AppData\Local\Packages\Windows.CBSPreview_cw5n1h2txyewy
|
||||
# - Check : "$env:LOCALAPPDATA\Packages\$((Get-AppxPackage -AllUsers 'Windows.CBSPreview').PackageFamilyName)"
|
||||
# 3. Metadata
|
||||
# - Parent : `%PROGRAMDATA\Microsoft\Windows\AppRepository\Packages\${PackageFullName}`
|
||||
# - Example : C:\ProgramData\Microsoft\Windows\AppRepository\Packages\Windows.CBSPreview_10.0.19580.1000_neutral_neutral_cw5n1h2txyewy
|
||||
# - Check : "$env:PROGRAMDATA\Microsoft\Windows\AppRepository\Packages\$((Get-AppxPackage -AllUsers 'Windows.CBSPreview').PackageFullName)"
|
||||
call:
|
||||
function: RunPowerShell
|
||||
parameters:
|
||||
code: |-
|
||||
$package = Get-AppxPackage -AllUsers '{{ $packageName }}'
|
||||
if (!$package) {
|
||||
Write-Host 'Not installed'
|
||||
exit 0
|
||||
$packageName = '{{ $packageName }}'
|
||||
$publisherId='{{ $publisherId }}'
|
||||
Write-Host "Soft-deleting `"$packageName`" folders."
|
||||
$directories = @(
|
||||
@{ Name = 'User-specific data'; Path = "$env:LOCALAPPDATA\Packages\$($package.PackageFamilyName)"; }
|
||||
@{ Name = 'Metadata'; Path = "$env:PROGRAMDATA\Microsoft\Windows\AppRepository\Packages\$($package.PackageFullName)"; }
|
||||
)
|
||||
$package = Get-AppxPackage -AllUsers $packageName
|
||||
if ($package -and $package.InstallLocation) {
|
||||
$directories += @{ Name = 'Installation'; Path = $package.InstallLocation; }
|
||||
} else {
|
||||
Write-Host "The package `"$packageName`" could not be found, residual files will still be handled."
|
||||
$packageFamilyName = "$($packageName)_$($publisherId)"
|
||||
$appShortName = ($packageName -Split '\.')[-1]
|
||||
$directories +=@(
|
||||
@{ Name = 'Installation (SystemApps)'; Path = "$env:WINDIR\SystemApps\$packageFamilyName"; }
|
||||
@{ Name = 'Installation (Root)'; Path = "$env:WINDIR\$appShortName"; }
|
||||
)
|
||||
}
|
||||
$directories = @($package.InstallLocation, "$env:LOCALAPPDATA\Packages\$($package.PackageFamilyName)")
|
||||
foreach($dir in $directories) {
|
||||
if ( !$dir -Or !(Test-Path "$dir") ) { continue }
|
||||
cmd /c ('takeown /f "' + $dir + '" /r /d y 1> nul')
|
||||
if($LASTEXITCODE) { throw 'Failed to take ownership' }
|
||||
cmd /c ('icacls "' + $dir + '" /grant administrators:F /t 1> nul')
|
||||
if($LASTEXITCODE) { throw 'Failed to take ownership' }
|
||||
$files = Get-ChildItem -File -Path $dir -Recurse -Force
|
||||
foreach($file in $files) {
|
||||
if($file.Name.EndsWith('.OLD')) { continue }
|
||||
$newName = $file.FullName + '.OLD'
|
||||
Write-Host "Rename '$($file.FullName)' to '$newName'"
|
||||
Move-Item -LiteralPath "$($file.FullName)" -Destination "$newName" -Force
|
||||
foreach($directory in $directories) {
|
||||
Write-Host "Processing folder: `"$($directory.Name)`"..."
|
||||
if (!$directory.Path) {
|
||||
Write-Host 'Skipping, path not found.'
|
||||
continue
|
||||
}
|
||||
if (!(Test-Path $directory.Path)) {
|
||||
Write-Host "Skipping, directory `"$($directory.Path)`" does not exist."
|
||||
continue
|
||||
}
|
||||
cmd /c ("takeown /f `"$($directory.Path)`" /r /d y 1> nul")
|
||||
if ($LASTEXITCODE) {
|
||||
Write-Error "Failed to obtain ownership for `"$($directory.Path)`"."
|
||||
continue
|
||||
}
|
||||
cmd /c ("icacls `"$($directory.Path))`" /grant administrators:F /t 1> nul")
|
||||
if ($LASTEXITCODE) {
|
||||
Write-Error "Failed to assign permissions for `"$($directory.Path)`"."
|
||||
continue
|
||||
}
|
||||
$files = Get-ChildItem -File -Path $directory.Path -Recurse -Force
|
||||
foreach ($file in $files) {
|
||||
if($file.Name.EndsWith('.OLD')) {
|
||||
continue
|
||||
}
|
||||
$newName = "$($file.FullName).OLD"
|
||||
try {
|
||||
Move-Item -LiteralPath "$($file.FullName)" -Destination "$newName" -Force -ErrorAction Stop
|
||||
Write-Host "Successfully renamed `"$($file.FullName)`"."
|
||||
} catch {
|
||||
Write-Error "Failed to rename `"$($file.FullName)`" to `"$newName`": $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
revertCode: |-
|
||||
$package = Get-AppxPackage -AllUsers '{{ $packageName }}'
|
||||
if (!$package) {
|
||||
Write-Error 'App could not be found' -ErrorAction Stop
|
||||
$packageName = '{{ $packageName }}'
|
||||
$publisherId='{{ $publisherId }}'
|
||||
Write-Host "Restoring `"$packageName`" folders."
|
||||
$directories = @(
|
||||
@{ Name = 'User-specific data'; Path = "$env:LOCALAPPDATA\Packages\$($package.PackageFamilyName)"; }
|
||||
@{ Name = 'Metadata'; Path = "$env:PROGRAMDATA\Microsoft\Windows\AppRepository\Packages\$($package.PackageFullName)"; }
|
||||
)
|
||||
$package = Get-AppxPackage -AllUsers $packageName
|
||||
if ($package -and $package.InstallLocation) {
|
||||
$directories += @{ Name = 'Installation'; Path = $package.InstallLocation; }
|
||||
} else {
|
||||
Write-Warning "The package `"$packageName`" could not be found, its files will still be handled."
|
||||
$packageFamilyName = "$($packageName)_$($publisherId)"
|
||||
$appShortName = ($packageName -Split '\.')[-1]
|
||||
$directories +=@(
|
||||
@{ Name = 'Installation (SystemApps)'; Path = "$env:WINDIR\SystemApps\$packageFamilyName"; }
|
||||
@{ Name = 'Installation (Root)'; Path = "$env:WINDIR\$appShortName"; }
|
||||
)
|
||||
}
|
||||
$directories = @($package.InstallLocation, "$env:LOCALAPPDATA\Packages\$($package.PackageFamilyName)")
|
||||
foreach($dir in $directories) {
|
||||
if ( !$dir -Or !(Test-Path "$dir") ) { continue; }
|
||||
cmd /c ('takeown /f "' + $dir + '" /r /d y 1> nul')
|
||||
if($LASTEXITCODE) { throw 'Failed to take ownership' }
|
||||
cmd /c ('icacls "' + $dir + '" /grant administrators:F /t 1> nul')
|
||||
if($LASTEXITCODE) { throw 'Failed to take ownership' }
|
||||
$files = Get-ChildItem -File -Path "$dir\*.OLD" -Recurse -Force
|
||||
foreach($file in $files) {
|
||||
foreach ($directory in $directories) {
|
||||
Write-Host "Processing folder: `"$($directory.Name)`" directory..."
|
||||
if (!$directory.Path) {
|
||||
Write-Host "Skipping `"$($directory.Name)`" directory, path not found."
|
||||
continue
|
||||
}
|
||||
if (!(Test-Path $directory.Path)) {
|
||||
Write-Host "Skipping, directory `"$($directory.Path)`" does not exist."
|
||||
continue
|
||||
}
|
||||
cmd /c ("takeown /f `"$($directory.Path)`" /r /d y 1> nul")
|
||||
if ($LASTEXITCODE) {
|
||||
Write-Error "Failed to obtain ownership for `"$($directory.Path)`"."
|
||||
continue
|
||||
}
|
||||
cmd /c ("icacls `"$($directory.Path)`" /grant administrators:F /t 1> nul")
|
||||
if ($LASTEXITCODE) {
|
||||
Write-Error "Failed to assign permissions for `"$($directory.Path)`"."
|
||||
continue
|
||||
}
|
||||
$files = Get-ChildItem -File -Path "$($directory.Path)\*.OLD" -Recurse -Force
|
||||
foreach ($file in $files) {
|
||||
$newName = $file.FullName.Substring(0, $file.FullName.Length - 4)
|
||||
Write-Host "Rename '$($file.FullName)' to '$newName'"
|
||||
Move-Item -LiteralPath "$($file.FullName)" -Destination "$newName" -Force
|
||||
try {
|
||||
Move-Item -LiteralPath "$($file.FullName)" -Destination "$newName" -Force -ErrorAction Stop
|
||||
Write-Host "Successfully renamed `"$($file.FullName)`" back to original."
|
||||
} catch {
|
||||
Write-Error "Failed to rename `"$($file.FullName)`" back to original `"$newName`": $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { ReadOnlyTreeNode } from '../../Node/TreeNode';
|
||||
import { RenderQueueOrderer } from './RenderQueueOrderer';
|
||||
|
||||
export class CollapseDepthOrderer implements RenderQueueOrderer {
|
||||
public orderNodes(nodes: Iterable<ReadOnlyTreeNode>): ReadOnlyTreeNode[] {
|
||||
return orderNodes(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
function orderNodes(nodes: Iterable<ReadOnlyTreeNode>): ReadOnlyTreeNode[] {
|
||||
return [...nodes]
|
||||
.sort((a, b) => {
|
||||
const [aCollapseStatus, bCollapseStatus] = [isNodeCollapsed(a), isNodeCollapsed(b)];
|
||||
if (aCollapseStatus !== bCollapseStatus) {
|
||||
return (aCollapseStatus ? 1 : 0) - (bCollapseStatus ? 1 : 0);
|
||||
}
|
||||
return a.hierarchy.depthInTree - b.hierarchy.depthInTree;
|
||||
});
|
||||
}
|
||||
|
||||
function isNodeCollapsed(node: ReadOnlyTreeNode): boolean {
|
||||
if (!node.state.current.isExpanded) {
|
||||
return true;
|
||||
}
|
||||
if (node.hierarchy.parent) {
|
||||
return isNodeCollapsed(node.hierarchy.parent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { ReadOnlyTreeNode } from '../../Node/TreeNode';
|
||||
import { RenderQueueOrderer } from './RenderQueueOrderer';
|
||||
|
||||
export class CollapsedParentOrderer implements RenderQueueOrderer {
|
||||
public orderNodes(nodes: Iterable<ReadOnlyTreeNode>): ReadOnlyTreeNode[] {
|
||||
return orderNodes(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
function orderNodes(nodes: Iterable<ReadOnlyTreeNode>): ReadOnlyTreeNode[] {
|
||||
return [...nodes]
|
||||
.map((node, index) => ({ node, index }))
|
||||
.sort((a, b) => {
|
||||
const [
|
||||
isANodeOfCollapsedParent,
|
||||
isBNodeOfCollapsedParent,
|
||||
] = [isParentCollapsed(a.node), isParentCollapsed(b.node)];
|
||||
if (isANodeOfCollapsedParent !== isBNodeOfCollapsedParent) {
|
||||
return (isANodeOfCollapsedParent ? 1 : 0) - (isBNodeOfCollapsedParent ? 1 : 0);
|
||||
}
|
||||
return a.index - b.index;
|
||||
})
|
||||
.map(({ node }) => node);
|
||||
}
|
||||
|
||||
function isParentCollapsed(node: ReadOnlyTreeNode): boolean {
|
||||
const parentNode = node.hierarchy.parent;
|
||||
if (parentNode) {
|
||||
if (!parentNode.state.current.isExpanded) {
|
||||
return true;
|
||||
}
|
||||
return isParentCollapsed(parentNode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { NodeRenderingStrategy } from './Scheduling/NodeRenderingStrategy';
|
||||
import { DelayScheduler } from './DelayScheduler';
|
||||
import { TimeoutDelayScheduler } from './Scheduling/TimeoutDelayScheduler';
|
||||
import { RenderQueueOrderer } from './Ordering/RenderQueueOrderer';
|
||||
import { CollapseDepthOrderer } from './Ordering/CollapseDepthOrderer';
|
||||
import { CollapsedParentOrderer } from './Ordering/CollapsedParentOrderer';
|
||||
|
||||
/**
|
||||
* Renders tree nodes gradually to prevent UI freeze when loading large amounts of nodes.
|
||||
@@ -21,7 +21,7 @@ export function useGradualNodeRendering(
|
||||
scheduler: DelayScheduler = new TimeoutDelayScheduler(),
|
||||
initialBatchSize = 30,
|
||||
subsequentBatchSize = 5,
|
||||
orderer: RenderQueueOrderer = new CollapseDepthOrderer(),
|
||||
orderer: RenderQueueOrderer = new CollapsedParentOrderer(),
|
||||
): NodeRenderingStrategy {
|
||||
const nodesToRender = new Set<ReadOnlyTreeNode>();
|
||||
const nodesBeingRendered = shallowRef(new Set<ReadOnlyTreeNode>());
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('Script', () => {
|
||||
describe('level', () => {
|
||||
it('cannot construct with invalid wrong value', () => {
|
||||
// arrange
|
||||
const invalidValue: RecommendationLevel = 55;
|
||||
const invalidValue: RecommendationLevel = 55 as never;
|
||||
const expectedError = 'invalid level';
|
||||
// act
|
||||
const construct = () => new ScriptBuilder()
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('ScriptingDefinition', () => {
|
||||
});
|
||||
it('throws if unknown', () => {
|
||||
// arrange
|
||||
const unknownValue: ScriptingLanguage = 666;
|
||||
const unknownValue: ScriptingLanguage = 666 as never;
|
||||
const errorMessage = `unsupported language: ${unknownValue}`;
|
||||
// act
|
||||
const act = () => new ScriptingDefinitionBuilder()
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { TreeNode } from '@/presentation/components/Scripts/View/Tree/TreeView/Node/TreeNode';
|
||||
import { CollapseDepthOrderer } from '@/presentation/components/Scripts/View/Tree/TreeView/Rendering/Ordering/CollapseDepthOrderer';
|
||||
import { HierarchyAccessStub } from '@tests/unit/shared/Stubs/HierarchyAccessStub';
|
||||
import { TreeNodeStateAccessStub } from '@tests/unit/shared/Stubs/TreeNodeStateAccessStub';
|
||||
import { TreeNodeStateDescriptorStub } from '@tests/unit/shared/Stubs/TreeNodeStateDescriptorStub';
|
||||
import { TreeNodeStub } from '@tests/unit/shared/Stubs/TreeNodeStub';
|
||||
|
||||
describe('CollapseDepthOrderer', () => {
|
||||
describe('orderNodes', () => {
|
||||
it('should order by collapsed state and then by depth in', () => {
|
||||
// arrange
|
||||
const node1 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
depthInTree: 1,
|
||||
});
|
||||
const node2 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
depthInTree: 2,
|
||||
});
|
||||
const node3 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
depthInTree: 3,
|
||||
});
|
||||
const node4 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
depthInTree: 4,
|
||||
});
|
||||
const nodes = [node1, node2, node3, node4];
|
||||
const expectedOrder = [node2, node1, node3, node4];
|
||||
// act
|
||||
const orderer = new CollapseDepthOrderer();
|
||||
const orderedNodes = orderer.orderNodes(nodes);
|
||||
// assert
|
||||
expect(orderedNodes.map((node) => node.id)).to.deep
|
||||
.equal(expectedOrder.map((node) => node.id));
|
||||
});
|
||||
it('should handle parent collapsed state', () => {
|
||||
// arrange
|
||||
const collapsedParent = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
depthInTree: 0,
|
||||
});
|
||||
const childWithCollapsedParent = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
depthInTree: 1,
|
||||
parent: collapsedParent,
|
||||
});
|
||||
const deepExpandedNode = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
depthInTree: 3,
|
||||
});
|
||||
const nodes = [childWithCollapsedParent, collapsedParent, deepExpandedNode];
|
||||
const expectedOrder = [
|
||||
deepExpandedNode, // comes first due to collapse parent of child
|
||||
collapsedParent,
|
||||
childWithCollapsedParent,
|
||||
];
|
||||
// act
|
||||
const orderer = new CollapseDepthOrderer();
|
||||
const orderedNodes = orderer.orderNodes(nodes);
|
||||
// assert
|
||||
expect(orderedNodes.map((node) => node.id)).to.deep
|
||||
.equal(expectedOrder.map((node) => node.id));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createNodeForOrder(options: {
|
||||
readonly isExpanded: boolean;
|
||||
readonly depthInTree: number;
|
||||
readonly parent?: TreeNode;
|
||||
}): TreeNode {
|
||||
return new TreeNodeStub()
|
||||
.withId([
|
||||
`isExpanded: ${options.isExpanded}`,
|
||||
`depthInTree: ${options.depthInTree}`,
|
||||
...(options.parent ? [`parent: ${options.parent.id}`] : []),
|
||||
].join(', '))
|
||||
.withState(
|
||||
new TreeNodeStateAccessStub()
|
||||
.withCurrent(
|
||||
new TreeNodeStateDescriptorStub()
|
||||
.withVisibility(true)
|
||||
.withExpansion(options.isExpanded),
|
||||
),
|
||||
)
|
||||
.withHierarchy(
|
||||
new HierarchyAccessStub()
|
||||
.withDepthInTree(options.depthInTree)
|
||||
.withParent(options.parent),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { TreeNode } from '@/presentation/components/Scripts/View/Tree/TreeView/Node/TreeNode';
|
||||
import { CollapsedParentOrderer } from '@/presentation/components/Scripts/View/Tree/TreeView/Rendering/Ordering/CollapsedParentOrderer';
|
||||
import { HierarchyAccessStub } from '@tests/unit/shared/Stubs/HierarchyAccessStub';
|
||||
import { TreeNodeStateAccessStub } from '@tests/unit/shared/Stubs/TreeNodeStateAccessStub';
|
||||
import { TreeNodeStateDescriptorStub } from '@tests/unit/shared/Stubs/TreeNodeStateDescriptorStub';
|
||||
import { TreeNodeStub } from '@tests/unit/shared/Stubs/TreeNodeStub';
|
||||
|
||||
describe('CollapsedParentOrderer', () => {
|
||||
describe('orderNodes', () => {
|
||||
const scenarios: ReadonlyArray<{
|
||||
readonly description: string;
|
||||
readonly nodes: TreeNode[];
|
||||
readonly expectedOrderedNodes: TreeNode[];
|
||||
}> = [
|
||||
{
|
||||
description: 'handles empty nodes list',
|
||||
nodes: [],
|
||||
expectedOrderedNodes: [],
|
||||
},
|
||||
(() => {
|
||||
const expectedNode = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
});
|
||||
return {
|
||||
description: 'handles single node list',
|
||||
nodes: [expectedNode],
|
||||
expectedOrderedNodes: [expectedNode],
|
||||
};
|
||||
})(),
|
||||
(() => {
|
||||
const node1 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
});
|
||||
const node2 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
});
|
||||
const node3 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
});
|
||||
const node4 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
});
|
||||
return {
|
||||
description: 'orders by index ignoring self collapsed state',
|
||||
nodes: [node1, node2, node3, node4],
|
||||
expectedOrderedNodes: [node1, node2, node3, node4],
|
||||
};
|
||||
})(),
|
||||
(() => {
|
||||
const node1 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
parent: createNodeForOrder({ isExpanded: true }),
|
||||
});
|
||||
const node2 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: createNodeForOrder({ isExpanded: true }),
|
||||
});
|
||||
const node3 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: createNodeForOrder({ isExpanded: true }),
|
||||
});
|
||||
const node4 = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
parent: createNodeForOrder({ isExpanded: true }),
|
||||
});
|
||||
return {
|
||||
description: 'orders by index if all parents are expanded',
|
||||
nodes: [node1, node2, node3, node4],
|
||||
expectedOrderedNodes: [node1, node2, node3, node4],
|
||||
};
|
||||
})(),
|
||||
(() => {
|
||||
const node1 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: createNodeForOrder({ isExpanded: false }),
|
||||
});
|
||||
const node2 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: createNodeForOrder({ isExpanded: true }),
|
||||
});
|
||||
const node3 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
});
|
||||
const node4 = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: createNodeForOrder({ isExpanded: false }),
|
||||
});
|
||||
return {
|
||||
description: 'order by parent collapsed state then by index',
|
||||
nodes: [node1, node2, node3, node4],
|
||||
expectedOrderedNodes: [node2, node3, node1, node4],
|
||||
};
|
||||
})(),
|
||||
(() => {
|
||||
const collapsedNode = createNodeForOrder({
|
||||
isExpanded: false,
|
||||
});
|
||||
const collapsedNodeChild = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: collapsedNode,
|
||||
});
|
||||
const collapsedNodeNestedChild = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: collapsedNodeChild,
|
||||
});
|
||||
const expandedNode = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
});
|
||||
const expandedNodeChild = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: expandedNode,
|
||||
});
|
||||
const expandedNodeNestedChild = createNodeForOrder({
|
||||
isExpanded: true,
|
||||
parent: expandedNodeChild,
|
||||
});
|
||||
return {
|
||||
description: 'should handle deep parent collapsed state',
|
||||
nodes: [
|
||||
collapsedNode, collapsedNodeChild, collapsedNodeNestedChild,
|
||||
expandedNode, expandedNodeChild, expandedNodeNestedChild,
|
||||
],
|
||||
expectedOrderedNodes: [
|
||||
collapsedNode, expandedNode, expandedNodeChild,
|
||||
expandedNodeNestedChild, collapsedNodeChild, collapsedNodeNestedChild,
|
||||
],
|
||||
};
|
||||
})(),
|
||||
];
|
||||
scenarios.forEach(({ description, nodes, expectedOrderedNodes }) => {
|
||||
it(description, () => {
|
||||
// act
|
||||
const orderer = new CollapsedParentOrderer();
|
||||
const orderedNodes = orderer.orderNodes(nodes);
|
||||
// assert
|
||||
expect(orderedNodes.map((node) => node.id)).to.deep
|
||||
.equal(expectedOrderedNodes.map((node) => node.id));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createNodeForOrder(options: {
|
||||
readonly isExpanded: boolean;
|
||||
readonly parent?: TreeNode;
|
||||
}): TreeNode {
|
||||
return new TreeNodeStub()
|
||||
.withId([
|
||||
`isExpanded: ${options.isExpanded}`,
|
||||
...(options.parent ? [`parent: ${options.parent.id}`] : []),
|
||||
].join(', '))
|
||||
.withState(
|
||||
new TreeNodeStateAccessStub()
|
||||
.withCurrent(
|
||||
new TreeNodeStateDescriptorStub()
|
||||
.withVisibility(true)
|
||||
.withExpansion(options.isExpanded),
|
||||
),
|
||||
)
|
||||
.withHierarchy(
|
||||
new HierarchyAccessStub()
|
||||
.withParent(options.parent),
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { TimeFunctions, TimeoutDelayScheduler } from '@/presentation/components/Scripts/View/Tree/TreeView/Rendering/Scheduling/TimeoutDelayScheduler';
|
||||
import { StubWithObservableMethodCalls } from '@tests/unit/shared/Stubs/StubWithObservableMethodCalls';
|
||||
import { createMockTimeout } from '@tests/unit/shared/Stubs/TimeoutStub';
|
||||
|
||||
describe('TimeoutDelayScheduler', () => {
|
||||
describe('scheduleNext', () => {
|
||||
@@ -56,7 +57,8 @@ describe('TimeoutDelayScheduler', () => {
|
||||
expect(setTimeoutCalls.length).toBe(2);
|
||||
const clearTimeoutCalls = timerStub.callHistory.filter((c) => c.methodName === 'clearTimeout');
|
||||
expect(clearTimeoutCalls.length).toBe(1);
|
||||
const [actualId] = clearTimeoutCalls[0].args;
|
||||
const [timeout] = clearTimeoutCalls[0].args;
|
||||
const actualId = Number(timeout);
|
||||
expect(actualId).toBe(idOfFirstSetTimeoutCall);
|
||||
});
|
||||
});
|
||||
@@ -78,6 +80,7 @@ class TimeFunctionsStub
|
||||
methodName: 'setTimeout',
|
||||
args: [callback, delayInMs],
|
||||
});
|
||||
return this.callHistory.filter((c) => c.methodName === 'setTimeout').length as unknown as ReturnType<typeof setTimeout>;
|
||||
const id = this.callHistory.filter((c) => c.methodName === 'setTimeout').length;
|
||||
return createMockTimeout(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { throttle, ITimer, TimeoutType } from '@/presentation/components/Shared/
|
||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||
import { IEventSubscription } from '@/infrastructure/Events/IEventSource';
|
||||
import { getAbsentObjectTestCases, itEachAbsentObjectValue } from '@tests/unit/shared/TestCases/AbsentTests';
|
||||
import { createMockTimeout } from '@tests/unit/shared/Stubs/TimeoutStub';
|
||||
|
||||
describe('throttle', () => {
|
||||
describe('validates parameters', () => {
|
||||
@@ -153,7 +154,7 @@ class TimerMock implements ITimer {
|
||||
});
|
||||
this.subscriptions.push(subscription);
|
||||
const id = this.subscriptions.length - 1;
|
||||
return TimerMock.mockTimeout(id);
|
||||
return createMockTimeout(id);
|
||||
}
|
||||
|
||||
public clearTimeout(timeoutId: TimeoutType): void {
|
||||
@@ -172,15 +173,4 @@ class TimerMock implements ITimer {
|
||||
this.currentTime = ms;
|
||||
this.timeChanged.notify(this.currentTime);
|
||||
}
|
||||
|
||||
private static mockTimeout(subscriptionId: number): TimeoutType {
|
||||
const throwNodeSpecificCode = () => { throw new Error('node specific code'); };
|
||||
return {
|
||||
[Symbol.toPrimitive]: () => subscriptionId,
|
||||
hasRef: throwNodeSpecificCode,
|
||||
refresh: throwNodeSpecificCode,
|
||||
ref: throwNodeSpecificCode,
|
||||
unref: throwNodeSpecificCode,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
13
tests/unit/shared/Stubs/TimeoutStub.ts
Normal file
13
tests/unit/shared/Stubs/TimeoutStub.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export function createMockTimeout(timerId: number): ReturnType<typeof setTimeout> {
|
||||
const throwErrorForNodeOperation = () => {
|
||||
throw new Error('node specific operation was called');
|
||||
};
|
||||
return {
|
||||
[Symbol.toPrimitive]: () => timerId,
|
||||
[Symbol.dispose]: throwErrorForNodeOperation, // Cancels the timeout in node
|
||||
hasRef: throwErrorForNodeOperation,
|
||||
refresh: throwErrorForNodeOperation,
|
||||
ref: throwErrorForNodeOperation,
|
||||
unref: throwErrorForNodeOperation,
|
||||
};
|
||||
}
|
||||
18
tst.sh
Executable file
18
tst.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
echo '--- Disable Location-Based Suggestions for Siri'
|
||||
if $(csrutil status | grep 'enabled'); then
|
||||
echo 'SIP must be disabled'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
original_file='/System/Library/LaunchAgents/com.apple.parsecd.plist'
|
||||
backup_file="/Users/tst/aq.disabled"
|
||||
if [ -f "$original_file" ]; then
|
||||
sudo launchctl unload -w "$original_file" 2> /dev/null
|
||||
if sudo mv "$original_file" "$backup_file"; then
|
||||
echo 'Disabled successfully'
|
||||
else
|
||||
>&2 echo 'Failed to disable'
|
||||
fi
|
||||
else
|
||||
echo 'Already disabled'
|
||||
fi
|
||||
Reference in New Issue
Block a user