Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
439cd303ff | ||
|
|
ec0c972d34 | ||
|
|
2a08855e5d | ||
|
|
1c6b3057ea | ||
|
|
ea5f9ec27d | ||
|
|
f2935e4008 | ||
|
|
487001af48 | ||
|
|
71e70e50c5 | ||
|
|
0a857aa09e | ||
|
|
b976b92031 | ||
|
|
db62ed7f3a | ||
|
|
36f0805590 | ||
|
|
49600c5f37 | ||
|
|
eb9ac35a92 | ||
|
|
77148980e0 | ||
|
|
b3d2e82025 | ||
|
|
b25b8cc805 | ||
|
|
8141a01ef7 | ||
|
|
a2f10857e2 | ||
|
|
aea04e5f7c | ||
|
|
60c80611ea | ||
|
|
b1ed3ce55f | ||
|
|
040ed2701c | ||
|
|
00d8e551db | ||
|
|
3e9c99f5f8 | ||
|
|
02bdc4cf04 | ||
|
|
5c43965f0b | ||
|
|
b2376ecc30 | ||
|
|
aeaa6deeb4 | ||
|
|
448e378dc4 | ||
|
|
ac2249f256 | ||
|
|
05932c5a36 | ||
|
|
6f46cdb4ed | ||
|
|
5f527a00cf | ||
|
|
1935db1019 | ||
|
|
1f515e7be5 | ||
|
|
1a5f92021f | ||
|
|
f3c7413f52 | ||
|
|
646db90585 | ||
|
|
1f8a0cf9ab |
32
.github/ISSUE_TEMPLATE/1-bug-report-scripts.md
vendored
32
.github/ISSUE_TEMPLATE/1-bug-report-scripts.md
vendored
@@ -11,9 +11,11 @@ Please fill in as much of the template below as you're able.
|
||||
As a small open source project with small community, it can sometimes take a long time for issues to be addressed so please be patient.
|
||||
-->
|
||||
|
||||
### Describe the bug
|
||||
### Description
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
<!--
|
||||
A clear and concise description of what the bug is.
|
||||
-->
|
||||
|
||||
### OS
|
||||
|
||||
@@ -23,14 +25,32 @@ On Windows you can find it using "Start button" > "Settings" > "System" > "About
|
||||
On macOS you can find it using "Apple menu (top left corner)" > "About This Mac".
|
||||
-->
|
||||
|
||||
### Screenshots
|
||||
### Reproduction steps
|
||||
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
<!--
|
||||
How can the bug be recreated?
|
||||
It's the most important information in the bug report. Bugs that cannot be reproduced cannot be fixed and verified.
|
||||
E.g.
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
-->
|
||||
|
||||
### Scripts
|
||||
|
||||
<!-- Which scripts did you execute? If applicable, please paste the executed scripts or attach the generated privacy.sexy file . -->
|
||||
<!--
|
||||
If applicable, please attach the generated privacy.sexy file instead of copy pasting which becomes too long.
|
||||
-->
|
||||
|
||||
### Screenshots
|
||||
|
||||
<!--
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
-->
|
||||
|
||||
### Additional information
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
<!--
|
||||
If applicable, add any other context about the problem here.
|
||||
-->
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/2-bug-report-generic.md
vendored
17
.github/ISSUE_TEMPLATE/2-bug-report-generic.md
vendored
@@ -11,13 +11,16 @@ Please fill in as much of the template below as you're able.
|
||||
As a small open source project with small community, it can sometimes take a long time for issues to be addressed so please be patient.
|
||||
-->
|
||||
|
||||
### Describe the bug
|
||||
### Description
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
<!--
|
||||
A clear and concise description of what the bug is.
|
||||
-->
|
||||
|
||||
### To Reproduce
|
||||
### Reproduction steps
|
||||
|
||||
<!--
|
||||
<!--
|
||||
It's the most important information in the bug report. Bugs that cannot be reproduced cannot be fixed and verified.
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
@@ -41,12 +44,12 @@ If applicable, add screenshots to help explain your problem.
|
||||
|
||||
<!--
|
||||
If applicable, mention how you were using privacy.sexy when the bug was encountered:
|
||||
- Web (on Desktop or mobile?)
|
||||
- Or desktop (Windows, macOS or Linux?)
|
||||
- Web (on Desktop or mobile?)
|
||||
- Or desktop (Windows, macOS or Linux?)
|
||||
-->
|
||||
|
||||
### Additional context
|
||||
|
||||
<!--
|
||||
Add any other context about the problem here.
|
||||
If applicable, add any other context about the problem here.
|
||||
-->
|
||||
|
||||
36
.github/ISSUE_TEMPLATE/3-feature-request.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/3-feature-request.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for privacy.sexy
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
<!--
|
||||
Thank you for suggesting an idea to improve privacy better 🤗.
|
||||
Please fill in as much of the template below as you're able.
|
||||
-->
|
||||
|
||||
### Problem description
|
||||
|
||||
<!--
|
||||
What are we trying to solve?
|
||||
Please add a clear and concise description of the problem you are seeking to solve with this feature request.
|
||||
E.g. I'm always frustrated when [...]
|
||||
-->
|
||||
|
||||
### Proposed solution
|
||||
|
||||
<!--
|
||||
Describe the solution you'd like in a clear and concise manner.
|
||||
-->
|
||||
|
||||
### Alternatives considered
|
||||
|
||||
<!--
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
-->
|
||||
|
||||
### Additional information
|
||||
|
||||
<!--
|
||||
If applicable, add any other context or screenshots about the feature request here.
|
||||
-->
|
||||
27
.github/ISSUE_TEMPLATE/3-feature_request.md
vendored
27
.github/ISSUE_TEMPLATE/3-feature_request.md
vendored
@@ -1,27 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for privacy.sexy
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
<!--
|
||||
Thank you for suggesting an idea to make privacy better. 🤗
|
||||
|
||||
Please fill in as much of the template below as you're able.
|
||||
-->
|
||||
|
||||
### Problem Description
|
||||
|
||||
<!-- Please add a clear and concise description of the problem you are seeking to solve with this feature request. Ex. I'm always frustrated when [...] -->
|
||||
|
||||
### Proposed solution
|
||||
|
||||
<!-- Describe the solution you'd like in a clear and concise manner. -->
|
||||
|
||||
### Alternatives considered
|
||||
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
### Additional information
|
||||
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
73
.github/ISSUE_TEMPLATE/4-new-script-suggestion.md
vendored
Normal file
73
.github/ISSUE_TEMPLATE/4-new-script-suggestion.md
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
name: New script suggestion
|
||||
about: Suggest a new script for privacy.sexy
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
<!--
|
||||
Thank you for suggesting an script to make privacy better. 🤗
|
||||
Please fill in as much of the template below as you're able.
|
||||
You could alternatively send a PR directly (see CONTRIBUTING.md).
|
||||
-->
|
||||
|
||||
### OS
|
||||
|
||||
<!--
|
||||
Which OS will the new script configure?
|
||||
Either "Windows" or "macOS".
|
||||
-->
|
||||
|
||||
### Name
|
||||
|
||||
<!--
|
||||
The name of the script.
|
||||
It should start with an imperative noun such as "disable", "turn off" , "clear"...
|
||||
E.g. "Disable webcam telemetry"
|
||||
-->
|
||||
|
||||
### Script code
|
||||
|
||||
<!--
|
||||
Code that will be executed when script is selected.
|
||||
Try to keep it as simple and backwards-compatible as possible.
|
||||
Allowed languages:
|
||||
- macOS: bash (sh)
|
||||
- Windows: PowerShell (ps1) or batchfile
|
||||
- 💡 Prioritize the one that's simpler, batchfile if similar.
|
||||
-->
|
||||
|
||||
### Revert code
|
||||
|
||||
<!--
|
||||
If applicable, add code that will revert the script code to its original (OS default) state.
|
||||
It may require additional time, but it's much appreciated by the community.
|
||||
Leave blank if the script is nonreversible (e.g. when clearing data without backup).
|
||||
-->
|
||||
|
||||
### Suggested category
|
||||
|
||||
<!--
|
||||
If applicable, suggest one more multiple suitable parent category of script.
|
||||
A category is the item where the script will be presented under.
|
||||
Most likely there already is a category for the script, so check the existing categories.
|
||||
If you're unsure, leave blank and maintainer(s) will choose one.
|
||||
-->
|
||||
|
||||
### Suggested recommendation level
|
||||
|
||||
<!--
|
||||
If applicable, suggest recommending the script or not recommending at all.
|
||||
A script should be only recommended if it'll be safe for your grandmother to run.
|
||||
So you have three options here:
|
||||
STANDARD: Non-breaking scripts that does not limit any functionality.
|
||||
STRICT: Scripts that can break certain functionality but not intrusive to common daily OS usage.
|
||||
NONE: Script is not recommended for newbies at all, only those who knows what's going on should select it.
|
||||
If you're unsure, leave blank and maintainer(s) will choose one.
|
||||
-->
|
||||
|
||||
### Additional documentation/references
|
||||
|
||||
<!--
|
||||
If applicable, refer to documentation that should show up on the script description.
|
||||
Sources (URLs) should be as high quality as possible e.g. vendor documentation is favored over user forums.
|
||||
-->
|
||||
4
.github/workflows/deploy-desktop.yaml
vendored
4
.github/workflows/deploy-desktop.yaml
vendored
@@ -26,7 +26,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run tests
|
||||
run: npm run test:unit
|
||||
run: |
|
||||
npm run test:unit
|
||||
npm run test:integration
|
||||
- name: Publish desktop app
|
||||
run: npm run electron:build -- -p always # https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#upload-release-to-github
|
||||
env:
|
||||
|
||||
4
.github/workflows/deploy-site.yaml
vendored
4
.github/workflows/deploy-site.yaml
vendored
@@ -90,7 +90,9 @@ jobs:
|
||||
working-directory: site
|
||||
-
|
||||
name: "App: Run tests"
|
||||
run: npm run test:unit
|
||||
run: |
|
||||
npm run test:unit
|
||||
npm run test:integration
|
||||
working-directory: site
|
||||
-
|
||||
name: "App: Build"
|
||||
|
||||
1
.github/workflows/quality-checks.yaml
vendored
1
.github/workflows/quality-checks.yaml
vendored
@@ -13,6 +13,7 @@ jobs:
|
||||
- npm run lint:md
|
||||
- npm run lint:md:relative-urls
|
||||
- npm run lint:md:consistency
|
||||
fail-fast: false # So it continues with other commands if one fails
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
2
.github/workflows/security-checks.yaml
vendored
2
.github/workflows/security-checks.yaml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
pull_request:
|
||||
paths: [ '/package.json', '/package-lock.json' ] # Allow PRs to be green if they do not introduce dependency change
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
- cron: '0 0 * * 0' # at 00:00 on every Sunday
|
||||
|
||||
jobs:
|
||||
npm-audit:
|
||||
|
||||
12
.github/workflows/test.yaml
vendored
12
.github/workflows/test.yaml
vendored
@@ -1,12 +1,17 @@
|
||||
name: Test
|
||||
|
||||
on: [ push, pull_request ]
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule: # for integration tests
|
||||
- cron: '0 0 * * 0' # at 00:00 on every Sunday
|
||||
|
||||
jobs:
|
||||
run-tests:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos, ubuntu, windows]
|
||||
fail-fast: false # So it still runs on other OSes if one of them fails
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
steps:
|
||||
-
|
||||
@@ -21,5 +26,8 @@ jobs:
|
||||
name: Install dependencies
|
||||
run: npm ci
|
||||
-
|
||||
name: Run tests
|
||||
name: Run unit tests
|
||||
run: npm run test:unit
|
||||
-
|
||||
name: Run integration tests
|
||||
run: npm run test:integration
|
||||
|
||||
47
CHANGELOG.md
47
CHANGELOG.md
@@ -1,5 +1,52 @@
|
||||
# Changelog
|
||||
|
||||
## 0.10.2 (2021-04-19)
|
||||
|
||||
* in CI/CD, run other tests/check even if one of them fails | [5c43965](https://github.com/undergroundwires/privacy.sexy/commit/5c43965f0bc44f991ada7d3bad68937a80665dc3)
|
||||
* fix desktop initial window size being bigger than current display size on smaller Linux/Windows screens | [02bdc4c](https://github.com/undergroundwires/privacy.sexy/commit/02bdc4cf0426c452f3fc9af52b819ca9b0757290)
|
||||
* refactor extra code, duplicates, complexity | [00d8e55](https://github.com/undergroundwires/privacy.sexy/commit/00d8e551db001247fadfb6f6af7a4c5ce19a9e64)
|
||||
* improve disabling ads and marketing #65 | [040ed27](https://github.com/undergroundwires/privacy.sexy/commit/040ed2701c4a468749901f4c5369b221bc0973c4)
|
||||
* document breaking behavior in script name #64 | [b1ed3ce](https://github.com/undergroundwires/privacy.sexy/commit/b1ed3ce55f2d003cad1ead23e674aa66d4eb5802)
|
||||
* add module alias '@tests/' | [60c8061](https://github.com/undergroundwires/privacy.sexy/commit/60c80611eab227791fabb883caf93418cef5fd00)
|
||||
* document chromium warning for policy changes | [aea04e5](https://github.com/undergroundwires/privacy.sexy/commit/aea04e5f7cd48fbb9b407b68ade75575a6064c82)
|
||||
* fix script revert activating recommendation level | [a2f1085](https://github.com/undergroundwires/privacy.sexy/commit/a2f10857e2a8debb3ce01f79b0dfbe8649ea9a17)
|
||||
* fix typo and dead URL in Windows scripts (#70) | [8141a01](https://github.com/undergroundwires/privacy.sexy/commit/8141a01ef798331b4d82f5ca95f7b18df4f6f912)
|
||||
* fix vue warning for undefined property during render | [b25b8cc](https://github.com/undergroundwires/privacy.sexy/commit/b25b8cc8052655af70b0695c6c3085974d783bb6)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.10.1...0.10.2)
|
||||
|
||||
## 0.10.1 (2021-03-25)
|
||||
|
||||
* refactor script compilation to make it easy to add new expressions #41 #53 | [646db90](https://github.com/undergroundwires/privacy.sexy/commit/646db9058541cebd0af437554de04fdc6bb63a6e)
|
||||
* restructure presentation layer | [f3c7413](https://github.com/undergroundwires/privacy.sexy/commit/f3c7413f529be4a00dba7b0ab23904b48ea13a35)
|
||||
* fix a test where "it" is not used inside "describe" | [1a5f920](https://github.com/undergroundwires/privacy.sexy/commit/1a5f92021f7423cd039f8f5326cd6f99b355c962)
|
||||
* bump dependencies to latest | [1f515e7](https://github.com/undergroundwires/privacy.sexy/commit/1f515e7be525291c960ccb71db05312db6da53f5)
|
||||
* fix throttle function not being able to run with argument(s) | [1935db1](https://github.com/undergroundwires/privacy.sexy/commit/1935db10192051401ab00ca2cd767955d0d3b866)
|
||||
* fix fs module hanging not allowing code to run | [5f527a0](https://github.com/undergroundwires/privacy.sexy/commit/5f527a00cf225d3e74b3f6577d6e2456e919de24)
|
||||
* refactor all modals to use same dialog component | [6f46cdb](https://github.com/undergroundwires/privacy.sexy/commit/6f46cdb4ed49a8941c6c0dde5c5e2a816c06daef)
|
||||
* fix safari cleanup scripts that are not working on modern versions | [05932c5](https://github.com/undergroundwires/privacy.sexy/commit/05932c5a36446d551c5bc811165e3295fbe15e3f)
|
||||
* refactor features to use shared functions #41 | [ac2249f](https://github.com/undergroundwires/privacy.sexy/commit/ac2249f25664827d8a6d2c7ebd659ccf126b0cde)
|
||||
* increase performance by polyfilling ResizeObserver only if required | [448e378](https://github.com/undergroundwires/privacy.sexy/commit/448e378dc4501f9de69af63634c87d0e5060bf52)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.10.0...0.10.1)
|
||||
|
||||
## 0.10.0 (2021-03-02)
|
||||
|
||||
* allow functions to call other functions #53 | [7661575](https://github.com/undergroundwires/privacy.sexy/commit/7661575573c6d3e8f4bc28bfa7a124a764c72ef9)
|
||||
* add option to run script directly in desktop app | [9a6b903](https://github.com/undergroundwires/privacy.sexy/commit/9a6b903b9297802845043fd41115756acd4a145c)
|
||||
* add script to automatically kill devicecensus process | [c9b91f6](https://github.com/undergroundwires/privacy.sexy/commit/c9b91f6d8f9bd16308b6beda119e7154a985b6cf)
|
||||
* refactor disabling application experience and document better | [45a3669](https://github.com/undergroundwires/privacy.sexy/commit/45a3669443d82855a52f60524d341c15f380f9e7)
|
||||
* escape printed characters to prevent command injection #45 | [1260eea](https://github.com/undergroundwires/privacy.sexy/commit/1260eea690e4fa5420e58c9de9f88cc29cb242db)
|
||||
* move code area to right on bigger screens | [cf39e6d](https://github.com/undergroundwires/privacy.sexy/commit/cf39e6d2541ea547f41d9553c380c54c24c58038)
|
||||
* more scripts to disable speech recognition and Cortana | [ee43fd9](https://github.com/undergroundwires/privacy.sexy/commit/ee43fd92a019ebd26c13890f9146c5b5bb56afaf)
|
||||
* add more macos scripts for privacy cleanup | [b0a7d0b](https://github.com/undergroundwires/privacy.sexy/commit/b0a7d0b53b3d8ac144a0241d70c037f460b0c0cc)
|
||||
* add better error messages to setting vscode settings | [65226f3](https://github.com/undergroundwires/privacy.sexy/commit/65226f3984480d0bc7932fd8d76a328f08308850)
|
||||
* remove windows scripts for removing non-bloating system apps #55 | [15004ff](https://github.com/undergroundwires/privacy.sexy/commit/15004ff1f1fb85a1d92e11ef695bcb2f37110610)
|
||||
* remove "preview" disclaimer from macOS | [970221b](https://github.com/undergroundwires/privacy.sexy/commit/970221b996e25fe5b029cbaa78607c9bbc8c3c0e)
|
||||
* update screenshot | [bd41af4](https://github.com/undergroundwires/privacy.sexy/commit/bd41af466fd135f7dc2f171633e4f60d8547c373)
|
||||
|
||||
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.9.2...0.10.0)
|
||||
|
||||
## 0.9.2 (2021-02-13)
|
||||
|
||||
* do not compile with unused locals vuejs/vetur#1063 | [73e0520](https://github.com/undergroundwires/privacy.sexy/commit/73e0520de70cdbaf0ecdc6e9be5e85f003fcfb79)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
- Proposing new features
|
||||
- Becoming a maintainer
|
||||
|
||||
## Pull Request Process
|
||||
## Pull request process
|
||||
|
||||
- [GitHub flow](https://guides.github.com/introduction/flow/index.html) is used
|
||||
- [GitHub flow](https://guides.github.com/introduction/flow/index.html) with [GitOps](./img/architecture/gitops.png) is used
|
||||
- Your pull requests are actively welcomed.
|
||||
- The steps:
|
||||
1. Fork the repo and create your branch from master.
|
||||
@@ -25,4 +25,10 @@
|
||||
|
||||
## License
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under its GNU General Public License v3.0.
|
||||
By contributing, you agree that your contributions will be licensed under its [GNU General Public License v3.0](./LICENSE).
|
||||
|
||||
## Read more
|
||||
|
||||
- See [tests](./docs/tests.md) for testing
|
||||
- See [extend script](./README.md#extend-scripts) for quick steps to extend scripts
|
||||
- See [architecture overview](./README.md#architecture-overview) to deep dive into privacy.sexy codebase
|
||||
|
||||
19
README.md
19
README.md
@@ -16,7 +16,7 @@
|
||||
|
||||
- Online version at [https://privacy.sexy](https://privacy.sexy)
|
||||
- 💡 No need to run any compiled software on your computer.
|
||||
- Alternatively download offline version for [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.9.2/privacy.sexy-Setup-0.9.2.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.9.2/privacy.sexy-0.9.2.dmg) or [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.9.2/privacy.sexy-0.9.2.AppImage).
|
||||
- Alternatively download offline version for [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.10.2/privacy.sexy-Setup-0.10.2.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.10.2/privacy.sexy-0.10.2.dmg) or [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.10.2/privacy.sexy-0.10.2.AppImage).
|
||||
- 💡 Single click to execute your script.
|
||||
- ❗ Come back regularly to apply latest version for stronger privacy and security.
|
||||
|
||||
@@ -34,17 +34,20 @@
|
||||
|
||||
## Extend scripts
|
||||
|
||||
1. Fork the repository
|
||||
2. Add more scripts in respective script collection in [collections](src/application/collections/) folder.
|
||||
- 📖 If you're unsure about the syntax you can refer to the [collection files | documentation](docs/collection-files.md).
|
||||
- 🙏 For any new script, please add `revertCode` and `docs` values if possible.
|
||||
3. Send a pull request 👌
|
||||
- You can either [create an issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose)
|
||||
- Or send a PR:
|
||||
1. Fork the repository
|
||||
2. Add more scripts in respective script collection in [collections](src/application/collections/) folder.
|
||||
- 📖 If you're unsure about the syntax you can refer to the [collection files | documentation](docs/collection-files.md).
|
||||
- 🙏 For any new script, please add `revertCode` and `docs` values if possible.
|
||||
3. Send a pull request 👌
|
||||
|
||||
## Commands
|
||||
|
||||
- Project setup: `npm install`
|
||||
- Testing
|
||||
- Run unit tests: `npm run test:unit`
|
||||
- Run integration tests: `npm run test:integration`
|
||||
- Lint: `npm run lint`
|
||||
- **Desktop app**
|
||||
- Development: `npm run electron:serve`
|
||||
@@ -53,8 +56,8 @@
|
||||
- Development: `npm run serve` to compile & hot-reload for development.
|
||||
- Production: `npm run build` to prepare files for distribution.
|
||||
- Or run using Docker:
|
||||
1. Build: `docker build -t undergroundwires/privacy.sexy:0.9.2 .`
|
||||
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.9.2 undergroundwires/privacy.sexy:0.9.2`
|
||||
1. Build: `docker build -t undergroundwires/privacy.sexy:0.10.2 .`
|
||||
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.10.2 undergroundwires/privacy.sexy:0.10.2`
|
||||
|
||||
## Architecture overview
|
||||
|
||||
|
||||
@@ -2,7 +2,15 @@
|
||||
|
||||
- It's mainly responsible for
|
||||
- creating and event based [application state](#application-state)
|
||||
- parsing and compiling [application data](#application-data)
|
||||
- [parsing](#parsing) and [compiling](#compiling) [application data](#application-data)
|
||||
- Consumed by [presentation layer](./presentation.md)
|
||||
|
||||
## Structure
|
||||
|
||||
- [`/src/` **`application/`**](./../src/application/): Contains all application related code.
|
||||
- [**`collections/`**](./../src/application/collections/): Holds [collection files](./collection-files.md)
|
||||
- [**`Common/`**](./../src/application/Common/): Contains common functionality that is shared in application layer.
|
||||
- `..`: other classes are categorized using folders-by-feature structure
|
||||
|
||||
## Application state
|
||||
|
||||
@@ -14,9 +22,23 @@
|
||||
|
||||
## Application data
|
||||
|
||||
- Compiled to `Application` domain object.
|
||||
- Compiled to [`Application`](./../src/domain/Application.ts) domain object.
|
||||
- The scripts are defined and controlled in different data files per OS
|
||||
- Enables [data-driven programming](https://en.wikipedia.org/wiki/Data-driven_programming) and easier contributions
|
||||
- Application data is defined in collection files and
|
||||
- 📖 See [Application data | Presentation layer](./presentation.md#application-data) to read how the application data is read by the presentation layer.
|
||||
- 📖 See [collection files documentation](./collection-files.md) to read more about how the data files are structured/defined and see [collection yaml files](./../src/application/collections/) to directly check the code.
|
||||
|
||||
## Parsing
|
||||
|
||||
- Application data is parsed to domain object [`Application.ts`](./../src/domain/Application.ts)
|
||||
- Steps
|
||||
1. (Compile time) Load application data from [collection yaml files](./../src/application/collections/) using webpack loader
|
||||
2. (Runtime) Parse and compile application and make it available to presentation layer by [`ApplicationFactory.ts`](./../src/application/ApplicationFactory.ts)
|
||||
|
||||
### Compiling
|
||||
|
||||
- Parsing the application files includes compiling scripts using [collection file defined functions](./collection-files.md#function)
|
||||
- To extend the syntax:
|
||||
1. Add a new parser under [SyntaxParsers](./../src/application/Parser/Script/Compiler/Expressions/SyntaxParsers) where you can look at other parsers to understand more.
|
||||
2. Register your in [CompositeExpressionParser](./../src/application/Parser/Script/Compiler/Expressions/Parser/CompositeExpressionParser.ts)
|
||||
|
||||
@@ -4,6 +4,20 @@
|
||||
- Desktop application is created using [Electron](https://www.electronjs.org/).
|
||||
- Event driven as in components simply listens to events from the state and act accordingly.
|
||||
|
||||
## Structure
|
||||
|
||||
- [`/src/` **`presentation/`**](./../src/presentation/): Contains all presentation related code including Vue and Electron configurations
|
||||
- [**`bootstrapping/`**](./../src/presentation/bootstrapping/): Registers Vue global objects including components and plugins.
|
||||
- [**`components/`**](./../src/presentation/components/): Contains all Vue components and their helper classes.
|
||||
- [**`Shared/`**](./../src/presentation/components/Shared): Contains Vue components and component helpers that are shared across other components.
|
||||
- [**`styles/`**](./../src/presentation/styles/): Contains shared styles used throughout different components.
|
||||
- [**`main.ts`**](./../src/presentation/main.ts): Application entry point that mounts and starts Vue application.
|
||||
- [**`background.ts`**](./../src/presentation/background.ts): Main process of Electron, started as first thing when app starts.
|
||||
- [**`/public/`**](./../public/): Contains static assets that will simply be copied and not go through webpack.
|
||||
- [**`/vue.config.js`**](./../vue.config.js): Global Vue CLI configurations loaded by `@vue/cli-service`
|
||||
- [**`/postcss.config.js`**](./../postcss.config.js): PostCSS configurations that are used by Vue CLI internally
|
||||
- [**`/babel.config.js`**](./../babel.config.js): Babel configurations for polyfills used by `@vue/cli-plugin-babel`
|
||||
|
||||
## Application data
|
||||
|
||||
- Components and should use [ApplicationFactory](./../src/application/ApplicationFactory.ts) singleton to reach the application domain.
|
||||
@@ -16,9 +30,22 @@
|
||||
|
||||
- Stateful components mutate or/and react to state changes in [ApplicationContext](./../src/application/Context/ApplicationContext.ts).
|
||||
- Stateless components that does not handle state extends `Vue`
|
||||
- Stateful components that depends on the collection state such as user selection, search queries and more extends [`StatefulVue`](./../src/presentation/StatefulVue.ts)
|
||||
- The single source of truth is a singleton of the state created and made available to presentation layer by [`StatefulVue`](./../src/presentation/StatefulVue.ts)
|
||||
- Stateful components that depends on the collection state such as user selection, search queries and more extends [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts)
|
||||
- The single source of truth is a singleton of the state created and made available to presentation layer by [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts)
|
||||
- `StatefulVue` includes abstract `handleCollectionState` that is fired once the component is loaded and also each time [collection](./collection-files.md) is changed.
|
||||
- Do not forget to subscribe from events when component is destroyed or if needed [collection](./collection-files.md) is changed.
|
||||
- 💡 `events` in base class [`StatefulVue`](./../src/presentation/StatefulVue.ts) makes lifecycling easier
|
||||
- 💡 `events` in base class [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts) makes lifecycling easier
|
||||
- 📖 See [Application state | Application layer](./presentation.md#application-state) where the state is implemented using using state pattern.
|
||||
|
||||
## Modals
|
||||
|
||||
- [Dialog.vue](./../src/presentation/components/Shared/Dialog.vue) is a shared component that can be used to show modal windows
|
||||
- Simply wrap the content inside of its slot and call `.show()` method on its reference.
|
||||
- Example:
|
||||
|
||||
```html
|
||||
<Dialog ref="testDialog">
|
||||
<div>Hello world</div>
|
||||
</Dialog>
|
||||
<div @click="$refs.testDialog.show()">Show dialog</div>
|
||||
```
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
# Unit tests
|
||||
# Tests
|
||||
|
||||
- Unit tests are defined in [`./tests`](./../tests)
|
||||
- There are two different types of tests executed:
|
||||
1. [Unit tests](#unit-tests)
|
||||
2. [Integration tests](#integration-tests)
|
||||
- 💡 You can use path/module alias `@/tests` in import statements.
|
||||
|
||||
## Unit tests
|
||||
|
||||
- Tests each component in isolation
|
||||
- Defined in [`./tests/unit`](./../tests/unit)
|
||||
- They follow same folder structure as [`./src`](./../src)
|
||||
|
||||
## Naming
|
||||
### Naming
|
||||
|
||||
- Each test suite first describe the system under test
|
||||
- E.g. tests for class `Application` is categorized under `Application`
|
||||
- Tests for specific methods are categorized under method name (if applicable)
|
||||
- E.g. test for `run()` is categorized under `run`
|
||||
|
||||
## Act, arrange, assert
|
||||
### Act, arrange, assert
|
||||
|
||||
- Tests use act, arrange and assert (AAA) pattern when applicable
|
||||
- **Arrange**
|
||||
@@ -23,7 +31,13 @@
|
||||
- Should elicit some sort of response
|
||||
- Starts with comment line `// assert`
|
||||
|
||||
## Stubs
|
||||
### Stubs
|
||||
|
||||
- Stubs are defined in [`./tests/stubs`](./../tests/unit/stubs)
|
||||
- They implement dummy behavior to be functional
|
||||
|
||||
## Integration tests
|
||||
|
||||
- Tests functionality of a component in combination with others (not isolated)
|
||||
- Ensure dependencies to third parties work as expected
|
||||
- Defined in [`./tests/integration`](./../tests/integration)
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 483 KiB After Width: | Height: | Size: 579 KiB |
23363
package-lock.json
generated
23363
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
61
package.json
61
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "privacy.sexy",
|
||||
"version": "0.9.2",
|
||||
"version": "0.10.2",
|
||||
"private": true,
|
||||
"description": "Enforce privacy & security best-practices on Windows and macOS, because privacy is sexy 🍑🍆",
|
||||
"author": "undergroundwires",
|
||||
@@ -8,6 +8,7 @@
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit",
|
||||
"test:integration": "vue-cli-service test:unit \"tests/integration/**/*.spec.ts\"",
|
||||
"lint": "npm run lint:vue && npm run lint:yaml && npm run lint:md && npm run lint:md:relative-urls && npm run lint:md:consistency",
|
||||
"electron:build": "vue-cli-service electron:build",
|
||||
"electron:serve": "vue-cli-service electron:serve",
|
||||
@@ -21,48 +22,50 @@
|
||||
},
|
||||
"main": "background.js",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.32",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.3",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.3",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.3",
|
||||
"@fortawesome/vue-fontawesome": "^2.0.2",
|
||||
"@juggle/resize-observer": "^3.3.1",
|
||||
"ace-builds": "^1.4.12",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js": "^3.12.1",
|
||||
"cross-fetch": "^3.1.4",
|
||||
"file-saver": "^2.0.5",
|
||||
"inversify": "^5.0.5",
|
||||
"inversify": "^5.1.1",
|
||||
"liquor-tree": "^0.2.70",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"v-tooltip": "2.0.2",
|
||||
"v-tooltip": "2.1.3",
|
||||
"vue": "^2.6.12",
|
||||
"vue-class-component": "^7.2.6",
|
||||
"vue-js-modal": "^2.0.0-rc.6",
|
||||
"vue-property-decorator": "^9.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ace": "0.0.44",
|
||||
"@types/chai": "^4.2.14",
|
||||
"@types/file-saver": "^2.0.1",
|
||||
"@types/mocha": "^8.2.0",
|
||||
"@vue/cli-plugin-babel": "^4.5.10",
|
||||
"@vue/cli-plugin-typescript": "^4.5.9",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.5.9",
|
||||
"@vue/cli-service": "^4.5.9",
|
||||
"@vue/test-utils": "1.1.2",
|
||||
"chai": "^4.2.0",
|
||||
"electron": "^11.1.0",
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"electron-log": "^4.3.1",
|
||||
"electron-updater": "^4.3.5",
|
||||
"@types/ace": "0.0.45",
|
||||
"@types/chai": "^4.2.18",
|
||||
"@types/file-saver": "^2.0.2",
|
||||
"@types/mocha": "^8.2.2",
|
||||
"@vue/cli-plugin-babel": "^4.5.13",
|
||||
"@vue/cli-plugin-typescript": "^4.5.13",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.5.13",
|
||||
"@vue/cli-service": "^4.5.13",
|
||||
"@vue/test-utils": "1.2.0",
|
||||
"chai": "^4.3.4",
|
||||
"electron": "^12.0.7",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-log": "^4.3.5",
|
||||
"electron-updater": "^4.3.8",
|
||||
"js-yaml-loader": "^1.2.2",
|
||||
"markdownlint-cli": "^0.26.0",
|
||||
"markdownlint-cli": "^0.27.1",
|
||||
"remark-cli": "^9.0.0",
|
||||
"remark-lint-no-dead-urls": "^1.1.0",
|
||||
"remark-preset-lint-consistent": "^4.0.0",
|
||||
"remark-validate-links": "^10.0.2",
|
||||
"sass": "^1.30.0",
|
||||
"sass-loader": "^10.1.0",
|
||||
"typescript": "^4.1.3",
|
||||
"vue-cli-plugin-electron-builder": "^2.0.0-rc.5",
|
||||
"remark-validate-links": "^10.0.4",
|
||||
"sass": "^1.32.12",
|
||||
"sass-loader": "^10.0.1",
|
||||
"tslib": "^2.2.0",
|
||||
"typescript": "^4.2.4",
|
||||
"vue-cli-plugin-electron-builder": "^2.0.0-rc.6",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"yaml-lint": "^1.2.4"
|
||||
},
|
||||
|
||||
21
src/application/Common/Array.ts
Normal file
21
src/application/Common/Array.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
// Compares to Array<T> objects for equality, ignoring order
|
||||
export function scrambledEqual<T>(array1: readonly T[], array2: readonly T[]) {
|
||||
if (!array1) { throw new Error('undefined first array'); }
|
||||
if (!array2) { throw new Error('undefined second array'); }
|
||||
const sortedArray1 = sort(array1);
|
||||
const sortedArray2 = sort(array2);
|
||||
return sequenceEqual(sortedArray1, sortedArray2);
|
||||
function sort(array: readonly T[]) {
|
||||
return array.slice().sort();
|
||||
}
|
||||
}
|
||||
|
||||
// Compares to Array<T> objects for equality in same order
|
||||
export function sequenceEqual<T>(array1: readonly T[], array2: readonly T[]) {
|
||||
if (!array1) { throw new Error('undefined first array'); }
|
||||
if (!array2) { throw new Error('undefined second array'); }
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
return array1.every((val, index) => val === array2[index]);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Because we cannot do "T extends enum" 😞 https://github.com/microsoft/TypeScript/issues/30611
|
||||
type EnumType = number | string;
|
||||
type EnumVariable<T extends EnumType, TEnumValue extends EnumType> = { [key in T]: TEnumValue };
|
||||
export type EnumType = number | string;
|
||||
export type EnumVariable<T extends EnumType, TEnumValue extends EnumType> = { [key in T]: TEnumValue };
|
||||
|
||||
export interface IEnumParser<TEnum> {
|
||||
parseEnum(value: string, propertyName: string): TEnum;
|
||||
@@ -41,3 +41,14 @@ export function getEnumValues<T extends EnumType, TEnumValue extends EnumType>(
|
||||
return getEnumNames(enumVariable)
|
||||
.map((level) => enumVariable[level]) as TEnumValue[];
|
||||
}
|
||||
|
||||
export function assertInRange<T extends EnumType, TEnumValue extends EnumType>(
|
||||
value: TEnumValue,
|
||||
enumVariable: EnumVariable<T, TEnumValue>) {
|
||||
if (value === undefined) {
|
||||
throw new Error('undefined enum value');
|
||||
}
|
||||
if (!(value in enumVariable)) {
|
||||
throw new RangeError(`enum value "${value}" is out of range`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
|
||||
export interface IScriptingLanguageFactory<T> {
|
||||
create(language: ScriptingLanguage): T;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { IScriptingLanguageFactory } from './IScriptingLanguageFactory';
|
||||
import { assertInRange } from '@/application/Common/Enum';
|
||||
|
||||
type Getter<T> = () => T;
|
||||
|
||||
export abstract class ScriptingLanguageFactory<T> implements IScriptingLanguageFactory<T> {
|
||||
private readonly getters = new Map<ScriptingLanguage, Getter<T>>();
|
||||
|
||||
public create(language: ScriptingLanguage): T {
|
||||
assertInRange(language, ScriptingLanguage);
|
||||
if (!this.getters.has(language)) {
|
||||
throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`);
|
||||
}
|
||||
const getter = this.getters.get(language);
|
||||
const instance = getter();
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected registerGetter(language: ScriptingLanguage, getter: Getter<T>) {
|
||||
assertInRange(language, ScriptingLanguage);
|
||||
if (!getter) {
|
||||
throw new Error('undefined getter');
|
||||
}
|
||||
if (this.getters.has(language)) {
|
||||
throw new Error(`${ScriptingLanguage[language]} is already registered`);
|
||||
}
|
||||
this.getters.set(language, getter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { IApplication } from '@/domain/IApplication';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||
import { EventSource } from '@/infrastructure/Events/EventSource';
|
||||
import { assertInRange } from '@/application/Common/Enum';
|
||||
|
||||
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
|
||||
|
||||
@@ -22,7 +23,7 @@ export class ApplicationContext implements IApplicationContext {
|
||||
public readonly app: IApplication,
|
||||
initialContext: OperatingSystem) {
|
||||
validateApp(app);
|
||||
validateOs(initialContext);
|
||||
assertInRange(initialContext, OperatingSystem);
|
||||
this.states = initializeStates(app);
|
||||
this.changeContext(initialContext);
|
||||
}
|
||||
@@ -50,18 +51,6 @@ function validateApp(app: IApplication) {
|
||||
}
|
||||
}
|
||||
|
||||
function validateOs(os: OperatingSystem) {
|
||||
if (os === undefined) {
|
||||
throw new Error('undefined os');
|
||||
}
|
||||
if (os === OperatingSystem.Unknown) {
|
||||
throw new Error('unknown os');
|
||||
}
|
||||
if (!(os in OperatingSystem)) {
|
||||
throw new Error(`os "${os}" is out of range`);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeStates(app: IApplication): StateMachine {
|
||||
const machine = new Map<OperatingSystem, ICategoryCollectionState>();
|
||||
for (const collection of app.collections) {
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { ICodeBuilder } from './ICodeBuilder';
|
||||
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
|
||||
import { BatchBuilder } from './Languages/BatchBuilder';
|
||||
import { ShellBuilder } from './Languages/ShellBuilder';
|
||||
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
|
||||
|
||||
export class CodeBuilderFactory implements ICodeBuilderFactory {
|
||||
public create(language: ScriptingLanguage): ICodeBuilder {
|
||||
switch (language) {
|
||||
case ScriptingLanguage.shellscript: return new ShellBuilder();
|
||||
case ScriptingLanguage.batchfile: return new BatchBuilder();
|
||||
default: throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`);
|
||||
}
|
||||
export class CodeBuilderFactory extends ScriptingLanguageFactory<ICodeBuilder> implements ICodeBuilderFactory {
|
||||
constructor() {
|
||||
super();
|
||||
this.registerGetter(ScriptingLanguage.shellscript, () => new ShellBuilder());
|
||||
this.registerGetter(ScriptingLanguage.batchfile, () => new BatchBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { ICodeBuilder } from './ICodeBuilder';
|
||||
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
|
||||
|
||||
export interface ICodeBuilderFactory {
|
||||
create(language: ScriptingLanguage): ICodeBuilder;
|
||||
export interface ICodeBuilderFactory extends IScriptingLanguageFactory<ICodeBuilder> {
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { IEventSource } from '@/infrastructure/Events/IEventSource';
|
||||
export interface IUserSelection {
|
||||
readonly changed: IEventSource<ReadonlyArray<SelectedScript>>;
|
||||
readonly selectedScripts: ReadonlyArray<SelectedScript>;
|
||||
readonly totalSelected: number;
|
||||
areAllSelected(category: ICategory): boolean;
|
||||
isAnySelected(category: ICategory): boolean;
|
||||
removeAllInCategory(categoryId: number): void;
|
||||
|
||||
@@ -101,10 +101,6 @@ export class UserSelection implements IUserSelection {
|
||||
return this.scripts.getItems();
|
||||
}
|
||||
|
||||
public get totalSelected(): number {
|
||||
return this.scripts.getItems().length;
|
||||
}
|
||||
|
||||
public selectAll(): void {
|
||||
for (const script of this.collection.getAllScripts()) {
|
||||
if (!this.scripts.exists(script.id)) {
|
||||
|
||||
@@ -4,17 +4,17 @@ import { IBrowserOsDetector } from './IBrowserOsDetector';
|
||||
|
||||
export class BrowserOsDetector implements IBrowserOsDetector {
|
||||
private readonly detectors = BrowserDetectors;
|
||||
public detect(userAgent: string): OperatingSystem {
|
||||
public detect(userAgent: string): OperatingSystem | undefined {
|
||||
if (!userAgent) {
|
||||
return OperatingSystem.Unknown;
|
||||
return undefined;
|
||||
}
|
||||
for (const detector of this.detectors) {
|
||||
const os = detector.detect(userAgent);
|
||||
if (os !== OperatingSystem.Unknown) {
|
||||
if (os !== undefined) {
|
||||
return os;
|
||||
}
|
||||
}
|
||||
return OperatingSystem.Unknown;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ export class DetectorBuilder {
|
||||
throw new Error('User agent is null or undefined');
|
||||
}
|
||||
if (this.existingPartsInUserAgent.some((part) => !userAgent.includes(part))) {
|
||||
return OperatingSystem.Unknown;
|
||||
return undefined;
|
||||
}
|
||||
if (this.notExistingPartsInUserAgent.some((part) => userAgent.includes(part))) {
|
||||
return OperatingSystem.Unknown;
|
||||
return undefined;
|
||||
}
|
||||
return this.os;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
|
||||
export interface IBrowserOsDetector {
|
||||
detect(userAgent: string): OperatingSystem;
|
||||
detect(userAgent: string): OperatingSystem | undefined;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function getProcessPlatform(variables: IEnvironmentVariables): string {
|
||||
return variables.process.platform;
|
||||
}
|
||||
|
||||
function getDesktopOsType(processPlatform: string): OperatingSystem {
|
||||
function getDesktopOsType(processPlatform: string): OperatingSystem | undefined {
|
||||
// https://nodejs.org/api/process.html#process_process_platform
|
||||
if (processPlatform === 'darwin') {
|
||||
return OperatingSystem.macOS;
|
||||
@@ -53,7 +53,7 @@ function getDesktopOsType(processPlatform: string): OperatingSystem {
|
||||
} else if (processPlatform === 'linux') {
|
||||
return OperatingSystem.Linux;
|
||||
}
|
||||
return OperatingSystem.Unknown;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isDesktop(variables: IEnvironmentVariables): boolean {
|
||||
|
||||
@@ -2,19 +2,20 @@ import { Category } from '@/domain/Category';
|
||||
import { CollectionData } from 'js-yaml-loader!@/*';
|
||||
import { parseCategory } from './CategoryParser';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { parseScriptingDefinition } from './ScriptingDefinitionParser';
|
||||
import { createEnumParser } from '../Common/Enum';
|
||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||
import { CategoryCollection } from '@/domain/CategoryCollection';
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext';
|
||||
import { ScriptingDefinitionParser } from './ScriptingDefinition/ScriptingDefinitionParser';
|
||||
|
||||
export function parseCategoryCollection(
|
||||
content: CollectionData,
|
||||
info: IProjectInformation,
|
||||
osParser = createEnumParser(OperatingSystem)): ICategoryCollection {
|
||||
validate(content);
|
||||
const scripting = parseScriptingDefinition(content.scripting, info);
|
||||
const scripting = new ScriptingDefinitionParser()
|
||||
.parse(content.scripting, info);
|
||||
const context = new CategoryCollectionParseContext(content.functions, scripting);
|
||||
const categories = new Array<Category>();
|
||||
for (const action of content.actions) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||
import { ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
import { FunctionData } from 'js-yaml-loader!*';
|
||||
import { FunctionData } from 'js-yaml-loader!@/*';
|
||||
import { IScriptCompiler } from './Compiler/IScriptCompiler';
|
||||
import { ScriptCompiler } from './Compiler/ScriptCompiler';
|
||||
import { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { ExpressionPosition } from './ExpressionPosition';
|
||||
import { ExpressionArguments, IExpression } from './IExpression';
|
||||
|
||||
export type ExpressionEvaluator = (args?: ExpressionArguments) => string;
|
||||
export class Expression implements IExpression {
|
||||
constructor(
|
||||
public readonly position: ExpressionPosition,
|
||||
public readonly evaluator: ExpressionEvaluator,
|
||||
public readonly parameters: readonly string[] = new Array<string>()) {
|
||||
if (!position) {
|
||||
throw new Error('undefined position');
|
||||
}
|
||||
if (!evaluator) {
|
||||
throw new Error('undefined evaluator');
|
||||
}
|
||||
}
|
||||
public evaluate(args?: ExpressionArguments): string {
|
||||
args = filterUnusedArguments(this.parameters, args);
|
||||
return this.evaluator(args);
|
||||
}
|
||||
}
|
||||
|
||||
function filterUnusedArguments(
|
||||
parameters: readonly string[], args: ExpressionArguments): ExpressionArguments {
|
||||
let result: ExpressionArguments = {};
|
||||
for (const parameter of Object.keys(args)) {
|
||||
if (parameters.includes(parameter)) {
|
||||
result = {
|
||||
...result,
|
||||
[parameter]: args[parameter],
|
||||
};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export class ExpressionPosition {
|
||||
constructor(
|
||||
public readonly start: number,
|
||||
public readonly end: number) {
|
||||
if (start === end) {
|
||||
throw new Error(`no length (start = end = ${start})`);
|
||||
}
|
||||
if (start > end) {
|
||||
throw Error(`start (${start}) after end (${end})`);
|
||||
}
|
||||
if (start < 0) {
|
||||
throw Error(`negative start position: ${start}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ExpressionPosition } from './ExpressionPosition';
|
||||
|
||||
export interface IExpression {
|
||||
readonly position: ExpressionPosition;
|
||||
readonly parameters?: readonly string[];
|
||||
evaluate(args?: ExpressionArguments): string;
|
||||
}
|
||||
|
||||
export interface ExpressionArguments {
|
||||
readonly [parameter: string]: string;
|
||||
}
|
||||
|
||||
@@ -1,31 +1,49 @@
|
||||
import { IExpressionsCompiler, ParameterValueDictionary } from './IExpressionsCompiler';
|
||||
import { generateIlCode, IILCode } from './ILCode';
|
||||
import { IExpression } from './Expression/IExpression';
|
||||
import { IExpressionParser } from './Parser/IExpressionParser';
|
||||
import { CompositeExpressionParser } from './Parser/CompositeExpressionParser';
|
||||
|
||||
export class ExpressionsCompiler implements IExpressionsCompiler {
|
||||
public static readonly instance: IExpressionsCompiler = new ExpressionsCompiler();
|
||||
protected constructor() { }
|
||||
public constructor(private readonly extractor: IExpressionParser = new CompositeExpressionParser()) { }
|
||||
public compileExpressions(code: string, parameters?: ParameterValueDictionary): string {
|
||||
let intermediateCode = generateIlCode(code);
|
||||
intermediateCode = substituteParameters(intermediateCode, parameters);
|
||||
return intermediateCode.compile();
|
||||
const expressions = this.extractor.findExpressions(code);
|
||||
const requiredParameterNames = expressions.map((e) => e.parameters).filter((p) => p).flat();
|
||||
const uniqueParameterNames = Array.from(new Set(requiredParameterNames));
|
||||
ensureRequiredArgsProvided(uniqueParameterNames, parameters);
|
||||
return compileExpressions(expressions, code, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
function substituteParameters(intermediateCode: IILCode, parameters: ParameterValueDictionary): IILCode {
|
||||
const parameterNames = intermediateCode.getUniqueParameterNames();
|
||||
ensureValuesProvided(parameterNames, parameters);
|
||||
for (const parameterName of parameterNames) {
|
||||
const parameterValue = parameters[parameterName];
|
||||
intermediateCode = intermediateCode.substituteParameter(parameterName, parameterValue);
|
||||
function compileExpressions(expressions: IExpression[], code: string, parameters?: ParameterValueDictionary) {
|
||||
let compiledCode = '';
|
||||
expressions = expressions
|
||||
.slice() // copy the array to not mutate the parameter
|
||||
.sort((a, b) => b.position.start - a.position.start);
|
||||
let index = 0;
|
||||
while (index !== code.length) {
|
||||
const nextExpression = expressions.pop();
|
||||
if (nextExpression) {
|
||||
compiledCode += code.substring(index, nextExpression.position.start);
|
||||
const expressionCode = nextExpression.evaluate(parameters);
|
||||
compiledCode += expressionCode;
|
||||
index = nextExpression.position.end;
|
||||
} else {
|
||||
compiledCode += code.substring(index, code.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return intermediateCode;
|
||||
return compiledCode;
|
||||
}
|
||||
|
||||
function ensureValuesProvided(names: string[], nameValues: ParameterValueDictionary) {
|
||||
nameValues = nameValues || {};
|
||||
const notProvidedNames = names.filter((name) => !Boolean(nameValues[name]));
|
||||
if (notProvidedNames.length) {
|
||||
throw new Error(`parameter value(s) not provided for: ${printList(notProvidedNames)}`);
|
||||
function ensureRequiredArgsProvided(parameters: readonly string[], args: ParameterValueDictionary) {
|
||||
parameters = parameters || [];
|
||||
args = args || {};
|
||||
if (!parameters.length) {
|
||||
return;
|
||||
}
|
||||
const notProvidedParameters = parameters.filter((parameter) => !Boolean(args[parameter]));
|
||||
if (notProvidedParameters.length) {
|
||||
throw new Error(`parameter value(s) not provided for: ${printList(notProvidedParameters)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
export interface IILCode {
|
||||
compile(): string;
|
||||
getUniqueParameterNames(): string[];
|
||||
substituteParameter(parameterName: string, parameterValue: string): IILCode;
|
||||
}
|
||||
|
||||
export function generateIlCode(rawText: string): IILCode {
|
||||
const ilCode = generateIl(rawText);
|
||||
return new ILCode(ilCode);
|
||||
}
|
||||
|
||||
class ILCode implements IILCode {
|
||||
private readonly ilCode: string;
|
||||
|
||||
constructor(ilCode: string) {
|
||||
this.ilCode = ilCode;
|
||||
}
|
||||
|
||||
public substituteParameter(parameterName: string, parameterValue: string): IILCode {
|
||||
const newCode = substituteParameter(this.ilCode, parameterName, parameterValue);
|
||||
return new ILCode(newCode);
|
||||
}
|
||||
|
||||
public getUniqueParameterNames(): string[] {
|
||||
return getUniqueParameterNames(this.ilCode);
|
||||
}
|
||||
|
||||
public compile(): string {
|
||||
ensureNoExpressionLeft(this.ilCode);
|
||||
return this.ilCode;
|
||||
}
|
||||
}
|
||||
|
||||
// Trim each expression and put them inside "{{exp|}}" e.g. "{{ $hello }}" becomes "{{exp|$hello}}"
|
||||
function generateIl(rawText: string): string {
|
||||
return rawText.replace(/\{\{([\s]*[^;\s\{]+[\s]*)\}\}/g, (_, match) => {
|
||||
return `\{\{exp|${match.trim()}\}\}`;
|
||||
});
|
||||
}
|
||||
|
||||
// finds all "{{exp|..}} left"
|
||||
function ensureNoExpressionLeft(ilCode: string) {
|
||||
const allSubstitutions = ilCode.matchAll(/\{\{exp\|(.*?)\}\}/g);
|
||||
const allMatches = Array.from(allSubstitutions, (match) => match[1]);
|
||||
const uniqueExpressions = getDistinctValues(allMatches);
|
||||
if (uniqueExpressions.length > 0) {
|
||||
throw new Error(`unknown expression: ${printList(uniqueExpressions)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Parses all distinct usages of {{exp|$parameterName}}
|
||||
function getUniqueParameterNames(ilCode: string) {
|
||||
const allSubstitutions = ilCode.matchAll(/\{\{exp\|\$([^;\s\{]+[\s]*)\}\}/g);
|
||||
const allParameters = Array.from(allSubstitutions, (match) => match[1]);
|
||||
const uniqueParameterNames = getDistinctValues(allParameters);
|
||||
return uniqueParameterNames;
|
||||
}
|
||||
|
||||
// substitutes {{exp|$parameterName}} to value of the parameter
|
||||
function substituteParameter(ilCode: string, parameterName: string, parameterValue: string) {
|
||||
const pattern = `{{exp|$${parameterName}}}`;
|
||||
return ilCode.split(pattern).join(parameterValue); // as .replaceAll() is not yet supported by TS
|
||||
}
|
||||
|
||||
function getDistinctValues(values: readonly string[]): string[] {
|
||||
return values.filter((value, index, self) => {
|
||||
return self.indexOf(value) === index;
|
||||
});
|
||||
}
|
||||
|
||||
function printList(list: readonly string[]): string {
|
||||
return `"${list.join('","')}"`;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { IExpression } from '../Expression/IExpression';
|
||||
import { IExpressionParser } from './IExpressionParser';
|
||||
import { ParameterSubstitutionParser } from '../SyntaxParsers/ParameterSubstitutionParser';
|
||||
|
||||
const parsers = [
|
||||
new ParameterSubstitutionParser(),
|
||||
];
|
||||
|
||||
export class CompositeExpressionParser implements IExpressionParser {
|
||||
public constructor(private readonly leafs: readonly IExpressionParser[] = parsers) {
|
||||
if (leafs.some((leaf) => !leaf)) { throw new Error('undefined leaf'); }
|
||||
}
|
||||
public findExpressions(code: string): IExpression[] {
|
||||
const expressions = new Array<IExpression>();
|
||||
for (const parser of this.leafs) {
|
||||
const newExpressions = parser.findExpressions(code);
|
||||
if (newExpressions && newExpressions.length) {
|
||||
expressions.push(...newExpressions);
|
||||
}
|
||||
}
|
||||
return expressions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { IExpression } from '../Expression/IExpression';
|
||||
|
||||
export interface IExpressionParser {
|
||||
findExpressions(code: string): IExpression[];
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { IExpressionParser } from './IExpressionParser';
|
||||
import { ExpressionPosition } from '../Expression/ExpressionPosition';
|
||||
import { IExpression } from '../Expression/IExpression';
|
||||
import { Expression, ExpressionEvaluator } from '../Expression/Expression';
|
||||
|
||||
export abstract class RegexParser implements IExpressionParser {
|
||||
protected abstract readonly regex: RegExp;
|
||||
public findExpressions(code: string): IExpression[] {
|
||||
return Array.from(this.findRegexExpressions(code));
|
||||
}
|
||||
|
||||
protected abstract buildExpression(match: RegExpMatchArray): IPrimitiveExpression;
|
||||
|
||||
private* findRegexExpressions(code: string): Iterable<IExpression> {
|
||||
const matches = Array.from(code.matchAll(this.regex));
|
||||
for (const match of matches) {
|
||||
const startPos = match.index;
|
||||
const endPos = startPos + match[0].length;
|
||||
let position: ExpressionPosition;
|
||||
try {
|
||||
position = new ExpressionPosition(startPos, endPos);
|
||||
} catch (error) {
|
||||
throw new Error(`[${this.constructor.name}] invalid script position: ${error.message}\nRegex ${this.regex}\nCode: ${code}`);
|
||||
}
|
||||
const primitiveExpression = this.buildExpression(match);
|
||||
const expression = new Expression(position, primitiveExpression.evaluator, primitiveExpression.parameters);
|
||||
yield expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface IPrimitiveExpression {
|
||||
evaluator: ExpressionEvaluator;
|
||||
parameters?: readonly string[];
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { RegexParser, IPrimitiveExpression } from '../Parser/RegexParser';
|
||||
|
||||
export class ParameterSubstitutionParser extends RegexParser {
|
||||
protected readonly regex = /{{\s*\$\s*([^}| ]+)\s*}}/g;
|
||||
protected buildExpression(match: RegExpMatchArray): IPrimitiveExpression {
|
||||
const parameterName = match[1];
|
||||
return {
|
||||
parameters: [ parameterName ],
|
||||
evaluator: (args) => args[parameterName],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FunctionData, InstructionHolder } from 'js-yaml-loader!*';
|
||||
import { FunctionData, InstructionHolder } from 'js-yaml-loader!@/*';
|
||||
import { SharedFunction } from './SharedFunction';
|
||||
import { SharedFunctionCollection } from './SharedFunctionCollection';
|
||||
import { ISharedFunctionCollection } from './ISharedFunctionCollection';
|
||||
@@ -49,6 +49,7 @@ function ensureValidFunctions(functions: readonly FunctionData[]) {
|
||||
ensureNoDuplicatesInParameterNames(functions);
|
||||
ensureNoDuplicateCode(functions);
|
||||
ensureEitherCallOrCodeIsDefined(functions);
|
||||
ensureExpectedParameterNameTypes(functions);
|
||||
}
|
||||
|
||||
function printList(list: readonly string[]): string {
|
||||
@@ -67,6 +68,17 @@ function ensureEitherCallOrCodeIsDefined(holders: readonly InstructionHolder[])
|
||||
throw new Error(`neither "code" or "call" is defined in ${printNames(hasEitherCodeOrCall)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureExpectedParameterNameTypes(functions: readonly FunctionData[]) {
|
||||
const unexpectedFunctions = functions.filter((func) => func.parameters && !isArrayOfStrings(func.parameters));
|
||||
if (unexpectedFunctions.length) {
|
||||
throw new Error(`unexpected parameter name type in ${printNames(unexpectedFunctions)}`);
|
||||
}
|
||||
function isArrayOfStrings(value: any): boolean {
|
||||
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
||||
}
|
||||
}
|
||||
|
||||
function printNames(holders: readonly InstructionHolder[]) {
|
||||
return printList(holders.map((holder) => holder.name));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FunctionData } from 'js-yaml-loader!*';
|
||||
import { FunctionData } from 'js-yaml-loader!@/*';
|
||||
import { ISharedFunctionCollection } from './ISharedFunctionCollection';
|
||||
|
||||
export interface IFunctionCompiler {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ISharedFunction } from './ISharedFunction';
|
||||
|
||||
export class SharedFunction implements ISharedFunction {
|
||||
public readonly parameters: readonly string[];
|
||||
constructor(
|
||||
public readonly name: string,
|
||||
public readonly parameters: readonly string[],
|
||||
parameters: readonly string[],
|
||||
public readonly code: string,
|
||||
public readonly revertCode: string,
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FunctionCallData, FunctionCallParametersData, FunctionData, ScriptFunctionCallData } from 'js-yaml-loader!*';
|
||||
import { FunctionCallData, FunctionCallParametersData, FunctionData, ScriptFunctionCallData } from 'js-yaml-loader!@/*';
|
||||
import { ICompiledCode } from './ICompiledCode';
|
||||
import { ISharedFunctionCollection } from '../Function/ISharedFunctionCollection';
|
||||
import { IFunctionCallCompiler } from './IFunctionCallCompiler';
|
||||
@@ -8,7 +8,7 @@ import { ExpressionsCompiler } from '../Expressions/ExpressionsCompiler';
|
||||
export class FunctionCallCompiler implements IFunctionCallCompiler {
|
||||
public static readonly instance: IFunctionCallCompiler = new FunctionCallCompiler();
|
||||
protected constructor(
|
||||
private readonly expressionsCompiler: IExpressionsCompiler = ExpressionsCompiler.instance) { }
|
||||
private readonly expressionsCompiler: IExpressionsCompiler = new ExpressionsCompiler()) { }
|
||||
public compileCall(
|
||||
call: ScriptFunctionCallData,
|
||||
functions: ISharedFunctionCollection): ICompiledCode {
|
||||
@@ -32,11 +32,12 @@ export class FunctionCallCompiler implements IFunctionCallCompiler {
|
||||
}
|
||||
|
||||
function ensureExpectedParameters(func: FunctionData, call: FunctionCallData) {
|
||||
if (!func.parameters && !call.parameters) {
|
||||
const actual = Object.keys(call.parameters || {});
|
||||
const expected = func.parameters || [];
|
||||
if (!actual.length && !expected.length) {
|
||||
return;
|
||||
}
|
||||
const unexpectedParameters = Object.keys(call.parameters || {})
|
||||
.filter((callParam) => !func.parameters.includes(callParam));
|
||||
const unexpectedParameters = actual.filter((callParam) => !expected.includes(callParam));
|
||||
if (unexpectedParameters.length) {
|
||||
throw new Error(
|
||||
`function "${func.name}" has unexpected parameter(s) provided: "${unexpectedParameters.join('", "')}"`);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ScriptFunctionCallData } from 'js-yaml-loader!*';
|
||||
import { ScriptFunctionCallData } from 'js-yaml-loader!@/*';
|
||||
import { ICompiledCode } from './ICompiledCode';
|
||||
import { ISharedFunctionCollection } from '../Function/ISharedFunctionCollection';
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
|
||||
|
||||
export interface ISyntaxFactory {
|
||||
create(language: ScriptingLanguage): ILanguageSyntax;
|
||||
export interface ISyntaxFactory extends IScriptingLanguageFactory<ILanguageSyntax> {
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { ILanguageSyntax } from '@/domain/ScriptCode';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { ISyntaxFactory } from './ISyntaxFactory';
|
||||
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
|
||||
import { BatchFileSyntax } from './BatchFileSyntax';
|
||||
import { ShellScriptSyntax } from './ShellScriptSyntax';
|
||||
import { ISyntaxFactory } from './ISyntaxFactory';
|
||||
|
||||
export class SyntaxFactory implements ISyntaxFactory {
|
||||
public create(language: ScriptingLanguage): ILanguageSyntax {
|
||||
switch (language) {
|
||||
case ScriptingLanguage.batchfile: return new BatchFileSyntax();
|
||||
case ScriptingLanguage.shellscript: return new ShellScriptSyntax();
|
||||
default: throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`);
|
||||
}
|
||||
export class SyntaxFactory extends ScriptingLanguageFactory<ILanguageSyntax> implements ISyntaxFactory {
|
||||
constructor() {
|
||||
super();
|
||||
this.registerGetter(ScriptingLanguage.batchfile, () => new BatchFileSyntax());
|
||||
this.registerGetter(ScriptingLanguage.shellscript, () => new ShellScriptSyntax());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { IExpressionsCompiler, ParameterValueDictionary } from '@/application/Parser/Script/Compiler/Expressions/IExpressionsCompiler';
|
||||
import { ParameterSubstitutionParser } from '@/application/Parser/Script/Compiler/Expressions/SyntaxParsers/ParameterSubstitutionParser';
|
||||
import { CompositeExpressionParser } from '@/application/Parser/Script/Compiler/Expressions/Parser/CompositeExpressionParser';
|
||||
import { ExpressionsCompiler } from '@/application/Parser/Script/Compiler/Expressions/ExpressionsCompiler';
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
import { ICodeSubstituter } from './ICodeSubstituter';
|
||||
|
||||
export class CodeSubstituter implements ICodeSubstituter {
|
||||
constructor(
|
||||
private readonly compiler: IExpressionsCompiler = createSubstituteCompiler(),
|
||||
private readonly date = new Date(),
|
||||
) {
|
||||
|
||||
}
|
||||
public substitute(code: string, info: IProjectInformation): string {
|
||||
if (!code) { throw new Error('undefined code'); }
|
||||
if (!info) { throw new Error('undefined info'); }
|
||||
const parameters: ParameterValueDictionary = {
|
||||
homepage: info.homepage,
|
||||
version: info.version,
|
||||
date: this.date.toUTCString(),
|
||||
};
|
||||
const compiledCode = this.compiler.compileExpressions(code, parameters);
|
||||
return compiledCode;
|
||||
}
|
||||
}
|
||||
|
||||
function createSubstituteCompiler(): IExpressionsCompiler {
|
||||
const parsers = [ new ParameterSubstitutionParser() ];
|
||||
const parser = new CompositeExpressionParser(parsers);
|
||||
const expressionCompiler = new ExpressionsCompiler(parser);
|
||||
return expressionCompiler;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
|
||||
export interface ICodeSubstituter {
|
||||
substitute(code: string, info: IProjectInformation): string;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||
import { ScriptingDefinitionData } from 'js-yaml-loader!@/*';
|
||||
import { ScriptingDefinition } from '@/domain/ScriptingDefinition';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
import { createEnumParser } from '../../Common/Enum';
|
||||
import { ICodeSubstituter } from './ICodeSubstituter';
|
||||
import { CodeSubstituter } from './CodeSubstituter';
|
||||
|
||||
export class ScriptingDefinitionParser {
|
||||
constructor(
|
||||
private readonly languageParser = createEnumParser(ScriptingLanguage),
|
||||
private readonly codeSubstituter: ICodeSubstituter = new CodeSubstituter(),
|
||||
) {
|
||||
}
|
||||
public parse(
|
||||
definition: ScriptingDefinitionData,
|
||||
info: IProjectInformation): IScriptingDefinition {
|
||||
if (!info) { throw new Error('undefined info'); }
|
||||
if (!definition) { throw new Error('undefined definition'); }
|
||||
const language = this.languageParser.parseEnum(definition.language, 'language');
|
||||
const startCode = this.codeSubstituter.substitute(definition.startCode, info);
|
||||
const endCode = this.codeSubstituter.substitute(definition.endCode, info);
|
||||
return new ScriptingDefinition(
|
||||
language,
|
||||
startCode,
|
||||
endCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||
import { ScriptingDefinitionData } from 'js-yaml-loader!@/*';
|
||||
import { ScriptingDefinition } from '@/domain/ScriptingDefinition';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { IProjectInformation } from '@/domain/IProjectInformation';
|
||||
import { createEnumParser } from '../Common/Enum';
|
||||
import { generateIlCode } from './Script/Compiler/Expressions/ILCode';
|
||||
|
||||
export function parseScriptingDefinition(
|
||||
definition: ScriptingDefinitionData,
|
||||
info: IProjectInformation,
|
||||
date = new Date(),
|
||||
languageParser = createEnumParser(ScriptingLanguage)): IScriptingDefinition {
|
||||
if (!info) {
|
||||
throw new Error('undefined info');
|
||||
}
|
||||
if (!definition) {
|
||||
throw new Error('undefined definition');
|
||||
}
|
||||
const language = languageParser.parseEnum(definition.language, 'language');
|
||||
const startCode = applySubstitutions(definition.startCode, info, date);
|
||||
const endCode = applySubstitutions(definition.endCode, info, date);
|
||||
return new ScriptingDefinition(
|
||||
language,
|
||||
startCode,
|
||||
endCode,
|
||||
);
|
||||
}
|
||||
|
||||
function applySubstitutions(code: string, info: IProjectInformation, date: Date): string {
|
||||
let ilCode = generateIlCode(code);
|
||||
ilCode = ilCode.substituteParameter('homepage', info.homepage);
|
||||
ilCode = ilCode.substituteParameter('version', info.version);
|
||||
ilCode = ilCode.substituteParameter('date', date.toUTCString());
|
||||
return ilCode.compile();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
declare module 'js-yaml-loader!*' {
|
||||
declare module 'js-yaml-loader!@/*' {
|
||||
export interface CollectionData {
|
||||
readonly os: string;
|
||||
readonly scripting: ScriptingDefinitionData;
|
||||
|
||||
@@ -83,41 +83,78 @@ actions:
|
||||
children:
|
||||
-
|
||||
name: Clear Safari browsing history
|
||||
docs:
|
||||
- https://discussions.apple.com/thread/7586106?answerId=30314600022#30314600022
|
||||
- https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
|
||||
code: |-
|
||||
rm -f ~/Library/Safari/History.plist
|
||||
rm -f ~/Library/Safari/HistoryIndex.sk
|
||||
rm -f ~/Library/Safari/History.db
|
||||
rm -f ~/Library/Safari/History.db-lock
|
||||
rm -f ~/Library/Safari/History.db-shm
|
||||
rm -f ~/Library/Safari/History.db-wal
|
||||
# For older versions of Safari
|
||||
rm -f ~/Library/Safari/History.plist # URL, visit count, webpage title, last visited timestamp, redirected URL, autocomplete
|
||||
rm -f ~/Library/Safari/HistoryIndex.sk # History index
|
||||
-
|
||||
name: Clear Safari downloads history
|
||||
docs: https://blog.d204n6.com/2020/09/macos-safari-preferences-and-privacy.html
|
||||
code: rm -f ~/Library/Safari/Downloads.plist
|
||||
-
|
||||
name: Clear Safari top sites
|
||||
code: rm -f ~/Library/Safari/TopSites.plist
|
||||
docs: https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
|
||||
code: rm -f ~/Library/Safari/TopSites.plist
|
||||
-
|
||||
name: Clear Safari last session history
|
||||
name: Clear Safari last session (open tabs) history
|
||||
docs:
|
||||
- https://apple.stackexchange.com/a/374116
|
||||
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-7127
|
||||
code: rm -f ~/Library/Safari/LastSession.plist
|
||||
-
|
||||
name: Clear Safari caches
|
||||
code: |-
|
||||
rm -f ~/Library/Caches/com.apple.Safari/Cache.db
|
||||
rm -f ~/Library/Safari/WebpageIcons.db
|
||||
rm -rf ~/Library/Caches/com.apple.Safari/Webpage Previews
|
||||
category: Clear Safari caches
|
||||
children:
|
||||
-
|
||||
name: Clear Safari cached blobs, URLs and timestamps
|
||||
docs: https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
|
||||
code: rm -f ~/Library/Caches/com.apple.Safari/Cache.db
|
||||
-
|
||||
name: Clear Safari web page icons displayed on URL bar
|
||||
docs:
|
||||
- https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
|
||||
- https://lifehacker.com/safaris-private-browsing-mode-saves-urls-in-an-easily-a-1691944343
|
||||
code: rm -f ~/Library/Safari/WebpageIcons.db
|
||||
-
|
||||
name: Clear Safari webpage previews (thumbnails)
|
||||
docs:
|
||||
- https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
|
||||
- https://www.reddit.com/r/apple/comments/18lp92/your_apple_computer_keeps_a_screen_shot_of_nearly/
|
||||
code: rm -rfv ~/Library/Caches/com.apple.Safari/Webpage\ Previews
|
||||
-
|
||||
name: Clear copy of the Safari history
|
||||
code: rm -rf ~/Library/Caches/Metadata/Safari/History
|
||||
docs: https://forensicsfromthesausagefactory.blogspot.com/2010/06/safari-history-spotlight-webhistory.html
|
||||
code: rm -rfv ~/Library/Caches/Metadata/Safari/History
|
||||
-
|
||||
name: Clear search history embedded in Safari preferences
|
||||
docs: https://krypted.com/tag/recentsearchstrings/
|
||||
code: defaults write ~/Library/Preferences/com.apple.Safari RecentSearchStrings '( )'
|
||||
-
|
||||
name: Clear Safari cookies
|
||||
code: rm -f ~/Library/Cookies/Cookies.plists
|
||||
docs:
|
||||
- https://www.toolbox.com/tech/operating-systems/blogs/understanding-the-safari-cookiesbinarycookies-file-format-010712/
|
||||
- https://link.springer.com/content/pdf/10.1007/0-387-36891-4_13.pdf
|
||||
code: |-
|
||||
rm -f ~/Library/Cookies/Cookies.binarycookies
|
||||
# Used before Safari 5.1
|
||||
rm -f ~/Library/Cookies/Cookies.plist
|
||||
-
|
||||
name: Clear Safari zoom level preferences per site
|
||||
code: rm -f ~/Library/Safari/PerSiteZoomPreferences.plists
|
||||
docs: https://blog.d204n6.com/2020/09/macos-safari-preferences-and-privacy.html
|
||||
code: rm -f ~/Library/Safari/PerSiteZoomPreferences.plist
|
||||
-
|
||||
name: Clear URLs that are allowed to display notifications in Safari
|
||||
docs: https://blog.d204n6.com/2020/09/macos-safari-preferences-and-privacy.html
|
||||
code: rm -f ~/Library/Safari/UserNotificationPreferences.plist
|
||||
-
|
||||
name: Clear Safari per-site preferences for Downloads, Geolocation, PopUps, and Autoplays
|
||||
docs: https://blog.d204n6.com/2020/09/macos-safari-preferences-and-privacy.html
|
||||
code: rm -f ~/Library/Safari/PerSitePreferences.db
|
||||
-
|
||||
category: Clear Firefox history
|
||||
@@ -148,7 +185,7 @@ actions:
|
||||
rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/sessionstore-backups/upgrade.js*-20*
|
||||
-
|
||||
name: Delete Firefox passwords
|
||||
docs: http://kb.mozillazine.org/Password_Manager
|
||||
docs: https://web.archive.org/web/20210425202923/http://kb.mozillazine.org/Password_Manager
|
||||
code: |-
|
||||
rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/signons.txt
|
||||
rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/signons2.txt
|
||||
@@ -400,7 +437,7 @@ actions:
|
||||
-
|
||||
name: Disable PowerShell Core telemetry
|
||||
recommend: standard
|
||||
docs: https://github.com/PowerShell/PowerShell/tree/release/v7.1.1#telemetry
|
||||
docs: https://github.com/PowerShell/PowerShell/blob/v7.1.0/README.md#telemetry
|
||||
call:
|
||||
-
|
||||
function: PersistUserEnvironmentConfiguration
|
||||
|
||||
@@ -600,7 +600,7 @@ actions:
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" /v "PreventDeviceMetadataFromNetwork" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Do not include drivers with Windows Updates
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.WindowsUpdate::ExcludeWUDriversInQualityUpdate
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.WindowsUpdate::ExcludeWUDriversInQualityUpdate
|
||||
recommend: strict
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" /v "ExcludeWUDriversInQualityUpdate" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" /v "ExcludeWUDriversInQualityUpdate" /t REG_DWORD /d 0 /f
|
||||
@@ -613,7 +613,7 @@ actions:
|
||||
-
|
||||
name: Disable cloud speech recognition
|
||||
recommend: standard
|
||||
docs: https://www.tenforums.com/tutorials/101902-turn-off-online-speech-recognition-windows-10-a.html
|
||||
docs: https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#186-speech
|
||||
code: reg add "HKCU\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy" /v "HasAccepted" /t "REG_DWORD" /d 0 /f
|
||||
revertCode: reg add "HKCU\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy" /v "HasAccepted" /t "REG_DWORD" /d 1 /f
|
||||
-
|
||||
@@ -629,7 +629,7 @@ actions:
|
||||
-
|
||||
name: Disable Windows feedback
|
||||
recommend: standard
|
||||
docs: https://www.tenforums.com/tutorials/2441-change-feedback-frequency-windows-10-a.html
|
||||
docs: https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#1816-feedback--diagnostics
|
||||
code: |-
|
||||
reg add "HKCU\SOFTWARE\Microsoft\Siuf\Rules" /v "NumberOfSIUFInPeriod" /t REG_DWORD /d 0 /f
|
||||
reg delete "HKCU\SOFTWARE\Microsoft\Siuf\Rules" /v "PeriodInNanoSeconds" /f
|
||||
@@ -656,8 +656,9 @@ actions:
|
||||
name: Deny app access to location
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://r-pufky.github.io/docs/operating-systems/windows/10/securing-installation/privacy/location.html
|
||||
- https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-privacy#privacy-letappsaccesslocation
|
||||
- https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-privacy#privacy-letappsaccesslocation # LetAppsAccessLocation
|
||||
- https://www.joseespitia.com/2019/07/24/registry-keys-for-windows-10-application-privacy-settings/ # ConsentStore\location
|
||||
- https://social.technet.microsoft.com/Forums/en-US/63904312-04af-41e5-8b57-1dd446ea45c5/ # lfsvc\Service\Configuration
|
||||
code: |-
|
||||
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" /v "Value" /d "Deny" /f
|
||||
:: For older Windows (before 1903)
|
||||
@@ -1039,7 +1040,6 @@ actions:
|
||||
revertCode: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\bluetoothSync" /v "Value" /d "Allow" /t REG_SZ /f
|
||||
-
|
||||
category: Disable app access to voice activation
|
||||
docs: https://www.tenforums.com/tutorials/130122-allow-deny-apps-access-use-voice-activation-windows-10-a.html
|
||||
children:
|
||||
-
|
||||
name: Disable apps and Cortana to activate with voice
|
||||
@@ -1248,45 +1248,72 @@ actions:
|
||||
-
|
||||
name: Disable ad customization with Advertising ID
|
||||
recommend: standard
|
||||
docs: https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#181-general
|
||||
code: |-
|
||||
reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo" /v "Enabled" /t REG_DWORD /d 0 /f
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" /v "DisabledByGroupPolicy" /t REG_DWORD /d 1 /f
|
||||
reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo" /v "Enabled" /t REG_DWORD /d "0" /f
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" /v "DisabledByGroupPolicy" /t REG_DWORD /d "1" /f
|
||||
revertCode: |-
|
||||
reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo" /v "Enabled" /t REG_DWORD /d "1" /f
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" /v "DisabledByGroupPolicy" /t REG_DWORD /d "0" /f
|
||||
-
|
||||
category: Disable cloud-based tips and ads
|
||||
children:
|
||||
-
|
||||
name: Disable Windows Tips
|
||||
recommend: standard
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.CloudContent::DisableSoftLanding
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableSoftLanding" /t REG_DWORD /d "1" /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableSoftLanding" /t REG_DWORD /d "0" /f
|
||||
-
|
||||
name: Disable Windows Spotlight (random wallpaper on lock screen)
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://docs.microsoft.com/en-us/windows/configuration/windows-spotlight
|
||||
- https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#25-windows-spotlight
|
||||
code: reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsSpotlightFeatures" /t "REG_DWORD" /d "1" /f
|
||||
revertCode: reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsSpotlightFeatures" /t "REG_DWORD" /d "0" /f
|
||||
-
|
||||
name: Disable Microsoft consumer experiences
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://www.stigviewer.com/stig/windows_10/2018-04-06/finding/V-71771
|
||||
- https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.CloudContent::DisableWindowsConsumerFeatures
|
||||
- https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#1816-feedback--diagnostics
|
||||
code: reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t "REG_DWORD" /d "1" /f
|
||||
revertCode: reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t "REG_DWORD" /d "0" /f
|
||||
-
|
||||
name: Disable targeted tips
|
||||
recommend: standard
|
||||
code: |-
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableSoftLanding" /t REG_DWORD /d 1 /f
|
||||
reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsSpotlightFeatures" /t "REG_DWORD" /d "1" /f
|
||||
reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t "REG_DWORD" /d "1" /f
|
||||
-
|
||||
name: Turn Off Suggested Content in Settings app
|
||||
recommend: standard
|
||||
docs: https://www.tenforums.com/tutorials/100541-turn-off-suggested-content-settings-app-windows-10-a.html
|
||||
docs:
|
||||
- https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/rds-vdi-recommendations-2004
|
||||
- https://www.blogsdna.com/28017/how-to-disable-turn-off-suggested-content-on-windows-10-setting-app.htm
|
||||
code: |-
|
||||
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v "SubscribedContent-338393Enabled" /d "0" /t REG_DWORD /f
|
||||
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v "SubscribedContent-353694Enabled" /d "0" /t REG_DWORD /f
|
||||
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager /v "SubscribedContent-353696Enabled" /d "0" /t REG_DWORD /f
|
||||
-
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /d "0" /t REG_DWORD /f
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353694Enabled" /d "0" /t REG_DWORD /f
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353696Enabled" /d "0" /t REG_DWORD /f
|
||||
revertCode: |-
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /d "1" /t REG_DWORD /f
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353694Enabled" /d "1" /t REG_DWORD /f
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353696Enabled" /d "1" /t REG_DWORD /f
|
||||
-
|
||||
category: Disable biometrics (breaks fingerprinting/facial login)
|
||||
children:
|
||||
-
|
||||
name: Do not allow the use of biometrics
|
||||
recommend: strict
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.Biometrics::Biometrics_EnableBio
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.Biometrics::Biometrics_EnableBio
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Biometrics" /v "Enabled" /t REG_DWORD /d "0" /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Biometrics" /v "Enabled" /t REG_DWORD /d "1" /f
|
||||
-
|
||||
name: Do not allow users to log on using biometrics
|
||||
recommend: strict
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.Biometrics::Biometrics_EnableCredProv
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.Biometrics::Biometrics_EnableCredProv
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Biometrics\Credential Provider" /v "Enabled" /t "REG_DWORD" /d "0" /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Biometrics\Credential Provider" /v "Enabled" /t "REG_DWORD" /d "1" /f
|
||||
-
|
||||
name: Do not start Windows Biometric Service
|
||||
recommend: strict
|
||||
docs:
|
||||
- http://batcmd.com/windows/10/services/wbiosrvc/
|
||||
- http://revertservice.com/10/wbiosrvc/
|
||||
docs: https://docs.microsoft.com/en-us/windows-server/security/windows-services/security-guidelines-for-disabling-system-services-in-windows-server#windows-biometric-service
|
||||
code: |-
|
||||
reg add "HKLM\SYSTEM\CurrentControlSet\Services\WbioSrvc" /v "Start" /t REG_DWORD /d 4 /f
|
||||
sc stop "WbioSrvc" & sc config "WbioSrvc" start=disabled
|
||||
@@ -1314,7 +1341,7 @@ actions:
|
||||
-
|
||||
name: Disable Website Access of Language List
|
||||
recommend: standard
|
||||
docs: https://www.tenforums.com/tutorials/82980-turn-off-website-access-language-list-windows-10-a.html
|
||||
docs: https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#181-general
|
||||
code: reg add "HKCU\Control Panel\International\User Profile" /v "HttpAcceptLanguageOptOut" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKCU\Control Panel\International\User Profile" /v "HttpAcceptLanguageOptOut" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
@@ -1335,7 +1362,7 @@ actions:
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\GameDVR" /v "AllowGameDVR" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Disable Windows DRM internet access
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.DigitalRights2::DisableOnline
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.DigitalRights2::DisableOnline
|
||||
recommend: standard
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\WMDRM" /v "DisableOnline" /t REG_DWORD /d 1 /f
|
||||
-
|
||||
@@ -1353,13 +1380,13 @@ actions:
|
||||
children:
|
||||
-
|
||||
name: Disable Windows Insider Service
|
||||
docs: http://revertservice.com/10/wisvc/
|
||||
docs: https://docs.microsoft.com/en-us/windows-server/security/windows-services/security-guidelines-for-disabling-system-services-in-windows-server#windows-insider-service
|
||||
recommend: standard
|
||||
code: sc stop "wisvc" & sc config "wisvc" start=disabled
|
||||
revertCode: sc config "wisvc" start=demand
|
||||
-
|
||||
name: Do not let Microsoft try features on this build
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.DataCollection::EnableExperimentation
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.DataCollection::EnableExperimentation
|
||||
recommend: standard
|
||||
code: |-
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v "EnableExperimentation" /t REG_DWORD /d 0 /f
|
||||
@@ -1371,13 +1398,13 @@ actions:
|
||||
reg delete "HKLM\SOFTWARE\Microsoft\PolicyManager\default\System\AllowExperimentation" /v "value" /f
|
||||
-
|
||||
name: Disable getting preview builds of Windows
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.AllowBuildPreview::AllowBuildPreview
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.AllowBuildPreview::AllowBuildPreview
|
||||
recommend: standard
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v "AllowBuildPreview" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v "AllowBuildPreview" /f
|
||||
-
|
||||
name: Remove "Windows Insider Program" from Settings
|
||||
docs: https://www.askvg.com/windows-10-tip-remove-windows-insider-program-section-from-settings-page/
|
||||
docs: https://winaero.com/how-to-hide-the-windows-insider-program-page-from-the-settings-app-in-windows-10/
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\WindowsSelfHost\UI\Visibility" /v "HideInsiderPage" /t "REG_DWORD" /d "1" /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Microsoft\WindowsSelfHost\UI\Visibility" /v "HideInsiderPage" /f
|
||||
-
|
||||
@@ -1445,7 +1472,10 @@ actions:
|
||||
-
|
||||
name: Disable Language Setting Sync
|
||||
recommend: standard
|
||||
docs: https://www.tenforums.com/tutorials/4077-turn-off-sync-settings-microsoft-account-windows-10-a.html
|
||||
docs:
|
||||
- https://winaero.com/turn-on-off-sync-settings-windows-10/
|
||||
- https://www.thewindowsclub.com/how-to-configure-windows-10-sync-settings-using-registry-editor
|
||||
- https://tuxicoman.jesuislibre.net/blog/wp-content/uploads/Windows10_Telemetrie_1709.pdf # from guide on confidentiality and privacy with Windows 10 distributed to the French police, previous version of guide: https://www.pmenier.net/dotclear/docext/win10/.Windows10-Presentation.pdf
|
||||
code: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\SettingSync\Groups\Language" /t REG_DWORD /v "Enabled" /d 0 /f
|
||||
revertCode: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\SettingSync\Groups\Language" /t REG_DWORD /v "Enabled" /d 1 /f
|
||||
-
|
||||
@@ -1515,7 +1545,7 @@ actions:
|
||||
-
|
||||
name: Do not send Watson events
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=SystemCenterEndpointProtection&Policy=Microsoft.Policies.Antimalware::reporting_disablegenericreports
|
||||
docs: https://admx.help/?Category=SystemCenterEndpointProtection&Policy=Microsoft.Policies.Antimalware::reporting_disablegenericreports
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" /v "DisableGenericReports" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" /v "DisableGenericReports" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
@@ -1526,7 +1556,7 @@ actions:
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://www.stigviewer.com/stig/windows_defender_antivirus/2017-12-27/finding/V-75161
|
||||
- https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.WindowsDefender::Spynet_LocalSettingOverrideSpynetReporting
|
||||
- https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.WindowsDefender::Spynet_LocalSettingOverrideSpynetReporting
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" /v "LocalSettingOverrideSpynetReporting" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" /v "LocalSettingOverrideSpynetReporting" /t REG_DWORD /d 1 /f
|
||||
-
|
||||
@@ -1534,7 +1564,7 @@ actions:
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://www.stigviewer.com/stig/windows_7/2012-07-02/finding/V-15713
|
||||
- https://getadmx.com/?Category=Windows_7_2008R2&Policy=Microsoft.Policies.WindowsDefender::SpyNetReporting
|
||||
- https://admx.help/?Category=Windows_7_2008R2&Policy=Microsoft.Policies.WindowsDefender::SpyNetReporting
|
||||
- https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-defender#defender-allowcloudprotection
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" /v "SpynetReporting" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" /v "SpynetReporting" /t REG_DWORD /d 1 /f
|
||||
@@ -1548,7 +1578,7 @@ actions:
|
||||
-
|
||||
name: Disable Malicious Software Reporting tool diagnostic data
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows10_Telemetry&Policy=Microsoft.Policies.Win10Privacy::DontReportInfection
|
||||
docs: https://admx.help/?Category=Windows10_Telemetry&Policy=Microsoft.Policies.Win10Privacy::DontReportInfection
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\MRT" /v "DontReportInfectionInformation" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\MRT" /v "DontReportInfectionInformation" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
@@ -1788,7 +1818,7 @@ actions:
|
||||
category: Chromium Edge settings
|
||||
children:
|
||||
-
|
||||
name: Disable Edge usage and crash-related data reporting # Obselete since Microsoft Edge version 89
|
||||
name: Disable Edge usage and crash-related data reporting (shows "Your browser is managed") # Obselete since Microsoft Edge version 89
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://admx.help/?Category=EdgeChromium&Policy=Microsoft.Policies.Edge::MetricsReportingEnabled
|
||||
@@ -1796,7 +1826,7 @@ actions:
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Edge" /v "MetricsReportingEnabled" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Policies\Microsoft\Edge" /v "MetricsReportingEnabled" /f
|
||||
-
|
||||
name: Disable sending site information # Obselete since Microsoft Edge version 89
|
||||
name: Disable sending site information (shows "Your browser is managed") # Obselete since Microsoft Edge version 89
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://admx.help/?Category=EdgeChromium&Policy=Microsoft.Policies.Edge::SendSiteInfoToImproveServices
|
||||
@@ -1805,7 +1835,9 @@ actions:
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Policies\Microsoft\Edge" /v "SendSiteInfoToImproveServices" /f
|
||||
-
|
||||
name: Disable Automatic Installation of Microsoft Edge Chromium
|
||||
docs: https://docs.microsoft.com/en-us/deployedge/microsoft-edge-blocker-toolkit
|
||||
docs:
|
||||
- https://admx.help/?Category=EdgeChromium_Blocker&Policy=Microsoft.Policies.EdgeUpdate::NoUpdate
|
||||
- https://web.archive.org/web/20210118230052/https://docs.microsoft.com/en-us/deployedge/microsoft-edge-blocker-toolkit
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\EdgeUpdate" /v "DoNotUpdateToEdgeWithChromium" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Microsoft\EdgeUpdate" /v "DoNotUpdateToEdgeWithChromium" /f
|
||||
-
|
||||
@@ -1819,26 +1851,26 @@ actions:
|
||||
-
|
||||
name: Disable MFU tracking
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.EdgeUI::DisableMFUTracking
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.EdgeUI::DisableMFUTracking
|
||||
code: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "DisableMFUTracking" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "DisableMFUTracking" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Disable recent apps
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.EdgeUI::DisableRecentApps
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.EdgeUI::DisableRecentApps
|
||||
code: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "DisableRecentApps" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "DisableRecentApps" /t REG_DWORD /d 0/f
|
||||
-
|
||||
name: Turn off backtracking
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.EdgeUI::TurnOffBackstack
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.EdgeUI::TurnOffBackstack
|
||||
code: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "TurnOffBackstack" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "TurnOffBackstack" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Disable Search Suggestions in Edge
|
||||
docs:
|
||||
- https://docs.microsoft.com/en-us/microsoft-edge/deploy/group-policies/address-bar-settings-gp
|
||||
- https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.MicrosoftEdge::AllowSearchSuggestionsinAddressBar
|
||||
- https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.MicrosoftEdge::AllowSearchSuggestionsinAddressBar
|
||||
recommend: standard
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes" /v "ShowSearchSuggestionsGlobal" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes" /v "ShowSearchSuggestionsGlobal" /t REG_DWORD /d 1 /f
|
||||
@@ -1894,7 +1926,7 @@ actions:
|
||||
category: Chrome cleanup
|
||||
children:
|
||||
-
|
||||
name: Do not share scanned software data to Google
|
||||
name: Do not share scanned software data to Google (shows "Your browser is managed")
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://www.chromium.org/administrators/policy-list-3#ChromeCleanupReportingEnabled
|
||||
@@ -1902,7 +1934,7 @@ actions:
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Google\Chrome" /v "ChromeCleanupReportingEnabled" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Policies\Google\Chrome" /v "ChromeCleanupReportingEnabled" /f
|
||||
-
|
||||
name: Prevent Chrome from scanning the system for cleanup
|
||||
name: Prevent Chrome from scanning the system for cleanup (shows "Your browser is managed")
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://www.chromium.org/administrators/policy-list-3#ChromeCleanupEnabled
|
||||
@@ -1910,7 +1942,7 @@ actions:
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Google\Chrome" /v "ChromeCleanupEnabled" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Policies\Google\Chrome" /v "ChromeCleanupEnabled" /f
|
||||
-
|
||||
name: Disable Chrome metrics reporting
|
||||
name: Disable Chrome metrics reporting (shows "Your browser is managed")
|
||||
recommend: standard
|
||||
docs: https://www.stigviewer.com/stig/google_chrome_v23_windows/2013-01-11/finding/V-35780
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Google\Chrome" /v "MetricsReportingEnabled" /t REG_DWORD /d 0 /f
|
||||
@@ -2009,7 +2041,7 @@ actions:
|
||||
reg add "HKCU\Software\Policies\Microsoft\WindowsMediaPlayer" /v "PreventRadioPresetsRetrieval" /t REG_DWORD /d 1 /f
|
||||
reg add "HKLM\SOFTWARE\Policies\Microsoft\WMDRM" /v "DisableOnline" /t REG_DWORD /d 1 /f
|
||||
-
|
||||
name: Disable dows Media Player Network Sharing Service
|
||||
name: Disable Windows Media Player Network Sharing Service
|
||||
recommend: standard
|
||||
code: sc stop "WMPNetworkSvc" & sc config "WMPNetworkSvc" start=disabled
|
||||
-
|
||||
@@ -2598,20 +2630,20 @@ actions:
|
||||
-
|
||||
name: Disable online tips
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.ControlPanel::AllowOnlineTips
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.ControlPanel::AllowOnlineTips
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "AllowOnlineTips" /t REG_DWORD /d 0 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "AllowOnlineTips" /t REG_DWORD /d 1 /f
|
||||
-
|
||||
name: Turn off Internet File Association service
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.InternetCommunicationManagement::ShellNoUseInternetOpenWith_2
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.InternetCommunicationManagement::ShellNoUseInternetOpenWith_2
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoInternetOpenWith" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoInternetOpenWith" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Turn off the "Order Prints" picture task
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.InternetCommunicationManagement::ShellRemoveOrderPrints_2
|
||||
- https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.InternetCommunicationManagement::ShellRemoveOrderPrints_2
|
||||
- https://www.stigviewer.com/stig/microsoft_windows_server_2012_member_server/2013-07-25/finding/WN12-CC-000042
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoOnlinePrintsWizard" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoOnlinePrintsWizard" /t REG_DWORD /d 0 /f
|
||||
@@ -2633,19 +2665,19 @@ actions:
|
||||
-
|
||||
name: Do not keep history of recently opened documents
|
||||
recommend: strict
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.StartMenu::NoRecentDocsHistory
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.StartMenu::NoRecentDocsHistory
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoRecentDocsHistory" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "NoRecentDocsHistory" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Clear history of recently opened documents on exit
|
||||
recommend: strict
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.StartMenu::ClearRecentDocsOnExit
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.StartMenu::ClearRecentDocsOnExit
|
||||
code: reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "ClearRecentDocsOnExit" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "ClearRecentDocsOnExit" /t REG_DWORD /d 01 /f
|
||||
-
|
||||
name: Disable Live Tiles push notifications
|
||||
recommend: standard
|
||||
docs: https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.Notifications::NoTileNotification
|
||||
docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.Notifications::NoTileNotification
|
||||
code: reg add "HKCU\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" /v "NoTileApplicationNotification" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKCU\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" /v "NoTileApplicationNotification" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
@@ -2653,26 +2685,27 @@ actions:
|
||||
recommend: standard
|
||||
docs:
|
||||
- https://www.stigviewer.com/stig/microsoft_windows_server_2012_member_server/2013-07-25/finding/WN12-CC-000030
|
||||
- https://getadmx.com/?Category=Windows_10_2016&Policy=Microsoft.Policies.InternetCommunicationManagement::ShellNoUseStoreOpenWith_1
|
||||
- https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.InternetCommunicationManagement::ShellNoUseStoreOpenWith_1
|
||||
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /v "NoUseStoreOpenWith" /t REG_DWORD /d 1 /f
|
||||
revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /v "NoUseStoreOpenWith" /t REG_DWORD /d 0 /f
|
||||
-
|
||||
name: Do not show recently used files in Quick Access
|
||||
recommend: strict
|
||||
docs: https://www.tenforums.com/tutorials/2713-add-remove-recent-files-quick-access-windows-10-a.html
|
||||
docs:
|
||||
- https://matthewhill.uk/windows/group-policy-disable-recent-files-frequent-folder-explorer/ # ShowRecent
|
||||
- https://www.howto-connect.com/delete-recent-frequent-from-file-explorer-on-windows-10/ # 3134ef9c-6b18-4996-ad04-ed5912e00eb5
|
||||
- https://docs.microsoft.com/en-us/windows/win32/sysinfo/32-bit-and-64-bit-application-data-in-the-registry # Wow6432Node
|
||||
code: |-
|
||||
if %PROCESSOR_ARCHITECTURE%==x86 ( REM is 32 bit?
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v "ShowRecent" /d 0 /t REG_DWORD /f
|
||||
) else (
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v "ShowRecent" /d 0 /t "REG_DWORD" /f
|
||||
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HomeFolderDesktop\NameSpace\DelegateFolders\{3134ef9c-6b18-4996-ad04-ed5912e00eb5}" /f
|
||||
if not %PROCESSOR_ARCHITECTURE%==x86 ( REM is 64 bit?
|
||||
reg delete "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\HomeFolderDesktop\NameSpace\DelegateFolders\{3134ef9c-6b18-4996-ad04-ed5912e00eb5}" /f
|
||||
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HomeFolderDesktop\NameSpace\DelegateFolders\{3134ef9c-6b18-4996-ad04-ed5912e00eb5}" /f
|
||||
)
|
||||
revertCode:
|
||||
if %PROCESSOR_ARCHITECTURE%==x86 ( REM is 32 bit?
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v "ShowRecent" /d 1 /t REG_DWORD /f
|
||||
) else (
|
||||
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v "ShowRecent" /d "1" /t "REG_DWORD" /f
|
||||
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HomeFolderDesktop\NameSpace\DelegateFolders\{3134ef9c-6b18-4996-ad04-ed5912e00eb5}" /f
|
||||
if not %PROCESSOR_ARCHITECTURE%==x86 ( REM is 64 bit?
|
||||
reg add "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\HomeFolderDesktop\NameSpace\DelegateFolders\{3134ef9c-6b18-4996-ad04-ed5912e00eb5}" /f
|
||||
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HomeFolderDesktop\NameSpace\DelegateFolders\{3134ef9c-6b18-4996-ad04-ed5912e00eb5}" /f
|
||||
)
|
||||
-
|
||||
name: Disable Sync Provider Notifications
|
||||
@@ -2680,12 +2713,15 @@ actions:
|
||||
revertCode: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ShowSyncProviderNotifications" /d 1 /t REG_DWORD /f
|
||||
-
|
||||
name: Turn hibernate off to disable sleep for quick start
|
||||
docs: http://www.windows10windows7.com/w10/win10zs/100102504.html
|
||||
docs: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/compact-os#ram-pagefilesys-and-hiberfilsys
|
||||
code: powercfg -h off
|
||||
revertCode: powercfg -h on
|
||||
-
|
||||
name: Enable camera on/off OSD notifications
|
||||
docs: https://www.tenforums.com/tutorials/166065-how-enable-disable-camera-off-osd-notifications-windows-10-a.html
|
||||
docs:
|
||||
- https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-coremmres-nophysicalcameraled
|
||||
- https://www.reddit.com/r/Surface/comments/88nyln/the_webcamled_took_anyone_it_apart/dwm64p5
|
||||
- https://answers.microsoft.com/en-us/windows/forum/all/enable-osd-notification-for-webcam/caf1fff4-78d3-4b93-905b-ef657097a44e
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\OEM\Device\Capture" /v "NoPhysicalCameraLED" /d 1 /t REG_DWORD /f
|
||||
revertCode: reg delete "HKLM\Software\Microsoft\OEM\Device\Capture" /v "NoPhysicalCameraLED" /f
|
||||
-
|
||||
@@ -2702,11 +2738,11 @@ actions:
|
||||
-
|
||||
name: Desktop
|
||||
code: |-
|
||||
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{31C0DD25-9439-4F12-BF41-7FF4EDA38722}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Hide" /f
|
||||
reg add "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{31C0DD25-9439-4F12-BF41-7FF4EDA38722}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Hide" /f
|
||||
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Hide" /f
|
||||
reg add "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Hide" /f
|
||||
revertCode: |-
|
||||
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{31C0DD25-9439-4F12-BF41-7FF4EDA38722}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Show" /f
|
||||
reg add "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{31C0DD25-9439-4F12-BF41-7FF4EDA38722}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Show" /f
|
||||
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Show" /f
|
||||
reg add "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}\PropertyBag" /v "ThisPCPolicy" /t REG_SZ /d "Show" /f
|
||||
-
|
||||
name: Documents
|
||||
code: |-
|
||||
@@ -2825,14 +2861,18 @@ actions:
|
||||
code: sc stop "XboxNetApiSvc" & sc config "XboxNetApiSvc" start=disabled
|
||||
revertCode: sc config "XboxNetApiSvc" start=demand
|
||||
-
|
||||
name: Volume Shadow Copy Service
|
||||
recommend: standard
|
||||
docs: https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service
|
||||
name: Disable Volume Shadow Copy Service (breaks System Restore and Windows Backup) # Also known as • Volume Snapshot Service • VSS • VSC
|
||||
recommend: strict
|
||||
docs:
|
||||
- https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service
|
||||
- https://www.schneier.com/blog/archives/2009/12/the_security_im.html
|
||||
code: sc stop "VSS" & sc config "VSS" start=disabled
|
||||
revertCode: sc config "VSS" start=demand
|
||||
-
|
||||
name: Disable NetBios for all interfaces
|
||||
docs: https://10dsecurity.com/saying-goodbye-netbios/
|
||||
docs:
|
||||
- https://bobcares.com/blog/disable-netbios-and-llmnr-protocols-in-windows-using-gpo/
|
||||
- https://social.technet.microsoft.com/Forums/windowsserver/en-US/c5f3c095-1ad2-4963-b075-787f800b81f2/
|
||||
call:
|
||||
function: RunPowerShell
|
||||
parameters:
|
||||
@@ -2986,7 +3026,7 @@ actions:
|
||||
packageName: Microsoft.Messaging
|
||||
-
|
||||
name: Mixed Reality Portal app
|
||||
docs: https://www.microsoft.com/en-us/p/mixed-reality-portal
|
||||
docs: https://www.microsoft.com/en-us/p/mixed-reality-portal/9ng1h8b3zc7m
|
||||
call:
|
||||
function: UninstallStoreApp
|
||||
parameters:
|
||||
@@ -3004,7 +3044,7 @@ actions:
|
||||
packageName: Microsoft.MicrosoftOfficeHub
|
||||
-
|
||||
name: OneNote app
|
||||
docs: https://www.microsoft.com/en-us/p/onenote-for-windows-10
|
||||
docs: https://www.microsoft.com/en-us/p/onenote-for-windows-10/9wzdncrfhvjl
|
||||
call:
|
||||
function: UninstallStoreApp
|
||||
parameters:
|
||||
@@ -3454,7 +3494,7 @@ actions:
|
||||
packageName: Microsoft.ECApp
|
||||
-
|
||||
name: Lock app (shows lock screen)
|
||||
docs: https://www.dashtech.org/can-you-disable-lockapp-exe-on-windows-10/
|
||||
docs: https://www.getwox.com/what-is-lockapp-exe/
|
||||
call:
|
||||
function: UninstallSystemApp
|
||||
parameters:
|
||||
@@ -3511,7 +3551,7 @@ actions:
|
||||
parameters:
|
||||
packageName: Microsoft.Windows.CapturePicker
|
||||
-
|
||||
name: Cloud Experience Host app # Allows to connect to corporate domains or Microsoft cloud based services
|
||||
name: Cloud Experience Host app (breaks Microsoft cloud/corporate sign in) # Allows to connect to corporate domains or Microsoft cloud based services
|
||||
recommend: strict
|
||||
call:
|
||||
function: UninstallSystemApp
|
||||
@@ -3776,22 +3816,31 @@ actions:
|
||||
children:
|
||||
-
|
||||
name: Direct Play feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"DirectPlay" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"DirectPlay" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: DirectPlay
|
||||
-
|
||||
name: Internet Explorer feature
|
||||
code: |-
|
||||
dism /Online /Disable-Feature /FeatureName:"Internet-Explorer-Optional-x64" /NoRestart
|
||||
dism /Online /Disable-Feature /FeatureName:"Internet-Explorer-Optional-x84" /NoRestart
|
||||
dism /Online /Disable-Feature /FeatureName:"Internet-Explorer-Optional-amd64" /NoRestart
|
||||
revertCode: |-
|
||||
dism /Online /Enable-Feature /FeatureName:"Internet-Explorer-Optional-x64" /NoRestart
|
||||
dism /Online /Enable-Feature /FeatureName:"Internet-Explorer-Optional-x84" /NoRestart
|
||||
dism /Online /Enable-Feature /FeatureName:"Internet-Explorer-Optional-amd64" /NoRestart
|
||||
call:
|
||||
-
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Internet-Explorer-Optional-x64
|
||||
-
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Internet-Explorer-Optional-x84
|
||||
-
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Internet-Explorer-Optional-amd64
|
||||
-
|
||||
name: Legacy Components feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"LegacyComponents" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"LegacyComponents" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: LegacyComponents
|
||||
-
|
||||
category: Server features for developers & administrators
|
||||
children:
|
||||
@@ -3800,39 +3849,55 @@ actions:
|
||||
children:
|
||||
-
|
||||
name: Hyper-V feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-All" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-All" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Microsoft-Hyper-V-All
|
||||
-
|
||||
name: Hyper-V GUI Management Tools feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-Management-Clients" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-Management-Clients" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Microsoft-Hyper-V-Management-Clients
|
||||
-
|
||||
name: Hyper-V Management Tools feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-Tools-All" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-Tools-All" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Microsoft-Hyper-V-Tools-All
|
||||
-
|
||||
name: Hyper-V Module for Windows PowerShell feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-Management-PowerShell" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-Management-PowerShell" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Microsoft-Hyper-V-Management-PowerShell
|
||||
-
|
||||
name: Telnet Client feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"TelnetClient" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"TelnetClient" /NoRestart
|
||||
docs: https://social.technet.microsoft.com/wiki/contents/articles/38433.windows-10-enabling-telnet-client.aspx
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: TelnetClient
|
||||
-
|
||||
name: Net.TCP Port Sharing feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"WCF-TCP-PortSharing45" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"WCF-TCP-PortSharing45" /NoRestart
|
||||
docs: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/net-tcp-port-sharing
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: WCF-TCP-PortSharing45
|
||||
-
|
||||
name: SMB Direct feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"SmbDirect" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"SmbDirect" /NoRestart
|
||||
docs: https://docs.microsoft.com/en-us/windows-server/storage/file-server/smb-direct
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: SmbDirect
|
||||
-
|
||||
name: TFTP Client feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"TFTP" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"TFTP" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: TFTP
|
||||
-
|
||||
category: Printing features
|
||||
children:
|
||||
@@ -3841,60 +3906,86 @@ actions:
|
||||
children:
|
||||
-
|
||||
name: Internet Printing Client
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-InternetPrinting-Client" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-InternetPrinting-Client" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Printing-Foundation-InternetPrinting-Client
|
||||
-
|
||||
name: LPD Print Service
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-LPDPrintService" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-LPDPrintService" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: LPDPrintService
|
||||
-
|
||||
name: LPR Port Monitor feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-LPRPortMonitor" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-LPRPortMonitor" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Printing-Foundation-LPRPortMonitor
|
||||
-
|
||||
name: Microsoft Print to PDF feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Printing-PrintToPDFServices-Features" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-PrintToPDFServices-Features" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Printing-PrintToPDFServices-Features
|
||||
-
|
||||
name: Print and Document Services feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-Features" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-Features" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Printing-Foundation-Features
|
||||
-
|
||||
name: Work Folders Client feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"WorkFolders-Client" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"WorkFolders-Client" /NoRestart
|
||||
docs: https://docs.microsoft.com/en-us/windows-server/storage/work-folders/work-folders-overview
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: WorkFolders-Client
|
||||
-
|
||||
category: XPS support
|
||||
children:
|
||||
-
|
||||
name: XPS Services feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Printing-XPSServices-Features" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-XPSServices-Features" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Printing-XPSServices-Features
|
||||
-
|
||||
name: XPS Viewer feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"Xps-Foundation-Xps-Viewer" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"Xps-Foundation-Xps-Viewer" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: Xps-Foundation-Xps-Viewer
|
||||
-
|
||||
name: Media Features feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"MediaPlayback" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"MediaPlayback" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: MediaPlayback
|
||||
-
|
||||
name: Scan Management feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"ScanManagementConsole" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"ScanManagementConsole" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: ScanManagementConsole
|
||||
-
|
||||
name: Windows Fax and Scan feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"FaxServicesClientPackage" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"FaxServicesClientPackage" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: FaxServicesClientPackage
|
||||
-
|
||||
name: Windows Media Player feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"WindowsMediaPlayer" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"WindowsMediaPlayer" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: WindowsMediaPlayer
|
||||
-
|
||||
name: Windows Search feature
|
||||
code: dism /Online /Disable-Feature /FeatureName:"SearchEngine-Client-Package" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"SearchEngine-Client-Package" /NoRestart
|
||||
call:
|
||||
function: DisableFeature
|
||||
parameters:
|
||||
featureName: SearchEngine-Client-Package
|
||||
-
|
||||
category: Uninstall capabilities & features on demand
|
||||
docs: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/features-on-demand-non-language-fod#fods-that-are-not-preinstalled-but-may-need-to-be-preinstalled
|
||||
@@ -4251,30 +4342,32 @@ actions:
|
||||
code: |-
|
||||
:: Configure time source
|
||||
w32tm /config /syncfromflags:manual /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org"
|
||||
:: Restart time service if running
|
||||
:: Stop time service if running
|
||||
SC queryex "w32time"|Find "STATE"|Find /v "RUNNING">Nul||(
|
||||
net stop w32time
|
||||
net start w32time
|
||||
)
|
||||
:: Sync now
|
||||
:: Start time service and sync now
|
||||
net start w32time
|
||||
w32tm /config /update
|
||||
w32tm /resync
|
||||
revertCode: |-
|
||||
:: Configure time source
|
||||
w32tm /config /syncfromflags:manual /manualpeerlist:"time.windows.com"
|
||||
:: Restart time service if running
|
||||
:: Stop time service if running
|
||||
SC queryex "w32time"|Find "STATE"|Find /v "RUNNING">Nul||(
|
||||
net stop w32time
|
||||
net start w32time
|
||||
)
|
||||
:: Sync now
|
||||
:: Start time servie and sync now
|
||||
net start w32time
|
||||
w32tm /config /update
|
||||
w32tm /resync
|
||||
-
|
||||
name: Disable Reserved Storage for updates
|
||||
name: Disable Reserved Storage for updates # since 19H1 (1903)
|
||||
docs:
|
||||
- https://techcommunity.microsoft.com/t5/storage-at-microsoft/windows-10-and-reserved-storage/ba-p/428327
|
||||
- https://www.tenforums.com/tutorials/124858-enable-disable-reserved-storage-windows-10-a.html
|
||||
- https://techcommunity.microsoft.com/t5/storage-at-microsoft/windows-10-and-reserved-storage/ba-p/428327 # Announcement
|
||||
- https://techcommunity.microsoft.com/t5/windows-it-pro-blog/managing-reserved-storage-in-windows-10-environments/ba-p/1297070#toc-hId--8696946 # Set-ReservedStorageState
|
||||
- https://www.howtogeek.com/425563/how-to-disable-reserved-storage-on-windows-10/ # ShippedWithReserves
|
||||
- https://techcommunity.microsoft.com/t5/windows-servicing/reserve-manager-enabled-with-low-disk-space-block/m-p/2073132 # PassedPolicy
|
||||
code: |-
|
||||
dism /online /Set-ReservedStorageState /State:Disabled /NoRestart
|
||||
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager" /v "MiscPolicyInfo" /t REG_DWORD /d "2" /f
|
||||
@@ -4298,6 +4391,11 @@ functions:
|
||||
# https://docs.microsoft.com/en-us/previous-versions/windows/desktop/xperf/image-file-execution-options
|
||||
code: reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\'{{ $processName }}'" /v "Debugger" /t REG_SZ /d "%windir%\System32\taskkill.exe" /f
|
||||
revertCode: reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\'{{ $processName }}'" /v "Debugger" /f
|
||||
-
|
||||
name: DisableFeature
|
||||
parameters: [ featureName ]
|
||||
code: dism /Online /Disable-Feature /FeatureName:"{{ $featureName }}" /NoRestart
|
||||
revertCode: dism /Online /Enable-Feature /FeatureName:"{{ $featureName }}" /NoRestart
|
||||
-
|
||||
name: UninstallStoreApp
|
||||
parameters: [ packageName ]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getEnumNames, getEnumValues } from '@/application/Common/Enum';
|
||||
import { getEnumNames, getEnumValues, assertInRange } from '@/application/Common/Enum';
|
||||
import { IEntity } from '../infrastructure/Entity/IEntity';
|
||||
import { ICategory } from './ICategory';
|
||||
import { IScript } from './IScript';
|
||||
@@ -21,7 +21,7 @@ export class CategoryCollection implements ICategoryCollection {
|
||||
throw new Error('undefined scripting definition');
|
||||
}
|
||||
this.queryable = makeQueryable(actions);
|
||||
ensureValidOs(os);
|
||||
assertInRange(os, OperatingSystem);
|
||||
ensureValid(this.queryable);
|
||||
ensureNoDuplicates(this.queryable.allCategories);
|
||||
ensureNoDuplicates(this.queryable.allScripts);
|
||||
@@ -54,18 +54,6 @@ export class CategoryCollection implements ICategoryCollection {
|
||||
}
|
||||
}
|
||||
|
||||
function ensureValidOs(os: OperatingSystem): void {
|
||||
if (os === undefined) {
|
||||
throw new Error('undefined os');
|
||||
}
|
||||
if (os === OperatingSystem.Unknown) {
|
||||
throw new Error('unknown os');
|
||||
}
|
||||
if (!(os in OperatingSystem)) {
|
||||
throw new Error(`os "${os}" is out of range`);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureNoDuplicates<TKey>(entities: ReadonlyArray<IEntity<TKey>>) {
|
||||
const totalOccurrencesById = new Map<TKey, number>();
|
||||
for (const entity of entities) {
|
||||
|
||||
@@ -10,5 +10,4 @@ export enum OperatingSystem {
|
||||
Android,
|
||||
iOS,
|
||||
WindowsPhone,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { IProjectInformation } from './IProjectInformation';
|
||||
import { OperatingSystem } from './OperatingSystem';
|
||||
import { assertInRange } from '@/application/Common/Enum';
|
||||
|
||||
export class ProjectInformation implements IProjectInformation {
|
||||
public readonly repositoryWebUrl: string;
|
||||
@@ -42,6 +43,7 @@ function getWebUrl(gitUrl: string) {
|
||||
}
|
||||
|
||||
function getFileName(os: OperatingSystem, version: string): string {
|
||||
assertInRange(os, OperatingSystem);
|
||||
switch (os) {
|
||||
case OperatingSystem.Linux:
|
||||
return `privacy.sexy-${version}.AppImage`;
|
||||
@@ -50,6 +52,6 @@ function getFileName(os: OperatingSystem, version: string): string {
|
||||
case OperatingSystem.Windows:
|
||||
return `privacy.sexy-Setup-${version}.exe`;
|
||||
default:
|
||||
throw new Error(`Unsupported os: ${OperatingSystem[os]}`);
|
||||
throw new RangeError(`Unsupported os: ${OperatingSystem[os]}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,7 @@ export class ScriptCode implements IScriptCode {
|
||||
syntax: ILanguageSyntax) {
|
||||
if (!syntax) { throw new Error('undefined syntax'); }
|
||||
validateCode(execute, syntax);
|
||||
if (revert) {
|
||||
try {
|
||||
validateCode(revert, syntax);
|
||||
if (execute === revert) {
|
||||
throw new Error(`Code itself and its reverting code cannot be the same`);
|
||||
}
|
||||
} catch (err) {
|
||||
throw Error(`(revert): ${err.message}`);
|
||||
}
|
||||
}
|
||||
validateRevertCode(revert, execute, syntax);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +16,20 @@ export interface ILanguageSyntax {
|
||||
readonly commonCodeParts: string[];
|
||||
}
|
||||
|
||||
function validateRevertCode(revertCode: string, execute: string, syntax: ILanguageSyntax) {
|
||||
if (!revertCode) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
validateCode(revertCode, syntax);
|
||||
if (execute === revertCode) {
|
||||
throw new Error(`Code itself and its reverting code cannot be the same`);
|
||||
}
|
||||
} catch (err) {
|
||||
throw Error(`(revert): ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateCode(code: string, syntax: ILanguageSyntax): void {
|
||||
if (!code || code.length === 0) {
|
||||
throw new Error(`code is empty or undefined`);
|
||||
@@ -47,7 +52,7 @@ function ensureCodeHasUniqueLines(code: string, syntax: ILanguageSyntax): void {
|
||||
}
|
||||
const duplicateLines = lines.filter((e, i, a) => a.indexOf(e) !== i);
|
||||
if (duplicateLines.length !== 0) {
|
||||
throw Error(`Duplicates detected in script :\n ${duplicateLines.join('\n')}`);
|
||||
throw Error(`Duplicates detected in script:\n${duplicateLines.map((line, index) => `(${index}) - ${line}`).join('\n')}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,16 +5,20 @@ import fs from 'fs';
|
||||
import child_process from 'child_process';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
|
||||
export async function runCodeAsync(
|
||||
code: string, folderName: string, fileExtension: string,
|
||||
node = getNodeJs(), environment = Environment.CurrentEnvironment): Promise<void> {
|
||||
const dir = node.path.join(node.os.tmpdir(), folderName);
|
||||
await node.fs.promises.mkdir(dir, {recursive: true});
|
||||
const filePath = node.path.join(dir, `run.${fileExtension}`);
|
||||
await node.fs.promises.writeFile(filePath, code);
|
||||
await node.fs.promises.chmod(filePath, '755');
|
||||
const command = getExecuteCommand(filePath, environment);
|
||||
node.child_process.exec(command);
|
||||
export class CodeRunner {
|
||||
constructor(
|
||||
private readonly node = getNodeJs(),
|
||||
private readonly environment = Environment.CurrentEnvironment) {
|
||||
}
|
||||
public async runCodeAsync(code: string, folderName: string, fileExtension: string): Promise<void> {
|
||||
const dir = this.node.path.join(this.node.os.tmpdir(), folderName);
|
||||
await this.node.fs.promises.mkdir(dir, {recursive: true});
|
||||
const filePath = this.node.path.join(dir, `run.${fileExtension}`);
|
||||
await this.node.fs.promises.writeFile(filePath, code);
|
||||
await this.node.fs.promises.chmod(filePath, '755');
|
||||
const command = getExecuteCommand(filePath, this.environment);
|
||||
this.node.child_process.exec(command);
|
||||
}
|
||||
}
|
||||
|
||||
function getExecuteCommand(scriptPath: string, environment: Environment): string {
|
||||
|
||||
5
src/infrastructure/Threading/AsyncSleep.ts
Normal file
5
src/infrastructure/Threading/AsyncSleep.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export type SchedulerType = (callback: (...args: any[]) => void, ms: number) => void;
|
||||
|
||||
export function sleepAsync(time: number, scheduler: SchedulerType = setTimeout) {
|
||||
return new Promise((resolve) => scheduler(() => resolve(undefined), time));
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="part">Select:</div>
|
||||
<div class="part">
|
||||
<div class="part">
|
||||
<SelectableOption
|
||||
label="None"
|
||||
:enabled="this.currentSelection == SelectionState.None"
|
||||
@click="selectAsync(SelectionState.None)"
|
||||
v-tooltip=" 'Deselect all selected scripts.<br/>' +
|
||||
'💡 Good start to dive deeper into tweaks and select only what you want.'"
|
||||
/>
|
||||
</div>
|
||||
<div class="part"> | </div>
|
||||
<div class="part">
|
||||
<SelectableOption
|
||||
label="Standard"
|
||||
:enabled="this.currentSelection == SelectionState.Standard"
|
||||
@click="selectAsync(SelectionState.Standard)"
|
||||
v-tooltip=" '🛡️ Balanced for privacy and functionality.<br/>' +
|
||||
'OS and applications will function normally.<br/>' +
|
||||
'💡 Recommended for everyone'"
|
||||
/>
|
||||
</div>
|
||||
<div class="part"> | </div>
|
||||
<div class="part">
|
||||
<SelectableOption
|
||||
label="Strict"
|
||||
:enabled="this.currentSelection == SelectionState.Strict"
|
||||
@click="selectAsync(SelectionState.Strict)"
|
||||
v-tooltip=" '🚫 Stronger privacy, disables risky functions that may leak your data.<br/>' +
|
||||
'⚠️ Double check to remove sripts where you would trade functionality for privacy<br/>' +
|
||||
'💡 Recommended for daily users that prefers more privacy over non-essential functions'"
|
||||
/>
|
||||
</div>
|
||||
<div class="part"> | </div>
|
||||
<div class="part">
|
||||
<SelectableOption
|
||||
label="All"
|
||||
:enabled="this.currentSelection == SelectionState.All"
|
||||
@click="selectAsync(SelectionState.All)"
|
||||
v-tooltip=" '🔒 Strongest privacy, disabling any functionality that may leak your data.<br/>' +
|
||||
'🛑 Not designed for daily users, it will break important functionalities.<br/>' +
|
||||
'💡 Only recommended for extreme use-cases like crime labs where no leak is acceptable'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component } from 'vue-property-decorator';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import SelectableOption from './SelectableOption.vue';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
|
||||
enum SelectionState {
|
||||
Standard,
|
||||
Strict,
|
||||
All,
|
||||
None,
|
||||
Custom,
|
||||
}
|
||||
@Component({
|
||||
components: {
|
||||
SelectableOption,
|
||||
},
|
||||
})
|
||||
export default class TheSelector extends StatefulVue {
|
||||
public SelectionState = SelectionState;
|
||||
public currentSelection = SelectionState.None;
|
||||
|
||||
public async selectAsync(type: SelectionState): Promise<void> {
|
||||
if (this.currentSelection === type) {
|
||||
return;
|
||||
}
|
||||
const context = await this.getCurrentContextAsync();
|
||||
selectType(context.state, type);
|
||||
}
|
||||
|
||||
protected handleCollectionState(newState: ICategoryCollectionState, oldState: ICategoryCollectionState): void {
|
||||
this.updateSelections(newState);
|
||||
newState.selection.changed.on(() => this.updateSelections(newState));
|
||||
if (oldState) {
|
||||
oldState.selection.changed.on(() => this.updateSelections(oldState));
|
||||
}
|
||||
}
|
||||
|
||||
private updateSelections(state: ICategoryCollectionState) {
|
||||
this.currentSelection = getCurrentSelectionState(state);
|
||||
}
|
||||
}
|
||||
|
||||
interface ITypeSelector {
|
||||
isSelected: (state: ICategoryCollectionState) => boolean;
|
||||
select: (state: ICategoryCollectionState) => void;
|
||||
}
|
||||
|
||||
const selectors = new Map<SelectionState, ITypeSelector>([
|
||||
[SelectionState.None, {
|
||||
select: (state) =>
|
||||
state.selection.deselectAll(),
|
||||
isSelected: (state) =>
|
||||
state.selection.totalSelected === 0,
|
||||
}],
|
||||
[SelectionState.Standard, {
|
||||
select: (state) =>
|
||||
state.selection.selectOnly(
|
||||
state.collection.getScriptsByLevel(RecommendationLevel.Standard)),
|
||||
isSelected: (state) =>
|
||||
hasAllSelectedLevelOf(RecommendationLevel.Standard, state),
|
||||
}],
|
||||
[SelectionState.Strict, {
|
||||
select: (state) =>
|
||||
state.selection.selectOnly(state.collection.getScriptsByLevel(RecommendationLevel.Strict)),
|
||||
isSelected: (state) =>
|
||||
hasAllSelectedLevelOf(RecommendationLevel.Strict, state),
|
||||
}],
|
||||
[SelectionState.All, {
|
||||
select: (state) =>
|
||||
state.selection.selectAll(),
|
||||
isSelected: (state) =>
|
||||
state.selection.totalSelected === state.collection.totalScripts,
|
||||
}],
|
||||
]);
|
||||
|
||||
function selectType(state: ICategoryCollectionState, type: SelectionState) {
|
||||
const selector = selectors.get(type);
|
||||
selector.select(state);
|
||||
}
|
||||
|
||||
function getCurrentSelectionState(state: ICategoryCollectionState): SelectionState {
|
||||
for (const [type, selector] of Array.from(selectors.entries())) {
|
||||
if (selector.isSelected(state)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return SelectionState.Custom;
|
||||
}
|
||||
|
||||
function hasAllSelectedLevelOf(level: RecommendationLevel, state: ICategoryCollectionState) {
|
||||
const scripts = state.collection.getScriptsByLevel(level);
|
||||
const selectedScripts = state.selection.selectedScripts;
|
||||
return areAllSelected(scripts, selectedScripts);
|
||||
}
|
||||
|
||||
function areAllSelected(
|
||||
expectedScripts: ReadonlyArray<IScript>,
|
||||
selection: ReadonlyArray<SelectedScript>): boolean {
|
||||
selection = selection.filter((selected) => !selected.revert);
|
||||
if (expectedScripts.length < selection.length) {
|
||||
return false;
|
||||
}
|
||||
const selectedScriptIds = selection.map((script) => script.id).sort();
|
||||
const expectedScriptIds = expectedScripts.map((script) => script.id).sort();
|
||||
return selectedScriptIds.every((id, index) => id === expectedScriptIds[index]);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/presentation/styles/fonts.scss";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
.part {
|
||||
display: flex;
|
||||
margin-right:5px;
|
||||
}
|
||||
font-family: $normal-font;
|
||||
}
|
||||
</style>
|
||||
@@ -1,30 +0,0 @@
|
||||
export function throttle<T extends []>(
|
||||
callback: (..._: T) => void, wait: number,
|
||||
timer: ITimer = NodeTimer): (..._: T) => void {
|
||||
let queuedToRun: ReturnType<typeof setTimeout>;
|
||||
let previouslyRun: number;
|
||||
return function invokeFn(...args: T) {
|
||||
const now = timer.dateNow();
|
||||
if (queuedToRun) {
|
||||
queuedToRun = timer.clearTimeout(queuedToRun) as undefined;
|
||||
}
|
||||
if (!previouslyRun || (now - previouslyRun >= wait)) {
|
||||
callback(...args);
|
||||
previouslyRun = now;
|
||||
} else {
|
||||
queuedToRun = timer.setTimeout(invokeFn.bind(null, ...args), wait - (now - previouslyRun));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface ITimer {
|
||||
setTimeout: (callback: () => void, ms: number) => ReturnType<typeof setTimeout>;
|
||||
clearTimeout: (timeoutId: ReturnType<typeof setTimeout>) => void;
|
||||
dateNow(): number;
|
||||
}
|
||||
|
||||
const NodeTimer: ITimer = {
|
||||
setTimeout: (callback, ms) => setTimeout(callback, ms),
|
||||
clearTimeout: (timeoutId) => clearTimeout(timeoutId),
|
||||
dateNow: () => Date.now(),
|
||||
};
|
||||
@@ -1,6 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
import { app, protocol, BrowserWindow, shell } from 'electron';
|
||||
// This is main process of Electron, started as first thing when app starts.
|
||||
// This script is running through entire life of the application.
|
||||
// It doesn't have any windows which you can see on screen, opens the main window from here.
|
||||
|
||||
import { app, protocol, BrowserWindow, shell, screen } from 'electron';
|
||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
|
||||
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
|
||||
import path from 'path';
|
||||
@@ -30,10 +34,12 @@ if (!process.env.IS_TEST) {
|
||||
|
||||
function createWindow() {
|
||||
// Create the browser window.
|
||||
const size = getWindowSize(1350, 955);
|
||||
win = new BrowserWindow({
|
||||
width: 1350,
|
||||
height: 955,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
webPreferences: {
|
||||
contextIsolation: false, // To reach node https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/1285
|
||||
// Use pluginOptions.nodeIntegration, leave this alone
|
||||
// See https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration
|
||||
nodeIntegration: (process.env
|
||||
@@ -110,14 +116,14 @@ if (isDevelopment) {
|
||||
function loadApplication(window: BrowserWindow) {
|
||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
// Load the url of the dev server if in development mode
|
||||
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string);
|
||||
loadUrlWithNodeWorkaround(win, process.env.WEBPACK_DEV_SERVER_URL as string);
|
||||
if (!process.env.IS_TEST) {
|
||||
win.webContents.openDevTools();
|
||||
}
|
||||
} else {
|
||||
createProtocol('app');
|
||||
// Load the index.html when not in development
|
||||
win.loadURL('app://./index.html');
|
||||
loadUrlWithNodeWorkaround(win, 'app://./index.html');
|
||||
// tslint:disable-next-line:max-line-length
|
||||
autoUpdater.checkForUpdatesAndNotify(); // https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#check-for-updates-in-background-js-ts
|
||||
}
|
||||
@@ -131,3 +137,19 @@ function configureExternalsUrlsOpenBrowser(window: BrowserWindow) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Workaround for https://github.com/electron/electron/issues/19554 otherwise fs does not work
|
||||
function loadUrlWithNodeWorkaround(window: BrowserWindow, url: string) {
|
||||
setTimeout(() => {
|
||||
window.loadURL(url);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function getWindowSize(idealWidth: number, idealHeight: number) {
|
||||
let { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
||||
// To ensure not creating a screen bigger than current screen size
|
||||
// Not using "enableLargerThanScreen" as it's macOS only (see https://www.electronjs.org/docs/api/browser-window)
|
||||
width = Math.min(width, idealWidth);
|
||||
height = Math.min(height, idealHeight);
|
||||
return { width, height };
|
||||
}
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
import TheHeader from '@/presentation/TheHeader.vue';
|
||||
import TheFooter from '@/presentation/TheFooter/TheFooter.vue';
|
||||
import TheCodeButtons from '@/presentation/Code/CodeButtons/TheCodeButtons.vue';
|
||||
import TheScriptArea from '@/presentation/Scripts/TheScriptArea.vue';
|
||||
import TheSearchBar from '@/presentation/TheSearchBar.vue';
|
||||
import TheHeader from '@/presentation/components/TheHeader.vue';
|
||||
import TheFooter from '@/presentation/components/TheFooter/TheFooter.vue';
|
||||
import TheCodeButtons from '@/presentation/components/Code/CodeButtons/TheCodeButtons.vue';
|
||||
import TheScriptArea from '@/presentation/components/Scripts/TheScriptArea.vue';
|
||||
import TheSearchBar from '@/presentation/components/TheSearchBar.vue';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@@ -17,25 +17,18 @@
|
||||
v-on:click="copyCodeAsync"
|
||||
icon-prefix="fas" icon-name="copy">
|
||||
</IconButton>
|
||||
<modal :name="macOsModalName" height="auto" :scrollable="true" :adaptive="true"
|
||||
v-if="this.isMacOsCollection">
|
||||
<div class="modal">
|
||||
<div class="modal__content">
|
||||
<MacOsInstructions :fileName="this.fileName" />
|
||||
</div>
|
||||
<div class="modal__close-button">
|
||||
<font-awesome-icon :icon="['fas', 'times']" @click="$modal.hide(macOsModalName)"/>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
<Dialog v-if="this.isMacOsCollection" ref="instructionsDialog">
|
||||
<MacOsInstructions :fileName="this.fileName" />
|
||||
</Dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component } from 'vue-property-decorator';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import { SaveFileDialog, FileType } from '@/infrastructure/SaveFileDialog';
|
||||
import { Clipboard } from '@/infrastructure/Clipboard';
|
||||
import Dialog from '@/presentation/components/Shared/Dialog.vue';
|
||||
import IconButton from './IconButton.vue';
|
||||
import MacOsInstructions from './MacOsInstructions.vue';
|
||||
import { Environment } from '@/application/Environment/Environment';
|
||||
@@ -44,18 +37,17 @@ import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { IApplicationCode } from '@/application/Context/State/Code/IApplicationCode';
|
||||
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { runCodeAsync } from '@/infrastructure/CodeRunner';
|
||||
import { CodeRunner } from '@/infrastructure/CodeRunner';
|
||||
import { IApplicationContext } from '@/application/Context/IApplicationContext';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
IconButton,
|
||||
MacOsInstructions,
|
||||
Dialog,
|
||||
},
|
||||
})
|
||||
export default class TheCodeButtons extends StatefulVue {
|
||||
public readonly macOsModalName = 'macos-instructions';
|
||||
|
||||
public readonly isDesktopVersion = Environment.CurrentEnvironment.isDesktop;
|
||||
public canRun = false;
|
||||
public hasCode = false;
|
||||
@@ -70,7 +62,7 @@ export default class TheCodeButtons extends StatefulVue {
|
||||
const context = await this.getCurrentContextAsync();
|
||||
saveCode(this.fileName, context.state);
|
||||
if (this.isMacOsCollection) {
|
||||
this.$modal.show(this.macOsModalName);
|
||||
(this.$refs.instructionsDialog as any).show();
|
||||
}
|
||||
}
|
||||
public async executeCodeAsync() {
|
||||
@@ -124,19 +116,17 @@ function buildFileName(scripting: IScriptingDefinition) {
|
||||
}
|
||||
|
||||
async function executeCodeAsync(context: IApplicationContext) {
|
||||
await runCodeAsync(
|
||||
/*code*/ context.state.code.current,
|
||||
/*appName*/ context.app.info.name,
|
||||
/*fileExtension*/ context.state.collection.scripting.fileExtension,
|
||||
);
|
||||
const runner = new CodeRunner();
|
||||
await runner.runCodeAsync(
|
||||
/*code*/ context.state.code.current,
|
||||
/*appName*/ context.app.info.name,
|
||||
/*fileExtension*/ context.state.collection.scripting.fileExtension,
|
||||
);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/presentation/styles/colors.scss";
|
||||
@import "@/presentation/styles/fonts.scss";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -145,26 +135,4 @@ async function executeCodeAsync(context: IApplicationContext) {
|
||||
.container > * + * {
|
||||
margin-left: 30px;
|
||||
}
|
||||
.modal {
|
||||
font-family: $normal-font;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
&__content {
|
||||
width: 100%;
|
||||
margin: 5%;
|
||||
}
|
||||
|
||||
&__close-button {
|
||||
width: auto;
|
||||
font-size: 1.5em;
|
||||
margin-right:0.25em;
|
||||
align-self: flex-start;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop } from 'vue-property-decorator';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import ace from 'ace-builds';
|
||||
import 'ace-builds/webpack-resolver';
|
||||
import { ICodeChangedEvent } from '@/application/Context/State/Code/Event/ICodeChangedEvent';
|
||||
@@ -17,7 +17,7 @@ import { IScript } from '@/domain/IScript';
|
||||
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
import { CodeBuilderFactory } from '@/application/Context/State/Code/Generation/CodeBuilderFactory';
|
||||
import Responsive from '@/presentation/Responsive.vue';
|
||||
import Responsive from '@/presentation/components/Shared/Responsive.vue';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
<script lang="ts">
|
||||
import CardListItem from './CardListItem.vue';
|
||||
import Responsive from '@/presentation/Responsive.vue';
|
||||
import Responsive from '@/presentation/components/Shared/Responsive.vue';
|
||||
import { Component } from 'vue-property-decorator';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import { ICategory } from '@/domain/ICategory';
|
||||
import { hasDirective } from './NonCollapsingDirective';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Watch, Emit } from 'vue-property-decorator';
|
||||
import ScriptsTree from '@/presentation/Scripts/ScriptsTree/ScriptsTree.vue';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import ScriptsTree from '@/presentation/components/Scripts/ScriptsTree/ScriptsTree.vue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@@ -1,26 +1,38 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<span class="part">Group by:</span>
|
||||
<MenuOptionList
|
||||
label="Group by"
|
||||
class="part">
|
||||
<MenuOptionListItem
|
||||
label="Cards"
|
||||
:enabled="!cardsSelected"
|
||||
@click="groupByCard()"
|
||||
/>
|
||||
<MenuOptionListItem
|
||||
label="None"
|
||||
:enabled="!noneSelected"
|
||||
@click="groupByNone()"
|
||||
/>
|
||||
</MenuOptionList>
|
||||
<span class="part">
|
||||
<span
|
||||
class="part"
|
||||
v-bind:class="{ 'disabled': cardsSelected, 'enabled': !cardsSelected}"
|
||||
@click="groupByCard()">Cards</span>
|
||||
<span class="part">|</span>
|
||||
<span class="part"
|
||||
v-bind:class="{ 'disabled': noneSelected, 'enabled': !noneSelected}"
|
||||
@click="groupByNone()">None</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
import { Grouping } from './Grouping';
|
||||
import MenuOptionList from './../MenuOptionList.vue';
|
||||
import MenuOptionListItem from './../MenuOptionListItem.vue';
|
||||
|
||||
const DefaultGrouping = Grouping.Cards;
|
||||
|
||||
@Component
|
||||
@Component({
|
||||
components: {
|
||||
MenuOptionList,
|
||||
MenuOptionListItem,
|
||||
},
|
||||
})
|
||||
export default class TheGrouper extends Vue {
|
||||
public cardsSelected = false;
|
||||
public noneSelected = false;
|
||||
@@ -50,29 +62,5 @@ export default class TheGrouper extends Vue {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/presentation/styles/colors.scss";
|
||||
@import "@/presentation/styles/fonts.scss";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
font-family: $normal-font;
|
||||
.part {
|
||||
display: flex;
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
|
||||
.enabled {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
font-weight:bold;
|
||||
text-decoration:underline;
|
||||
}
|
||||
}
|
||||
.disabled {
|
||||
color:$gray;
|
||||
}
|
||||
|
||||
</style>
|
||||
38
src/presentation/components/Scripts/Menu/MenuOptionList.vue
Normal file
38
src/presentation/components/Scripts/Menu/MenuOptionList.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="list">
|
||||
<div v-if="label">{{ label }}:</div>
|
||||
<div class="items">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Prop } from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class MenuOptionList extends Vue {
|
||||
@Prop() public label: string;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/presentation/styles/fonts.scss";
|
||||
|
||||
$gap: 0.25rem;
|
||||
.list {
|
||||
font-family: $normal-font;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.items {
|
||||
* + *::before {
|
||||
content: '|';
|
||||
padding-right: $gap;
|
||||
padding-left: $gap;
|
||||
}
|
||||
}
|
||||
> *:not(:last-child) {
|
||||
margin-right: $gap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,18 +1,20 @@
|
||||
<template>
|
||||
<span
|
||||
v-bind:class="{ 'disabled': enabled, 'enabled': !enabled}"
|
||||
v-non-collapsing
|
||||
@click="onClicked()">{{label}}</span>
|
||||
<span> <!-- Parent wrapper allows adding content inside with CSS without making it clickable -->
|
||||
<span
|
||||
v-bind:class="{ 'disabled': !enabled, 'enabled': enabled}"
|
||||
v-non-collapsing
|
||||
@click="enabled && onClicked()">{{label}}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Emit, Vue } from 'vue-property-decorator';
|
||||
import { NonCollapsing } from '@/presentation/Scripts/Cards/NonCollapsingDirective';
|
||||
import { NonCollapsing } from '@/presentation/components/Scripts/Cards/NonCollapsingDirective';
|
||||
|
||||
@Component({
|
||||
directives: { NonCollapsing },
|
||||
})
|
||||
export default class SelectableOption extends Vue {
|
||||
export default class MenuOptionListItem extends Vue {
|
||||
@Prop() public enabled: boolean;
|
||||
@Prop() public label: string;
|
||||
@Emit('click') public onClicked() { return; }
|
||||
@@ -0,0 +1,86 @@
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
|
||||
import { RecommendationLevel } from '@/domain/RecommendationLevel';
|
||||
import { scrambledEqual } from '@/application/Common/Array';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
|
||||
export enum SelectionType {
|
||||
Standard,
|
||||
Strict,
|
||||
All,
|
||||
None,
|
||||
Custom,
|
||||
}
|
||||
|
||||
export class SelectionTypeHandler {
|
||||
constructor(private readonly state: ICategoryCollectionState) {
|
||||
if (!state) { throw new Error('undefined state'); }
|
||||
}
|
||||
public selectType(type: SelectionType) {
|
||||
if (type === SelectionType.Custom) {
|
||||
throw new Error('cannot select custom type');
|
||||
}
|
||||
const selector = selectors.get(type);
|
||||
selector.select(this.state);
|
||||
}
|
||||
public getCurrentSelectionType(): SelectionType {
|
||||
for (const [type, selector] of Array.from(selectors.entries())) {
|
||||
if (selector.isSelected(this.state)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return SelectionType.Custom;
|
||||
}
|
||||
}
|
||||
|
||||
interface ISingleTypeHandler {
|
||||
isSelected: (state: ICategoryCollectionState) => boolean;
|
||||
select: (state: ICategoryCollectionState) => void;
|
||||
}
|
||||
|
||||
const selectors = new Map<SelectionType, ISingleTypeHandler>([
|
||||
[SelectionType.None, {
|
||||
select: (state) =>
|
||||
state.selection.deselectAll(),
|
||||
isSelected: (state) =>
|
||||
state.selection.selectedScripts.length === 0,
|
||||
}],
|
||||
[SelectionType.Standard, getRecommendationLevelSelector(RecommendationLevel.Standard)],
|
||||
[SelectionType.Strict, getRecommendationLevelSelector(RecommendationLevel.Strict)],
|
||||
[SelectionType.All, {
|
||||
select: (state) =>
|
||||
state.selection.selectAll(),
|
||||
isSelected: (state) =>
|
||||
state.selection.selectedScripts.length === state.collection.totalScripts,
|
||||
}],
|
||||
]);
|
||||
|
||||
function getRecommendationLevelSelector(level: RecommendationLevel): ISingleTypeHandler {
|
||||
return {
|
||||
select: (state) => selectOnly(level, state),
|
||||
isSelected: (state) => hasAllSelectedLevelOf(level, state),
|
||||
};
|
||||
}
|
||||
|
||||
function hasAllSelectedLevelOf(level: RecommendationLevel, state: ICategoryCollectionState) {
|
||||
const scripts = state.collection.getScriptsByLevel(level);
|
||||
const selectedScripts = state.selection.selectedScripts;
|
||||
return areAllSelected(scripts, selectedScripts);
|
||||
}
|
||||
|
||||
function selectOnly(level: RecommendationLevel, state: ICategoryCollectionState) {
|
||||
const scripts = state.collection.getScriptsByLevel(level);
|
||||
state.selection.selectOnly(scripts);
|
||||
}
|
||||
|
||||
function areAllSelected(
|
||||
expectedScripts: ReadonlyArray<IScript>,
|
||||
selection: ReadonlyArray<SelectedScript>): boolean {
|
||||
selection = selection.filter((selected) => !selected.revert);
|
||||
if (expectedScripts.length < selection.length) {
|
||||
return false;
|
||||
}
|
||||
const selectedScriptIds = selection.map((script) => script.id);
|
||||
const expectedScriptIds = expectedScripts.map((script) => script.id);
|
||||
return scrambledEqual(selectedScriptIds, expectedScriptIds);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<MenuOptionList label="Select">
|
||||
<MenuOptionListItem
|
||||
label="None"
|
||||
:enabled="this.currentSelection !== SelectionType.None"
|
||||
@click="selectType(SelectionType.None)"
|
||||
v-tooltip=" 'Deselect all selected scripts.<br/>' +
|
||||
'💡 Good start to dive deeper into tweaks and select only what you want.'"
|
||||
/>
|
||||
<MenuOptionListItem
|
||||
label="Standard"
|
||||
:enabled="this.currentSelection !== SelectionType.Standard"
|
||||
@click="selectType(SelectionType.Standard)"
|
||||
v-tooltip=" '🛡️ Balanced for privacy and functionality.<br/>' +
|
||||
'OS and applications will function normally.<br/>' +
|
||||
'💡 Recommended for everyone'"
|
||||
/>
|
||||
<MenuOptionListItem
|
||||
label="Strict"
|
||||
:enabled="this.currentSelection !== SelectionType.Strict"
|
||||
@click="selectType(SelectionType.Strict)"
|
||||
v-tooltip=" '🚫 Stronger privacy, disables risky functions that may leak your data.<br/>' +
|
||||
'⚠️ Double check to remove scripts where you would trade functionality for privacy<br/>' +
|
||||
'💡 Recommended for daily users that prefers more privacy over non-essential functions'"
|
||||
/>
|
||||
<MenuOptionListItem
|
||||
label="All"
|
||||
:enabled="this.currentSelection !== SelectionType.All"
|
||||
@click="selectType(SelectionType.All)"
|
||||
v-tooltip=" '🔒 Strongest privacy, disabling any functionality that may leak your data.<br/>' +
|
||||
'🛑 Not designed for daily users, it will break important functionalities.<br/>' +
|
||||
'💡 Only recommended for extreme use-cases like crime labs where no leak is acceptable'"
|
||||
/>
|
||||
</MenuOptionList>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component } from 'vue-property-decorator';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
import { SelectionType, SelectionTypeHandler } from './SelectionTypeHandler';
|
||||
import MenuOptionList from './../MenuOptionList.vue';
|
||||
import MenuOptionListItem from '../MenuOptionListItem.vue';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
MenuOptionList,
|
||||
MenuOptionListItem,
|
||||
},
|
||||
})
|
||||
export default class TheSelector extends StatefulVue {
|
||||
public SelectionType = SelectionType;
|
||||
public currentSelection = SelectionType.None;
|
||||
private selectionTypeHandler: SelectionTypeHandler;
|
||||
|
||||
public async selectType(type: SelectionType) {
|
||||
if (this.currentSelection === type) {
|
||||
return;
|
||||
}
|
||||
this.selectionTypeHandler.selectType(type);
|
||||
}
|
||||
|
||||
protected handleCollectionState(newState: ICategoryCollectionState): void {
|
||||
this.events.unsubscribeAll();
|
||||
this.selectionTypeHandler = new SelectionTypeHandler(newState);
|
||||
this.updateSelections();
|
||||
this.events.register(newState.selection.changed.on(() => this.updateSelections()));
|
||||
}
|
||||
|
||||
private updateSelections() {
|
||||
this.currentSelection = this.selectionTypeHandler.getCurrentSelectionType();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -1,30 +1,32 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<!-- <div>OS:</div> -->
|
||||
<div class="os-list">
|
||||
<div v-for="os in this.allOses" :key="os.name">
|
||||
<span
|
||||
class="os-name"
|
||||
v-bind:class="{ 'current': currentOs === os.os }"
|
||||
v-on:click="changeOsAsync(os.os)">
|
||||
{{ os.name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MenuOptionList>
|
||||
<MenuOptionListItem
|
||||
v-for="os in this.allOses" :key="os.name"
|
||||
:enabled="currentOs !== os.os"
|
||||
@click="changeOsAsync(os.os)"
|
||||
:label="os.name"
|
||||
/>
|
||||
</MenuOptionList>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component } from 'vue-property-decorator';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
import { ApplicationFactory } from '@/application/ApplicationFactory';
|
||||
import MenuOptionList from './MenuOptionList.vue';
|
||||
import MenuOptionListItem from './MenuOptionListItem.vue';
|
||||
|
||||
@Component
|
||||
@Component({
|
||||
components: {
|
||||
MenuOptionList,
|
||||
MenuOptionListItem,
|
||||
},
|
||||
})
|
||||
export default class TheOsChanger extends StatefulVue {
|
||||
public allOses: Array<{ name: string, os: OperatingSystem }> = [];
|
||||
public currentOs: OperatingSystem = OperatingSystem.Unknown;
|
||||
public currentOs?: OperatingSystem = null;
|
||||
|
||||
public async created() {
|
||||
const app = await ApplicationFactory.Current.getAppAsync();
|
||||
@@ -52,31 +54,5 @@ function renderOsName(os: OperatingSystem): string {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/presentation/styles/fonts.scss";
|
||||
@import "@/presentation/styles/colors.scss";
|
||||
.container {
|
||||
font-family: $normal-font;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.os-list {
|
||||
display: flex;
|
||||
margin-left: 0.25rem;
|
||||
div + div::before {
|
||||
content: "|";
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
.os-name {
|
||||
&:not(.current) {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
&.current {
|
||||
color: $gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -14,7 +14,7 @@ import { Component } from 'vue-property-decorator';
|
||||
import TheOsChanger from './TheOsChanger.vue';
|
||||
import TheSelector from './Selector/TheSelector.vue';
|
||||
import TheGrouper from './Grouping/TheGrouper.vue';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
import { IEventSubscription } from '@/infrastructure/Events/IEventSource';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Watch } from 'vue-property-decorator';
|
||||
import { StatefulVue } from '@/presentation/StatefulVue';
|
||||
import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
|
||||
import { IScript } from '@/domain/IScript';
|
||||
import { ICategory } from '@/domain/ICategory';
|
||||
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user