Compare commits

..

40 Commits

Author SHA1 Message Date
undergroundwires
439cd303ff Fix dead URLs 2021-08-27 21:53:13 +01:00
undergroundwires
ec0c972d34 Fix excessive highlighting on hover
It fixes whitespace on left when being highlighted when hovering on macOS (OS selection button on top)
The commit also unifies the way top menu buttons are displayed by reusing `MenuOptionListItem`s (renamed from `SelectableOption`) and `MenuOptionList`. This ensures right and consistent behavior.
Finally it fixes `enabled` property in menu option setting disabled state instead.
2021-08-26 21:08:38 +01:00
undergroundwires
2a08855e5d Fix tests for ParameterSubstitutionParser
Fix nested mocha "it"s and "different parameters" test having wrong expectation
and add a test for whitespace tolerance.
2021-08-25 17:15:54 +01:00
undergroundwires
1c6b3057ea Fix select options being clickable when disabled 2021-08-24 21:18:52 +01:00
undergroundwires
ea5f9ec27d Fix infinitely subscribing to state changes 2021-08-23 17:38:14 +01:00
undergroundwires
f2935e4008 Improve issue templates
- Use same multi-lined comment convention
- Highlight that "additional information" in a bug report is optional
- Remove recommendation for pasting script in a bug report as it's too long
- Rename feature request issue file to follow same naming convention
- Document also creating a issue as a way to extend scripts
- Add reproduction steps in script bug reports
- Use names instead of commands in heading
2021-08-22 15:59:44 +01:00
Bram Ceulemans
487001af48 Fix typo on main page (#82) 2021-08-21 19:07:27 +00:00
Marc05
71e70e50c5 Fix NTP configuration before running the service (#72)
Co-authored-by: Marc05 <git@marc05.net>
2021-08-20 17:21:08 +00:00
undergroundwires
0a857aa09e bump dependencies to latest #75, #69 2021-05-08 23:46:59 +02:00
undergroundwires
b976b92031 fix hiding recent files in quick access
It fixes x64 / x86 conditions in "Do not show recently used files in Quick Access" script. Wow6432Node only exists in x64 systems for x86 application data which is also consumed by explorer.exe. So it should only be edited in x64 systems. The rest of the registry settings ("ShowRecent" and default "DelegateFolders") applies to both x64 and x86 systems.
2021-05-07 16:49:07 +02:00
undergroundwires
db62ed7f3a fix broken URLs and automate broken URL checks #70
This commit:
- Fixes broken URLs using archive.org or other references.
- Replaces tenforums.com URLs with better documentation as they tend to return HTTP status code 403 to tests and also are low quality source.
- Changes all insecure http sources to https alternatives
- Adds integration tests to check for broken URLs
  - There's logic implemented for having a delay inbetween when sending requests to same domains, however it's not used as the sources can respond to totally parallelized requests.
- Run test pipeline weekly to get notified about broken URls without commits
2021-05-05 23:57:41 +02:00
undergroundwires
36f0805590 unify usage of sleepAsync and add tests
The tests mock JS setTimeout API. However promise.resolve() is not working without flushing the promise queue (which could be done just by awaiting Promise.resolve()), similar issue has been discussed in facebook/jest#2157.
2021-05-04 19:10:23 +02:00
undergroundwires
49600c5f37 add initial integration tests
Integration tests are executed using vue-cli-service with double quotes as following: `vue-cli-service test:unit "tests/integration/**/*.spec.ts"`. Using single quotes (mochajs/mocha#1828) works on macOS and Ubuntu but does not on Windows (tests are not found). Double quotes is the only portable way that works on all three platforms (mochajs/mocha#3136).
2021-05-03 15:48:01 +02:00
Marc05
eb9ac35a92 fix incorrect modification of Desktop folder on ThisPC (#71)
Fixes hiding "Desktop" from This PC and Dialog boxes not working as expected
2021-04-25 16:02:36 +02:00
undergroundwires
77148980e0 unrecommend VSS and document its breaking behavior 2021-04-21 20:07:38 +02:00
undergroundwires-bot
b3d2e82025 ⬆️ bump everywhere to 0.10.2 2021-04-20 16:47:11 +00:00
undergroundwires
b25b8cc805 fix vue warning for undefined property during render
currentOs is not recognized as reactive property as it's set to "undefined". JavaScript does not accept "undefined" as valid value to initialize. A property needs to be initialized with a non-undefined value to become reactive in a class-based component. Otherwise Vue warns: Property or method "currentOs" is not defined on the instance but referenced during render.
2021-04-19 18:21:06 +02:00
Marc05
8141a01ef7 fix typo and dead URL in Windows scripts (#70)
Co-authored-by: Marc05 <git@marc05.net>
2021-04-18 19:12:50 +02:00
undergroundwires
a2f10857e2 fix script revert activating recommendation level
Reverting any single of the scripts from standard recommendation pool
shows "Standard" selection as selected which is wrong. This commit fixes
it, refactors selection handling in a separate class and it also adds
missing tests. It removes UserSelection.totalSelected propertty in favor of using
UserSelection.selectedScripts.length to provide unified way of accessing
the information.
2021-04-17 14:34:29 +01:00
undergroundwires
aea04e5f7c document chromium warning for policy changes
Chromium shows "Your browser is managed" or "Your browser is managed by an organization" warnings when its behavior is manipulated using policies. This message confuses some users, so the commit marks this behavior to let users know why the box appears.
Read more:
- https://chromium.googlesource.com/chromium/src/+/refs/tags/92.0.4475.1/chrome/browser/ui/managed_ui.cc#67
- https://support.google.com/chrome/thread/3262871
2021-04-16 17:56:31 +02:00
undergroundwires
60c80611ea add module alias '@tests/'
Alias would remove unnecessary repetitions and less relative paths make changes easier when moving around files. This commit cleans also up some relative paths ('../../../') by using the alias and orders imports. It updates both path alias in tsconfig and module alias in Vue CLI's bundler (vuejs/vue-cli#2398).
2021-04-15 18:34:40 +02:00
undergroundwires
b1ed3ce55f document breaking behavior in script name #64
Removing Cloud Experience Hosting app breaks Microsoft cloud and
corporate sign in. It's now documented more cleary in the name of the
script.
2021-04-14 15:44:22 +01:00
undergroundwires
040ed2701c improve disabling ads and marketing #65
This commit documents the behavior better with more granularity of
choice and also adds options to revert the code.
2021-04-13 16:39:44 +01:00
undergroundwires
00d8e551db refactor extra code, duplicates, complexity
- refactor array equality check and add tests
- remove OperatingSystem.Unknown causing extra logic, return undefined instead
- refactor enum validation to share same logic
- refactor scripting language factories to share same logic
- refactor too many args in runCodeAsync
- refactor ScriptCode constructor to reduce complexity
- fix writing useless write to member object since another property write always override it
2021-04-11 14:37:02 +01:00
dependabot[bot]
3e9c99f5f8 Bump y18n from 3.2.1 to 3.2.2 (#66)
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-06 20:29:15 +02:00
undergroundwires
02bdc4cf04 fix desktop initial window size being bigger than current display size on smaller Linux/Windows screens 2021-04-05 14:31:31 +01:00
undergroundwires
5c43965f0b in CI/CD, run other tests/check even if one of them fails 2021-03-28 14:26:20 +01:00
dependabot[bot]
b2376ecc30 Bump elliptic from 6.5.3 to 6.5.4 (#62)
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-27 17:15:30 +01:00
undergroundwires-bot
aeaa6deeb4 ⬆️ bump everywhere to 0.10.1 2021-03-26 14:57:03 +00:00
undergroundwires
448e378dc4 increase performance by polyfilling ResizeObserver only if required 2021-03-25 13:24:19 +01:00
undergroundwires
ac2249f256 refactor features to use shared functions #41 2021-03-24 15:29:39 +01:00
undergroundwires
05932c5a36 fix safari cleanup scripts that are not working on modern versions 2021-03-23 19:06:20 +01:00
undergroundwires
6f46cdb4ed refactor all modals to use same dialog component 2021-03-20 16:13:25 +01:00
undergroundwires
5f527a00cf fix fs module hanging not allowing code to run
Run button on Windows stopped working as CodeRunner was hanging when
executing fs.promises.mkdir as described in electron/electron#20951
It started happening after electron update to v12 in 1f515e7.
This commit adds the workaround suggested in electron/electron#19554
that fixes the issue.
2021-03-14 17:26:56 +01:00
undergroundwires
1935db1019 fix throttle function not being able to run with argument(s) 2021-03-13 12:54:13 +01:00
undergroundwires
1f515e7be5 bump dependencies to latest
- fix npm vulnerabilities #62
- change ResizeObserver polyfill dependency que-etc/resize-observer-polyfill#80
- bump typescript to 4.2.x and add tslib for importing helpers
- update electron to v12.x and set contextIsolation to false (nklayman/vue-cli-plugin-electron-builder#1285, electron/electron#11608) to reach node APIs as it's now disabled by default (electron/electron#27949)
2021-03-11 14:50:35 +01:00
undergroundwires
1a5f92021f fix a test where "it" is not used inside "describe" 2021-03-08 17:21:11 +01:00
undergroundwires
f3c7413f52 restructure presentation layer
- Move most GUI related code to /presentation
- Move components to /components (separate from bootstrap and style)
- Move shared components helpers to /components/shared
- Rename Bootstrapping to bootstrapping to enforce same naming
  convention in /presentation
2021-03-07 19:37:54 +01:00
undergroundwires
646db90585 refactor script compilation to make it easy to add new expressions #41 #53 2021-03-05 15:52:49 +01:00
undergroundwires-bot
1f8a0cf9ab ⬆️ bump everywhere to 0.10.0 2021-03-02 16:08:31 +00:00
218 changed files with 25786 additions and 3041 deletions

View File

@@ -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. 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 ### 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". 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 ### 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 ### Additional information
<!-- Add any other context about the problem here. --> <!--
If applicable, add any other context about the problem here.
-->

View File

@@ -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. 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. -->
### To Reproduce
<!-- <!--
A clear and concise description of what the bug is.
-->
### 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: Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 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: If applicable, mention how you were using privacy.sexy when the bug was encountered:
- Web (on Desktop or mobile?) - Web (on Desktop or mobile?)
- Or desktop (Windows, macOS or Linux?) - Or desktop (Windows, macOS or Linux?)
--> -->
### Additional context ### Additional context
<!-- <!--
Add any other context about the problem here. If applicable, add any other context about the problem here.
--> -->

View 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.
-->

View File

@@ -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. -->

View 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.
-->

View File

@@ -26,7 +26,9 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Run tests - name: Run tests
run: npm run test:unit run: |
npm run test:unit
npm run test:integration
- name: Publish desktop app - 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 run: npm run electron:build -- -p always # https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#upload-release-to-github
env: env:

View File

@@ -90,7 +90,9 @@ jobs:
working-directory: site working-directory: site
- -
name: "App: Run tests" name: "App: Run tests"
run: npm run test:unit run: |
npm run test:unit
npm run test:integration
working-directory: site working-directory: site
- -
name: "App: Build" name: "App: Build"

View File

@@ -13,6 +13,7 @@ jobs:
- npm run lint:md - npm run lint:md
- npm run lint:md:relative-urls - npm run lint:md:relative-urls
- npm run lint:md:consistency - npm run lint:md:consistency
fail-fast: false # So it continues with other commands if one fails
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2

View File

@@ -5,7 +5,7 @@ on:
pull_request: pull_request:
paths: [ '/package.json', '/package-lock.json' ] # Allow PRs to be green if they do not introduce dependency change paths: [ '/package.json', '/package-lock.json' ] # Allow PRs to be green if they do not introduce dependency change
schedule: schedule:
- cron: '0 0 * * 0' - cron: '0 0 * * 0' # at 00:00 on every Sunday
jobs: jobs:
npm-audit: npm-audit:

View File

@@ -1,12 +1,17 @@
name: Test 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: jobs:
run-tests: run-tests:
strategy: strategy:
matrix: matrix:
os: [macos, ubuntu, windows] os: [macos, ubuntu, windows]
fail-fast: false # So it still runs on other OSes if one of them fails
runs-on: ${{ matrix.os }}-latest runs-on: ${{ matrix.os }}-latest
steps: steps:
- -
@@ -21,5 +26,8 @@ jobs:
name: Install dependencies name: Install dependencies
run: npm ci run: npm ci
- -
name: Run tests name: Run unit tests
run: npm run test:unit run: npm run test:unit
-
name: Run integration tests
run: npm run test:integration

View File

@@ -1,5 +1,52 @@
# Changelog # 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) ## 0.9.2 (2021-02-13)
* do not compile with unused locals vuejs/vetur#1063 | [73e0520](https://github.com/undergroundwires/privacy.sexy/commit/73e0520de70cdbaf0ecdc6e9be5e85f003fcfb79) * do not compile with unused locals vuejs/vetur#1063 | [73e0520](https://github.com/undergroundwires/privacy.sexy/commit/73e0520de70cdbaf0ecdc6e9be5e85f003fcfb79)

View File

@@ -7,9 +7,9 @@
- Proposing new features - Proposing new features
- Becoming a maintainer - 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. - Your pull requests are actively welcomed.
- The steps: - The steps:
1. Fork the repo and create your branch from master. 1. Fork the repo and create your branch from master.
@@ -25,4 +25,10 @@
## License ## 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

View File

@@ -16,7 +16,7 @@
- Online version at [https://privacy.sexy](https://privacy.sexy) - Online version at [https://privacy.sexy](https://privacy.sexy)
- 💡 No need to run any compiled software on your computer. - 💡 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. - 💡 Single click to execute your script.
- ❗ Come back regularly to apply latest version for stronger privacy and security. - ❗ Come back regularly to apply latest version for stronger privacy and security.
@@ -34,17 +34,20 @@
## Extend scripts ## Extend scripts
1. Fork the repository - You can either [create an issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose)
2. Add more scripts in respective script collection in [collections](src/application/collections/) folder. - 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). - 📖 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. - 🙏 For any new script, please add `revertCode` and `docs` values if possible.
3. Send a pull request 👌 3. Send a pull request 👌
## Commands ## Commands
- Project setup: `npm install` - Project setup: `npm install`
- Testing - Testing
- Run unit tests: `npm run test:unit` - Run unit tests: `npm run test:unit`
- Run integration tests: `npm run test:integration`
- Lint: `npm run lint` - Lint: `npm run lint`
- **Desktop app** - **Desktop app**
- Development: `npm run electron:serve` - Development: `npm run electron:serve`
@@ -53,8 +56,8 @@
- Development: `npm run serve` to compile & hot-reload for development. - Development: `npm run serve` to compile & hot-reload for development.
- Production: `npm run build` to prepare files for distribution. - Production: `npm run build` to prepare files for distribution.
- Or run using Docker: - Or run using Docker:
1. Build: `docker build -t 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.9.2 undergroundwires/privacy.sexy:0.9.2` 2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.10.2 undergroundwires/privacy.sexy:0.10.2`
## Architecture overview ## Architecture overview

View File

@@ -2,7 +2,15 @@
- It's mainly responsible for - It's mainly responsible for
- creating and event based [application state](#application-state) - 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 ## Application state
@@ -14,9 +22,23 @@
## Application data ## 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 - 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 - Enables [data-driven programming](https://en.wikipedia.org/wiki/Data-driven_programming) and easier contributions
- Application data is defined in collection files and - 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 [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. - 📖 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)

View File

@@ -4,6 +4,20 @@
- Desktop application is created using [Electron](https://www.electronjs.org/). - 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. - 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 ## Application data
- Components and should use [ApplicationFactory](./../src/application/ApplicationFactory.ts) singleton to reach the application domain. - 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). - 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` - 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) - 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/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. - `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. - 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. - 📖 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>
```

View File

@@ -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) - They follow same folder structure as [`./src`](./../src)
## Naming ### Naming
- Each test suite first describe the system under test - Each test suite first describe the system under test
- E.g. tests for class `Application` is categorized under `Application` - E.g. tests for class `Application` is categorized under `Application`
- Tests for specific methods are categorized under method name (if applicable) - Tests for specific methods are categorized under method name (if applicable)
- E.g. test for `run()` is categorized under `run` - 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 - Tests use act, arrange and assert (AAA) pattern when applicable
- **Arrange** - **Arrange**
@@ -23,7 +31,13 @@
- Should elicit some sort of response - Should elicit some sort of response
- Starts with comment line `// assert` - Starts with comment line `// assert`
## Stubs ### Stubs
- Stubs are defined in [`./tests/stubs`](./../tests/unit/stubs) - Stubs are defined in [`./tests/stubs`](./../tests/unit/stubs)
- They implement dummy behavior to be functional - 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

23339
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "privacy.sexy", "name": "privacy.sexy",
"version": "0.9.2", "version": "0.10.2",
"private": true, "private": true,
"description": "Enforce privacy & security best-practices on Windows and macOS, because privacy is sexy 🍑🍆", "description": "Enforce privacy & security best-practices on Windows and macOS, because privacy is sexy 🍑🍆",
"author": "undergroundwires", "author": "undergroundwires",
@@ -8,6 +8,7 @@
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit", "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", "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:build": "vue-cli-service electron:build",
"electron:serve": "vue-cli-service electron:serve", "electron:serve": "vue-cli-service electron:serve",
@@ -21,48 +22,50 @@
}, },
"main": "background.js", "main": "background.js",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.1", "@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-regular-svg-icons": "^5.15.1", "@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.1", "@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.2", "@fortawesome/vue-fontawesome": "^2.0.2",
"@juggle/resize-observer": "^3.3.1",
"ace-builds": "^1.4.12", "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", "file-saver": "^2.0.5",
"inversify": "^5.0.5", "inversify": "^5.1.1",
"liquor-tree": "^0.2.70", "liquor-tree": "^0.2.70",
"resize-observer-polyfill": "^1.5.1", "v-tooltip": "2.1.3",
"v-tooltip": "2.0.2",
"vue": "^2.6.12", "vue": "^2.6.12",
"vue-class-component": "^7.2.6", "vue-class-component": "^7.2.6",
"vue-js-modal": "^2.0.0-rc.6", "vue-js-modal": "^2.0.0-rc.6",
"vue-property-decorator": "^9.1.2" "vue-property-decorator": "^9.1.2"
}, },
"devDependencies": { "devDependencies": {
"@types/ace": "0.0.44", "@types/ace": "0.0.45",
"@types/chai": "^4.2.14", "@types/chai": "^4.2.18",
"@types/file-saver": "^2.0.1", "@types/file-saver": "^2.0.2",
"@types/mocha": "^8.2.0", "@types/mocha": "^8.2.2",
"@vue/cli-plugin-babel": "^4.5.10", "@vue/cli-plugin-babel": "^4.5.13",
"@vue/cli-plugin-typescript": "^4.5.9", "@vue/cli-plugin-typescript": "^4.5.13",
"@vue/cli-plugin-unit-mocha": "^4.5.9", "@vue/cli-plugin-unit-mocha": "^4.5.13",
"@vue/cli-service": "^4.5.9", "@vue/cli-service": "^4.5.13",
"@vue/test-utils": "1.1.2", "@vue/test-utils": "1.2.0",
"chai": "^4.2.0", "chai": "^4.3.4",
"electron": "^11.1.0", "electron": "^12.0.7",
"electron-devtools-installer": "^3.1.1", "electron-devtools-installer": "^3.2.0",
"electron-log": "^4.3.1", "electron-log": "^4.3.5",
"electron-updater": "^4.3.5", "electron-updater": "^4.3.8",
"js-yaml-loader": "^1.2.2", "js-yaml-loader": "^1.2.2",
"markdownlint-cli": "^0.26.0", "markdownlint-cli": "^0.27.1",
"remark-cli": "^9.0.0", "remark-cli": "^9.0.0",
"remark-lint-no-dead-urls": "^1.1.0", "remark-lint-no-dead-urls": "^1.1.0",
"remark-preset-lint-consistent": "^4.0.0", "remark-preset-lint-consistent": "^4.0.0",
"remark-validate-links": "^10.0.2", "remark-validate-links": "^10.0.4",
"sass": "^1.30.0", "sass": "^1.32.12",
"sass-loader": "^10.1.0", "sass-loader": "^10.0.1",
"typescript": "^4.1.3", "tslib": "^2.2.0",
"vue-cli-plugin-electron-builder": "^2.0.0-rc.5", "typescript": "^4.2.4",
"vue-cli-plugin-electron-builder": "^2.0.0-rc.6",
"vue-template-compiler": "^2.6.12", "vue-template-compiler": "^2.6.12",
"yaml-lint": "^1.2.4" "yaml-lint": "^1.2.4"
}, },

View 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]);
}

View File

@@ -1,6 +1,6 @@
// Because we cannot do "T extends enum" 😞 https://github.com/microsoft/TypeScript/issues/30611 // Because we cannot do "T extends enum" 😞 https://github.com/microsoft/TypeScript/issues/30611
type EnumType = number | string; export type EnumType = number | string;
type EnumVariable<T extends EnumType, TEnumValue extends EnumType> = { [key in T]: TEnumValue }; export type EnumVariable<T extends EnumType, TEnumValue extends EnumType> = { [key in T]: TEnumValue };
export interface IEnumParser<TEnum> { export interface IEnumParser<TEnum> {
parseEnum(value: string, propertyName: string): TEnum; parseEnum(value: string, propertyName: string): TEnum;
@@ -41,3 +41,14 @@ export function getEnumValues<T extends EnumType, TEnumValue extends EnumType>(
return getEnumNames(enumVariable) return getEnumNames(enumVariable)
.map((level) => enumVariable[level]) as TEnumValue[]; .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`);
}
}

View File

@@ -0,0 +1,5 @@
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
export interface IScriptingLanguageFactory<T> {
create(language: ScriptingLanguage): T;
}

View File

@@ -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);
}
}

View File

@@ -5,6 +5,7 @@ import { IApplication } from '@/domain/IApplication';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { ICategoryCollection } from '@/domain/ICategoryCollection'; import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { EventSource } from '@/infrastructure/Events/EventSource'; import { EventSource } from '@/infrastructure/Events/EventSource';
import { assertInRange } from '@/application/Common/Enum';
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>; type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
@@ -22,7 +23,7 @@ export class ApplicationContext implements IApplicationContext {
public readonly app: IApplication, public readonly app: IApplication,
initialContext: OperatingSystem) { initialContext: OperatingSystem) {
validateApp(app); validateApp(app);
validateOs(initialContext); assertInRange(initialContext, OperatingSystem);
this.states = initializeStates(app); this.states = initializeStates(app);
this.changeContext(initialContext); 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 { function initializeStates(app: IApplication): StateMachine {
const machine = new Map<OperatingSystem, ICategoryCollectionState>(); const machine = new Map<OperatingSystem, ICategoryCollectionState>();
for (const collection of app.collections) { for (const collection of app.collections) {

View File

@@ -1,15 +1,14 @@
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage'; import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ICodeBuilder } from './ICodeBuilder'; import { ICodeBuilder } from './ICodeBuilder';
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
import { BatchBuilder } from './Languages/BatchBuilder'; import { BatchBuilder } from './Languages/BatchBuilder';
import { ShellBuilder } from './Languages/ShellBuilder'; import { ShellBuilder } from './Languages/ShellBuilder';
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
export class CodeBuilderFactory implements ICodeBuilderFactory { export class CodeBuilderFactory extends ScriptingLanguageFactory<ICodeBuilder> implements ICodeBuilderFactory {
public create(language: ScriptingLanguage): ICodeBuilder { constructor() {
switch (language) { super();
case ScriptingLanguage.shellscript: return new ShellBuilder(); this.registerGetter(ScriptingLanguage.shellscript, () => new ShellBuilder());
case ScriptingLanguage.batchfile: return new BatchBuilder(); this.registerGetter(ScriptingLanguage.batchfile, () => new BatchBuilder());
default: throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`);
}
} }
} }

View File

@@ -1,6 +1,5 @@
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ICodeBuilder } from './ICodeBuilder'; import { ICodeBuilder } from './ICodeBuilder';
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
export interface ICodeBuilderFactory { export interface ICodeBuilderFactory extends IScriptingLanguageFactory<ICodeBuilder> {
create(language: ScriptingLanguage): ICodeBuilder;
} }

View File

@@ -6,7 +6,6 @@ import { IEventSource } from '@/infrastructure/Events/IEventSource';
export interface IUserSelection { export interface IUserSelection {
readonly changed: IEventSource<ReadonlyArray<SelectedScript>>; readonly changed: IEventSource<ReadonlyArray<SelectedScript>>;
readonly selectedScripts: ReadonlyArray<SelectedScript>; readonly selectedScripts: ReadonlyArray<SelectedScript>;
readonly totalSelected: number;
areAllSelected(category: ICategory): boolean; areAllSelected(category: ICategory): boolean;
isAnySelected(category: ICategory): boolean; isAnySelected(category: ICategory): boolean;
removeAllInCategory(categoryId: number): void; removeAllInCategory(categoryId: number): void;

View File

@@ -101,10 +101,6 @@ export class UserSelection implements IUserSelection {
return this.scripts.getItems(); return this.scripts.getItems();
} }
public get totalSelected(): number {
return this.scripts.getItems().length;
}
public selectAll(): void { public selectAll(): void {
for (const script of this.collection.getAllScripts()) { for (const script of this.collection.getAllScripts()) {
if (!this.scripts.exists(script.id)) { if (!this.scripts.exists(script.id)) {

View File

@@ -4,17 +4,17 @@ import { IBrowserOsDetector } from './IBrowserOsDetector';
export class BrowserOsDetector implements IBrowserOsDetector { export class BrowserOsDetector implements IBrowserOsDetector {
private readonly detectors = BrowserDetectors; private readonly detectors = BrowserDetectors;
public detect(userAgent: string): OperatingSystem { public detect(userAgent: string): OperatingSystem | undefined {
if (!userAgent) { if (!userAgent) {
return OperatingSystem.Unknown; return undefined;
} }
for (const detector of this.detectors) { for (const detector of this.detectors) {
const os = detector.detect(userAgent); const os = detector.detect(userAgent);
if (os !== OperatingSystem.Unknown) { if (os !== undefined) {
return os; return os;
} }
} }
return OperatingSystem.Unknown; return undefined;
} }
} }

View File

@@ -29,10 +29,10 @@ export class DetectorBuilder {
throw new Error('User agent is null or undefined'); throw new Error('User agent is null or undefined');
} }
if (this.existingPartsInUserAgent.some((part) => !userAgent.includes(part))) { if (this.existingPartsInUserAgent.some((part) => !userAgent.includes(part))) {
return OperatingSystem.Unknown; return undefined;
} }
if (this.notExistingPartsInUserAgent.some((part) => userAgent.includes(part))) { if (this.notExistingPartsInUserAgent.some((part) => userAgent.includes(part))) {
return OperatingSystem.Unknown; return undefined;
} }
return this.os; return this.os;
} }

View File

@@ -1,5 +1,5 @@
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
export interface IBrowserOsDetector { export interface IBrowserOsDetector {
detect(userAgent: string): OperatingSystem; detect(userAgent: string): OperatingSystem | undefined;
} }

View File

@@ -44,7 +44,7 @@ function getProcessPlatform(variables: IEnvironmentVariables): string {
return variables.process.platform; return variables.process.platform;
} }
function getDesktopOsType(processPlatform: string): OperatingSystem { function getDesktopOsType(processPlatform: string): OperatingSystem | undefined {
// https://nodejs.org/api/process.html#process_process_platform // https://nodejs.org/api/process.html#process_process_platform
if (processPlatform === 'darwin') { if (processPlatform === 'darwin') {
return OperatingSystem.macOS; return OperatingSystem.macOS;
@@ -53,7 +53,7 @@ function getDesktopOsType(processPlatform: string): OperatingSystem {
} else if (processPlatform === 'linux') { } else if (processPlatform === 'linux') {
return OperatingSystem.Linux; return OperatingSystem.Linux;
} }
return OperatingSystem.Unknown; return undefined;
} }
function isDesktop(variables: IEnvironmentVariables): boolean { function isDesktop(variables: IEnvironmentVariables): boolean {

View File

@@ -2,19 +2,20 @@ import { Category } from '@/domain/Category';
import { CollectionData } from 'js-yaml-loader!@/*'; import { CollectionData } from 'js-yaml-loader!@/*';
import { parseCategory } from './CategoryParser'; import { parseCategory } from './CategoryParser';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { parseScriptingDefinition } from './ScriptingDefinitionParser';
import { createEnumParser } from '../Common/Enum'; import { createEnumParser } from '../Common/Enum';
import { ICategoryCollection } from '@/domain/ICategoryCollection'; import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { CategoryCollection } from '@/domain/CategoryCollection'; import { CategoryCollection } from '@/domain/CategoryCollection';
import { IProjectInformation } from '@/domain/IProjectInformation'; import { IProjectInformation } from '@/domain/IProjectInformation';
import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext'; import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext';
import { ScriptingDefinitionParser } from './ScriptingDefinition/ScriptingDefinitionParser';
export function parseCategoryCollection( export function parseCategoryCollection(
content: CollectionData, content: CollectionData,
info: IProjectInformation, info: IProjectInformation,
osParser = createEnumParser(OperatingSystem)): ICategoryCollection { osParser = createEnumParser(OperatingSystem)): ICategoryCollection {
validate(content); validate(content);
const scripting = parseScriptingDefinition(content.scripting, info); const scripting = new ScriptingDefinitionParser()
.parse(content.scripting, info);
const context = new CategoryCollectionParseContext(content.functions, scripting); const context = new CategoryCollectionParseContext(content.functions, scripting);
const categories = new Array<Category>(); const categories = new Array<Category>();
for (const action of content.actions) { for (const action of content.actions) {

View File

@@ -1,6 +1,6 @@
import { IScriptingDefinition } from '@/domain/IScriptingDefinition'; import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { ILanguageSyntax } from '@/domain/ScriptCode'; import { ILanguageSyntax } from '@/domain/ScriptCode';
import { FunctionData } from 'js-yaml-loader!*'; import { FunctionData } from 'js-yaml-loader!@/*';
import { IScriptCompiler } from './Compiler/IScriptCompiler'; import { IScriptCompiler } from './Compiler/IScriptCompiler';
import { ScriptCompiler } from './Compiler/ScriptCompiler'; import { ScriptCompiler } from './Compiler/ScriptCompiler';
import { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext'; import { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';

View File

@@ -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;
}

View File

@@ -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}`);
}
}
}

View File

@@ -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;
}

View File

@@ -1,31 +1,49 @@
import { IExpressionsCompiler, ParameterValueDictionary } from './IExpressionsCompiler'; 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 { export class ExpressionsCompiler implements IExpressionsCompiler {
public static readonly instance: IExpressionsCompiler = new ExpressionsCompiler(); public constructor(private readonly extractor: IExpressionParser = new CompositeExpressionParser()) { }
protected constructor() { }
public compileExpressions(code: string, parameters?: ParameterValueDictionary): string { public compileExpressions(code: string, parameters?: ParameterValueDictionary): string {
let intermediateCode = generateIlCode(code); const expressions = this.extractor.findExpressions(code);
intermediateCode = substituteParameters(intermediateCode, parameters); const requiredParameterNames = expressions.map((e) => e.parameters).filter((p) => p).flat();
return intermediateCode.compile(); const uniqueParameterNames = Array.from(new Set(requiredParameterNames));
ensureRequiredArgsProvided(uniqueParameterNames, parameters);
return compileExpressions(expressions, code, parameters);
} }
} }
function substituteParameters(intermediateCode: IILCode, parameters: ParameterValueDictionary): IILCode { function compileExpressions(expressions: IExpression[], code: string, parameters?: ParameterValueDictionary) {
const parameterNames = intermediateCode.getUniqueParameterNames(); let compiledCode = '';
ensureValuesProvided(parameterNames, parameters); expressions = expressions
for (const parameterName of parameterNames) { .slice() // copy the array to not mutate the parameter
const parameterValue = parameters[parameterName]; .sort((a, b) => b.position.start - a.position.start);
intermediateCode = intermediateCode.substituteParameter(parameterName, parameterValue); 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) { function ensureRequiredArgsProvided(parameters: readonly string[], args: ParameterValueDictionary) {
nameValues = nameValues || {}; parameters = parameters || [];
const notProvidedNames = names.filter((name) => !Boolean(nameValues[name])); args = args || {};
if (notProvidedNames.length) { if (!parameters.length) {
throw new Error(`parameter value(s) not provided for: ${printList(notProvidedNames)}`); return;
}
const notProvidedParameters = parameters.filter((parameter) => !Boolean(args[parameter]));
if (notProvidedParameters.length) {
throw new Error(`parameter value(s) not provided for: ${printList(notProvidedParameters)}`);
} }
} }

View File

@@ -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('","')}"`;
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,5 @@
import { IExpression } from '../Expression/IExpression';
export interface IExpressionParser {
findExpressions(code: string): IExpression[];
}

View File

@@ -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[];
}

View File

@@ -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],
};
}
}

View File

@@ -1,4 +1,4 @@
import { FunctionData, InstructionHolder } from 'js-yaml-loader!*'; import { FunctionData, InstructionHolder } from 'js-yaml-loader!@/*';
import { SharedFunction } from './SharedFunction'; import { SharedFunction } from './SharedFunction';
import { SharedFunctionCollection } from './SharedFunctionCollection'; import { SharedFunctionCollection } from './SharedFunctionCollection';
import { ISharedFunctionCollection } from './ISharedFunctionCollection'; import { ISharedFunctionCollection } from './ISharedFunctionCollection';
@@ -49,6 +49,7 @@ function ensureValidFunctions(functions: readonly FunctionData[]) {
ensureNoDuplicatesInParameterNames(functions); ensureNoDuplicatesInParameterNames(functions);
ensureNoDuplicateCode(functions); ensureNoDuplicateCode(functions);
ensureEitherCallOrCodeIsDefined(functions); ensureEitherCallOrCodeIsDefined(functions);
ensureExpectedParameterNameTypes(functions);
} }
function printList(list: readonly string[]): string { 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)}`); 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[]) { function printNames(holders: readonly InstructionHolder[]) {
return printList(holders.map((holder) => holder.name)); return printList(holders.map((holder) => holder.name));
} }

View File

@@ -1,4 +1,4 @@
import { FunctionData } from 'js-yaml-loader!*'; import { FunctionData } from 'js-yaml-loader!@/*';
import { ISharedFunctionCollection } from './ISharedFunctionCollection'; import { ISharedFunctionCollection } from './ISharedFunctionCollection';
export interface IFunctionCompiler { export interface IFunctionCompiler {

View File

@@ -1,9 +1,10 @@
import { ISharedFunction } from './ISharedFunction'; import { ISharedFunction } from './ISharedFunction';
export class SharedFunction implements ISharedFunction { export class SharedFunction implements ISharedFunction {
public readonly parameters: readonly string[];
constructor( constructor(
public readonly name: string, public readonly name: string,
public readonly parameters: readonly string[], parameters: readonly string[],
public readonly code: string, public readonly code: string,
public readonly revertCode: string, public readonly revertCode: string,
) { ) {

View File

@@ -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 { ICompiledCode } from './ICompiledCode';
import { ISharedFunctionCollection } from '../Function/ISharedFunctionCollection'; import { ISharedFunctionCollection } from '../Function/ISharedFunctionCollection';
import { IFunctionCallCompiler } from './IFunctionCallCompiler'; import { IFunctionCallCompiler } from './IFunctionCallCompiler';
@@ -8,7 +8,7 @@ import { ExpressionsCompiler } from '../Expressions/ExpressionsCompiler';
export class FunctionCallCompiler implements IFunctionCallCompiler { export class FunctionCallCompiler implements IFunctionCallCompiler {
public static readonly instance: IFunctionCallCompiler = new FunctionCallCompiler(); public static readonly instance: IFunctionCallCompiler = new FunctionCallCompiler();
protected constructor( protected constructor(
private readonly expressionsCompiler: IExpressionsCompiler = ExpressionsCompiler.instance) { } private readonly expressionsCompiler: IExpressionsCompiler = new ExpressionsCompiler()) { }
public compileCall( public compileCall(
call: ScriptFunctionCallData, call: ScriptFunctionCallData,
functions: ISharedFunctionCollection): ICompiledCode { functions: ISharedFunctionCollection): ICompiledCode {
@@ -32,11 +32,12 @@ export class FunctionCallCompiler implements IFunctionCallCompiler {
} }
function ensureExpectedParameters(func: FunctionData, call: FunctionCallData) { 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; return;
} }
const unexpectedParameters = Object.keys(call.parameters || {}) const unexpectedParameters = actual.filter((callParam) => !expected.includes(callParam));
.filter((callParam) => !func.parameters.includes(callParam));
if (unexpectedParameters.length) { if (unexpectedParameters.length) {
throw new Error( throw new Error(
`function "${func.name}" has unexpected parameter(s) provided: "${unexpectedParameters.join('", "')}"`); `function "${func.name}" has unexpected parameter(s) provided: "${unexpectedParameters.join('", "')}"`);

View File

@@ -1,4 +1,4 @@
import { ScriptFunctionCallData } from 'js-yaml-loader!*'; import { ScriptFunctionCallData } from 'js-yaml-loader!@/*';
import { ICompiledCode } from './ICompiledCode'; import { ICompiledCode } from './ICompiledCode';
import { ISharedFunctionCollection } from '../Function/ISharedFunctionCollection'; import { ISharedFunctionCollection } from '../Function/ISharedFunctionCollection';

View File

@@ -1,6 +1,5 @@
import { ILanguageSyntax } from '@/domain/ScriptCode'; import { ILanguageSyntax } from '@/domain/ScriptCode';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage'; import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
export interface ISyntaxFactory { export interface ISyntaxFactory extends IScriptingLanguageFactory<ILanguageSyntax> {
create(language: ScriptingLanguage): ILanguageSyntax;
} }

View File

@@ -1,15 +1,14 @@
import { ILanguageSyntax } from '@/domain/ScriptCode'; import { ILanguageSyntax } from '@/domain/ScriptCode';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage'; import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ISyntaxFactory } from './ISyntaxFactory'; import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
import { BatchFileSyntax } from './BatchFileSyntax'; import { BatchFileSyntax } from './BatchFileSyntax';
import { ShellScriptSyntax } from './ShellScriptSyntax'; import { ShellScriptSyntax } from './ShellScriptSyntax';
import { ISyntaxFactory } from './ISyntaxFactory';
export class SyntaxFactory implements ISyntaxFactory { export class SyntaxFactory extends ScriptingLanguageFactory<ILanguageSyntax> implements ISyntaxFactory {
public create(language: ScriptingLanguage): ILanguageSyntax { constructor() {
switch (language) { super();
case ScriptingLanguage.batchfile: return new BatchFileSyntax(); this.registerGetter(ScriptingLanguage.batchfile, () => new BatchFileSyntax());
case ScriptingLanguage.shellscript: return new ShellScriptSyntax(); this.registerGetter(ScriptingLanguage.shellscript, () => new ShellScriptSyntax());
default: throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`);
}
} }
} }

View File

@@ -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;
}

View File

@@ -0,0 +1,5 @@
import { IProjectInformation } from '@/domain/IProjectInformation';
export interface ICodeSubstituter {
substitute(code: string, info: IProjectInformation): string;
}

View File

@@ -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,
);
}
}

View File

@@ -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();
}

View File

@@ -1,4 +1,4 @@
declare module 'js-yaml-loader!*' { declare module 'js-yaml-loader!@/*' {
export interface CollectionData { export interface CollectionData {
readonly os: string; readonly os: string;
readonly scripting: ScriptingDefinitionData; readonly scripting: ScriptingDefinitionData;

View File

@@ -83,41 +83,78 @@ actions:
children: children:
- -
name: Clear Safari browsing history name: Clear Safari browsing history
docs:
- https://discussions.apple.com/thread/7586106?answerId=30314600022#30314600022
- https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
code: |- code: |-
rm -f ~/Library/Safari/History.plist rm -f ~/Library/Safari/History.db
rm -f ~/Library/Safari/HistoryIndex.sk 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 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 code: rm -f ~/Library/Safari/Downloads.plist
- -
name: Clear Safari top sites name: Clear Safari top sites
docs: https://davidkoepi.wordpress.com/2013/04/20/safariforensic/
code: rm -f ~/Library/Safari/TopSites.plist 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 code: rm -f ~/Library/Safari/LastSession.plist
- -
name: Clear Safari caches category: Clear Safari caches
code: |- children:
rm -f ~/Library/Caches/com.apple.Safari/Cache.db -
rm -f ~/Library/Safari/WebpageIcons.db name: Clear Safari cached blobs, URLs and timestamps
rm -rf ~/Library/Caches/com.apple.Safari/Webpage Previews 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 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 name: Clear search history embedded in Safari preferences
docs: https://krypted.com/tag/recentsearchstrings/
code: defaults write ~/Library/Preferences/com.apple.Safari RecentSearchStrings '( )' code: defaults write ~/Library/Preferences/com.apple.Safari RecentSearchStrings '( )'
- -
name: Clear Safari cookies 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 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 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 code: rm -f ~/Library/Safari/UserNotificationPreferences.plist
- -
name: Clear Safari per-site preferences for Downloads, Geolocation, PopUps, and Autoplays 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 code: rm -f ~/Library/Safari/PerSitePreferences.db
- -
category: Clear Firefox history category: Clear Firefox history
@@ -148,7 +185,7 @@ actions:
rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/sessionstore-backups/upgrade.js*-20* rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/sessionstore-backups/upgrade.js*-20*
- -
name: Delete Firefox passwords 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: |- code: |-
rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/signons.txt rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/signons.txt
rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/signons2.txt rm -fv ~/Library/Application\ Support/Firefox/Profiles/*/signons2.txt
@@ -400,7 +437,7 @@ actions:
- -
name: Disable PowerShell Core telemetry name: Disable PowerShell Core telemetry
recommend: standard 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: call:
- -
function: PersistUserEnvironmentConfiguration function: PersistUserEnvironmentConfiguration

View File

@@ -600,7 +600,7 @@ actions:
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" /v "PreventDeviceMetadataFromNetwork" /t REG_DWORD /d 0 /f 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 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 recommend: strict
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" /v "ExcludeWUDriversInQualityUpdate" /t REG_DWORD /d 1 /f 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 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 name: Disable cloud speech recognition
recommend: standard 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 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 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 name: Disable Windows feedback
recommend: standard 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: |- code: |-
reg add "HKCU\SOFTWARE\Microsoft\Siuf\Rules" /v "NumberOfSIUFInPeriod" /t REG_DWORD /d 0 /f 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 reg delete "HKCU\SOFTWARE\Microsoft\Siuf\Rules" /v "PeriodInNanoSeconds" /f
@@ -656,8 +656,9 @@ actions:
name: Deny app access to location name: Deny app access to location
recommend: standard recommend: standard
docs: 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 # LetAppsAccessLocation
- https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-privacy#privacy-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: |- code: |-
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" /v "Value" /d "Deny" /f reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" /v "Value" /d "Deny" /f
:: For older Windows (before 1903) :: 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 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 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: children:
- -
name: Disable apps and Cortana to activate with voice name: Disable apps and Cortana to activate with voice
@@ -1248,45 +1248,72 @@ actions:
- -
name: Disable ad customization with Advertising ID name: Disable ad customization with Advertising ID
recommend: standard recommend: standard
docs: https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#181-general
code: |- code: |-
reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo" /v "Enabled" /t REG_DWORD /d 0 /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 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
- -
name: Disable targeted tips category: Disable cloud-based tips and ads
children:
-
name: Disable Windows Tips
recommend: standard recommend: standard
code: |- docs: https://admx.help/?Category=Windows_10_2016&Policy=Microsoft.Policies.CloudContent::DisableSoftLanding
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableSoftLanding" /t REG_DWORD /d 1 /f 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 revertCode: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableSoftLanding" /t REG_DWORD /d "0" /f
reg add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t "REG_DWORD" /d "1" /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: Turn Off Suggested Content in Settings app name: Turn Off Suggested Content in Settings app
recommend: standard 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: |- 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-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-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-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) category: Disable biometrics (breaks fingerprinting/facial login)
children: children:
- -
name: Do not allow the use of biometrics name: Do not allow the use of biometrics
recommend: strict 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 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 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 name: Do not allow users to log on using biometrics
recommend: strict 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 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 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 name: Do not start Windows Biometric Service
recommend: strict recommend: strict
docs: docs: https://docs.microsoft.com/en-us/windows-server/security/windows-services/security-guidelines-for-disabling-system-services-in-windows-server#windows-biometric-service
- http://batcmd.com/windows/10/services/wbiosrvc/
- http://revertservice.com/10/wbiosrvc/
code: |- code: |-
reg add "HKLM\SYSTEM\CurrentControlSet\Services\WbioSrvc" /v "Start" /t REG_DWORD /d 4 /f reg add "HKLM\SYSTEM\CurrentControlSet\Services\WbioSrvc" /v "Start" /t REG_DWORD /d 4 /f
sc stop "WbioSrvc" & sc config "WbioSrvc" start=disabled sc stop "WbioSrvc" & sc config "WbioSrvc" start=disabled
@@ -1314,7 +1341,7 @@ actions:
- -
name: Disable Website Access of Language List name: Disable Website Access of Language List
recommend: standard 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 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 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 reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\GameDVR" /v "AllowGameDVR" /t REG_DWORD /d 0 /f
- -
name: Disable Windows DRM internet access 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 recommend: standard
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\WMDRM" /v "DisableOnline" /t REG_DWORD /d 1 /f code: reg add "HKLM\SOFTWARE\Policies\Microsoft\WMDRM" /v "DisableOnline" /t REG_DWORD /d 1 /f
- -
@@ -1353,13 +1380,13 @@ actions:
children: children:
- -
name: Disable Windows Insider Service 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 recommend: standard
code: sc stop "wisvc" & sc config "wisvc" start=disabled code: sc stop "wisvc" & sc config "wisvc" start=disabled
revertCode: sc config "wisvc" start=demand revertCode: sc config "wisvc" start=demand
- -
name: Do not let Microsoft try features on this build 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 recommend: standard
code: |- code: |-
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v "EnableExperimentation" /t REG_DWORD /d 0 /f 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 reg delete "HKLM\SOFTWARE\Microsoft\PolicyManager\default\System\AllowExperimentation" /v "value" /f
- -
name: Disable getting preview builds of Windows 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 recommend: standard
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v "AllowBuildPreview" /t REG_DWORD /d 0 /f 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 revertCode: reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds" /v "AllowBuildPreview" /f
- -
name: Remove "Windows Insider Program" from Settings 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 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 revertCode: reg delete "HKLM\SOFTWARE\Microsoft\WindowsSelfHost\UI\Visibility" /v "HideInsiderPage" /f
- -
@@ -1445,7 +1472,10 @@ actions:
- -
name: Disable Language Setting Sync name: Disable Language Setting Sync
recommend: standard 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 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 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 name: Do not send Watson events
recommend: standard 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 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 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 recommend: standard
docs: docs:
- https://www.stigviewer.com/stig/windows_defender_antivirus/2017-12-27/finding/V-75161 - 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 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 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 recommend: standard
docs: docs:
- https://www.stigviewer.com/stig/windows_7/2012-07-02/finding/V-15713 - 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 - 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 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 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 name: Disable Malicious Software Reporting tool diagnostic data
recommend: standard 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 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 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 category: Chromium Edge settings
children: 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 recommend: standard
docs: docs:
- https://admx.help/?Category=EdgeChromium&Policy=Microsoft.Policies.Edge::MetricsReportingEnabled - 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 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 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 recommend: standard
docs: docs:
- https://admx.help/?Category=EdgeChromium&Policy=Microsoft.Policies.Edge::SendSiteInfoToImproveServices - 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 revertCode: reg delete "HKLM\SOFTWARE\Policies\Microsoft\Edge" /v "SendSiteInfoToImproveServices" /f
- -
name: Disable Automatic Installation of Microsoft Edge Chromium 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 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 revertCode: reg delete "HKLM\SOFTWARE\Microsoft\EdgeUpdate" /v "DoNotUpdateToEdgeWithChromium" /f
- -
@@ -1819,26 +1851,26 @@ actions:
- -
name: Disable MFU tracking name: Disable MFU tracking
recommend: standard 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 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 revertCode: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "DisableMFUTracking" /t REG_DWORD /d 0 /f
- -
name: Disable recent apps name: Disable recent apps
recommend: standard 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 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 revertCode: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "DisableRecentApps" /t REG_DWORD /d 0/f
- -
name: Turn off backtracking name: Turn off backtracking
recommend: standard 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 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 revertCode: reg add "HKCU\Software\Policies\Microsoft\Windows\EdgeUI" /v "TurnOffBackstack" /t REG_DWORD /d 0 /f
- -
name: Disable Search Suggestions in Edge name: Disable Search Suggestions in Edge
docs: docs:
- https://docs.microsoft.com/en-us/microsoft-edge/deploy/group-policies/address-bar-settings-gp - 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 recommend: standard
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftEdge\SearchScopes" /v "ShowSearchSuggestionsGlobal" /t REG_DWORD /d 0 /f 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 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 category: Chrome cleanup
children: 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 recommend: standard
docs: docs:
- https://www.chromium.org/administrators/policy-list-3#ChromeCleanupReportingEnabled - 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 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 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 recommend: standard
docs: docs:
- https://www.chromium.org/administrators/policy-list-3#ChromeCleanupEnabled - 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 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 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 recommend: standard
docs: https://www.stigviewer.com/stig/google_chrome_v23_windows/2013-01-11/finding/V-35780 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 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 "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 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 recommend: standard
code: sc stop "WMPNetworkSvc" & sc config "WMPNetworkSvc" start=disabled code: sc stop "WMPNetworkSvc" & sc config "WMPNetworkSvc" start=disabled
- -
@@ -2598,20 +2630,20 @@ actions:
- -
name: Disable online tips name: Disable online tips
recommend: standard 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 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 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 name: Turn off Internet File Association service
recommend: standard 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 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 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 name: Turn off the "Order Prints" picture task
recommend: standard recommend: standard
docs: 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 - 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 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 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 name: Do not keep history of recently opened documents
recommend: strict 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 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 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 name: Clear history of recently opened documents on exit
recommend: strict 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 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 revertCode: reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v "ClearRecentDocsOnExit" /t REG_DWORD /d 01 /f
- -
name: Disable Live Tiles push notifications name: Disable Live Tiles push notifications
recommend: standard 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 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 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 recommend: standard
docs: docs:
- https://www.stigviewer.com/stig/microsoft_windows_server_2012_member_server/2013-07-25/finding/WN12-CC-000030 - 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 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 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 name: Do not show recently used files in Quick Access
recommend: strict 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: |- 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
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v "ShowRecent" /d 0 /t REG_DWORD /f
) else (
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 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
) )
revertCode: 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
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v "ShowRecent" /d 1 /t REG_DWORD /f
) else (
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 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
) )
- -
name: Disable Sync Provider Notifications 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 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 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 code: powercfg -h off
revertCode: powercfg -h on revertCode: powercfg -h on
- -
name: Enable camera on/off OSD notifications 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 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 revertCode: reg delete "HKLM\Software\Microsoft\OEM\Device\Capture" /v "NoPhysicalCameraLED" /f
- -
@@ -2702,11 +2738,11 @@ actions:
- -
name: Desktop name: Desktop
code: |- 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\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\{31C0DD25-9439-4F12-BF41-7FF4EDA38722}\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: |- 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\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\{31C0DD25-9439-4F12-BF41-7FF4EDA38722}\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 name: Documents
code: |- code: |-
@@ -2825,14 +2861,18 @@ actions:
code: sc stop "XboxNetApiSvc" & sc config "XboxNetApiSvc" start=disabled code: sc stop "XboxNetApiSvc" & sc config "XboxNetApiSvc" start=disabled
revertCode: sc config "XboxNetApiSvc" start=demand revertCode: sc config "XboxNetApiSvc" start=demand
- -
name: 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: standard recommend: strict
docs: https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service 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 code: sc stop "VSS" & sc config "VSS" start=disabled
revertCode: sc config "VSS" start=demand revertCode: sc config "VSS" start=demand
- -
name: Disable NetBios for all interfaces 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: call:
function: RunPowerShell function: RunPowerShell
parameters: parameters:
@@ -2986,7 +3026,7 @@ actions:
packageName: Microsoft.Messaging packageName: Microsoft.Messaging
- -
name: Mixed Reality Portal app 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: call:
function: UninstallStoreApp function: UninstallStoreApp
parameters: parameters:
@@ -3004,7 +3044,7 @@ actions:
packageName: Microsoft.MicrosoftOfficeHub packageName: Microsoft.MicrosoftOfficeHub
- -
name: OneNote app 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: call:
function: UninstallStoreApp function: UninstallStoreApp
parameters: parameters:
@@ -3454,7 +3494,7 @@ actions:
packageName: Microsoft.ECApp packageName: Microsoft.ECApp
- -
name: Lock app (shows lock screen) 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: call:
function: UninstallSystemApp function: UninstallSystemApp
parameters: parameters:
@@ -3511,7 +3551,7 @@ actions:
parameters: parameters:
packageName: Microsoft.Windows.CapturePicker 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 recommend: strict
call: call:
function: UninstallSystemApp function: UninstallSystemApp
@@ -3776,22 +3816,31 @@ actions:
children: children:
- -
name: Direct Play feature name: Direct Play feature
code: dism /Online /Disable-Feature /FeatureName:"DirectPlay" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"DirectPlay" /NoRestart function: DisableFeature
parameters:
featureName: DirectPlay
- -
name: Internet Explorer feature name: Internet Explorer feature
code: |- call:
dism /Online /Disable-Feature /FeatureName:"Internet-Explorer-Optional-x64" /NoRestart -
dism /Online /Disable-Feature /FeatureName:"Internet-Explorer-Optional-x84" /NoRestart function: DisableFeature
dism /Online /Disable-Feature /FeatureName:"Internet-Explorer-Optional-amd64" /NoRestart parameters:
revertCode: |- featureName: Internet-Explorer-Optional-x64
dism /Online /Enable-Feature /FeatureName:"Internet-Explorer-Optional-x64" /NoRestart -
dism /Online /Enable-Feature /FeatureName:"Internet-Explorer-Optional-x84" /NoRestart function: DisableFeature
dism /Online /Enable-Feature /FeatureName:"Internet-Explorer-Optional-amd64" /NoRestart parameters:
featureName: Internet-Explorer-Optional-x84
-
function: DisableFeature
parameters:
featureName: Internet-Explorer-Optional-amd64
- -
name: Legacy Components feature name: Legacy Components feature
code: dism /Online /Disable-Feature /FeatureName:"LegacyComponents" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"LegacyComponents" /NoRestart function: DisableFeature
parameters:
featureName: LegacyComponents
- -
category: Server features for developers & administrators category: Server features for developers & administrators
children: children:
@@ -3800,39 +3849,55 @@ actions:
children: children:
- -
name: Hyper-V feature name: Hyper-V feature
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-All" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-All" /NoRestart function: DisableFeature
parameters:
featureName: Microsoft-Hyper-V-All
- -
name: Hyper-V GUI Management Tools feature name: Hyper-V GUI Management Tools feature
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-Management-Clients" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-Management-Clients" /NoRestart function: DisableFeature
parameters:
featureName: Microsoft-Hyper-V-Management-Clients
- -
name: Hyper-V Management Tools feature name: Hyper-V Management Tools feature
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-Tools-All" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-Tools-All" /NoRestart function: DisableFeature
parameters:
featureName: Microsoft-Hyper-V-Tools-All
- -
name: Hyper-V Module for Windows PowerShell feature name: Hyper-V Module for Windows PowerShell feature
code: dism /Online /Disable-Feature /FeatureName:"Microsoft-Hyper-V-Management-PowerShell" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Microsoft-Hyper-V-Management-PowerShell" /NoRestart function: DisableFeature
parameters:
featureName: Microsoft-Hyper-V-Management-PowerShell
- -
name: Telnet Client feature 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 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 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 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 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 docs: https://docs.microsoft.com/en-us/windows-server/storage/file-server/smb-direct
call:
function: DisableFeature
parameters:
featureName: SmbDirect
- -
name: TFTP Client feature name: TFTP Client feature
code: dism /Online /Disable-Feature /FeatureName:"TFTP" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"TFTP" /NoRestart function: DisableFeature
parameters:
featureName: TFTP
- -
category: Printing features category: Printing features
children: children:
@@ -3841,60 +3906,86 @@ actions:
children: children:
- -
name: Internet Printing Client name: Internet Printing Client
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-InternetPrinting-Client" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-InternetPrinting-Client" /NoRestart function: DisableFeature
parameters:
featureName: Printing-Foundation-InternetPrinting-Client
- -
name: LPD Print Service name: LPD Print Service
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-LPDPrintService" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-LPDPrintService" /NoRestart function: DisableFeature
parameters:
featureName: LPDPrintService
- -
name: LPR Port Monitor feature name: LPR Port Monitor feature
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-LPRPortMonitor" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-LPRPortMonitor" /NoRestart function: DisableFeature
parameters:
featureName: Printing-Foundation-LPRPortMonitor
- -
name: Microsoft Print to PDF feature name: Microsoft Print to PDF feature
code: dism /Online /Disable-Feature /FeatureName:"Printing-PrintToPDFServices-Features" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-PrintToPDFServices-Features" /NoRestart function: DisableFeature
parameters:
featureName: Printing-PrintToPDFServices-Features
- -
name: Print and Document Services feature name: Print and Document Services feature
code: dism /Online /Disable-Feature /FeatureName:"Printing-Foundation-Features" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-Foundation-Features" /NoRestart function: DisableFeature
parameters:
featureName: Printing-Foundation-Features
- -
name: Work Folders Client feature 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 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 category: XPS support
children: children:
- -
name: XPS Services feature name: XPS Services feature
code: dism /Online /Disable-Feature /FeatureName:"Printing-XPSServices-Features" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Printing-XPSServices-Features" /NoRestart function: DisableFeature
parameters:
featureName: Printing-XPSServices-Features
- -
name: XPS Viewer feature name: XPS Viewer feature
code: dism /Online /Disable-Feature /FeatureName:"Xps-Foundation-Xps-Viewer" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"Xps-Foundation-Xps-Viewer" /NoRestart function: DisableFeature
parameters:
featureName: Xps-Foundation-Xps-Viewer
- -
name: Media Features feature name: Media Features feature
code: dism /Online /Disable-Feature /FeatureName:"MediaPlayback" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"MediaPlayback" /NoRestart function: DisableFeature
parameters:
featureName: MediaPlayback
- -
name: Scan Management feature name: Scan Management feature
code: dism /Online /Disable-Feature /FeatureName:"ScanManagementConsole" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"ScanManagementConsole" /NoRestart function: DisableFeature
parameters:
featureName: ScanManagementConsole
- -
name: Windows Fax and Scan feature name: Windows Fax and Scan feature
code: dism /Online /Disable-Feature /FeatureName:"FaxServicesClientPackage" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"FaxServicesClientPackage" /NoRestart function: DisableFeature
parameters:
featureName: FaxServicesClientPackage
- -
name: Windows Media Player feature name: Windows Media Player feature
code: dism /Online /Disable-Feature /FeatureName:"WindowsMediaPlayer" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"WindowsMediaPlayer" /NoRestart function: DisableFeature
parameters:
featureName: WindowsMediaPlayer
- -
name: Windows Search feature name: Windows Search feature
code: dism /Online /Disable-Feature /FeatureName:"SearchEngine-Client-Package" /NoRestart call:
revertCode: dism /Online /Enable-Feature /FeatureName:"SearchEngine-Client-Package" /NoRestart function: DisableFeature
parameters:
featureName: SearchEngine-Client-Package
- -
category: Uninstall capabilities & features on demand 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 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: |- code: |-
:: Configure time source :: Configure time source
w32tm /config /syncfromflags:manual /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" 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||( SC queryex "w32time"|Find "STATE"|Find /v "RUNNING">Nul||(
net stop w32time net stop w32time
net start w32time
) )
:: Sync now :: Start time service and sync now
net start w32time
w32tm /config /update w32tm /config /update
w32tm /resync w32tm /resync
revertCode: |- revertCode: |-
:: Configure time source :: Configure time source
w32tm /config /syncfromflags:manual /manualpeerlist:"time.windows.com" 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||( SC queryex "w32time"|Find "STATE"|Find /v "RUNNING">Nul||(
net stop w32time net stop w32time
net start w32time
) )
:: Sync now :: Start time servie and sync now
net start w32time
w32tm /config /update w32tm /config /update
w32tm /resync w32tm /resync
- -
name: Disable Reserved Storage for updates name: Disable Reserved Storage for updates # since 19H1 (1903)
docs: docs:
- https://techcommunity.microsoft.com/t5/storage-at-microsoft/windows-10-and-reserved-storage/ba-p/428327 - https://techcommunity.microsoft.com/t5/storage-at-microsoft/windows-10-and-reserved-storage/ba-p/428327 # Announcement
- https://www.tenforums.com/tutorials/124858-enable-disable-reserved-storage-windows-10-a.html - 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: |- code: |-
dism /online /Set-ReservedStorageState /State:Disabled /NoRestart dism /online /Set-ReservedStorageState /State:Disabled /NoRestart
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager" /v "MiscPolicyInfo" /t REG_DWORD /d "2" /f 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 # 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 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 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 name: UninstallStoreApp
parameters: [ packageName ] parameters: [ packageName ]

View File

@@ -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 { IEntity } from '../infrastructure/Entity/IEntity';
import { ICategory } from './ICategory'; import { ICategory } from './ICategory';
import { IScript } from './IScript'; import { IScript } from './IScript';
@@ -21,7 +21,7 @@ export class CategoryCollection implements ICategoryCollection {
throw new Error('undefined scripting definition'); throw new Error('undefined scripting definition');
} }
this.queryable = makeQueryable(actions); this.queryable = makeQueryable(actions);
ensureValidOs(os); assertInRange(os, OperatingSystem);
ensureValid(this.queryable); ensureValid(this.queryable);
ensureNoDuplicates(this.queryable.allCategories); ensureNoDuplicates(this.queryable.allCategories);
ensureNoDuplicates(this.queryable.allScripts); 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>>) { function ensureNoDuplicates<TKey>(entities: ReadonlyArray<IEntity<TKey>>) {
const totalOccurrencesById = new Map<TKey, number>(); const totalOccurrencesById = new Map<TKey, number>();
for (const entity of entities) { for (const entity of entities) {

View File

@@ -10,5 +10,4 @@ export enum OperatingSystem {
Android, Android,
iOS, iOS,
WindowsPhone, WindowsPhone,
Unknown,
} }

View File

@@ -1,5 +1,6 @@
import { IProjectInformation } from './IProjectInformation'; import { IProjectInformation } from './IProjectInformation';
import { OperatingSystem } from './OperatingSystem'; import { OperatingSystem } from './OperatingSystem';
import { assertInRange } from '@/application/Common/Enum';
export class ProjectInformation implements IProjectInformation { export class ProjectInformation implements IProjectInformation {
public readonly repositoryWebUrl: string; public readonly repositoryWebUrl: string;
@@ -42,6 +43,7 @@ function getWebUrl(gitUrl: string) {
} }
function getFileName(os: OperatingSystem, version: string): string { function getFileName(os: OperatingSystem, version: string): string {
assertInRange(os, OperatingSystem);
switch (os) { switch (os) {
case OperatingSystem.Linux: case OperatingSystem.Linux:
return `privacy.sexy-${version}.AppImage`; return `privacy.sexy-${version}.AppImage`;
@@ -50,6 +52,6 @@ function getFileName(os: OperatingSystem, version: string): string {
case OperatingSystem.Windows: case OperatingSystem.Windows:
return `privacy.sexy-Setup-${version}.exe`; return `privacy.sexy-Setup-${version}.exe`;
default: default:
throw new Error(`Unsupported os: ${OperatingSystem[os]}`); throw new RangeError(`Unsupported os: ${OperatingSystem[os]}`);
} }
} }

View File

@@ -7,16 +7,7 @@ export class ScriptCode implements IScriptCode {
syntax: ILanguageSyntax) { syntax: ILanguageSyntax) {
if (!syntax) { throw new Error('undefined syntax'); } if (!syntax) { throw new Error('undefined syntax'); }
validateCode(execute, syntax); validateCode(execute, syntax);
if (revert) { validateRevertCode(revert, execute, syntax);
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}`);
}
}
} }
} }
@@ -25,6 +16,20 @@ export interface ILanguageSyntax {
readonly commonCodeParts: string[]; 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 { function validateCode(code: string, syntax: ILanguageSyntax): void {
if (!code || code.length === 0) { if (!code || code.length === 0) {
throw new Error(`code is empty or undefined`); 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); const duplicateLines = lines.filter((e, i, a) => a.indexOf(e) !== i);
if (duplicateLines.length !== 0) { 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')}`);
} }
} }

View File

@@ -5,16 +5,20 @@ import fs from 'fs';
import child_process from 'child_process'; import child_process from 'child_process';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
export async function runCodeAsync( export class CodeRunner {
code: string, folderName: string, fileExtension: string, constructor(
node = getNodeJs(), environment = Environment.CurrentEnvironment): Promise<void> { private readonly node = getNodeJs(),
const dir = node.path.join(node.os.tmpdir(), folderName); private readonly environment = Environment.CurrentEnvironment) {
await node.fs.promises.mkdir(dir, {recursive: true}); }
const filePath = node.path.join(dir, `run.${fileExtension}`); public async runCodeAsync(code: string, folderName: string, fileExtension: string): Promise<void> {
await node.fs.promises.writeFile(filePath, code); const dir = this.node.path.join(this.node.os.tmpdir(), folderName);
await node.fs.promises.chmod(filePath, '755'); await this.node.fs.promises.mkdir(dir, {recursive: true});
const command = getExecuteCommand(filePath, environment); const filePath = this.node.path.join(dir, `run.${fileExtension}`);
node.child_process.exec(command); 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 { function getExecuteCommand(scriptPath: string, environment: Environment): string {

View 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));
}

View File

@@ -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>

View File

@@ -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(),
};

View File

@@ -1,6 +1,10 @@
'use strict'; '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 { createProtocol } from 'vue-cli-plugin-electron-builder/lib';
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'; import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer';
import path from 'path'; import path from 'path';
@@ -30,10 +34,12 @@ if (!process.env.IS_TEST) {
function createWindow() { function createWindow() {
// Create the browser window. // Create the browser window.
const size = getWindowSize(1350, 955);
win = new BrowserWindow({ win = new BrowserWindow({
width: 1350, width: size.width,
height: 955, height: size.height,
webPreferences: { webPreferences: {
contextIsolation: false, // To reach node https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/1285
// Use pluginOptions.nodeIntegration, leave this alone // Use pluginOptions.nodeIntegration, leave this alone
// See https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration // See https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration
nodeIntegration: (process.env nodeIntegration: (process.env
@@ -110,14 +116,14 @@ if (isDevelopment) {
function loadApplication(window: BrowserWindow) { function loadApplication(window: BrowserWindow) {
if (process.env.WEBPACK_DEV_SERVER_URL) { if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode // 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) { if (!process.env.IS_TEST) {
win.webContents.openDevTools(); win.webContents.openDevTools();
} }
} else { } else {
createProtocol('app'); createProtocol('app');
// Load the index.html when not in development // 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 // 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 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 };
}

View File

@@ -12,11 +12,11 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator'; import { Component, Vue } from 'vue-property-decorator';
import TheHeader from '@/presentation/TheHeader.vue'; import TheHeader from '@/presentation/components/TheHeader.vue';
import TheFooter from '@/presentation/TheFooter/TheFooter.vue'; import TheFooter from '@/presentation/components/TheFooter/TheFooter.vue';
import TheCodeButtons from '@/presentation/Code/CodeButtons/TheCodeButtons.vue'; import TheCodeButtons from '@/presentation/components/Code/CodeButtons/TheCodeButtons.vue';
import TheScriptArea from '@/presentation/Scripts/TheScriptArea.vue'; import TheScriptArea from '@/presentation/components/Scripts/TheScriptArea.vue';
import TheSearchBar from '@/presentation/TheSearchBar.vue'; import TheSearchBar from '@/presentation/components/TheSearchBar.vue';
@Component({ @Component({
components: { components: {

View File

@@ -17,25 +17,18 @@
v-on:click="copyCodeAsync" v-on:click="copyCodeAsync"
icon-prefix="fas" icon-name="copy"> icon-prefix="fas" icon-name="copy">
</IconButton> </IconButton>
<modal :name="macOsModalName" height="auto" :scrollable="true" :adaptive="true" <Dialog v-if="this.isMacOsCollection" ref="instructionsDialog">
v-if="this.isMacOsCollection">
<div class="modal">
<div class="modal__content">
<MacOsInstructions :fileName="this.fileName" /> <MacOsInstructions :fileName="this.fileName" />
</div> </Dialog>
<div class="modal__close-button">
<font-awesome-icon :icon="['fas', 'times']" @click="$modal.hide(macOsModalName)"/>
</div>
</div>
</modal>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component } from 'vue-property-decorator'; 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 { SaveFileDialog, FileType } from '@/infrastructure/SaveFileDialog';
import { Clipboard } from '@/infrastructure/Clipboard'; import { Clipboard } from '@/infrastructure/Clipboard';
import Dialog from '@/presentation/components/Shared/Dialog.vue';
import IconButton from './IconButton.vue'; import IconButton from './IconButton.vue';
import MacOsInstructions from './MacOsInstructions.vue'; import MacOsInstructions from './MacOsInstructions.vue';
import { Environment } from '@/application/Environment/Environment'; import { Environment } from '@/application/Environment/Environment';
@@ -44,18 +37,17 @@ import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { IApplicationCode } from '@/application/Context/State/Code/IApplicationCode'; import { IApplicationCode } from '@/application/Context/State/Code/IApplicationCode';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition'; import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { runCodeAsync } from '@/infrastructure/CodeRunner'; import { CodeRunner } from '@/infrastructure/CodeRunner';
import { IApplicationContext } from '@/application/Context/IApplicationContext'; import { IApplicationContext } from '@/application/Context/IApplicationContext';
@Component({ @Component({
components: { components: {
IconButton, IconButton,
MacOsInstructions, MacOsInstructions,
Dialog,
}, },
}) })
export default class TheCodeButtons extends StatefulVue { export default class TheCodeButtons extends StatefulVue {
public readonly macOsModalName = 'macos-instructions';
public readonly isDesktopVersion = Environment.CurrentEnvironment.isDesktop; public readonly isDesktopVersion = Environment.CurrentEnvironment.isDesktop;
public canRun = false; public canRun = false;
public hasCode = false; public hasCode = false;
@@ -70,7 +62,7 @@ export default class TheCodeButtons extends StatefulVue {
const context = await this.getCurrentContextAsync(); const context = await this.getCurrentContextAsync();
saveCode(this.fileName, context.state); saveCode(this.fileName, context.state);
if (this.isMacOsCollection) { if (this.isMacOsCollection) {
this.$modal.show(this.macOsModalName); (this.$refs.instructionsDialog as any).show();
} }
} }
public async executeCodeAsync() { public async executeCodeAsync() {
@@ -124,7 +116,8 @@ function buildFileName(scripting: IScriptingDefinition) {
} }
async function executeCodeAsync(context: IApplicationContext) { async function executeCodeAsync(context: IApplicationContext) {
await runCodeAsync( const runner = new CodeRunner();
await runner.runCodeAsync(
/*code*/ context.state.code.current, /*code*/ context.state.code.current,
/*appName*/ context.app.info.name, /*appName*/ context.app.info.name,
/*fileExtension*/ context.state.collection.scripting.fileExtension, /*fileExtension*/ context.state.collection.scripting.fileExtension,
@@ -134,9 +127,6 @@ async function executeCodeAsync(context: IApplicationContext) {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/presentation/styles/colors.scss";
@import "@/presentation/styles/fonts.scss";
.container { .container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -145,26 +135,4 @@ async function executeCodeAsync(context: IApplicationContext) {
.container > * + * { .container > * + * {
margin-left: 30px; 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> </style>

View File

@@ -9,7 +9,7 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop } from 'vue-property-decorator'; 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 from 'ace-builds';
import 'ace-builds/webpack-resolver'; import 'ace-builds/webpack-resolver';
import { ICodeChangedEvent } from '@/application/Context/State/Code/Event/ICodeChangedEvent'; import { ICodeChangedEvent } from '@/application/Context/State/Code/Event/ICodeChangedEvent';
@@ -17,7 +17,7 @@ import { IScript } from '@/domain/IScript';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage'; import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState'; import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
import { CodeBuilderFactory } from '@/application/Context/State/Code/Generation/CodeBuilderFactory'; import { CodeBuilderFactory } from '@/application/Context/State/Code/Generation/CodeBuilderFactory';
import Responsive from '@/presentation/Responsive.vue'; import Responsive from '@/presentation/components/Shared/Responsive.vue';
@Component({ @Component({
components: { components: {

View File

@@ -26,9 +26,9 @@
<script lang="ts"> <script lang="ts">
import CardListItem from './CardListItem.vue'; 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 { Component } from 'vue-property-decorator';
import { StatefulVue } from '@/presentation/StatefulVue'; import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
import { ICategory } from '@/domain/ICategory'; import { ICategory } from '@/domain/ICategory';
import { hasDirective } from './NonCollapsingDirective'; import { hasDirective } from './NonCollapsingDirective';
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState'; import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';

View File

@@ -33,8 +33,8 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop, Watch, Emit } from 'vue-property-decorator'; import { Component, Prop, Watch, Emit } from 'vue-property-decorator';
import ScriptsTree from '@/presentation/Scripts/ScriptsTree/ScriptsTree.vue'; import ScriptsTree from '@/presentation/components/Scripts/ScriptsTree/ScriptsTree.vue';
import { StatefulVue } from '@/presentation/StatefulVue'; import { StatefulVue } from '@/presentation/components/Shared/StatefulVue';
@Component({ @Component({
components: { components: {

View File

@@ -1,15 +1,20 @@
<template> <template>
<div class="container"> <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">
<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> </div>
</template> </template>
@@ -17,10 +22,17 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator'; import { Component, Vue } from 'vue-property-decorator';
import { Grouping } from './Grouping'; import { Grouping } from './Grouping';
import MenuOptionList from './../MenuOptionList.vue';
import MenuOptionListItem from './../MenuOptionListItem.vue';
const DefaultGrouping = Grouping.Cards; const DefaultGrouping = Grouping.Cards;
@Component @Component({
components: {
MenuOptionList,
MenuOptionListItem,
},
})
export default class TheGrouper extends Vue { export default class TheGrouper extends Vue {
public cardsSelected = false; public cardsSelected = false;
public noneSelected = false; public noneSelected = false;
@@ -50,29 +62,5 @@ export default class TheGrouper extends Vue {
</script> </script>
<style scoped lang="scss"> <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> </style>

View 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>

View File

@@ -1,18 +1,20 @@
<template> <template>
<span> <!-- Parent wrapper allows adding content inside with CSS without making it clickable -->
<span <span
v-bind:class="{ 'disabled': enabled, 'enabled': !enabled}" v-bind:class="{ 'disabled': !enabled, 'enabled': enabled}"
v-non-collapsing v-non-collapsing
@click="onClicked()">{{label}}</span> @click="enabled && onClicked()">{{label}}</span>
</span>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Prop, Emit, Vue } from 'vue-property-decorator'; 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({ @Component({
directives: { NonCollapsing }, directives: { NonCollapsing },
}) })
export default class SelectableOption extends Vue { export default class MenuOptionListItem extends Vue {
@Prop() public enabled: boolean; @Prop() public enabled: boolean;
@Prop() public label: string; @Prop() public label: string;
@Emit('click') public onClicked() { return; } @Emit('click') public onClicked() { return; }

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -1,30 +1,32 @@
<template> <template>
<div class="container"> <MenuOptionList>
<!-- <div>OS:</div> --> <MenuOptionListItem
<div class="os-list"> v-for="os in this.allOses" :key="os.name"
<div v-for="os in this.allOses" :key="os.name"> :enabled="currentOs !== os.os"
<span @click="changeOsAsync(os.os)"
class="os-name" :label="os.name"
v-bind:class="{ 'current': currentOs === os.os }" />
v-on:click="changeOsAsync(os.os)"> </MenuOptionList>
{{ os.name }}
</span>
</div>
</div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component } from 'vue-property-decorator'; import { Component } from 'vue-property-decorator';
import { OperatingSystem } from '@/domain/OperatingSystem'; 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 { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
import { ApplicationFactory } from '@/application/ApplicationFactory'; 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 { export default class TheOsChanger extends StatefulVue {
public allOses: Array<{ name: string, os: OperatingSystem }> = []; public allOses: Array<{ name: string, os: OperatingSystem }> = [];
public currentOs: OperatingSystem = OperatingSystem.Unknown; public currentOs?: OperatingSystem = null;
public async created() { public async created() {
const app = await ApplicationFactory.Current.getAppAsync(); const app = await ApplicationFactory.Current.getAppAsync();
@@ -52,31 +54,5 @@ function renderOsName(os: OperatingSystem): string {
</script> </script>
<style scoped lang="scss"> <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> </style>

View File

@@ -14,7 +14,7 @@ import { Component } from 'vue-property-decorator';
import TheOsChanger from './TheOsChanger.vue'; import TheOsChanger from './TheOsChanger.vue';
import TheSelector from './Selector/TheSelector.vue'; import TheSelector from './Selector/TheSelector.vue';
import TheGrouper from './Grouping/TheGrouper.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 { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';
import { IEventSubscription } from '@/infrastructure/Events/IEventSource'; import { IEventSubscription } from '@/infrastructure/Events/IEventSource';

View File

@@ -16,7 +16,7 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop, Watch } from 'vue-property-decorator'; 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 { IScript } from '@/domain/IScript';
import { ICategory } from '@/domain/ICategory'; import { ICategory } from '@/domain/ICategory';
import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState'; import { ICategoryCollectionState } from '@/application/Context/State/ICategoryCollectionState';

Some files were not shown because too many files have changed in this diff Show More