Compare commits

...

290 Commits

Author SHA1 Message Date
undergroundwires
c65209e6a9 Unrecommend and complete Windows Push Notif. #101
- Add more script documentation in code and reference URLs.
- Unrecommend as "Standard" recommend as "Strict" due to lack of
  documentation for its privacy intrusive behavior.
- Add mising WpnUserService for disabling it completely.
2021-12-03 01:08:55 +01:00
undergroundwires
d2518b11a7 Improve Windows defender docs and errors #104
- Improve error messages with cause of the problem and suggested solution.
- Document:
  * Disabling `WinDefend` breaks `Set-MpPreference` and Microsoft Store
    (as reported in #104).
  * Document services that `netsh advfirewall` depends on.
- Fix some bad whitespace character in documentation.
2021-11-27 20:22:18 +01:00
undergroundwires
70cdf3865a Improve and unify disabling of Windows services
Refactor, unify and improve the logic to to start/stop and
enable/disable services, and also add more documentation.

Rework functions:
  - Unify way of disabling Windows services using templating.
  - Capitalize as `startupMode` (where startup is single word) everywhere.
  - Use also text parameters (automatic, manual..) instead of numeric
    values (2,3...) when providing parameters to any service disable
    function.

Improve documentation:
  - Add reference URLs about disabled services.
  - Add more code documentation for querying status and allowed values.

Logic improvements include:
  - Check if service is running before stopping/starting the service.
  - Do not start the service it's not an Automatic service.
  - Check whether service is already disabled.
  - When reverting, start the service if it has Automatic startup. But
    do not start the service it has different startup (e.g. manual).
    Also starts the service even though start up is configured as
    desired (before it quit before doing service start).

Improve outputs (logs):
  - Remove false-positive error messages.
  - When a service cannot be stopped/start; mention in output that the
    service will be started/stopped after reboot.
  - Show success message once service is enabled/disabled.
  - Fix reboot messages when enabling/disabling services,
  - Do not write stderr if service cannot be stopped/started as it's not
    not the main goal of the function.

Add missing revert code for the ones missing them:
  - Disable diagnostics telemetry
  - Disable Windows Media Player Network Sharing Service

> Function: DisableServiceInRegistry
- Fix not exitting if service does not exist when reverting
- Show success message once service is enabled/disabled
- Fix double "Enabled.." messages
- Fix unintended registry addition

> Function: DisablePerUserService
- Change implementation to call DisableServiceInRegistry.
- Fix both services are skipped if one of them fails.
- Fix reverting a service sets wrong startup mode.
2021-11-25 21:34:15 +01:00
undergroundwires
7c02ffb6c9 Fix Defender error due to non-english Windows #104
German edition of Windows returns German output for `schtasks.exe`
commands. So checking for "Running" fails immediately as reported #104.

Revert recent change from using `Get-ScheduledTask` and
`Unregister-ScheduledTask` to `schtasks.exe`. Also remove unused
`$powershellFile` variable.
2021-11-21 13:14:58 +01:00
undergroundwires
f2d9881382 Fix unintendedly inlined Windows scripts
- Fix reverting "Disable SQM OS key".
- Fix applying "Disable Visual Studio Code data collection" scripts.
- Fix reverting "Do not show recently used files in Quick Access".
- Add unit tests for automatically checking similar issues in future.
2021-11-19 21:07:22 +01:00
undergroundwires
d7761ab30e Fix Defender features errors in Windows #104
- Refactor to use `Set-MpPreference` in a function instead.
- Better support for both Windows and Windows 11 with platform-specific
  logic, due to poor `Remove-MpPreference` used in Windows 10:
     * Use `Remove-MpPreference` on Windows 11, but switch to
       `Set-MpPreference` for some edge cases using a flag.
     * Use `Set-MpPreference` on Windows 10 by default, and use
       `Remove-MpPreference` for only small amount of cases where it is
       supported.
- Set default value instead of `Remove-MpPreference` on Windows 10 when
  it does not work as expected.
- Improve error messages when:
  * Command name (cmdlet) is not supported
  * Command parameter is not support
  * Failing due to Defender service not working
  * Argument is not supported (e.g. for 'Broad')
- Skip if a parameter or argument is not supported instead of failing.
- Set OS defaults when using `Set-MpPreference` when `Remove-MpPreference`
  does not set the OS defaults.
- Skip setting the setting if it already is as desired.
- Remove redundant scripts in "Disable remediation actions" setting
  `LowThreatDefaultAction`, `ModerateThreatDefaultAction`,
  `HighThreatDefaultAction` and `SevereThreatDefaultAction`. As they are
  all controlled by and limited to value of `UnknownThreatDefaultAction`.
- Fix registry policies not matching cmdlet behavior:
     > CheckForSignaturesBeforeRunningScan
     > SignatureUpdateCatchupInterval
- Fix reverting registry policies (`reg delete` command and error
  output):
    > Disable Malicious Software Reporting tool diagnostic data
    > Turn off block at first sight
- Fix DisableCatchupQuickScan MpPreference command being in wrong
  category by moving it to its right category and adding its correct
  equivalent.
2021-11-17 00:03:59 +01:00
undergroundwires
bf83c58982 Refactor Saas naming, structure and modules
- Add more documentation.
- Use `main.scss` instead of importing components individually. This
  improves productivity without compilation errors due to missing
  imports and allows for easier future file/folder changes and
  refactorings inside `./styles`.
- Use partials with underscored naming. Because it documents that the
  files should not be individually imported.
- Introduce `third-party-extensions` folder to group styles that
  overwrites third party components.
- Refactor variable names from generic to specific.
- Use Sass modules (`@use` and `@forward`) over depreciated `@import`
  syntax.
- Separate font assets from Sass files (`styles/`). Create `assets/`
  folder that will contain both.
- Create `_globals.css` for global styling of common element instead of
  using `App.vue`.
2021-11-14 17:48:49 +01:00
undergroundwires
2e082932c9 Fix disabling/enabling Defender on Windows #104
Change behavior of registry reverting from adding default value to
removing value that overrides. It then leaves the system in cleaner
state, removes "managed by your organization" warning, and makes the
scripts more future-proof providing compatibility with Microsoft patches
updating the defaults. This is implemented by using `reg delete` over
`reg add` and `Remove-MpPreference` over `Set-MpPreference`.

> Disable Windows Defender Scheduled Scan task
Surpress the error when reverting the script as the task may not exist
in some Windows versions.

> Limit catch-up security intelligence (signature) updates
Change to "Disable" instead of "Limit", and bring back its revert code.

Fix reverting of following scripts setting non-default values:
  > Turn off Windows Defender SpyNet reporting
  > Disable checking for signatures before scan
  > Limit CPU usage during idle scans to minumum
  > Disable scanning when not idle
  > Disable scanning on mapped network drives on full-scan

Fix following scripts setting unexpected behavior:
  > Disable running scheduled auto-remediation
  > Limit CPU usage during idle scans to minumum
  > Disable randomizing scheduled task times
  > Disable creating system restore point on a daily basis

Add more documentation for MpPreference module:
  - Add more reference URLs
  - Add status query as documentation
  - Add information regarding default values
  - Describe meaning of enumeration values
  - Document commands not doing expected in Windows 11
2021-11-12 17:26:22 +01:00
undergroundwires
2f90cac52a Improve tests for UserSelection
- Refactor for more logic reuse
- Adds more assertments for events
2021-11-09 21:49:56 +01:00
undergroundwires
20a0071c0d Fix Windows TrustedInstaller session errors
- Fix errors (stderr stream) not being logged.
- Use `schtasks /delete` instead of `Unregister-ScheduledTask` as
  PowerShell command sometimes fail for existing tasks.
- Refactor to use `-TaskName` to explicit describe parameter, and use
  linebreaks for `Register-ScheduledTask` call with many parameters.
2021-11-09 00:14:56 +01:00
undergroundwires-bot
a40f83d6b6 ⬆️ bump everywhere to 0.11.1 2021-11-06 17:47:52 +00:00
undergroundwires
0db8cc4206 Fix website not loading on Safari
It's caused by lookahead regex used in dash comment regex for inlining
PowerShell. This commit changes dash comment inlining.

- Change regex to one without lookahead.
- Add more test cases for inlining dash comment in tricky situations.
- Refactor makeInlineComment to be it's own function to easily test
  other regex options.
- Document all regex alternatives.
- Remove redundant null check (`||`) with adding safe navigation
  operator  (`?`) to allow variable before check to be null instead of
  throwing exception.
2021-11-04 18:42:44 +01:00
undergroundwires
97ddc027cb Fix dead URLs and use forks as GitHub references
Change all GitHub URLs with forks so they survive if their maintainer
decides to remove them.

Fix dead URLs in:
  - "Windows Push Notification Service" (#101)
  - "Limit CPU usage during scans to minimum"
  - "Disable NVIDIA telemetry"
2021-11-03 20:08:56 +01:00
undergroundwires
82c43ba2e3 Refactor to remove "Async" function name suffix
Remove convention where Async suffix is added to functions that returns
a Promise. It was a habit from C#, but is not widely used in JavaScript
/ TypeScript world, also bloats the code. The code is more consistent
with third party dependencies/frameworks without the suffix.
2021-11-01 19:02:22 +01:00
undergroundwires
799fb091b8 Fix failing URL status checking integration tests
Implement following redirects over `fetch` supporting cookies.
`node-fetch` does not support sending cookies during redirect. However,
this is needed to not end-up in a redirect loop for a sign-in callback.

Fix integration tests failing due to redirects and 403 errors:
  - Many redirects from `answers.microsoft.com` was throwing: throwing
    `FetchError: maximum redirect reached` error. It was caused by not
    having cookies when following redirects therefore having an infinite
    sign-in callback for the webpage.
  - Fixes integration tests failing due to additional referer header being
    sent by the application. It adds support for making exceptions to
    additional header sending through a list of regexes.

Add in-depth documentation for URL status checking.
2021-10-30 16:19:10 +01:00
undergroundwires
5ead1a087d Fix, document, unrecommend Windows browser cleanup
The main goal is to highlight and exclude scripts that clears user data
(such as Chrome bookmarks) from standard recommendation, thus allowing
more granular and intentional user selection. Because scripts that are
recommended as "standard" should be non-breaking.

Standard: Recommend only clearing data that would not be noticable by
user. E.g. caches and logs.
Strict	: Recommend clearing data that may be noticable by user, but
does not affect stored consciously data by user. E.g. cookies.
Do not recommend if data is stored consciously by user. E.g. favorites
/ bookmarks.

[General]
  - Change wording from "Clear xx traces" to "Clean xx history" to make
  it more clear and unify the naming with macOS scripts.
  - More documentation both in code and both as more references.

[Chrome]
  - Unrecommend deleting Chrome user profile.
  - Document what each chrome clean-up script is doing in more detail.

[Internet Explorer]
  - Document IE scripts better.
  - For Cookie cleanup, add solutions for later Windows version.
  - Unrecommend some from standard.
  - Remove undocumented `Local Settings\Traces` folder.
  - Take ownership before deleting Temporary Internet Files. Fixes
    permission error.
  - Remove `INetCookies\PrivacIE` script because it's undocumented and
    we already have cleanup for its parent folder (`INetCookies`).
  - Remove "%USERPROFILE%\Local Settings\Traces" due to lack of
    documentation.

[Safari]
  - Remove cleanup for undocumented traces folders `Safari\Traces`.
  - Document with subcategories and references.
  - Fix clearing all data not pointing to `localappdata`.
  - Unrecomend clearing all data.

[Opera]
  - Rename to "Clear all.." to show intent.
  - Unrecommend as it removes everything.
2021-10-28 17:43:04 +01:00
undergroundwires
64631a4552 Update dependencies
- Bump dependencies to latest.
- Remove unused inversify dependency.
- Lock sass-loader to a version that's compatible to 10. Because later
  versions (>=11) require Webpack v5 while Vue CLI v4 uses Webpack v4.
- Changes slashes as division to `math.div` as it's depreciated by SASS
  https://sass-lang.com/documentation/breaking-changes/slash
2021-10-23 20:25:03 +01:00
undergroundwires-bot
f47cb04860 ⬆️ bump everywhere to 0.11.0 2021-10-21 14:57:54 +00:00
undergroundwires
504fa056d7 Update screenshot 2021-10-21 15:48:43 +01:00
undergroundwires
739287ac71 Fix minor issues with Defender scripts
Suppress errors:
  - when deleting registry keys because the condition where key does
    not exist is not really an error,
  - when disabling a task that does not exist because absence of a task
    when trying to disable it is still a positive condition for goal to
    get rid of it,
  - when stopping or starting a service because goal is to
    disable/enable the service.

> Turn off SmartScreen App Install Control feature
- Add missing `/f` flag

> Remove "Scan with Windows Defender" option from context menu
- Add missing `/f` flag
- Remove redundant delete line in revert code
- Add missing whitespace before `/v` flag
- Instead of deleting with `/v ""`, use `/va` for explicit indent

> Disable Malicious Software Reporting tool diagnostic data
- Fix typo in revert scripts

> Turn off tamper protection
> Restrict threat history to administrators
Fix permission errors using TrustedInstaller session

> `Set-MpPreference` scripts
- Show warning when Set-MpPreference parameter is missing instead of an
  error The reasons include:
    - If the parameter is missing, functionality may be missing i.e.
      there's nothing to disable
    - In most cases different way of disabling registry is provided
    - Error is not clear and too verbose and should be implemented in a
      better way
- Add back "Limiting Defender definition updates" script due to being
  able to handle if aparameter is missing
- Add documentation for command in its script

> Disable the Potentially Unwanted Application (PUA) feature
- Fix revert code disabling another functionality

> Disable bidirectional scanning of incoming
- Fix typo

> Disable Microsoft Defender Antivirus
- Correct wrong comment regarding deprecation

> Disable Windows Defender Security Center Service
- Fix disabling not working on Windows 11
2021-10-21 15:37:09 +01:00
undergroundwires
ab8bce7686 Support disabling of protected services #74
Add new ways to disable Defender on Windows:
  1. Disable through renaming required files
  2. Disable using registry changes
  3. Disable using TrustedInstaller user

Add support for running code as TrustedInstaller 🥳. It allows running
commands in OS-protected areas. It is written in PowerShell and it uses
PowerShell syntax like backticks that are inlined in special way. So the
commit extends inlining support and allows writing PowerShell using:
  - Comments
  - Here-strings
  - Backticks

Add disabling of more Defender service

Improve documentation and categorization of services.
2021-10-20 21:12:47 +02:00
undergroundwires
e6152fa76f Improve security hardening for macOS
- Moves security improvements to its own action.
- Add more scripts and documentation for security improvements
- Move "Disable Spotlight indexing" out of wrong firewall category
- Add more documentation
2021-10-19 22:16:40 +02:00
undergroundwires
a8031d18d5 Change theme colors
Change almost all colors for better look.
2021-10-18 21:23:04 +01:00
undergroundwires
9aa8166891 Change PowerShell double quotes escape
It changes the way privacy.sexy escape double quotes inside batch
command when running PowerShell scripts as an argument to
PowerShell.exe. It uses more robust and stable way offering support for
wider use-cases.
2021-10-17 15:37:06 +01:00
undergroundwires
236a0f6c82 Add privacy over security scripts for macOS #83
It adds scripts to:
  - Disable OS security modules.
  - Clean quarantine data.
  - Disable auto-updates.
2021-10-16 19:49:41 +02:00
undergroundwires
2492f2d814 Add more ways to disable and clean Defender #74
Adds more scripts to:
 - disable Windows Defender functions,
 - remove it from the user interface,
 - clean its scan history.

Improves the documentation:
 - Adds more documentation reference URLs.
 - Restructures scripts in a way to better document their behavior. All
   Defender scripts are now under "Disable Windows Defender" and
   "Privacy over security".

Changes recommendations, and simply recommends less:
 - Defender cloud configurations are now only documented on "Strict"
   mode.
 - Watson event sending with "DisableGenericReports" is disabled due to
   lack of documentation and depreciation.
2021-10-15 17:21:37 +01:00
undergroundwires
410bcd8244 Add semi-automatic update support for macOS
For fully automatic macOS updates, electron-updater requires:
  1. Distributing macOS file as .zip (electron-userland/electron-builder#2199)
  2. Code signing for the application

privacy.sexy as of today lacks both the distribution and code signing.
This commit introduces auto-updates through automatically checking for
updates, downloading them but requiring user to drag application icons
to Applications by opening dmg file.

This commit also fixes:
  1. Progress state in update progress bar not being shown.
  2. Downloading updates were being triggered even though it was not
desired as downloads are being handled using different based on OS and
user choice.

In the end it refactors the code for handling updates of two different
kinds, and making message dialog use enums for results instead of
response integers as well as setting default and cancel button behavior.
Refactorings make behaviors more explicit and extends the control.
2021-10-13 21:25:09 +01:00
undergroundwires
b08a6b5cec Use a consistent color system
1. Renames color names in palette. Using names such as "primary" and
"secondary" that are in consistent with designs such as material,
bootstrap and metro UI palettes. It adds `color-` prefix on color
variables in line with Vue Design System.
2. Introduces necessary changes to follow the system color system
   everywhere without using any other color:
     - It changes tooltip background from black to darker primary
     colors.
     - It overrides unset styles from tree component
     - It ensures footer has same color as top menu.
3. Removes opacity CSS changes to have better control on choices. To
   achieve that:
     - It introduces new "light" variants of main colors
     - It switches to colors with different variants (e.g. in Dialogs it
       uses primary color as button as it has variants that can be
       activated on hover meanwhile on-surface color is single).
4. Styles a tags (anchor elements) globally for consistency
2021-10-11 19:33:34 +02:00
undergroundwires
37ad26a082 Remove integration tests from deployments #90
Integration tests may depend on third parties and can fail from time to
time. In some situations failing tests can be acceptable to go forward
with deployments. They should not be a requirement that blocks
deployments. They may lead to unintended lack of distributed packages as
seen in #90.
2021-10-09 12:39:05 +01:00
undergroundwires
0696ed8396 Improve disabling of SmartScreen #74
This commit renames "smart screen" to "SmartScreen" which is the
official name from Microsoft.

It categorizes scripts to document the behavior in a more clear way. It
adds structured depth. It moves all SmartScreen scripts under Defender,
as it's now part of Defender offering since latest branding.

In addition, the commit adds more documentation and more scripts such as
disabling SmartScreen for Edge.
2021-10-08 22:38:41 +02:00
undergroundwires
9942df16c8 Increase default screen width on desktop app
Goal is to show 3 card in a row as default. It gives more consistent
look to privacy.sexy across web and desktop.
2021-10-05 22:25:59 +01:00
undergroundwires
20b7d283b0 Add support for more depth in function calls
It allow pipes to be used in nested functions. Before, pipes were added
to a variable before variable content was evaluated/compiled by
another function. This commit ensures that the commits are evaluted in
expected order.

The issue is solved by stopping precompiling functions. It makes code
less complex. It adds to compile time of the script file but nothing
noticable and something optimizable.

The problem was that the call trees we're not executed in expected
order. E.g. let's say we have functionA that outputs something like
"Hello {{ $name| pipe }}", and we have function B calling with "name:
dear {{ $firstName}}", and at last we have a script that's calling
function B with "firstName: undergroundwires". Before, expressions were
evaluated directly, meaning that function A would become:
"Hello Dear {{ $firstName}}", as you see the pipe in function A
is lost here after being applied to function B and not reaching
$firstTime input value. Parsing expressions in the end allows for pipes
etc. to not get lost.

The commit also does necessary name refactorings and folder refactorings
to reflect logical changes. `FunctionCompiler` is renamed to
`SharedFunctionsParser` as precompiling is removed and it just simply
parses now. `/FunctionCall/` is moved to `/Function/Call`.

Finally, it improves documentation and adds more tests.
2021-10-04 18:13:25 +01:00
undergroundwires
f39ee76c0c Add script to remove Meet Now icon in Windows 2021-09-24 19:22:09 +01:00
undergroundwires
4b2390736a Support disabling per-user services in Windows #16
Some services in Windows have random characters appended to them. This
commit fixes the scripts that has been trying to disable them but
failing in newer Windows versions where they become per-user.
2021-09-20 23:05:15 +01:00
undergroundwires
c8cb7a5c28 Improve alignment, padding/margin issues on UI
1. It vertically centers top script menu (including selectors for view,
   OS and recommendation levels). Before, it did not utilize the empty
   space on smaller screens when of the menu items overflowed to a new
   line. This commit fixes it, also adds margin on top selectors on
   small screens.
2. It adds vertical margin between slider items on vertical view. It
   also refactors slider component so that the `v-deep` is no longer
   used, instead style is set through properties.
3. It ensures symmetrical margin on both sides of the handle in slider
   during horizontal view. Before, the left margin did not exist and
   right margin was too wide. This commit balances right and left margin
   of the arrow.
4. It changes the way margining is done for the card list. It removes
   internal margin from cards, because when they have them they also add
   that to the outer card list. This commit solves it in a way that
   unifies setting gap between cards and setting gap between cards.
   The styles are controlled on card list instead. This way same margins
   and paddings is also applied to non-card view (i.e. scripts tree).
   Before margining was done separately and those views looked
   diferently.
5. It improves styling of cards. It uses variables instead of hardcoded
   values and also refactors and renames variables for simpler
   understanding.
2021-09-19 15:33:40 +01:00
undergroundwires
5217b0b758 Add pipes to write pretty PowerShell #53
This commit introduces two pipes: `inlinePowerShell`,
`escapeDoubleQuotes`. The types when used together allows writing adding
clean and real PowerShell scripts as they are (without inlinining or
escaping them), removing the need to have hard-coded inlining/escaping.

It enables writing better PowerShell, makes it easier to maintain and
extend PowerShell scripts. Also allows writing more stable code with
less "unseen" bugs due to manual escaping/inlining. This commit
naturally reveals and fixes double quotes not being escaped in "Empty
trash bin" script.

This is solved by unifying the use of RunPowerShell function by all
scripts using PowerShell. The function inlines and escapes the scripts
as compile time to be send them to PowerShell.exe as an argument and
then invokes PowerShell.exe with generated ugly code.
2021-09-13 21:23:57 +01:00
undergroundwires
ddf417a16a Add new UX for optionally downloading updates
Before we used native method from electron for updating and notifying
(`checkForUpdatesAndNotify`). It simply checked if there's an update,
downloaded it, applied in the background and showed OS notification.

The flow is now updated. Updates will be checked, user will be asked to
confirm about whether to download and apply the updates, then a UI with
progress bar will be shown and user will be asked to restart the
application.

This commit also moves electron related logic to `/electron/` folder (as
there are now multiple files) to keep them structured. Also the electon
entrypoint `background.ts` is renamed to `main.ts`. The reason it was
named  `background.ts` by vue-cli-plugin-electron-builder was to remove
the confusion between `main.ts` of Vue itself. However, as they are
kept in different folders, but this is not the case for us.

Better than `checkForUpdatesAndNotify`.
Organizes electron desktop app logic in same folder to allow using
multiple files in a structured manner.
2021-09-11 11:04:08 +01:00
undergroundwires
2f0321f315 Bump node environment to 15.x
It updates node version to 15.x to be able to use
`String.prototype.replaceAll()`
2021-09-09 22:12:59 +01:00
undergroundwires
4d7ff7edc5 Add support for pipes in templates #53
The goal is to be able to modify values of variables used in templates.
It enables future functionality such as escaping, inlining etc.

It adds support applying predefined pipes to variables. Pipes
can be applied to variable substitution in with and parameter
substitution expressions. They work in similar way to piping in Unix
where each pipe applied to the compiled result of pipe before.

It adds support for using pipes in `with` and parameter substitution
expressions. It also refactors how their regex is build to reuse more of
the logic by abstracting regex building into a new class.

Finally, it separates and extends documentation for templating.
2021-09-08 18:58:30 +01:00
undergroundwires
862914b06e Add "with" expression for templating #53
Allows optionally rendering content if an argument is given. The
expression is designed to be used with `optional` parameters.

Goal is to allow using `RunPowerShell` function on every function that
consists of PowerShell code. Before this commit, they were all required
to provide revertCode, or none of them could be able to have it. It
would not work because some scripts can be reverted, meanwhile some are
one-way scripts that cannot be reverted (such as cleaning scripts). In
this case a way to optionally render revertCode was required. `with`
expression give each callee script ability to turn off `revertCode` if
not needed, therefore enables using `RunPowerShell` everywhere.

This commit also improves error message for script code for better
debugging and refactors parser tests for more code reuse. It also adds
more tests to parameter substitution, and renames some tests of both
expressions for consistency.
2021-09-06 21:02:41 +01:00
undergroundwires
6c3c2e6709 Improve macOS scripts for cleaning OS logs
Categorizes existing scripts on deeper level and adds more
documentation, also adds new scripts for other system log artifacts.
2021-09-05 21:51:33 +02:00
undergroundwires
c92dc1e253 Add scripts to disable, hide and opt-out from Siri 2021-09-04 23:39:14 +02:00
undergroundwires
e73c0ad1bf Do not collapse cards on links and code area #88
Detects clickable elements automatically and exempts them from
collapsing cards, also interacting with code area does no longer
collapse cards.

This commit also fixes subscribing to clicks on document every time card
list is loaded, but never unsubscribing. This impacts performance and
causes memory leaks. Now, registered event listener is removed every
time card list component is destroyed.
2021-09-03 19:44:44 +02:00
undergroundwires
6a89c6224b Add optionality for parameters
This commit allows for parameters that does not require any arguments to
be provided in function calls. It changes collection syntax where
parameters are list of objects instead of primitive strings. A
parameter has now 'name' and 'optional' properties. 'name' is required
and used in same way as older strings as parameter definitions.
'Optional' property is optional, 'false' is the default behavior if
undefined. It also adds additional validation to restrict parameter
names to alphanumeric strings to have a clear syntax in expressions.
2021-09-02 18:59:25 +01:00
undergroundwires
dcccb61781 Tighten parameter substitution tolerance
In collection templating syntax, do not tolerate whitespace after dollar sign. So while `{{ $param }}` is valid `{{ $ param }}` will be ignored.
2021-08-30 18:57:05 +01:00
undergroundwires
c0c475ff56 Change "grouping" to "view"
1. *Grouping* becomes *view*. Because *view* is more clear and extensible than *grouping*. It increases flexibility to extend by e.g. adding *flat* as a new view as discussed in #50, in this case "flat *view*" would make more sense than "flat *grouping*".
2. *None* becomes *tree*. Because *tree* is more descriptive than *none*.

Updates labels on top menu. As labels are updated, the file structure/names are refactored to follow the same concept. `TheScriptsList` is renamed to `TheScriptsView`. Also refactors `ViewChanger` so view types are presented in same way.
2021-08-29 11:33:16 +01:00
undergroundwires-bot
6dc768817f ⬆️ bump everywhere to 0.10.3 2021-08-28 10:22:47 +00:00
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
undergroundwires
bd41af466f update screenshot 2021-03-02 16:28:07 +01:00
undergroundwires
970221b996 remove "preview" disclaimer from macOS 2021-03-01 17:01:34 +01:00
undergroundwires
15004ff1f1 remove windows scripts for removing non-bloating system apps #55 2021-02-28 13:43:42 +01:00
undergroundwires
65226f3984 add better error messages to setting vscode settings 2021-02-27 14:40:14 +01:00
undergroundwires
b0a7d0b53b add more macos scripts for privacy cleanup 2021-02-26 14:27:12 +01:00
undergroundwires
ee43fd92a0 more scripts to disable speech recognition and Cortana 2021-02-25 16:37:57 +01:00
undergroundwires
cf39e6d254 move code area to right on bigger screens 2021-02-22 16:46:06 +01:00
undergroundwires
1260eea690 escape printed characters to prevent command injection #45 2021-02-21 12:34:33 +01:00
undergroundwires
45a3669443 refactor disabling application experience and document better 2021-02-20 12:13:08 +01:00
undergroundwires
c9b91f6d8f add script to automatically kill devicecensus process 2021-02-19 11:12:28 +01:00
undergroundwires
9a6b903b92 add option to run script directly in desktop app 2021-02-18 09:39:24 +01:00
undergroundwires
7661575573 allow functions to call other functions #53 2021-02-14 11:18:31 +01:00
undergroundwires-bot
f1abd7682f ⬆️ bump everywhere to 0.9.2 2021-02-13 11:08:41 +00:00
zy26
575636e6b7 correct the typo in application.md (#60) 2021-02-13 11:57:57 +01:00
undergroundwires
daa997b21b add GitHub issue templates 2021-02-10 21:16:56 +01:00
undergroundwires
5934b17283 refactor and add tests for NonCollapsingDirective 2021-02-09 08:53:29 +01:00
undergroundwires
d7de420d5c add test to ensure correct shared functions are being parsed 2021-02-08 07:10:41 +01:00
undergroundwires
df273f7f63 refactor state handling to make application available independent of the state 2021-02-07 12:32:05 +01:00
undergroundwires
67b2d1c11c refactor vscode configuration scripts using functions #41 2021-02-06 11:37:45 +01:00
undergroundwires
15353d0e25 make compiler throw if a function call includes an unexpected parameter 2021-02-05 13:27:40 +01:00
undergroundwires
f1e21babbf refactor event handling to consume base class for lifecycling 2021-02-04 19:58:09 +01:00
undergroundwires
34b8822ac8 fix wrong path for NvTelemtry file in NVIDIA script 2021-01-27 08:07:33 +01:00
undergroundwires
73e0520de7 do not compile with unused locals vuejs/vetur#1063 2021-01-26 06:00:19 +01:00
undergroundwires-bot
fbc3b109b9 ⬆️ bump everywhere to 0.9.1 2021-01-24 06:22:52 +00:00
undergroundwires
229c13a195 improve explanation for selections 2021-01-23 06:06:25 +01:00
undergroundwires
d7f9ef1cbe fix node APIs no longer working on desktop nklayman/vue-cli-plugin-electron-builder#610, nklayman/vue-cli-plugin-electron-builder#742 2021-01-22 06:07:30 +01:00
undergroundwires
7930bef48c transpile using babel for legacy browser support 2021-01-21 04:38:02 +01:00
undergroundwires
8b0e47da38 fix selection state indicator on cards not showing up 2021-01-20 05:30:19 +01:00
undergroundwires
2316e3fb68 specify desktop publish targets as defaults (may) change 2021-01-19 06:51:09 +01:00
undergroundwires
4015e2ccd8 in CI/CD, publish packages for other OSes if single one fails 2021-01-17 07:14:23 +01:00
undergroundwires
cf907d029a in CI/CD, allow publishing to github if release is more than 2 hours old electron-userland/electron-builder#2074 2021-01-16 08:14:38 +01:00
undergroundwires-bot
79a6c8b2ef ⬆️ bump everywhere to 0.9.0 2021-01-15 03:26:07 +00:00
undergroundwires
c318bd301a update screenshot 2021-01-15 04:25:04 +01:00
undergroundwires
86a2b2fda0 add scripts to manage chromium based edge 2021-01-14 05:23:46 +01:00
undergroundwires
8a8b7319d5 add initial macOS support #40 2021-01-13 16:31:20 +01:00
undergroundwires
2428de23ee fix unintended null file creation #52 2021-01-12 04:13:51 +01:00
undergroundwires
7ec889e759 recommend removing cortana taskbar icon on standard mode 2021-01-11 03:09:31 +01:00
undergroundwires
9d009c40dd document app connector removal and recommend on strict mode 2021-01-11 03:05:15 +01:00
undergroundwires
663d63bde0 recommend onedrive removal on strict mode 2021-01-10 01:35:30 +01:00
undergroundwires
6b83dcbf8f move application.yaml to collections/windows.yaml #40 2021-01-09 02:02:16 +01:00
undergroundwires
72e925fb6f improve uninstalling apps to show errors and exit if taking ownership fails #51 2021-01-08 01:16:58 +01:00
undergroundwires
c299e95bc6 fix typo causing uninstalling capabilities to fail #51 2021-01-07 00:59:00 +01:00
undergroundwires
2e40605d59 refactor to allow switching ICategoryCollection context #40 2021-01-05 22:28:38 +01:00
undergroundwires
3455a2ca6c add script to clean previous windows installation #35 2021-01-04 00:35:45 +01:00
undergroundwires
6fe858d86a rename Application to CategoryCollection #40 2021-01-02 17:50:47 +01:00
undergroundwires
7cc161c828 rework Cortana scripts to remove duplicates, better document and support Windows version 2004/2009 #43 2021-01-01 23:23:55 +01:00
undergroundwires
e14bf2bfa0 add scripts to prevent family safety monitoring 2020-12-30 19:49:38 +01:00
undergroundwires
34672414c3 refactor folders to move "/state" (IApplicationState) inside "/context" (IApplicationContext) 2020-12-29 05:45:03 +01:00
undergroundwires
f7557bcc0f refactor application.yaml to become an os definition #40 2020-12-27 18:14:38 +01:00
undergroundwires-bot
e4b6cdfb18 ⬆️ bump everywhere to 0.8.2 2020-12-27 14:42:30 +00:00
undergroundwires
8cd3352017 rename "disable" to "uninstall" for removing capabilities #47 2020-12-26 16:13:50 +01:00
undergroundwires
c4ec6a1445 refactor capabilities to use a shared function #41 #47 2020-12-25 22:38:06 +01:00
undergroundwires
b3117c27f2 rename app launch tracking tweak to make it more clear #44 2020-12-24 23:39:47 +01:00
undergroundwires
54ba4dbb0b in ci/cd, do not run security checks if PRs do not change dependencies #48 2020-12-23 22:42:30 +01:00
Marc05
a744415eb2 correct typos (#48)
Co-authored-by: Marc05 <git@marc05.net>
2020-12-23 22:23:42 +01:00
undergroundwires
55f936fee9 fix type assignment error after typescript upgrade 2020-12-22 23:12:48 +01:00
undergroundwires
d9e44e2574 update dependencies to latest #46 2020-12-21 22:20:49 +01:00
greaterthanstar
52d4313156 replace ampersand in "Movies & TV app" with "and" to prevent batch file from misinterpreting it (#45) 2020-12-20 21:48:52 +01:00
undergroundwires-bot
c2b531e968 ⬆️ bump everywhere to 0.8.1 2020-11-16 18:38:23 +00:00
undergroundwires
ab7d617886 replace deprecated github ::set-env command 2020-11-16 19:37:28 +01:00
undergroundwires
b247b12c3f move Microsoft.Appconnector to right category 2020-11-16 18:38:00 +01:00
undergroundwires
c26bc209eb fix errors when file already exists 2020-11-14 19:55:37 +01:00
undergroundwires
ad1872e7cd fix not being able to rename paths including brackets 2020-11-14 19:55:37 +01:00
undergroundwires
29c7704e0b unrecommend some system apps and document more 2020-11-14 19:51:21 +01:00
undergroundwires
e41e40c5bf fix wrong app names caused by wrong Microsoft docs 2020-11-11 16:18:35 +01:00
undergroundwires
31e08d231d fix not being able to uninstall system apps 2020-11-10 17:15:53 +01:00
undergroundwires
45b8dd972b refactor unused imports 2020-11-08 15:33:31 +01:00
undergroundwires
4e72673373 fix reinstalling store apps by searching appx for all users 2020-11-07 14:03:08 +01:00
undergroundwires
92c3dd9232 fix clearing jump lists causing os to break and user pin removal #37 2020-11-07 14:01:02 +01:00
undergroundwires
2c5ab3ea7d fix reinstalling store apps by searching appx for all users 2020-11-06 18:31:01 +01:00
undergroundwires
ffa279f3df refactor removing bloatware to use functions #41 2020-11-05 20:27:18 +01:00
undergroundwires-bot
89dddfbb23 ⬆️ bump everywhere to 0.8.0 2020-11-01 18:00:39 +00:00
undergroundwires
cfedcd724c update screenshot 2020-11-01 18:55:40 +01:00
undergroundwires
fd28eaad06 hide scrollbars on code area when not overflowing 2020-11-01 18:49:27 +01:00
undergroundwires
8ce06facbd add support for shared functions #41 2020-11-01 18:36:55 +01:00
undergroundwires
1a9db31c77 add all dist folders in gitignore because of files auto-generated by vscode 2020-11-01 01:53:27 +01:00
undergroundwires
ac70b063b8 rework disabling metadata retrieval 2020-10-28 22:32:05 +01:00
undergroundwires
d0019c2c9b update recommendations to be safer and consistent 2020-10-27 16:41:56 +01:00
sopla4ever
4c68408f1e add scripts to increase cryptography, enable camera notifications and remove todo app (#36)
Co-authored-by: undergroundwires <undergroundwires@users.noreply.github.com>
2020-10-26 11:52:48 +01:00
undergroundwires
1072505219 show icons on cards during indeterminate and fully selected states 2020-10-25 12:55:40 +01:00
undergroundwires
07fc555324 change "download" button to "save" on desktop 2020-10-23 17:11:44 +01:00
undergroundwires
50fb29038a switch places of download and copy buttons 2020-10-22 17:02:38 +01:00
Charles Zwicker
3785c623f8 Add GroupMe and Spotify removal option (#34)
Co-authored-by: undergroundwires <undergroundwires@users.noreply.github.com>
Co-authored-by: Charles Zwicker <czwicker54@gmail.com>
2020-10-20 16:51:30 +02:00
undergroundwires
14be3017c5 add support for different recommendation levels: strict and standard 2020-10-19 15:12:03 +01:00
undergroundwires-bot
978bab0b81 ⬆️ bump everywhere to 0.7.6 2020-10-17 22:58:06 +00:00
undergroundwires
d9d7f62d81 run tests on all operating systems: macos, ubuntu, windows 2020-10-18 02:10:20 +01:00
undergroundwires
11e0613165 update dependencies to latest 2020-10-17 23:17:44 +01:00
undergroundwires
77c3d2bbb8 simplify "why" section 2020-09-23 20:42:05 +01:00
undergroundwires
784a67afff refactor to read more from package.json 2020-09-22 20:41:12 +01:00
undergroundwires
19a092dd31 add more reversibility 2020-09-21 23:05:31 +01:00
undergroundwires
4c2f74949b add robots.txt to explicitly allow indexing 2020-09-19 01:23:33 +01:00
undergroundwires
a3fc3782ef add docs for default0 pointing to github discussion (#30) 2020-09-20 13:58:19 +01:00
undergroundwires-bot
cdc93f032a ⬆️ bumped to 0.7.5 2020-09-19 13:41:58 +00:00
undergroundwires
7dd15ed064 fix typo 2020-09-19 15:39:48 +01:00
undergroundwires
d169434157 fix pasting in search bar after page load showing no results 2020-09-18 20:07:03 +01:00
undergroundwires
6efed72bf2 fix rendering issue in older edge/IE 2020-09-17 15:41:46 +01:00
Clayton Errington
15db311801 fix the recycling bin option (#32)
* update the recycling bin option

Powershell has a module in PS 5.1+ called Clear-Recyclebin that works better than the CMD method - rd /s %systemdrive%\$Recycle.bin

* update recycling bin delete command

one liner of ComObject in powershell instead of cmd asking for confirmation. adds better backwards compatibility.
2020-09-16 20:22:33 +00:00
undergroundwires
82d509129b fix tests and checks are not running on PRs 2020-09-16 19:10:25 +01:00
undergroundwires
939d838e35 fix reverting (reinstalling) capabilities not working 2020-09-16 02:09:23 +01:00
undergroundwires-bot
6de4ce58c4 ⬆️ bumped to 0.7.4 2020-09-14 13:57:39 +00:00
undergroundwires
ee66196d9a fix wrong path in clear all firefox user profile settings 2020-09-14 16:04:38 +01:00
undergroundwires
3c13a9e837 fix missing reg value in denying app access to account 2020-09-14 16:03:03 +01:00
undergroundwires
22b23a9ece fix spectre protection getting single lined #31 2020-09-14 16:00:20 +01:00
undergroundwires
4ae385b7fc fix checked checkbox has blue border 2020-09-13 18:42:19 +01:00
undergroundwires-bot
d9abc7f0b2 ⬆️ bumped to 0.7.3 2020-09-12 13:14:13 +00:00
undergroundwires
1f19b2528a fix typo in a test 2020-09-12 14:42:27 +01:00
undergroundwires
1f11c39773 add more detailed error message 2020-09-12 00:14:27 +01:00
undergroundwires
b6ccb5927a fix comment lines are being detected as duplicate in validation 2020-09-12 00:13:58 +01:00
undergroundwires
1d465ee318 add reversibility and more scripts to denying app access with better structure 2020-09-12 00:11:10 +01:00
undergroundwires
3ab48b1cf5 fix naming of firefox cleanup to mention profiles 2020-09-11 14:26:32 +01:00
undergroundwires
de4ac978bd fix wrong path to the main telemetry file 2020-09-10 12:52:29 +01:00
undergroundwires
8df5faf4ef improve CPU specific tweaks by conditional platform checks and reversibility 2020-09-09 13:55:21 +01:00
undergroundwires
99a2035fdb fix nvidia tweak error message, categorize and add reversibility 2020-09-08 19:41:03 +01:00
undergroundwires
a0d61728ea fix vscode settings file override and add more configs 2020-09-07 13:42:59 +01:00
undergroundwires-bot
312bf6102c ⬆️ bumped to 0.7.2 2020-09-06 18:10:12 +00:00
undergroundwires
f4885b6f1c add best practice suggestion to come back 2020-09-06 02:41:11 +01:00
undergroundwires
ca63a0979e fix wording in default text in text area 2020-09-06 02:37:47 +01:00
undergroundwires
1f266c3353 fix indeterminate state being lost 2020-09-06 15:26:19 +01:00
undergroundwires
c7b2a70312 add reversibility to removing bloatware 2020-09-06 19:03:36 +01:00
undergroundwires
255133af4d fix bad highlighting of selected nodes when using keyboard navigation 2020-09-04 01:24:35 +01:00
undergroundwires
db74531cd4 add reversibility for biometric disabling and do not recommend it 2020-09-06 16:39:48 +01:00
undergroundwires
f36d8bfc78 update onesync documentation and do not recommend it as it breaks other apps 2020-09-05 23:31:31 +01:00
undergroundwires-bot
3b31ace726 ⬆️ bumped to 0.7.1 2020-09-04 11:42:03 +00:00
undergroundwires
6badfef9da refactor unused imports 2020-09-04 13:29:42 +01:00
undergroundwires
8c38dd73d8 fix new/changed script higlighting not working on production builds 2020-09-04 13:26:35 +01:00
undergroundwires
b8682a852a rename screenshot image file 2020-09-04 13:25:36 +01:00
undergroundwires
8c17929151 fix some browsers (including firefox) downloading the script as a text file 2020-09-04 12:20:41 +01:00
undergroundwires-bot
bb92c9ec28 ⬆️ bumped to 0.7.0 2020-09-02 21:26:40 +00:00
undergroundwires
b4aacea2a3 update the screenshot to show off highlighting 2020-09-02 19:12:24 +01:00
undergroundwires
8bbe6ebf75 fix search (got broken in b789250) with tests and refactorings 2020-09-02 22:44:20 +01:00
undergroundwires
a23d28f2cf refactor unused imports & variables 2020-09-01 21:32:31 +01:00
undergroundwires
f51e8859ee add reversibility on category level 2020-09-01 21:18:16 +01:00
undergroundwires
d235dee955 exclude paint, wordpad and notepad from bloatware removal 2020-09-01 21:03:14 +01:00
undergroundwires
2afef4ea3d do not hardcode capability versions and make them reversible 2020-08-26 00:58:52 +01:00
undergroundwires
f709d6a566 fix "Configure Defender" being in wrong category #28 2020-09-01 20:06:44 +01:00
undergroundwires
532915b95d categorize, fix, make scripts reversible in "UI for privacy", "security improvements" and "configure browsers" 2020-09-01 20:03:43 +01:00
Francesco Saltori
456e40bedf Add disabling of PowerShell 7+ telemetry (#29) 2020-09-01 19:57:43 +02:00
undergroundwires
018b7e270f add disabling ccleaner telemetry 2020-08-20 00:29:35 +01:00
undergroundwires
f8b8b4c97a add disabling firefox telemetry 2020-08-30 17:42:05 +01:00
undergroundwires
978d7d0863 add more OneDrive cleanup scripts and categorize them 2020-08-30 16:05:02 +01:00
undergroundwires
594a14d6ca categorize, fix and extend windows log files cleanup 2020-08-24 21:21:21 +01:00
undergroundwires
c628aa9aef updated dependencies to latest and audit fixes (#25) 2020-08-28 16:46:09 +01:00
undergroundwires
3060ebf79c fix NTP script documentation is on wrong place 2020-08-28 14:16:11 +01:00
undergroundwires
1a34c7374b add more windows defender tweaks, categorization and reversibility 2020-08-27 20:32:19 +01:00
undergroundwires
c262681011 add removal of ghost (default0) telemetry user 2020-08-26 21:31:12 +01:00
undergroundwires
f8ba5c46e4 prompt admin priviliges automatically 2020-08-26 01:58:29 +01:00
undergroundwires
b789250cb8 add auto-highlighting of selected/updated code 2020-08-25 16:52:38 +01:00
undergroundwires
5df458739d move script generation to /generation 2020-08-25 16:44:47 +01:00
undergroundwires
d6fa9a2a03 [search] added clear/close button 2020-08-24 02:50:47 +01:00
undergroundwires
ec15af01dd [search] better (multilined) message when there are no results 2020-08-24 02:50:47 +01:00
undergroundwires-bot
7073336f81 ⬆️ bumped to 0.6.2 2020-08-16 16:16:50 +00:00
undergroundwires
3d3380f27e 🔥 removed disabling ClickToRun as it breaks office 2020-08-16 16:58:05 +02:00
undergroundwires
c69998c7cb 🐛 fixed changing time server not working 2020-08-16 16:48:37 +01:00
undergroundwires
1663bfeac7 added script to clear dotnet telemery 2020-08-16 14:19:44 +02:00
undergroundwires
afc3bfb3b8 ⚙️ enhanced tweak to disable for office telemetry 2020-08-16 14:18:20 +02:00
undergroundwires
b6bfc25727 🐛 fixed removing onedrive does not delete scheduled tasks 2020-08-10 19:12:04 +02:00
undergrounwdires
7fac0fe79f 🐛 fixed blank screen and icons on mac 2020-08-10 18:40:16 +01:00
undergrounwdires
5967347b80 🐛 fixed disabling error reporting for november 2019 update 2020-08-09 16:23:28 +02:00
undergroundwires-bot
855a445c1a ⬆️ bumped to 0.6.1 2020-08-09 01:03:43 +00:00
undergroundwires
1cc12195a3 fixed removing onedrive does not clean start menu / quick access 2020-08-09 03:00:19 +01:00
undergroundwires
66d4d39d5b refactorings 2020-08-09 03:00:18 +01:00
undergroundwires
a5dbe66fc1 tweaks to disable webcam, speech and compatibility telemetry 2020-08-09 03:00:18 +01:00
undergroundwires
4c8be45e28 fixed mac / linux download links 2020-08-09 03:00:18 +01:00
undergroundwires
6049a2b834 moved windows connect now to security & recommended 2020-08-09 03:00:18 +01:00
undergroundwires
831c014f97 more scripts can be reverted 2020-08-09 03:00:18 +01:00
undergroundwires
5c15a7a64a fixed typo in footer 2020-08-09 03:00:18 +01:00
dependabot[bot]
e43992b278 Bump elliptic from 6.5.2 to 6.5.3 (#23)
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-08-09 03:00:18 +01:00
undergroundwires
5963d2bac5 updated documentation 2020-08-09 03:00:18 +01:00
undergroundwires
45816a2bcc updated dependencies to latest 2020-08-09 03:00:17 +01:00
undergroundwires
60a5a2aa40 reworked on footer & removed github icon 2020-08-09 03:00:17 +01:00
undergroundwires
04b9b59e14 support for desktop versions #20 2020-08-09 03:00:13 +01:00
undergroundwires
4ff4b52202 code area now shows "how" before "why" 2020-07-24 15:43:19 +01:00
undergroundwires
73c426844a runs tests on each push on the repository 2020-07-19 15:14:23 +01:00
undergroundwires
25ce236a77 fixed dead links in documentation 2020-07-19 02:37:54 +01:00
undergroundwires-bot
9b20175545 ⬆️ bumped to 0.5.0 2020-07-19 00:32:13 +00:00
undergroundwires
92a7118d1c patched loadash vulnerability (#18) 2020-07-19 02:27:01 +01:00
undergroundwires
a9f9e90443 all cards in same line now have same height 2020-07-19 02:27:01 +01:00
undergroundwires
31d2067f07 opening a card scrolls to its content div 2020-07-19 02:27:01 +01:00
undergroundwires
dd7e1416b4 do not collapse card when on "Search" and "Select" 2020-07-19 02:27:01 +01:00
undergroundwires
1d5225de07 search placeholder shows total scripts 2020-07-19 02:27:01 +01:00
undergroundwires
9c063d59de added ability to revert (#21) 2020-07-19 02:26:56 +01:00
undergroundwires-bot
57028987f1 ⬆️ bumped to 0.4.10 2020-07-15 16:52:43 +01:00
undergroundwires
9e722ddfb3 fixed script errors & added tests 2020-07-15 16:52:18 +01:00
undergroundwires-bot
646a8e0b9f ⬆️ bumped to 0.4.9 2020-07-14 21:38:19 +00:00
undergroundwires
f27a2871d7 simplified docker builds 2020-07-14 18:20:15 +01:00
undergroundwires
909c44d72a updated to may 2020 update 2020-07-14 18:20:15 +01:00
undergroundwires
53cf595e17 disable office telemetry Disassembler0/Win10-Initial-Setup-Script#288 2020-07-14 18:20:15 +01:00
undergroundwires
2c4eb78c3f more tweaks #16 2020-07-11 17:05:21 +01:00
Disk2019
d7a1325c0b updated one more typo (#19) 2020-07-11 00:34:59 +01:00
undergroundwires
30efbcc621 can disable features, capabilities & remove onedrive #16 2020-07-11 00:23:23 +01:00
undergroundwires
628c16eb95 stopping services before disabling #16 2020-07-11 00:23:23 +01:00
undergroundwires
d8552c62ff added more scripts #16 (#17) 2020-07-11 00:23:13 +01:00
undergroundwires-bot
df84083536 ⬆️ bumped to 0.4.7 2020-06-29 20:29:16 +00:00
Disk2019
461a4f122b Fixed types + script in "Clear Windows log files" (#15)
Kindly cross check & approve
2020-06-29 20:28:14 +00:00
undergroundwires
c937af8ee7 removed HKU tweak as all HKU's are changed #10 2020-06-29 16:20:35 +01:00
undergroundwires-bot
636d4279c8 ⬆️ bumped to 0.4.6 2020-06-29 14:15:03 +00:00
Disk2019
019b838925 Updated Some More Tweaks (#13) 2020-06-29 16:06:22 +01:00
Disk2019
0fc18459cd Updated Some Tweaks (#11)
ResetBase is by Default Disabled in Win10 Dism.exe /online /Cleanup-Image /StartComponentCleanup . Hence added this tweak to enable it in script on line 271 .
Updated HKU Tweaks to Correct HKCU Values & removed last experimental tweak as its not needed anymore & does not do anything exccept loading default user hive & then unloading it.
2020-06-29 15:51:40 +01:00
undergroundwires
583c5660d6 removed failing continuous deployment #14 2020-06-29 14:51:52 +01:00
Disk2019
52d5713a99 Fixed Some More Issues (#12)
Fixed typo issues :
Force enable data execution prevention (DEP)
disable cortana
Disable diagnostics telemetry
Empty trash bin
2020-06-19 20:08:16 +00:00
undergroundwires-bot
b34a66f270 ⬆️ bumped to 0.4.5 2020-06-13 00:59:26 +00:00
dependabot[bot]
eed996f608 Bump websocket-extensions from 0.1.3 to 0.1.4 (#9)
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-06-13 00:59:03 +00:00
undergroundwires-bot
b96c5d0557 ⬆️ bumped to 0.4.4 2020-05-24 19:25:47 +01:00
439 changed files with 65003 additions and 7017 deletions

9
.dockerignore Normal file
View File

@@ -0,0 +1,9 @@
node_modules
dist
dist_electron
.vs
.vscode
.github
.git
docs
docker

View File

@@ -0,0 +1,56 @@
---
name: Bug report (script bug or unexpected script behavior)
about: Create a bug report for generated scripts to help privacy.sexy improve
labels: bug
title: '[BUG]: '
---
<!--
Thank you for reporting an issue with generated script(s).
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.
-->
### Description
<!--
A clear and concise description of what the bug is.
-->
### OS
<!--
Which OS are you using? What version of OS you were using?
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".
-->
### Reproduction steps
<!--
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
<!--
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
<!--
If applicable, add any other context about the problem here.
-->

View File

@@ -0,0 +1,55 @@
---
name: Bug report (unrelated to generated scripts)
about: Create a bug report that's not related to generated scripts to help privacy.sexy improve
labels: bug
title: '[BUG]: '
---
<!--
Thank you for reporting an issue.
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.
-->
### Description
<!--
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:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
-->
### Expected behavior
<!--
A clear and concise description of what you expected to happen.
-->
### Screenshots
<!--
If applicable, add screenshots to help explain your problem.
-->
### Distribution
<!--
If applicable, mention how you were using privacy.sexy when the bug was encountered:
- Web (on Desktop or mobile?)
- Or desktop (Windows, macOS or Linux?)
-->
### Additional context
<!--
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

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

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: true

View File

@@ -1,23 +1,17 @@
name: Bump & release name: Bump & release
on: on:
pull_request:
types: [closed]
branches:
- master
push: # Ensure a new release is created for each new tag push: # Ensure a new release is created for each new tag
tags: tags:
- '[0-9]+.[0-9]+.[0-9]+' - '[0-9]+.[0-9]+.[0-9]+'
jobs: jobs:
bump-version-and-release: bump-version-and-release:
if: > # Push => Ensure only changes from master. PR => to not trigger when closing PR without merging if: github.event.base_ref == 'refs/heads/master'
(github.event_name == 'push' && github.event.base_ref == 'refs/heads/master')
|| github.event.pull_request.merged == true
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- - uses: undergroundwires/bump-everywhere@master
uses: undergroundwires/bump-everywhere@master
with: with:
user: undergroundwires-bot user: undergroundwires-bot
release-token: ${{secrets.BUMP_GITHUB_PAT}} # Does not trigger release pipeline if we use default token: https://github.community/t5/GitHub-Actions/Github-Action-trigger-on-release-not-working-if-releases-was/td-p/34559 release-token: ${{ secrets.BUMP_GITHUB_PAT }} # Does not trigger release pipeline if we use default token: https://github.community/t5/GitHub-Actions/Github-Action-trigger-on-release-not-working-if-releases-was/td-p/34559
# GitHub does not inject secrets if pipeline runs from fork or a fork is merged to main repo.

34
.github/workflows/deploy-desktop.yaml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: Deploy desktop
on:
release:
types: [created] # will be triggered when a NON-draft release is created and published.
jobs:
publish-desktop-app:
name: ${{ matrix.os }}
strategy:
matrix:
os: [macos, ubuntu, windows]
fail-fast: false # So publish runs for other OSes if one fails
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
with:
ref: master # otherwise it defaults to the version tag missing bump commit
fetch-depth: 0 # fetch all history
- name: Checkout to bump commit
run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)"
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: 15.x
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit
- name: Publish desktop app
run: npm run electron:build -- -p always # https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#upload-release-to-github
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EP_GH_IGNORE_TIME: true # Otherwise publishing fails if GitHub release is more than 2 hours old https://github.com/electron-userland/electron-builder/issues/2074

View File

@@ -1,11 +1,11 @@
name: Build & deploy name: Deploy site
on: on:
release: release:
types: [created] # will be triggered when a NON-draft release is created and published. types: [created] # will be triggered when a NON-draft release is created and published.
jobs: jobs:
build-and-deploy: aws-deploy: # see: https://github.com/undergroundwires/aws-static-site-with-cd
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- -
@@ -23,7 +23,7 @@ jobs:
--secret-access-key ${{secrets.AWS_DEPLOYMENT_USER_SECRET_ACCESS_KEY}} \ --secret-access-key ${{secrets.AWS_DEPLOYMENT_USER_SECRET_ACCESS_KEY}} \
--region us-east-1 \ --region us-east-1 \
&& \ && \
echo "::set-env name=SESSION_NAME::${{github.actor}}-${{github.event_name}}-$(echo ${{github.sha}} | cut -c1-8)" echo "SESSION_NAME=${{github.actor}}-${{github.event_name}}-$(echo ${{github.sha}} | cut -c1-8)" >> $GITHUB_ENV
working-directory: aws working-directory: aws
- -
name: "Infrastructure: Deploy IAM stack" name: "Infrastructure: Deploy IAM stack"
@@ -83,13 +83,13 @@ jobs:
name: "App: Setup node" name: "App: Setup node"
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: '14.x' node-version: 15.x
- -
name: "App: Install dependencies" name: "App: Install dependencies"
run: npm install run: npm ci
working-directory: site working-directory: site
- -
name: "App: Run tests" name: "App: Run unit tests"
run: npm run test:unit run: npm run test:unit
working-directory: site working-directory: site
- -

View File

@@ -1,37 +1,27 @@
name: Quality checks name: Quality checks
on: on: [ push, pull_request ]
pull_request:
branches:
- master
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
lint-command:
- npm run lint:vue
- npm run lint:yaml
- npm run lint:md
- npm run lint:md:relative-urls
- npm run lint:md:consistency
fail-fast: false # So it continues with other commands if one fails
steps: steps:
- - name: Checkout
name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- - name: Setup node
name: Setup node
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: 14.x node-version: 15.x
- - name: Install dependencies
name: Install dependencies
run: npm ci run: npm ci
- - name: Lint
name: Lint vue run: ${{ matrix.lint-command }}
run: npm run lint:vue
-
name: Lint yaml
run: npm run lint:yaml
-
name: 'Validate md: Relative URLs'
run: npm run lint:md:relative-urls
-
name: 'Validate md: Enforce standards'
run: npm run lint:md
-
name: 'Validate md: Ensure consistency'
run: npm run lint:md:consistency

View File

@@ -1,11 +1,11 @@
name: Security checks name: Security checks
on: on:
push:
pull_request: pull_request:
branches: paths: [ '/package.json', '/package-lock.json' ] # Allow PRs to be green if they do not introduce dependency change
- master
schedule: schedule:
- cron: '0 0 * * 0' - cron: '0 0 * * 0' # at 00:00 on every Sunday
jobs: jobs:
npm-audit: npm-audit:
@@ -18,7 +18,7 @@ jobs:
name: Setup node name: Setup node
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: 14.x node-version: 15.x
- -
name: NPM audit name: NPM audit
run: npm audit run: exit "$(npm audit)" # Since node 15.x, it does not fail with error if we don't explicitly exit

View File

@@ -1,13 +1,18 @@
name: Test name: Test
on: on:
push:
pull_request: pull_request:
branches: schedule: # for integration tests
- master - cron: '0 0 * * 0' # at 00:00 on every Sunday
jobs: jobs:
run-tests: run-tests:
runs-on: ubuntu-latest strategy:
matrix:
os: [macos, ubuntu, windows]
fail-fast: false # So it still runs on other OSes if one of them fails
runs-on: ${{ matrix.os }}-latest
steps: steps:
- -
name: Checkout name: Checkout
@@ -16,10 +21,13 @@ jobs:
name: Setup node name: Setup node
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: '14.x' node-version: 15.x
- -
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

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
node_modules node_modules
/dist dist/
.vs .vs
.vscode .vscode
#Electron-builder output
/dist_electron

View File

@@ -1,82 +1,484 @@
# Changelog # Changelog
## 0.11.1 (2021-11-04)
* Update dependencies | [64631a4](https://github.com/undergroundwires/privacy.sexy/commit/64631a4552fad7f7b06286aba8d3ca2d731f9342)
* Fix, document, unrecommend Windows browser cleanup | [5ead1a0](https://github.com/undergroundwires/privacy.sexy/commit/5ead1a087d91948890bc4ae6fea176123f18c285)
* Fix failing URL status checking integration tests | [799fb09](https://github.com/undergroundwires/privacy.sexy/commit/799fb091b8eb06c70ac0c67f2ef5385dce73501f)
* Refactor to remove "Async" function name suffix | [82c43ba](https://github.com/undergroundwires/privacy.sexy/commit/82c43ba2e37fb6e7f62ccd9bec8c5f48575f0613)
* Fix dead URLs and use forks as GitHub references | [97ddc02](https://github.com/undergroundwires/privacy.sexy/commit/97ddc027cb5395a74991cabc1d8c875ee945636d)
* Fix website not loading on Safari | [0db8cc4](https://github.com/undergroundwires/privacy.sexy/commit/0db8cc420655e01cbbed57c4658489b761a15899)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.11.0...0.11.1)
## 0.11.0 (2021-10-21)
* Change "grouping" to "view" | [c0c475f](https://github.com/undergroundwires/privacy.sexy/commit/c0c475ff564b23a4dabcc03ac2909207a8eb61ce)
* Tighten parameter substitution tolerance | [dcccb61](https://github.com/undergroundwires/privacy.sexy/commit/dcccb617813625c224a28242c5b965bb4cd6f189)
* Add optionality for parameters | [6a89c62](https://github.com/undergroundwires/privacy.sexy/commit/6a89c6224bdef5eb96980471f3b3935b9351b197)
* Do not collapse cards on links and code area #88 | [e73c0ad](https://github.com/undergroundwires/privacy.sexy/commit/e73c0ad1bf922b1dd3360fc5aafc3434951fa63c)
* Add scripts to disable, hide and opt-out from Siri | [c92dc1e](https://github.com/undergroundwires/privacy.sexy/commit/c92dc1e25387c65a3a41ca64d2a23cf8131b4c86)
* Improve macOS scripts for cleaning OS logs | [6c3c2e6](https://github.com/undergroundwires/privacy.sexy/commit/6c3c2e6709ec84f8e0411f19c024bab2c7e5753b)
* Add "with" expression for templating #53 | [862914b](https://github.com/undergroundwires/privacy.sexy/commit/862914b06ea9ef74c4b58a9a4164a10a38273638)
* Add support for pipes in templates #53 | [4d7ff7e](https://github.com/undergroundwires/privacy.sexy/commit/4d7ff7edc5a96cc0d99d3c1ca4fdf9bbdace3fd2)
* Bump node environment to 15.x | [2f0321f](https://github.com/undergroundwires/privacy.sexy/commit/2f0321f315ac0da8c713dd50e37032f1de194942)
* Add new UX for optionally downloading updates | [ddf417a](https://github.com/undergroundwires/privacy.sexy/commit/ddf417a16a79551b43576befab0541ea08487969)
* Add pipes to write pretty PowerShell #53 | [5217b0b](https://github.com/undergroundwires/privacy.sexy/commit/5217b0b7587ccfe509ba8adc3a7748b9bae14d7a)
* Improve alignment, padding/margin issues on UI | [c8cb7a5](https://github.com/undergroundwires/privacy.sexy/commit/c8cb7a5c28420557319606da82f56b011e88f470)
* Support disabling per-user services in Windows #16 | [4b23907](https://github.com/undergroundwires/privacy.sexy/commit/4b2390736ac1f9de2d5176b7b07da0e827112f9a)
* Add script to remove Meet Now icon in Windows | [f39ee76](https://github.com/undergroundwires/privacy.sexy/commit/f39ee76c0cda95f54502b19d5c49390fd0f12b5e)
* Add support for more depth in function calls | [20b7d28](https://github.com/undergroundwires/privacy.sexy/commit/20b7d283b02dd751dfbde18ef1fe334c6bf76e2b)
* Increase default screen width on desktop app | [9942df1](https://github.com/undergroundwires/privacy.sexy/commit/9942df16c8334ff041fb92f432a3a29e351c88df)
* Improve disabling of SmartScreen #74 | [0696ed8](https://github.com/undergroundwires/privacy.sexy/commit/0696ed8396e298a358bec17adb91c9145dd90418)
* Remove integration tests from deployments #90 | [37ad26a](https://github.com/undergroundwires/privacy.sexy/commit/37ad26a082851c02497c36e7fce40555b9480e11)
* Use a consistent color system | [b08a6b5](https://github.com/undergroundwires/privacy.sexy/commit/b08a6b5cecf4a53023053695292146edbd24b960)
* Add semi-automatic update support for macOS | [410bcd8](https://github.com/undergroundwires/privacy.sexy/commit/410bcd82445097c29c9fcf0eabf7af9ebcb93c1e)
* Add more ways to disable and clean Defender #74 | [2492f2d](https://github.com/undergroundwires/privacy.sexy/commit/2492f2d8141b3abdf590ccad59680b1f50ecb59e)
* Add privacy over security scripts for macOS #83 | [236a0f6](https://github.com/undergroundwires/privacy.sexy/commit/236a0f6c8241294fc397194cd1b20bdeccbbb50b)
* Change PowerShell double quotes escape | [9aa8166](https://github.com/undergroundwires/privacy.sexy/commit/9aa816689146ee6cd86d8262112677c38651c6bd)
* Change theme colors | [a8031d1](https://github.com/undergroundwires/privacy.sexy/commit/a8031d18d520dd3b0567f7b8cfe2dcd694b65073)
* Improve security hardening for macOS | [e6152fa](https://github.com/undergroundwires/privacy.sexy/commit/e6152fa76f5e7d23b0f79d5dd98713daaecbff90)
* Support disabling of protected services #74 | [ab8bce7](https://github.com/undergroundwires/privacy.sexy/commit/ab8bce768650a10677f0a13b3a9fae93c83802ff)
* Fix minor issues with Defender scripts | [739287a](https://github.com/undergroundwires/privacy.sexy/commit/739287ac71b3f8b04348fc101f1fa06f2d7d86a2)
* Update screenshot | [504fa05](https://github.com/undergroundwires/privacy.sexy/commit/504fa056d7d8b17fc20afd398f9a557495fca7e8)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.10.3...0.11.0)
## 0.10.3 (2021-08-27)
* unrecommend VSS and document its breaking behavior | [7714898](https://github.com/undergroundwires/privacy.sexy/commit/77148980e08859f89c15c6604e55b56ce4f74358)
* fix incorrect modification of Desktop folder on ThisPC (#71) | [eb9ac35](https://github.com/undergroundwires/privacy.sexy/commit/eb9ac35a923325cc2c9983ef71c0d904337a58f5)
* add initial integration tests | [49600c5](https://github.com/undergroundwires/privacy.sexy/commit/49600c5f37ca33c1687885fdf02a71ef7d3e6e8c)
* unify usage of sleepAsync and add tests | [36f0805](https://github.com/undergroundwires/privacy.sexy/commit/36f08055909f371fd9cbe3480ea813b963aea22b)
* fix broken URLs and automate broken URL checks #70 | [db62ed7](https://github.com/undergroundwires/privacy.sexy/commit/db62ed7f3ac63e9f2d762eb946060595eb9f5626)
* fix hiding recent files in quick access | [b976b92](https://github.com/undergroundwires/privacy.sexy/commit/b976b920318dba55b32d39f148fdca4f6be3cce3)
* bump dependencies to latest #75, #69 | [0a857aa](https://github.com/undergroundwires/privacy.sexy/commit/0a857aa09ee703d34ad0422bd1731158017a9a58)
* Fix NTP configuration before running the service (#72) | [71e70e5](https://github.com/undergroundwires/privacy.sexy/commit/71e70e50c51249bb10f6203414948b325acc2b2a)
* Fix typo on main page (#82) | [487001a](https://github.com/undergroundwires/privacy.sexy/commit/487001af485fdbb958615d7b52c09c2e386ddaf2)
* Improve issue templates | [f2935e4](https://github.com/undergroundwires/privacy.sexy/commit/f2935e4008f1231ef174f8932290e11715564d20)
* Fix infinitely subscribing to state changes | [ea5f9ec](https://github.com/undergroundwires/privacy.sexy/commit/ea5f9ec27df7cec6ac575e23fef18948d2b8e68a)
* Fix select options being clickable when disabled | [1c6b305](https://github.com/undergroundwires/privacy.sexy/commit/1c6b3057ea6e45125cadf374f20a905712ccdf3c)
* Fix tests for `ParameterSubstitutionParser` | [2a08855](https://github.com/undergroundwires/privacy.sexy/commit/2a08855e5d1bdf74354fd692cbfebd1a48e495ac)
* Fix excessive highlighting on hover | [ec0c972](https://github.com/undergroundwires/privacy.sexy/commit/ec0c972d348ffd5897f115d201031b704875b56a)
* Fix dead URLs | [439cd30](https://github.com/undergroundwires/privacy.sexy/commit/439cd303ff3db96a53664e5f44fefe12b95c5e6c)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.10.2...0.10.3)
## 0.10.2 (2021-04-19)
* in CI/CD, run other tests/check even if one of them fails | [5c43965](https://github.com/undergroundwires/privacy.sexy/commit/5c43965f0bc44f991ada7d3bad68937a80665dc3)
* fix desktop initial window size being bigger than current display size on smaller Linux/Windows screens | [02bdc4c](https://github.com/undergroundwires/privacy.sexy/commit/02bdc4cf0426c452f3fc9af52b819ca9b0757290)
* refactor extra code, duplicates, complexity | [00d8e55](https://github.com/undergroundwires/privacy.sexy/commit/00d8e551db001247fadfb6f6af7a4c5ce19a9e64)
* improve disabling ads and marketing #65 | [040ed27](https://github.com/undergroundwires/privacy.sexy/commit/040ed2701c4a468749901f4c5369b221bc0973c4)
* document breaking behavior in script name #64 | [b1ed3ce](https://github.com/undergroundwires/privacy.sexy/commit/b1ed3ce55f2d003cad1ead23e674aa66d4eb5802)
* add module alias '@tests/' | [60c8061](https://github.com/undergroundwires/privacy.sexy/commit/60c80611eab227791fabb883caf93418cef5fd00)
* document chromium warning for policy changes | [aea04e5](https://github.com/undergroundwires/privacy.sexy/commit/aea04e5f7cd48fbb9b407b68ade75575a6064c82)
* fix script revert activating recommendation level | [a2f1085](https://github.com/undergroundwires/privacy.sexy/commit/a2f10857e2a8debb3ce01f79b0dfbe8649ea9a17)
* fix typo and dead URL in Windows scripts (#70) | [8141a01](https://github.com/undergroundwires/privacy.sexy/commit/8141a01ef798331b4d82f5ca95f7b18df4f6f912)
* fix vue warning for undefined property during render | [b25b8cc](https://github.com/undergroundwires/privacy.sexy/commit/b25b8cc8052655af70b0695c6c3085974d783bb6)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.10.1...0.10.2)
## 0.10.1 (2021-03-25)
* refactor script compilation to make it easy to add new expressions #41 #53 | [646db90](https://github.com/undergroundwires/privacy.sexy/commit/646db9058541cebd0af437554de04fdc6bb63a6e)
* restructure presentation layer | [f3c7413](https://github.com/undergroundwires/privacy.sexy/commit/f3c7413f529be4a00dba7b0ab23904b48ea13a35)
* fix a test where "it" is not used inside "describe" | [1a5f920](https://github.com/undergroundwires/privacy.sexy/commit/1a5f92021f7423cd039f8f5326cd6f99b355c962)
* bump dependencies to latest | [1f515e7](https://github.com/undergroundwires/privacy.sexy/commit/1f515e7be525291c960ccb71db05312db6da53f5)
* fix throttle function not being able to run with argument(s) | [1935db1](https://github.com/undergroundwires/privacy.sexy/commit/1935db10192051401ab00ca2cd767955d0d3b866)
* fix fs module hanging not allowing code to run | [5f527a0](https://github.com/undergroundwires/privacy.sexy/commit/5f527a00cf225d3e74b3f6577d6e2456e919de24)
* refactor all modals to use same dialog component | [6f46cdb](https://github.com/undergroundwires/privacy.sexy/commit/6f46cdb4ed49a8941c6c0dde5c5e2a816c06daef)
* fix safari cleanup scripts that are not working on modern versions | [05932c5](https://github.com/undergroundwires/privacy.sexy/commit/05932c5a36446d551c5bc811165e3295fbe15e3f)
* refactor features to use shared functions #41 | [ac2249f](https://github.com/undergroundwires/privacy.sexy/commit/ac2249f25664827d8a6d2c7ebd659ccf126b0cde)
* increase performance by polyfilling ResizeObserver only if required | [448e378](https://github.com/undergroundwires/privacy.sexy/commit/448e378dc4501f9de69af63634c87d0e5060bf52)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.10.0...0.10.1)
## 0.10.0 (2021-03-02)
* allow functions to call other functions #53 | [7661575](https://github.com/undergroundwires/privacy.sexy/commit/7661575573c6d3e8f4bc28bfa7a124a764c72ef9)
* add option to run script directly in desktop app | [9a6b903](https://github.com/undergroundwires/privacy.sexy/commit/9a6b903b9297802845043fd41115756acd4a145c)
* add script to automatically kill devicecensus process | [c9b91f6](https://github.com/undergroundwires/privacy.sexy/commit/c9b91f6d8f9bd16308b6beda119e7154a985b6cf)
* refactor disabling application experience and document better | [45a3669](https://github.com/undergroundwires/privacy.sexy/commit/45a3669443d82855a52f60524d341c15f380f9e7)
* escape printed characters to prevent command injection #45 | [1260eea](https://github.com/undergroundwires/privacy.sexy/commit/1260eea690e4fa5420e58c9de9f88cc29cb242db)
* move code area to right on bigger screens | [cf39e6d](https://github.com/undergroundwires/privacy.sexy/commit/cf39e6d2541ea547f41d9553c380c54c24c58038)
* more scripts to disable speech recognition and Cortana | [ee43fd9](https://github.com/undergroundwires/privacy.sexy/commit/ee43fd92a019ebd26c13890f9146c5b5bb56afaf)
* add more macos scripts for privacy cleanup | [b0a7d0b](https://github.com/undergroundwires/privacy.sexy/commit/b0a7d0b53b3d8ac144a0241d70c037f460b0c0cc)
* add better error messages to setting vscode settings | [65226f3](https://github.com/undergroundwires/privacy.sexy/commit/65226f3984480d0bc7932fd8d76a328f08308850)
* remove windows scripts for removing non-bloating system apps #55 | [15004ff](https://github.com/undergroundwires/privacy.sexy/commit/15004ff1f1fb85a1d92e11ef695bcb2f37110610)
* remove "preview" disclaimer from macOS | [970221b](https://github.com/undergroundwires/privacy.sexy/commit/970221b996e25fe5b029cbaa78607c9bbc8c3c0e)
* update screenshot | [bd41af4](https://github.com/undergroundwires/privacy.sexy/commit/bd41af466fd135f7dc2f171633e4f60d8547c373)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.9.2...0.10.0)
## 0.9.2 (2021-02-13)
* do not compile with unused locals vuejs/vetur#1063 | [73e0520](https://github.com/undergroundwires/privacy.sexy/commit/73e0520de70cdbaf0ecdc6e9be5e85f003fcfb79)
* fix wrong path for NvTelemtry file in NVIDIA script | [34b8822](https://github.com/undergroundwires/privacy.sexy/commit/34b8822ac821acb47e483e21b57e380551bcf455)
* refactor event handling to consume base class for lifecycling | [f1e21ba](https://github.com/undergroundwires/privacy.sexy/commit/f1e21babbfaac21903594a37e30163bfe3338279)
* make compiler throw if a function call includes an unexpected parameter | [15353d0](https://github.com/undergroundwires/privacy.sexy/commit/15353d0e2513c89ee4ffd9d9c5e9e83ef69b96b6)
* refactor vscode configuration scripts using functions #41 | [67b2d1c](https://github.com/undergroundwires/privacy.sexy/commit/67b2d1c11cd5b131dff93a4437db79d96ed8b3dc)
* refactor state handling to make application available independent of the state | [df273f7](https://github.com/undergroundwires/privacy.sexy/commit/df273f7f635ab156ac51a8dfb3fec66c4979f1c4)
* add test to ensure correct shared functions are being parsed | [d7de420](https://github.com/undergroundwires/privacy.sexy/commit/d7de420d5c91bd9ce64880cd4a4391ad3a0a5401)
* refactor and add tests for NonCollapsingDirective | [5934b17](https://github.com/undergroundwires/privacy.sexy/commit/5934b1728328c3b2ece1597b74dd87477d162175)
* add GitHub issue templates | [daa997b](https://github.com/undergroundwires/privacy.sexy/commit/daa997b21b624d133c6f5e4cd6b70214588f9144)
* correct the typo in application.md (#60) | [575636e](https://github.com/undergroundwires/privacy.sexy/commit/575636e6b728a2bdd1a9bd72c57bbf2752f10887)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.9.1...0.9.2)
## 0.9.1 (2021-01-23)
* in CI/CD, allow publishing to github if release is more than 2 hours old electron-userland/electron-builder#2074 | [cf907d0](https://github.com/undergroundwires/privacy.sexy/commit/cf907d029a6d80682ba78ec887a9c4fab639db51)
* in CI/CD, publish packages for other OSes if single one fails | [4015e2c](https://github.com/undergroundwires/privacy.sexy/commit/4015e2ccd8492e0693365b70fbfe3bd0ac7a6ea2)
* specify desktop publish targets as defaults (may) change | [2316e3f](https://github.com/undergroundwires/privacy.sexy/commit/2316e3fb6867e5d765eafcf675b77f88bd2a0f52)
* fix selection state indicator on cards not showing up | [8b0e47d](https://github.com/undergroundwires/privacy.sexy/commit/8b0e47da38c49cfe2645d7d25970c448ecd200f8)
* transpile using babel for legacy browser support | [7930bef](https://github.com/undergroundwires/privacy.sexy/commit/7930bef48c4e9a4fe0823673958ed8377f5ee533)
* fix node APIs no longer working on desktop nklayman/vue-cli-plugin-electron-builder#610, nklayman/vue-cli-plugin-electron-builder#742 | [d7f9ef1](https://github.com/undergroundwires/privacy.sexy/commit/d7f9ef1cbebe911aa19f29be8c5fa9360550793e)
* improve explanation for selections | [229c13a](https://github.com/undergroundwires/privacy.sexy/commit/229c13a195dee92e4a31731b7b41c319273a16f1)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.9.0...0.9.1)
## 0.9.0 (2021-01-15)
* refactor application.yaml to become an os definition #40 | [f7557bc](https://github.com/undergroundwires/privacy.sexy/commit/f7557bcc0faf44e8395b68c7eb14c5f715f07b92)
* refactor folders to move "/state" (IApplicationState) inside "/context" (IApplicationContext) | [3467241](https://github.com/undergroundwires/privacy.sexy/commit/34672414c3e0757173036e351df0a73c1708ded5)
* add scripts to prevent family safety monitoring | [e14bf2b](https://github.com/undergroundwires/privacy.sexy/commit/e14bf2bfa03efe28ff39942c9891fca605f13eed)
* rework Cortana scripts to remove duplicates, better document and support Windows version 2004/2009 #43 | [7cc161c](https://github.com/undergroundwires/privacy.sexy/commit/7cc161c828a3fa49f6f254e31834a95a502b7aa2)
* rename Application to CategoryCollection #40 | [6fe858d](https://github.com/undergroundwires/privacy.sexy/commit/6fe858d86aeb0f8b6d5ae5c2a5e3c25ff32e5f6f)
* add script to clean previous windows installation #35 | [3455a2c](https://github.com/undergroundwires/privacy.sexy/commit/3455a2ca6ce13f9b0e866d88532a5c3d6de30d4d)
* refactor to allow switching ICategoryCollection context #40 | [2e40605](https://github.com/undergroundwires/privacy.sexy/commit/2e40605d59eb764768457c6af561487e7ff09777)
* fix typo causing uninstalling capabilities to fail #51 | [c299e95](https://github.com/undergroundwires/privacy.sexy/commit/c299e95bc6d588317b69a9efcf5752ff5c9c3926)
* improve uninstalling apps to show errors and exit if taking ownership fails #51 | [72e925f](https://github.com/undergroundwires/privacy.sexy/commit/72e925fb6f908cd58fb50618f29726b3fb54a7f1)
* move application.yaml to collections/windows.yaml #40 | [6b83dcb](https://github.com/undergroundwires/privacy.sexy/commit/6b83dcbf8fa08b4efe9974c7d7a667458f7c595c)
* recommend onedrive removal on strict mode | [663d63b](https://github.com/undergroundwires/privacy.sexy/commit/663d63bde08dd1b0d43ec144c758399cec90ec70)
* document app connector removal and recommend on strict mode | [9d009c4](https://github.com/undergroundwires/privacy.sexy/commit/9d009c40dd411c73c7ae032a78ec51490ecce024)
* recommend removing cortana taskbar icon on standard mode | [7ec889e](https://github.com/undergroundwires/privacy.sexy/commit/7ec889e759df04bba99d3b6c4d0597809bd94058)
* fix unintended null file creation #52 | [2428de2](https://github.com/undergroundwires/privacy.sexy/commit/2428de23ee02de987e7e6ec80ebd67be369d9048)
* add initial macOS support #40 | [8a8b731](https://github.com/undergroundwires/privacy.sexy/commit/8a8b7319d539b31c1d8ad9eaf541762d64f02493)
* add scripts to manage chromium based edge | [86a2b2f](https://github.com/undergroundwires/privacy.sexy/commit/86a2b2fda0b6a2565c550758c7c175fa795926b7)
* update screenshot | [c318bd3](https://github.com/undergroundwires/privacy.sexy/commit/c318bd301a2cbebbf5cdba06c0f18ac291aa4788)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.8.2...0.9.0)
## 0.8.2 (2020-12-26)
* replace ampersand in "Movies & TV app" with "and" to prevent batch file from misinterpreting it (#45) | [52d4313](https://github.com/undergroundwires/privacy.sexy/commit/52d4313156d2dcbc508b7271e7d9dfd45723d7bc)
* update dependencies to latest #46 | [d9e44e2](https://github.com/undergroundwires/privacy.sexy/commit/d9e44e25744e5d0aa01b8fc0f0af74c48027aea3)
* fix type assignment error after typescript upgrade | [55f936f](https://github.com/undergroundwires/privacy.sexy/commit/55f936fee9f86757f63fa8952d89711feb247e5b)
* correct typos (#48) | [a744415](https://github.com/undergroundwires/privacy.sexy/commit/a744415eb2ab65ee4f519f863fdd6a43953377bb)
* in ci/cd, do not run security checks if PRs do not change dependencies #48 | [54ba4db](https://github.com/undergroundwires/privacy.sexy/commit/54ba4dbb0bf8f08f9479f8facb2e12c786c1bc51)
* rename app launch tracking tweak to make it more clear #44 | [b3117c2](https://github.com/undergroundwires/privacy.sexy/commit/b3117c27f283c2d5a25fd94021a9f628a272cda6)
* refactor capabilities to use a shared function #41 #47 | [c4ec6a1](https://github.com/undergroundwires/privacy.sexy/commit/c4ec6a1445d2fd5eb923c97b54aee01e272e13a8)
* rename "disable" to "uninstall" for removing capabilities #47 | [8cd3352](https://github.com/undergroundwires/privacy.sexy/commit/8cd3352017f9dc85f8efcd7b450d90f555d3e92e)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.8.1...0.8.2)
## 0.8.1 (2020-11-16)
* refactor removing bloatware to use functions #41 | [ffa279f](https://github.com/undergroundwires/privacy.sexy/commit/ffa279f3dfe51db564f0a3859543eb212170e173)
* fix reinstalling store apps by searching appx for all users | [2c5ab3e](https://github.com/undergroundwires/privacy.sexy/commit/2c5ab3ea7da159cfb9fbfbbb7cdd28afbee965ea)
* fix clearing jump lists causing os to break and user pin removal #37 | [92c3dd9](https://github.com/undergroundwires/privacy.sexy/commit/92c3dd923257ac940eab6cbab858698ed55a09b7)
* fix reinstalling store apps by searching appx for all users | [4e72673](https://github.com/undergroundwires/privacy.sexy/commit/4e7267337301fe4a0480ba0603218fca25c2d096)
* refactor unused imports | [45b8dd9](https://github.com/undergroundwires/privacy.sexy/commit/45b8dd972b1edf9e263858c23b27e7a1d2e07077)
* fix not being able to uninstall system apps | [31e08d2](https://github.com/undergroundwires/privacy.sexy/commit/31e08d231d52e2a691400468b7c599c142a29448)
* fix wrong app names caused by wrong Microsoft docs | [e41e40c](https://github.com/undergroundwires/privacy.sexy/commit/e41e40c5bf01e2971d3054fcd3a48f8465a96622)
* unrecommend some system apps and document more | [29c7704](https://github.com/undergroundwires/privacy.sexy/commit/29c7704e0bd38f6e9923cde84accb569b02d2dd6)
* fix not being able to rename paths including brackets | [ad1872e](https://github.com/undergroundwires/privacy.sexy/commit/ad1872e7cd4ad7ef9facf33fadfa8c6a55065dd3)
* fix errors when file already exists | [c26bc20](https://github.com/undergroundwires/privacy.sexy/commit/c26bc209eb167aa71cad10b7f3ea02d0dedd97b0)
* move Microsoft.Appconnector to right category | [b247b12](https://github.com/undergroundwires/privacy.sexy/commit/b247b12c3f009aab4350e33f4779fd193e570050)
* replace deprecated github ::set-env command | [ab7d617](https://github.com/undergroundwires/privacy.sexy/commit/ab7d617886a65fe4f3c2daa929168e5678ccae60)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.8.0...0.8.1)
## 0.8.0 (2020-11-01)
* add support for different recommendation levels: strict and standard | [14be301](https://github.com/undergroundwires/privacy.sexy/commit/14be3017c55ed5e0d9bdecb63fcc4e1131e79ab0)
* Add GroupMe and Spotify removal option (#34) | [3785c62](https://github.com/undergroundwires/privacy.sexy/commit/3785c623f837b182d82fa383dfe7709722a67248)
* switch places of download and copy buttons | [50fb290](https://github.com/undergroundwires/privacy.sexy/commit/50fb29038ae19b17ec006093db02cf1e568d53c3)
* change "download" button to "save" on desktop | [07fc555](https://github.com/undergroundwires/privacy.sexy/commit/07fc555324d8bf4fa3594a9701daaa124a873153)
* show icons on cards during indeterminate and fully selected states | [1072505](https://github.com/undergroundwires/privacy.sexy/commit/1072505219edc47d82a91f148d1f310f32869fea)
* add scripts to increase cryptography, enable camera notifications and remove todo app (#36) | [4c68408](https://github.com/undergroundwires/privacy.sexy/commit/4c68408f1ec339dc8d39c7ab044f825a7f7185cb)
* update recommendations to be safer and consistent | [d0019c2](https://github.com/undergroundwires/privacy.sexy/commit/d0019c2c9b1eea620e2e8e02b586903ce62b80e3)
* rework disabling metadata retrieval | [ac70b06](https://github.com/undergroundwires/privacy.sexy/commit/ac70b063b8a15bc528256185792939685be6b36f)
* add all dist folders in gitignore because of files auto-generated by vscode | [1a9db31](https://github.com/undergroundwires/privacy.sexy/commit/1a9db31c7778c3269a71c0bd9665827efda70a02)
* add support for shared functions #41 | [8ce06fa](https://github.com/undergroundwires/privacy.sexy/commit/8ce06facbd54184402a4b1af3c7303e64db85b8a)
* hide scrollbars on code area when not overflowing | [fd28eaa](https://github.com/undergroundwires/privacy.sexy/commit/fd28eaad061c75ea1aa7e0f0d60ea37a7e52f8c4)
* update screenshot | [cfedcd7](https://github.com/undergroundwires/privacy.sexy/commit/cfedcd724cad7708b30c7390a7bca3b6313b6726)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.6...0.8.0)
## 0.7.6 (2020-10-18)
* add docs for default0 pointing to github discussion (#30) | [a3fc378](https://github.com/undergroundwires/privacy.sexy/commit/a3fc3782efd346b4c99d2a0b40df2eb0229f5b36)
* add robots.txt to explicitly allow indexing | [4c2f749](https://github.com/undergroundwires/privacy.sexy/commit/4c2f74949b0758d33049bdfa4f0124a28958f8ea)
* add more reversibility | [19a092d](https://github.com/undergroundwires/privacy.sexy/commit/19a092dd31fb3588277f1ab3120b409d98506752)
* refactor to read more from package.json | [784a67a](https://github.com/undergroundwires/privacy.sexy/commit/784a67afff681bc19147d03c947de0e165d97e87)
* simplify "why" section | [77c3d2b](https://github.com/undergroundwires/privacy.sexy/commit/77c3d2bbb8d13db86bb82ed0b5cbeaacfdea3db9)
* update dependencies to latest | [11e0613](https://github.com/undergroundwires/privacy.sexy/commit/11e06131655398db08faeeacff62062e46e0dddd)
* run tests on all operating systems: macos, ubuntu, windows | [d9d7f62](https://github.com/undergroundwires/privacy.sexy/commit/d9d7f62d81d4d8f95104d33211e82641884d711f)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.5...0.7.6)
## 0.7.5 (2020-09-14)
* fix reverting (reinstalling) capabilities not working | [939d838](https://github.com/undergroundwires/privacy.sexy/commit/939d838e3535bb1c9b00c8ea9dacb735ae41d700)
* fix tests and checks are not running on PRs | [82d5091](https://github.com/undergroundwires/privacy.sexy/commit/82d509129b4e4a5df4b84786a0d6842a7d26e888)
* fix the recycling bin option (#32) | [15db311](https://github.com/undergroundwires/privacy.sexy/commit/15db3118012a172a2191a2afad57084a65b34642)
* fix rendering issue in older edge/IE | [6efed72](https://github.com/undergroundwires/privacy.sexy/commit/6efed72bf25c2ddf0901caab7f22966ca13cd47a)
* fix pasting in search bar after page load showing no results | [d169434](https://github.com/undergroundwires/privacy.sexy/commit/d1694341578288eeaf8b80caf9296a38d76789f0)
* fix typo | [7dd15ed](https://github.com/undergroundwires/privacy.sexy/commit/7dd15ed06433e0e6583ab0fa46a683ce6554bbea)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.4...0.7.5)
## 0.7.4 (2020-09-12)
* fix checked checkbox has blue border | [4ae385b](https://github.com/undergroundwires/privacy.sexy/commit/4ae385b7fcea9014a68442714b7d99e2ee7df7d0)
* fix spectre protection getting single lined #31 | [22b23a9](https://github.com/undergroundwires/privacy.sexy/commit/22b23a9ece446c7f9abd4ede293051eb616ad50a)
* fix missing reg value in denying app access to account | [3c13a9e](https://github.com/undergroundwires/privacy.sexy/commit/3c13a9e837e06e097450b31d7eb0c0e6bf20cefb)
* fix wrong path in clear all firefox user profile settings | [ee66196](https://github.com/undergroundwires/privacy.sexy/commit/ee66196d9a60f27d17ae7f62d02b4f119a47e6e0)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.3...0.7.4)
## 0.7.3 (2020-09-12)
* fix vscode settings file override and add more configs | [a0d6172](https://github.com/undergroundwires/privacy.sexy/commit/a0d61728ead04b4455437f85820121a848db9e00)
* fix nvidia tweak error message, categorize and add reversibility | [99a2035](https://github.com/undergroundwires/privacy.sexy/commit/99a2035fdb0766a4dfc2753133eab0d7666516cd)
* improve CPU specific tweaks by conditional platform checks and reversibility | [8df5faf](https://github.com/undergroundwires/privacy.sexy/commit/8df5faf4ef05a49da63973bd0fbb5c5d07d5bd93)
* fix wrong path to the main telemetry file | [de4ac97](https://github.com/undergroundwires/privacy.sexy/commit/de4ac978bdda79573b36d355697b8a028d2c0beb)
* fix naming of firefox cleanup to mention profiles | [3ab48b1](https://github.com/undergroundwires/privacy.sexy/commit/3ab48b1cf5f7f934f07e468ef2318ccee07f530c)
* add reversibility and more scripts to denying app access with better structure | [1d465ee](https://github.com/undergroundwires/privacy.sexy/commit/1d465ee3189d0e5a827453b3f0eb4361efe23770)
* fix comment lines are being detected as duplicate in validation | [b6ccb59](https://github.com/undergroundwires/privacy.sexy/commit/b6ccb5927a20412976a54fd2215eb645092f98a8)
* add more detailed error message | [1f11c39](https://github.com/undergroundwires/privacy.sexy/commit/1f11c39773c12eccfb3efb898b58c2f6f37ab9ca)
* fix typo in a test | [1f19b25](https://github.com/undergroundwires/privacy.sexy/commit/1f19b2528a69383e63e579d2885f01cd804abf6c)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.2...0.7.3)
## 0.7.2 (2020-09-06)
* update onesync documentation and do not recommend it as it breaks other apps | [f36d8bf](https://github.com/undergroundwires/privacy.sexy/commit/f36d8bfc7848bb65ac0c641e318a689bf3816ccf)
* add reversibility for biometric disabling and do not recommend it | [db74531](https://github.com/undergroundwires/privacy.sexy/commit/db74531cd4139615c6d595959217d3651f099019)
* fix bad highlighting of selected nodes when using keyboard navigation | [255133a](https://github.com/undergroundwires/privacy.sexy/commit/255133af4dfae40171406648a3e2920f16d71cb3)
* add reversibility to removing bloatware | [c7b2a70](https://github.com/undergroundwires/privacy.sexy/commit/c7b2a703128470a05f12c9c6e8002444def37ef8)
* fix indeterminate state being lost | [1f266c3](https://github.com/undergroundwires/privacy.sexy/commit/1f266c33535f72b69c65985bf2eff27cd2c5a104)
* fix wording in default text in text area | [ca63a09](https://github.com/undergroundwires/privacy.sexy/commit/ca63a0979ef55d07d09d9443e5cea9aa888870a5)
* add best practice suggestion to come back | [f4885b6](https://github.com/undergroundwires/privacy.sexy/commit/f4885b6f1c82752f2143934e336d6d1b1af03015)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.1...0.7.2)
## 0.7.1 (2020-09-04)
* fix some browsers (including firefox) downloading the script as a text file | [8c17929](https://github.com/undergroundwires/privacy.sexy/commit/8c17929151f9c4fa5f48564492bbf400ced95eea)
* rename screenshot image file | [b8682a8](https://github.com/undergroundwires/privacy.sexy/commit/b8682a852a14ed6cf49986695d9510b840ac9d3d)
* fix new/changed script higlighting not working on production builds | [8c38dd7](https://github.com/undergroundwires/privacy.sexy/commit/8c38dd73d8c7b77d8d341c0389f4d7229f9b97fd)
* refactor unused imports | [6badfef](https://github.com/undergroundwires/privacy.sexy/commit/6badfef9daace0c5de3fd33652a82bfe22261b11)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.7.0...0.7.1)
## 0.7.0 (2020-09-02)
* [search] better (multilined) message when there are no results | [ec15af0](https://github.com/undergroundwires/privacy.sexy/commit/ec15af01dd020b364c2174fe562fd66227c2320c)
* [search] added clear/close button | [d6fa9a2](https://github.com/undergroundwires/privacy.sexy/commit/d6fa9a2a03c0ebe68b94f0b80cc52b4e200c9213)
* move script generation to /generation | [5df4587](https://github.com/undergroundwires/privacy.sexy/commit/5df458739d076719e350ba194c4f3f772884fcdb)
* add auto-highlighting of selected/updated code | [b789250](https://github.com/undergroundwires/privacy.sexy/commit/b789250cb89e2130b08e1a927df8181cf945dfeb)
* prompt admin priviliges automatically | [f8ba5c4](https://github.com/undergroundwires/privacy.sexy/commit/f8ba5c46e4923d9c35f200f8a08aa6437f7c0ecc)
* add removal of ghost (default0) telemetry user | [c262681](https://github.com/undergroundwires/privacy.sexy/commit/c262681011f39b4412669b6cf233476f676ca550)
* add more windows defender tweaks, categorization and reversibility | [1a34c73](https://github.com/undergroundwires/privacy.sexy/commit/1a34c7374ba56bafa0209bbb55c81b233bb419ed)
* fix NTP script documentation is on wrong place | [3060ebf](https://github.com/undergroundwires/privacy.sexy/commit/3060ebf79cf242370433495cc3e1878b7581b202)
* updated dependencies to latest and audit fixes (#25) | [c628aa9](https://github.com/undergroundwires/privacy.sexy/commit/c628aa9aef8ab7c815661d3c1711e7fbc65c69a2)
* categorize, fix and extend windows log files cleanup | [594a14d](https://github.com/undergroundwires/privacy.sexy/commit/594a14d6ca76cbd27a21877b8c373c1930589ca6)
* add more OneDrive cleanup scripts and categorize them | [978d7d0](https://github.com/undergroundwires/privacy.sexy/commit/978d7d08638dd161082f239ed088b12302f29458)
* add disabling firefox telemetry | [f8b8b4c](https://github.com/undergroundwires/privacy.sexy/commit/f8b8b4c97ab734d5ba7370894b694993924388da)
* add disabling ccleaner telemetry | [018b7e2](https://github.com/undergroundwires/privacy.sexy/commit/018b7e270f207aac926cb12f8069ebfcdce193ce)
* Add disabling of PowerShell 7+ telemetry (#29) | [456e40b](https://github.com/undergroundwires/privacy.sexy/commit/456e40bedf9afcc846f9b13f1ea144cef6115cf6)
* categorize, fix, make scripts reversible in "UI for privacy", "security improvements" and "configure browsers" | [532915b](https://github.com/undergroundwires/privacy.sexy/commit/532915b95da9fecd6b981d91bf489359e4e53caa)
* fix "Configure Defender" being in wrong category #28 | [f709d6a](https://github.com/undergroundwires/privacy.sexy/commit/f709d6a566ed7846b677b383863deda9680a2a9c)
* do not hardcode capability versions and make them reversible | [2afef4e](https://github.com/undergroundwires/privacy.sexy/commit/2afef4ea3d0d3d09aa1fa1eedba8493680bd8f10)
* exclude paint, wordpad and notepad from bloatware removal | [d235dee](https://github.com/undergroundwires/privacy.sexy/commit/d235dee95514a01745aef9479d07f88ffb4b40b8)
* add reversibility on category level | [f51e885](https://github.com/undergroundwires/privacy.sexy/commit/f51e8859eeb32c944126d692cfe03a0320c8b568)
* refactor unused imports & variables | [a23d28f](https://github.com/undergroundwires/privacy.sexy/commit/a23d28f2cfa2d64d45460697cf5ee9d6b5920752)
* fix search (got broken in b789250) with tests and refactorings | [8bbe6eb](https://github.com/undergroundwires/privacy.sexy/commit/8bbe6ebf750f1a1cbab493fb99b5ea91f4e21609)
* update the screenshot to show off highlighting | [b4aacea](https://github.com/undergroundwires/privacy.sexy/commit/b4aacea2a3e0bbcf2d8a79ff67f51c0f19e888a6)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.6.2...0.7.0)
## 0.6.2 (2020-08-16)
* 🐛 fixed disabling error reporting for november 2019 update | [5967347](https://github.com/undergroundwires/privacy.sexy/commit/5967347b80976a519f6f4eb1972a62f3e600df2b)
* 🐛 fixed blank screen and icons on mac | [7fac0fe](https://github.com/undergroundwires/privacy.sexy/commit/7fac0fe79f252e8f9dda4f6f83cd6fa4ba2b539f)
* 🐛 fixed removing onedrive does not delete scheduled tasks | [b6bfc25](https://github.com/undergroundwires/privacy.sexy/commit/b6bfc2572740c0cd46d3bc0058fa767dd5fa862e)
* ⚙️ enhanced tweak to disable for office telemetry | [afc3bfb](https://github.com/undergroundwires/privacy.sexy/commit/afc3bfb3b8896f332c9a196973ded3dce8fd21e4)
* ✨ added script to clear dotnet telemery | [1663bfe](https://github.com/undergroundwires/privacy.sexy/commit/1663bfeac7b6580b1335ca5fcf3587b69c080c72)
* 🐛 fixed changing time server not working | [c69998c](https://github.com/undergroundwires/privacy.sexy/commit/c69998c7cb29ffcf40f0af03b73150736581da69)
* 🔥 removed disabling ClickToRun as it breaks office | [3d3380f](https://github.com/undergroundwires/privacy.sexy/commit/3d3380f27ebeea53f17f49974aaa89300ffaf2dd)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.6.1...0.6.2)
## 0.6.1 (2020-08-09)
* updated documentation | [5963d2b](https://github.com/undergroundwires/privacy.sexy/commit/5963d2bac551083f9d16cce6b851abf0e8b88ce7)
* fixed typo in footer | [5c15a7a](https://github.com/undergroundwires/privacy.sexy/commit/5c15a7a64aaf24578a32713dec491bf494216303)
* more scripts can be reverted | [831c014](https://github.com/undergroundwires/privacy.sexy/commit/831c014f977515454ee6dc664d77a8c434495501)
* moved windows connect now to security & recommended | [6049a2b](https://github.com/undergroundwires/privacy.sexy/commit/6049a2b834d8d17af741f8d8f8b07cd15153b001)
* fixed mac / linux download links | [4c8be45](https://github.com/undergroundwires/privacy.sexy/commit/4c8be45e287b5ea009d6f828f7f327f37850569e)
* tweaks to disable webcam, speech and compatibility telemetry | [a5dbe66](https://github.com/undergroundwires/privacy.sexy/commit/a5dbe66fc175e39397f296ab2ff703e9b0ab4d7c)
* refactorings | [66d4d39](https://github.com/undergroundwires/privacy.sexy/commit/66d4d39d5bf3db305450514c6b6224654dafbfb2)
* fixed removing onedrive does not clean start menu / quick access | [1cc1219](https://github.com/undergroundwires/privacy.sexy/commit/1cc12195a3e9a11c590d3ed64d80299b50f74838)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.6.0...0.6.1)
## 0.6.0 (2020-07-26)
* fixed dead links in documentation | [25ce236](https://github.com/undergroundwires/privacy.sexy/commit/25ce236a7737decaf2eb9b8c29a4c4f34d43f770)
* runs tests on each push on the repository | [73c4268](https://github.com/undergroundwires/privacy.sexy/commit/73c426844a0330718a9ab7de12b61ca05e853323)
* code area now shows "how" before "why" | [4ff4b52](https://github.com/undergroundwires/privacy.sexy/commit/4ff4b52202b1c5dbfe2b80580bbe7d93132ab05c)
* support for desktop versions #20 | [04b9b59](https://github.com/undergroundwires/privacy.sexy/commit/04b9b59e14766ccd251474ad3710baf1f682fd49)
* reworked on footer & removed github icon | [60a5a2a](https://github.com/undergroundwires/privacy.sexy/commit/60a5a2aa4026d384bef9e6a203f1b7514a269c33)
* updated dependencies to latest | [45816a2](https://github.com/undergroundwires/privacy.sexy/commit/45816a2bccb3d11a50e3f2bc19c0a6cc2587deaa)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.5.0...0.6.0)
## 0.5.0 (2020-07-19)
* added ability to revert (#21) | [9c063d5](https://github.com/undergroundwires/privacy.sexy/commit/9c063d59defa6297c64f50b49403e8bd10620de9)
* search placeholder shows total scripts | [1d5225d](https://github.com/undergroundwires/privacy.sexy/commit/1d5225de07186f853f4cf7aedd4998f5d00c107a)
* do not collapse card when on "Search" and "Select" | [dd7e141](https://github.com/undergroundwires/privacy.sexy/commit/dd7e1416b4df54bf71b719d4654db88769dc0994)
* opening a card scrolls to its content div | [31d2067](https://github.com/undergroundwires/privacy.sexy/commit/31d2067f076c3159483baec49975617dddbd158d)
* all cards in same line now have same height | [a9f9e90](https://github.com/undergroundwires/privacy.sexy/commit/a9f9e9044385d9aed3b5551fc6c6823e813fd1e5)
* patched loadash vulnerability (#18) | [92a7118](https://github.com/undergroundwires/privacy.sexy/commit/92a7118d1c5013312772e075b9ee5a79c93710b8)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.10...0.5.0)
## 0.4.10 (2020-07-15)
* fixed script errors & added tests | [9e722dd](https://github.com/undergroundwires/privacy.sexy/commit/9e722ddfb3825fb29d6298025baaaa033120d017)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.9...0.4.10)
## 0.4.9 (2020-07-14)
* disable office telemetry Disassembler0/Win10-Initial-Setup-Script#288 | [53cf595](https://github.com/undergroundwires/privacy.sexy/commit/53cf595e1726ee3de79137fd566978fd512d218f)
* updated to may 2020 update | [909c44d](https://github.com/undergroundwires/privacy.sexy/commit/909c44d72a4a602ee8f27d06b6ec706c1e432ce1)
* simplified docker builds | [f27a287](https://github.com/undergroundwires/privacy.sexy/commit/f27a2871d74e5117fc029be82caef12246e10879)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.8...0.4.9)
## 0.4.8 (2020-07-11)
* added more scripts #16 (#17) | [d8552c6](https://github.com/undergroundwires/privacy.sexy/commit/d8552c62ffea13ce62abce836c7dd4980eef6bb9)
* stopping services before disabling #16 | [628c16e](https://github.com/undergroundwires/privacy.sexy/commit/628c16eb952495f5b3f6d794161b355f4b08b819)
* can disable features, capabilities & remove onedrive #16 | [30efbcc](https://github.com/undergroundwires/privacy.sexy/commit/30efbcc621eb83dd5a9c1e66b8f1f5350eb95006)
* updated one more typo (#19) | [d7a1325](https://github.com/undergroundwires/privacy.sexy/commit/d7a1325c0b7665ce712dc411965d00fc1d6fa384)
* more tweaks #16 | [2c4eb78](https://github.com/undergroundwires/privacy.sexy/commit/2c4eb78c3f156cb0d033977cffbe7464697680f5)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.7...0.4.8)
## 0.4.7 (2020-06-30)
* removed HKU tweak as all HKU's are changed #10 | [c937af8](https://github.com/undergroundwires/privacy.sexy/commit/c937af8ee7da9aa95131e56abf7bf24800390fe6)
* Fixed types + script in "Clear Windows log files" (#15) | [461a4f1](https://github.com/undergroundwires/privacy.sexy/commit/461a4f122b342369db5cc08c5e30961c64e68cdd)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.6...0.4.7)
## 0.4.6 (2020-06-16)
* Fixed Some More Issues (#12) | [52d5713](https://github.com/undergroundwires/privacy.sexy/commit/52d5713a99422cdf900aba819e49e998abac33cc)
* removed failing continuous deployment #14 | [583c566](https://github.com/undergroundwires/privacy.sexy/commit/583c5660d6ac934b845a044e013357aa91f61c15)
* Updated Some Tweaks (#11) | [0fc1845](https://github.com/undergroundwires/privacy.sexy/commit/0fc18459cde57684f00764815062f838f932aed5)
* Updated Some More Tweaks (#13) | [019b838](https://github.com/undergroundwires/privacy.sexy/commit/019b838925e963b7ec052ac76c6faf5650b9eb67)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.5...0.4.6)
## 0.4.5 (2020-06-13)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.4...0.4.5)
## 0.4.4 (2020-05-24)
* fixed close card button not being visible & cleanup | [0d2efe5](https://github.com/undergroundwires/privacy.sexy/commit/0d2efe5b05aa965458b78b8fa43754ce2f4fe11b)
* new footer with privacy policy | [e2ab124](https://github.com/undergroundwires/privacy.sexy/commit/e2ab124fb799f56ada3570fdc911361cb803e889)
* one command to lint everything "npm run lint" | [bb98d20](https://github.com/undergroundwires/privacy.sexy/commit/bb98d20637cbf1d524ebb2973e308773006e3153)
* fix "group by" overflows on smaller screens | [c668a97](https://github.com/undergroundwires/privacy.sexy/commit/c668a97950a1cb7c8bf2a7fd8a72d1101e65e8ce)
* clicking outside of a card closes it | [aab8f21](https://github.com/undergroundwires/privacy.sexy/commit/aab8f21a8d8dbed54798af581e6e1ad9e86a4be1)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.3...0.4.4)
## 0.4.3 (2020-05-23) ## 0.4.3 (2020-05-23)
* removed redundant documentation | [commit](https://github.com/undergroundwires/privacy.sexy/commit/749a140eb8dba09cb67fec2f8dec937e66e3cff5) * removed redundant documentation | [749a140](https://github.com/undergroundwires/privacy.sexy/commit/749a140eb8dba09cb67fec2f8dec937e66e3cff5)
* fixed broke link | [commit](https://github.com/undergroundwires/privacy.sexy/commit/97b7e03233d9718a8df30cb01ce06ca9489a0295) * fixed broke link | [97b7e03](https://github.com/undergroundwires/privacy.sexy/commit/97b7e03233d9718a8df30cb01ce06ca9489a0295)
* simplified heading | [commit](https://github.com/undergroundwires/privacy.sexy/commit/226074c5342f7463c06fcff1457d352ca30295a3) * simplified heading | [226074c](https://github.com/undergroundwires/privacy.sexy/commit/226074c5342f7463c06fcff1457d352ca30295a3)
* reading version from package.json instead of version file #5 | [commit](https://github.com/undergroundwires/privacy.sexy/commit/691f989682179016ddcbf55a05cded29155288c9) * reading version from package.json instead of version file #5 | [691f989](https://github.com/undergroundwires/privacy.sexy/commit/691f989682179016ddcbf55a05cded29155288c9)
* automatically increases patch number #5 | [commit](https://github.com/undergroundwires/privacy.sexy/commit/3e3bc07576f7c7e74e3e11fc7d197cbb9a9fb8c0) * automatically increases patch number #5 | [3e3bc07](https://github.com/undergroundwires/privacy.sexy/commit/3e3bc07576f7c7e74e3e11fc7d197cbb9a9fb8c0)
* using deployment operations from aws-static-site-with-cd | [commit](https://github.com/undergroundwires/privacy.sexy/commit/997be7113f676888892ffa35566d9ebb58a3e9ea) * using deployment operations from aws-static-site-with-cd | [997be71](https://github.com/undergroundwires/privacy.sexy/commit/997be7113f676888892ffa35566d9ebb58a3e9ea)
* automated using bump-everywhere + more quality checks (#8) | [commit](https://github.com/undergroundwires/privacy.sexy/commit/a27ca65b9eb29f009553e047bfb52f4200c0bd17) * automated using bump-everywhere + more quality checks (#8) | [4a91e8c](https://github.com/undergroundwires/privacy.sexy/commit/4a91e8ccd8a707bc6bea34ee28cff7fa4f66ee2f)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.2...0.4.3) [compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.2...0.4.3)
## 0.4.2 (2020-02-29) ## 0.4.2 (2020-02-29)
* added missing semicolon for masking | [commit](https://github.com/undergroundwires/privacy.sexy/commit/e63ac4ae67da68243a525af149ff30e5d485b641) * added missing semicolon for masking | [e63ac4a](https://github.com/undergroundwires/privacy.sexy/commit/e63ac4ae67da68243a525af149ff30e5d485b641)
* set font on input | [commit](https://github.com/undergroundwires/privacy.sexy/commit/0c39a06be5e4b0a2031ad5e9f5220dd669afee53) * set font on input | [0c39a06](https://github.com/undergroundwires/privacy.sexy/commit/0c39a06be5e4b0a2031ad5e9f5220dd669afee53)
* shortened all HKEY paths | [commit](https://github.com/undergroundwires/privacy.sexy/commit/802b36bdd8dcc1f0a2853fe7da2ea2fccd69a88c) * shortened all HKEY paths | [802b36b](https://github.com/undergroundwires/privacy.sexy/commit/802b36bdd8dcc1f0a2853fe7da2ea2fccd69a88c)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.1...0.4.2) [compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.1...0.4.2)
## 0.4.1 (2020-01-11) ## 0.4.1 (2020-01-11)
* fixed search bug | [commit](https://github.com/undergroundwires/privacy.sexy/commit/31364bdfec503af09ffbb58044a17dfb833fc8d9) * fixed search bug | [31364bd](https://github.com/undergroundwires/privacy.sexy/commit/31364bdfec503af09ffbb58044a17dfb833fc8d9)
* hide grouping while searching | [commit](https://github.com/undergroundwires/privacy.sexy/commit/92f1a36bcb1e1fe7c90efe8ccd3ede55991e9d9c) * hide grouping while searching | [92f1a36](https://github.com/undergroundwires/privacy.sexy/commit/92f1a36bcb1e1fe7c90efe8ccd3ede55991e9d9c)
* 👀🔍 showing search queries | [commit](https://github.com/undergroundwires/privacy.sexy/commit/97a7747933d2b515cc03ab8243e6a8ae702ef16a) * 👀🔍 showing search queries | [97a7747](https://github.com/undergroundwires/privacy.sexy/commit/97a7747933d2b515cc03ab8243e6a8ae702ef16a)
* more efficient queries with single lowercase | [commit](https://github.com/undergroundwires/privacy.sexy/commit/19813b691746d98670823025c460480400e34b6e) * more efficient queries with single lowercase | [19813b6](https://github.com/undergroundwires/privacy.sexy/commit/19813b691746d98670823025c460480400e34b6e)
* using right 🔍 input type | [commit](https://github.com/undergroundwires/privacy.sexy/commit/0ce354ea0956391ad3f37b252daac1127bfc601a) * using right 🔍 input type | [0ce354e](https://github.com/undergroundwires/privacy.sexy/commit/0ce354ea0956391ad3f37b252daac1127bfc601a)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.0...0.4.1) [compare](https://github.com/undergroundwires/privacy.sexy/compare/0.4.0...0.4.1)
## 0.4.0 (2020-01-11) ## 0.4.0 (2020-01-11)
* 🔍 support for search | [commit](https://github.com/undergroundwires/privacy.sexy/commit/89862b2775703257b9dc2e19fbebde2c0d0fbda0) * 🔍 support for search | [89862b2](https://github.com/undergroundwires/privacy.sexy/commit/89862b2775703257b9dc2e19fbebde2c0d0fbda0)
* more scripts & better organized | [commit](https://github.com/undergroundwires/privacy.sexy/commit/95baf3175b0d2c7df516f7893a96346b94ac8eca) * more scripts & better organized | [95baf31](https://github.com/undergroundwires/privacy.sexy/commit/95baf3175b0d2c7df516f7893a96346b94ac8eca)
* refactorings | [commit](https://github.com/undergroundwires/privacy.sexy/commit/e3f82e069e305f6d94eab335470c8e7b44295dd6) * refactorings | [e3f82e0](https://github.com/undergroundwires/privacy.sexy/commit/e3f82e069e305f6d94eab335470c8e7b44295dd6)
* more margin for the scripts | [commit](https://github.com/undergroundwires/privacy.sexy/commit/5ea46ecbf52236953d19f09a8eade08b83e6cd34) * more margin for the scripts | [5ea46ec](https://github.com/undergroundwires/privacy.sexy/commit/5ea46ecbf52236953d19f09a8eade08b83e6cd34)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.3.0...0.4.0) [compare](https://github.com/undergroundwires/privacy.sexy/compare/0.3.0...0.4.0)
## 0.3.0 (2020-01-09) ## 0.3.0 (2020-01-09)
* added description & more descriptive title | [commit](https://github.com/undergroundwires/privacy.sexy/commit/99576340b648550149871e2c0fe0b0d8c2dd0d7c) * added description & more descriptive title | [9957634](https://github.com/undergroundwires/privacy.sexy/commit/99576340b648550149871e2c0fe0b0d8c2dd0d7c)
* allow robots | [commit](https://github.com/undergroundwires/privacy.sexy/commit/eee0e785ec2c5e6bed53d21b4126a57773e35dba) * allow robots | [eee0e78](https://github.com/undergroundwires/privacy.sexy/commit/eee0e785ec2c5e6bed53d21b4126a57773e35dba)
* removed unused references | [commit](https://github.com/undergroundwires/privacy.sexy/commit/cfd888f3afc5c260a0a4a73f2843b86b9f1df2cd) * removed unused references | [cfd888f](https://github.com/undergroundwires/privacy.sexy/commit/cfd888f3afc5c260a0a4a73f2843b86b9f1df2cd)
* 🚫 disable NVIDIA telemetry | [commit](https://github.com/undergroundwires/privacy.sexy/commit/ab28f4ed8538d51e1777c86302a63a0cd9c3cb2a) * 🚫 disable NVIDIA telemetry | [ab28f4e](https://github.com/undergroundwires/privacy.sexy/commit/ab28f4ed8538d51e1777c86302a63a0cd9c3cb2a)
* backwards compatibility for fonts | [commit](https://github.com/undergroundwires/privacy.sexy/commit/4bc13e11926a6df77079646499e799742153b4ab) * backwards compatibility for fonts | [4bc13e1](https://github.com/undergroundwires/privacy.sexy/commit/4bc13e11926a6df77079646499e799742153b4ab)
* added back meta needed for responsiveness | [commit](https://github.com/undergroundwires/privacy.sexy/commit/ed872ef3d9f6c92afc0ce0d06998c60463a8b4e8) * added back meta needed for responsiveness | [ed872ef](https://github.com/undergroundwires/privacy.sexy/commit/ed872ef3d9f6c92afc0ce0d06998c60463a8b4e8)
* fancy-font is renamed to main and now used | [commit](https://github.com/undergroundwires/privacy.sexy/commit/6825001c61426194dc363b96b57a321241f3ba57) * fancy-font is renamed to main and now used | [6825001](https://github.com/undergroundwires/privacy.sexy/commit/6825001c61426194dc363b96b57a321241f3ba57)
* added support for grouping | [commit](https://github.com/undergroundwires/privacy.sexy/commit/ec6b3c54072a77bb4305da1c234db6c649218b88) * added support for grouping | [ec6b3c5](https://github.com/undergroundwires/privacy.sexy/commit/ec6b3c54072a77bb4305da1c234db6c649218b88)
* less hyphens as it looks better on mobile | [commit](https://github.com/undergroundwires/privacy.sexy/commit/e0b080af69157f46ba12e2c25e794f5384671b51) * less hyphens as it looks better on mobile | [e0b080a](https://github.com/undergroundwires/privacy.sexy/commit/e0b080af69157f46ba12e2c25e794f5384671b51)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.2.0...0.3.0) [compare](https://github.com/undergroundwires/privacy.sexy/compare/0.2.0...0.3.0)
## 0.2.0 (2020-01-06) ## 0.2.0 (2020-01-06)
* added GitHub Actions badge for build & deploy | [commit](https://github.com/undergroundwires/privacy.sexy/commit/a229aca68a92bbcd8e8176ac1dd25ce03509e074) * added GitHub Actions badge for build & deploy | [a229aca](https://github.com/undergroundwires/privacy.sexy/commit/a229aca68a92bbcd8e8176ac1dd25ce03509e074)
* more badges 📛🏆📜 | [commit](https://github.com/undergroundwires/privacy.sexy/commit/090e8319091044e53484ba8338510f6fb7c3cb80) * more badges 📛🏆📜 | [090e831](https://github.com/undergroundwires/privacy.sexy/commit/090e8319091044e53484ba8338510f6fb7c3cb80)
* typo fixes + whitespace refactorings | [commit](https://github.com/undergroundwires/privacy.sexy/commit/e99f210c9dcf61a21e445e2a331384b6066f2c98) * typo fixes + whitespace refactorings | [e99f210](https://github.com/undergroundwires/privacy.sexy/commit/e99f210c9dcf61a21e445e2a331384b6066f2c98)
* switched content information to "why" section | [commit](https://github.com/undergroundwires/privacy.sexy/commit/beb3c8339f83a224ca66ad8a911a9265ffe7c9c0) * switched content information to "why" section | [beb3c83](https://github.com/undergroundwires/privacy.sexy/commit/beb3c8339f83a224ca66ad8a911a9265ffe7c9c0)
* fixed contribution URL | [commit](https://github.com/undergroundwires/privacy.sexy/commit/7b4277d7706ccf6ba7e4b7b01aa46f8e3852cfc6) * fixed contribution URL | [7b4277d](https://github.com/undergroundwires/privacy.sexy/commit/7b4277d7706ccf6ba7e4b7b01aa46f8e3852cfc6)
* fixed wrong relation + lighter style | [commit](https://github.com/undergroundwires/privacy.sexy/commit/8d05b03c9f3c9fc015be6615da8c283809712065) * fixed wrong relation + lighter style | [8d05b03](https://github.com/undergroundwires/privacy.sexy/commit/8d05b03c9f3c9fc015be6615da8c283809712065)
* better URL validation | [commit](https://github.com/undergroundwires/privacy.sexy/commit/aff463dd64fecff92a786fcba88621dff6b1cf73) * better URL validation | [aff463d](https://github.com/undergroundwires/privacy.sexy/commit/aff463dd64fecff92a786fcba88621dff6b1cf73)
* refactoring to new function | [commit](https://github.com/undergroundwires/privacy.sexy/commit/c646c102730481c3f4648eb714dc0a84ce35b13c) * refactoring to new function | [c646c10](https://github.com/undergroundwires/privacy.sexy/commit/c646c102730481c3f4648eb714dc0a84ce35b13c)
* optimized find queries & refactorings | [commit](https://github.com/undergroundwires/privacy.sexy/commit/d38f6cd6a8b33e11df854c7abea05974dc04d4ce) * optimized find queries & refactorings | [d38f6cd](https://github.com/undergroundwires/privacy.sexy/commit/d38f6cd6a8b33e11df854c7abea05974dc04d4ce)
* 🎨 styled no JS error | [commit](https://github.com/undergroundwires/privacy.sexy/commit/c359f1d89c6874b3cc94154b993e33f58bd32268) * 🎨 styled no JS error | [c359f1d](https://github.com/undergroundwires/privacy.sexy/commit/c359f1d89c6874b3cc94154b993e33f58bd32268)
* simplified finding duplicates | [commit](https://github.com/undergroundwires/privacy.sexy/commit/57037aaefcc0e80f0f4719cea89568490a731028) * simplified finding duplicates | [57037aa](https://github.com/undergroundwires/privacy.sexy/commit/57037aaefcc0e80f0f4719cea89568490a731028)
* fixed maintainability badge URL | [commit](https://github.com/undergroundwires/privacy.sexy/commit/aaea47e7d15fe41dea26968db0107a0c53d108f3) * fixed maintainability badge URL | [aaea47e](https://github.com/undergroundwires/privacy.sexy/commit/aaea47e7d15fe41dea26968db0107a0c53d108f3)
* fixed wrong line dumps | [commit](https://github.com/undergroundwires/privacy.sexy/commit/5ccc7c59528885ae7729197df3dfa00f924a2b3f) * fixed wrong line dumps | [5ccc7c5](https://github.com/undergroundwires/privacy.sexy/commit/5ccc7c59528885ae7729197df3dfa00f924a2b3f)
* refactorings in parsing | [commit](https://github.com/undergroundwires/privacy.sexy/commit/2aa3742e30646bf1d1f3779419d161c3fb6c4808) * refactorings in parsing | [2aa3742](https://github.com/undergroundwires/privacy.sexy/commit/2aa3742e30646bf1d1f3779419d161c3fb6c4808)
* using free function | [commit](https://github.com/undergroundwires/privacy.sexy/commit/20020af7c1d8de13948d8761fd4e7f0affb2badb) * using free function | [20020af](https://github.com/undergroundwires/privacy.sexy/commit/20020af7c1d8de13948d8761fd4e7f0affb2badb)
* default selection is now none | [commit](https://github.com/undergroundwires/privacy.sexy/commit/3140cc663b86394d543de90228aa53e6a304d8d9) * default selection is now none | [3140cc6](https://github.com/undergroundwires/privacy.sexy/commit/3140cc663b86394d543de90228aa53e6a304d8d9)
* added hyphen lines for longer names | [commit](https://github.com/undergroundwires/privacy.sexy/commit/cced601d686d550f4225018e5311b7433efbb5ae) * added hyphen lines for longer names | [cced601](https://github.com/undergroundwires/privacy.sexy/commit/cced601d686d550f4225018e5311b7433efbb5ae)
* more descriptive subtitle | [commit](https://github.com/undergroundwires/privacy.sexy/commit/2cf9214b14d9720f747a71b3864ba7a28acf0ff4) * more descriptive subtitle | [2cf9214](https://github.com/undergroundwires/privacy.sexy/commit/2cf9214b14d9720f747a71b3864ba7a28acf0ff4)
* added footer with version | [commit](https://github.com/undergroundwires/privacy.sexy/commit/10a34fae2f1a219ec52db0c74edb39b46ebd8abc) * added footer with version | [10a34fa](https://github.com/undergroundwires/privacy.sexy/commit/10a34fae2f1a219ec52db0c74edb39b46ebd8abc)
* using font variables | [commit](https://github.com/undergroundwires/privacy.sexy/commit/60e6348dc8d53f1e81ebdb2ec0e1962aac1e9842) * using font variables | [60e6348](https://github.com/undergroundwires/privacy.sexy/commit/60e6348dc8d53f1e81ebdb2ec0e1962aac1e9842)
* code-gen refactorings | [commit](https://github.com/undergroundwires/privacy.sexy/commit/246e753ddc9dc8bf630e538663584bf3423cc749) * code-gen refactorings | [246e753](https://github.com/undergroundwires/privacy.sexy/commit/246e753ddc9dc8bf630e538663584bf3423cc749)
* added text when nothing is chosen | [commit](https://github.com/undergroundwires/privacy.sexy/commit/a7da75d4428090423b692ce45423f5bd300d8442) * added text when nothing is chosen | [a7da75d](https://github.com/undergroundwires/privacy.sexy/commit/a7da75d4428090423b692ce45423f5bd300d8442)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.1.0...0.2.0) [compare](https://github.com/undergroundwires/privacy.sexy/compare/0.1.0...0.2.0)

34
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,34 @@
# Contributing
- Love your input! Contributing to this project should be as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer
## Pull request process
- [GitHub flow](https://guides.github.com/introduction/flow/index.html) with [GitOps](./img/architecture/gitops.png) is used
- Your pull requests are actively welcomed.
- The steps:
1. Fork the repo and create your branch from master.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. Issue that pull request!
- 🙏 DO
- Document your changes in the pull request
- ❗ DON'T
- Do not update the versions, current version is only [set by the maintainer](./img/architecture/gitops.png) and updated automatically by [bump-everywhere](https://github.com/undergroundwires/bump-everywhere)
## License
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

@@ -1,20 +1,12 @@
# +-+-+-+-+-+ +-+-+-+-+-+ # Build
# |B|u|i|l|d| |S|t|a|g|e|
# +-+-+-+-+-+ +-+-+-+-+-+
FROM node:lts-alpine as build-stage FROM node:lts-alpine as build-stage
WORKDIR /app WORKDIR /app
COPY package*.json ./ COPY package*.json ./
RUN npm install RUN npm install
COPY . . COPY . .
RUN npm run build RUN npm run build
# For testing purposes, it's easy to run http-server on lts-alpine such as continuing from here:
# RUN npm install -g http-server
# EXPOSE 8080
# CMD [ "http-server", "dist" ]
# +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+ # Production stage
# |P|r|o|d|u|c|t|i|o|n| |S|t|a|g|e|
# +-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+
FROM nginx:stable-alpine as production-stage FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80 EXPOSE 80

View File

@@ -1,8 +1,8 @@
# privacy.sexy # privacy.sexy
> Web tool to enforce privacy & security best-practices on Windows, because privacy is sexy 🍑🍆 > Enforce privacy & security best-practices on Windows and macOS, because privacy is sexy 🍑🍆
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/undergroundwires/privacy.sexy/issues) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](./CONTRIBUTING.md)
[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/undergroundwires/privacy.sexy.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/undergroundwires/privacy.sexy/context:javascript) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/undergroundwires/privacy.sexy.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/undergroundwires/privacy.sexy/context:javascript)
[![Maintainability](https://api.codeclimate.com/v1/badges/3a70b7ef602e2264342c/maintainability)](https://codeclimate.com/github/undergroundwires/privacy.sexy/maintainability) [![Maintainability](https://api.codeclimate.com/v1/badges/3a70b7ef602e2264342c/maintainability)](https://codeclimate.com/github/undergroundwires/privacy.sexy/maintainability)
[![Tests status](https://github.com/undergroundwires/privacy.sexy/workflows/Test/badge.svg)](https://github.com/undergroundwires/privacy.sexy/actions) [![Tests status](https://github.com/undergroundwires/privacy.sexy/workflows/Test/badge.svg)](https://github.com/undergroundwires/privacy.sexy/actions)
@@ -12,54 +12,68 @@
[![Deploy status](https://github.com/undergroundwires/privacy.sexy/workflows/Build%20&%20deploy/badge.svg)](https://github.com/undergroundwires/privacy.sexy/actions) [![Deploy status](https://github.com/undergroundwires/privacy.sexy/workflows/Build%20&%20deploy/badge.svg)](https://github.com/undergroundwires/privacy.sexy/actions)
[![Auto-versioned by bump-everywhere](https://github.com/undergroundwires/bump-everywhere/blob/master/badge.svg?raw=true)](https://github.com/undergroundwires/bump-everywhere) [![Auto-versioned by bump-everywhere](https://github.com/undergroundwires/bump-everywhere/blob/master/badge.svg?raw=true)](https://github.com/undergroundwires/bump-everywhere)
[https://privacy.sexy](https://privacy.sexy) ## Get started
- Online version at [https://privacy.sexy](https://privacy.sexy)
- 💡 No need to run any compiled software on your computer.
- Alternatively download offline version for [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.11.1/privacy.sexy-Setup-0.11.1.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.11.1/privacy.sexy-0.11.1.dmg) or [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.11.1/privacy.sexy-0.11.1.AppImage).
- 💡 Single click to execute your script.
- ❗ Come back regularly to apply latest version for stronger privacy and security.
[![privacy.sexy application](img/screenshot.png?raw=true)](https://privacy.sexy)
## Why ## Why
- You don't need to run any compiled software on your system, just run the generated scripts. - Rich tweak pool to harden security & privacy of the OS and other software on it
- It's open source, both application & infrastructure is 100% transparent - Free (both free as in beer and free as in speech)
- Fully automated C/CD pipeline to AWS for provisioning serverless infrastructure using GitHub actions. - No need to run any compiled software that has access to your system, just run the generated scripts
- Have full visibility into what the tweaks do as you enable them. - Have full visibility into what the tweaks do as you enable them
- Easily extendable - Ability to revert (undo) applied scripts
- Everything is transparent: both application and its infrastructure are open-source and automated
- Easily extendable with [own powerful templating language](./docs/templating.md)
- Each script is independently executable without cross-dependencies
## Extend scripts ## Extend scripts
Fork it & add more scripts in [application.yaml](src/application/application.yaml) and send a pull request 👌 - You can either [create an issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose)
- Or send a PR:
1. Fork the repository
2. Add more scripts in respective script collection in [collections](src/application/collections/) folder.
- 📖 If you're unsure about the syntax you can refer to the [collection files | documentation](docs/collection-files.md).
- 🙏 For any new script, please add `revertCode` and `docs` values if possible.
3. Send a pull request 👌
## Commands ## Commands
- Setup and run - Project setup: `npm install`
- For development: - Testing
- `npm install` to project setup. - Run unit tests: `npm run test:unit`
- `npm run serve` to compile & hot-reload for development. - Run integration tests: `npm run test:integration`
- Production (using Docker): - Lint: `npm run lint`
- Build `docker build -t undergroundwires/privacy.sexy .` - **Desktop app**
- Run `docker run -it -p 8080:8080 --rm --name privacy.sexy-1 undergroundwires/privacy.sexy` - Development: `npm run electron:serve`
- Prepare for production: `npm run build` - Production: `npm run electron:build` to build an executable
- Run tests: `npm run test:unit` - **Webpage**
- Lint and fix files: `npm run lint` - Development: `npm run serve` to compile & hot-reload for development.
- Production: `npm run build` to prepare files for distribution.
- Or run using Docker:
1. Build: `docker build -t undergroundwires/privacy.sexy:0.11.1 .`
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.11.1 undergroundwires/privacy.sexy:0.11.1`
## Architecture ## Architecture overview
### Application ### Application
- Powered by **TypeScript** + **Vue.js** 💪 - Powered by **TypeScript**, **Vue.js** and **Electron** 💪
- and driven by **Domain-driven design**, **Event-driven architecture**, **Data-driven programming** concepts. - and driven by **Domain-driven design**, **Event-driven architecture**, **Data-driven programming** concepts.
- Application uses highly decoupled models & services in different DDD layers. - Application uses highly decoupled models & services in different DDD layers.
- **Domain layer** is where the application is modelled with validation logic. - 📖 Read more on • [Presentation](./docs/presentation.md) • [Application](./docs/application.md)
- **Presentation Layer**
- Consists of Vue.js components & UI stuff.
- Event driven as in components simply listens to events from the state and act accordingly.
- **Application Layer**
- Keeps the application state
- The [state](src/application/State/ApplicationState.ts) is a mutable singleton & event producer.
- The application is defined & controlled in a [single YAML file](src/application/application.yaml) (see [Data-driven programming](https://en.wikipedia.org/wiki/Data-driven_programming))
![DDD + vue.js](docs/app-ddd.png) ![DDD + vue.js](img/architecture/app-ddd.png)
### AWS Infrastructure ### AWS Infrastructure
[![AWS solution](docs/aws-solution.png)](https://github.com/undergroundwires/aws-static-site-with-cd) [![AWS solution](img/architecture/aws-solution.png)](https://github.com/undergroundwires/aws-static-site-with-cd)
- It uses infrastructure from the following repository: [aws-static-site-with-cd](https://github.com/undergroundwires/aws-static-site-with-cd) - It uses infrastructure from the following repository: [aws-static-site-with-cd](https://github.com/undergroundwires/aws-static-site-with-cd)
- Runs on AWS 100% serverless and automatically provisioned using [GitHub Actions](.github/workflows/). - Runs on AWS 100% serverless and automatically provisioned using [GitHub Actions](.github/workflows/).
@@ -71,4 +85,4 @@ Fork it & add more scripts in [application.yaml](src/application/application.yam
- Versioning, tagging, creation of `CHANGELOG.md` and releasing is automated using [bump-everywhere](https://github.com/undergroundwires/bump-everywhere) action - Versioning, tagging, creation of `CHANGELOG.md` and releasing is automated using [bump-everywhere](https://github.com/undergroundwires/bump-everywhere) action
- Everything that's merged in the master goes directly to production. - Everything that's merged in the master goes directly to production.
[![CI/CD to AWS with GitHub Actions](docs/gitops.png)](.github/workflows/) [![CI/CD to AWS with GitHub Actions](img/architecture/gitops.png)](.github/workflows/)

5
babel.config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

5
build/README.md Normal file
View File

@@ -0,0 +1,5 @@
# build
- These are the file that are used by electron.
- Logos are created by from the [PNG icon](./../public/icon.png)
- by running `npx electron-icon-builder --input=./public/icon.png --output=build --flatten`

BIN
build/icons/1024x1024.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
build/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
build/icons/16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

BIN
build/icons/24x24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
build/icons/256x256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
build/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
build/icons/48x48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
build/icons/512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
build/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
build/icons/icon.icns Normal file

Binary file not shown.

BIN
build/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

View File

@@ -1 +0,0 @@
<mxfile host="www.draw.io" modified="2019-12-27T03:04:27.829Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" etag="O-1eaon4mqUmgvki0auB" version="12.4.3" pages="1"><diagram id="rhL8jzEM8kVVyiS98U7u" name="Page-1">3Zpdk6I4FIZ/jZdakPDlpa3tzlTNbnVVV83OzE1XhACZAUKF2Or8+k0wCBhau1f8GrpayUkC5HlzTg7IAE7T9V8M5fHfNMDJABjBegBnAwA8YIpPadhsDS50t4aIkWBrMmvDM/mNldFQ1iUJcNFqyClNOMnbRp9mGfZ5y4YYo6t2s5Am7bPmKMKa4dlHiW79lwQ8VsOyjdr+CZMors5sGqomRVVjZShiFNBVwwQfB3DKKOXbvXQ9xYlkV3HZ9pu/Ubu7MIYz/p4OD0/efJxMXmZfs6kd/vj2Txp+HlrVxfFNNWIcCACqSBmPaUQzlDzW1gdGl1mA5WENUarbfKE0F0ZTGH9izjdKTbTkVJhiniaqFq8J/ya7j2xV+t6oma3VkcvCpipknG0anWTxe7Ou7laWqn4FZ/QXntKEsnJ8cFxuomY7cjncN4kqU0GXzMcHMFYzE7EI8wPtwE534S+YplhcqejHcII4eW1fB1IzN9q1q8UVO0rfj2gNrqL1TreWarWI96AbPFG3suuEMbRpNMgpyXjROPKTNIgGKnZC5Zsqctp77n24NTDtvQmzPX09fXbjOGFGwatGj0bsMEbAfmf4uONpaF0zfKjjvqJkqc70xHAhxirOTTNtIrRlXsWE4+cclRhWIlNoSxqSJGkwDmzsBVYXfQ8soOPIHjTj1TyrrgwzjteHxdDhqQ6O23Yf5U2res2H1coeN9Z7xzgTbehc07XMlmu907PMtmeBm3AtcCHX+n8RftwO2iZsBe2j7YHrnj/IQ+9eUsSbmlCnpgwnRQ+gxepJnifE7yNUtwKvFrpDW/51ieGUmzpCw77ddiKdFMXtdhTf3Yw1wzjoCOPu2cK4fS/Oc9P3V/AeEiSoOd2Mpoj0mxotzCAIO7mbhgvH+Ayp0XjPqca6UwGrw6nsczmVpYH+nIUMCSJLny8Z7hV46PnY97uALzzbso0zAHf3clGnA7h3ySjmaMDxK1aZzRugzY+DDrHTDTpwxwvD6GeF8PbYujpbtwMtOBdaV0PLcE4Lwqk6+F3jhR0L8EXxenqoeMw44ffIdj8uXB3uWIPLY4ZRQLLoD8B79dBg6ll8Kn9e6TfsLpDvBbALLoCWZQf9wBXJSRuuYelw7ZHZgRecC6+er4ldEhy7R7pVxMA2R+Obg2xrkAuO+KEU7R18e6C15+xm9ZTjiqjOk2X1MbOc47DMrqej52Olp02o+YDDSGhE/NsDZ+pLymXBVWPoBjfaiNFfG9rtMdMXCg1SEaNc7pK0fJ+giUTCEHyTSUKiTNi4fIizs35BC5w8yYRfTlw4W1DOaSoaJLLiAfm/olKAVjokN9GkPNmkyLfvPcg0CFWFkKylZA/qemYx5/KFiYkkAeZ+kFkj4tMsJEJaNvLFGcFcrHxIfEm7iDlz4UK0GKIsGC6Y+JQmW6Ykc+i4L1+X+GfxIpuINMUb5VXG1+t9r60Jb1/yMQPQ16771x1+WPchCugC79QHnvfyjIqiR91NcGPC6yvx/QtvHhV+ka3Ep5B1Lf7FnlgYpFk+3Sp6Uhq4+zkqBCNdbQh1tStb/2rrucT9q20cVTukLMLZsMBU/rI/d8Stwjwn5fPTYkhzTlLyu0wKenR0WN0O7MTXpbc6pLc+LL0o1m/WbX8JrV9PhI//AQ==</diagram></mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

44
docs/application.md Normal file
View File

@@ -0,0 +1,44 @@
# Application
- It's mainly responsible for
- creating and event based [application state](#application-state)
- [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
- [ApplicationContext.ts](./../src/application/Context/ApplicationContext.ts) holds the [CategoryCollectionState](./../src/application/Context/State/CategoryCollectionState.ts) for each OS
- Uses [state pattern](https://en.wikipedia.org/wiki/State_pattern)
- Same instance is shared throughout the application to ensure consistent state
- 📖 See [Application State | Presentation layer](./presentation.md#application-state) to read more about how the state should be managed by the presentation layer.
- 📖 See [ApplicationContext.ts](./../src/application/Context/ApplicationContext.ts) to start diving into the state code.
## Application data
- Compiled to [`Application`](./../src/domain/Application.ts) domain object.
- The scripts are defined and controlled in different data files per OS
- Enables [data-driven programming](https://en.wikipedia.org/wiki/Data-driven_programming) and easier contributions
- Application data is defined in collection files and
- 📖 See [Application data | Presentation layer](./presentation.md#application-data) to read how the application data is read by the presentation layer.
- 📖 See [collection files documentation](./collection-files.md) to read more about how the data files are structured/defined and see [collection yaml files](./../src/application/collections/) to directly check the code.
## Parsing
- Application data is parsed to domain object [`Application.ts`](./../src/domain/Application.ts)
- Steps
1. (Compile time) Load application data from [collection yaml files](./../src/application/collections/) using webpack loader
2. (Runtime) Parse and compile application and make it available to presentation layer by [`ApplicationFactory.ts`](./../src/application/ApplicationFactory.ts)
### Compiling
- Parsing the application files includes compiling scripts using [collection file defined functions](./collection-files.md#function)
- To extend the syntax:
1. Add a new parser under [SyntaxParsers](./../src/application/Parser/Script/Compiler/Expressions/SyntaxParsers) where you can look at other parsers to understand more.
2. Register your in [CompositeExpressionParser](./../src/application/Parser/Script/Compiler/Expressions/Parser/CompositeExpressionParser.ts)

173
docs/collection-files.md Normal file
View File

@@ -0,0 +1,173 @@
# Collection files
- privacy.sexy is a data-driven application where it reads the necessary OS-specific logic from yaml files in [`application/collections`](./../src/application/collections/)
- 💡 Best practices
- If you repeat yourself, try to utilize [YAML-defined functions](#Function)
- Always try to add documentation and a way to revert a tweak in [scripts](#Script)
- 📖 Types in code: [`collection.yaml.d.ts`](./../src/application/collections/collection.yaml.d.ts)
## Objects
### `Collection`
- A collection simply defines:
- different categories and their scripts in a tree structure
- OS specific details
- Also allows defining common [function](#Function)s to be used throughout the collection if you'd like different scripts to share same code.
#### `Collection` syntax
- `os:` *`string`* (**required**)
- Operating system that the [Collection](#collection) is written for.
- 📖 See [OperatingSystem.ts](./../src/domain/OperatingSystem.ts) enumeration for allowed values.
- `actions: [` ***[`Category`](#Category)*** `, ... ]` **(required)**
- Each [category](#category) is rendered as different cards in card presentation.
- ❗ A [Collection](#collection) must consist of at least one category.
- `functions: [` ***[`Function`](#Function)*** `, ... ]`
- Functions are optionally defined to re-use the same code throughout different scripts.
- `scripting:` ***[`ScriptingDefinition`](#ScriptingDefinition)*** **(required)**
- Defines the scripting language that the code of other action uses.
### `Category`
- Category has a parent that has tree-like structure where it can have subcategories or subscripts.
- It's a logical grouping of different scripts and other categories.
#### `Category` syntax
- `category:` *`string`* (**required**)
- Name of the category
- ❗ Must be unique throughout the [Collection](#collection)
- `children: [` ***[`Category`](#Category)*** `|` [***`Script`***](#Script) `, ... ]` (**required**)
- ❗ Category must consist of at least one subcategory or script.
- Children can be combination of scripts and subcategories.
### `Script`
- Script represents a single tweak.
- A script can be of two different types (just like [functions](#function)):
1. Inline script; a script with an inline code
- Must define `code` property and optionally `revertCode` but not `call`
2. Caller script; a script that calls other functions
- Must define `call` property but not `code` or `revertCode`
- 🙏 For any new script, please add `revertCode` and `docs` values if possible.
#### `Script` syntax
- `name`: *`string`* (**required**)
- Name of the script
- ❗ Must be unique throughout the [Collection](#collection)
- E.g. `Disable targeted ads`
- `code`: *`string`* (may be **required**)
- Batch file commands that will be executed
- 💡 If defined, best practice to also define `revertCode`
- ❗ If not defined `call` must be defined, do not define if `call` is defined.
- `revertCode`: `string`
- Code that'll undo the change done by `code` property.
- E.g. let's say `code` sets an environment variable as `setx POWERSHELL_TELEMETRY_OPTOUT 1`
- then `revertCode` should be doing `setx POWERSHELL_TELEMETRY_OPTOUT 0`
- ❗ Do not define if `call` is defined.
- `call`: ***[`FunctionCall`](#FunctionCall)*** | `[` ***[`FunctionCall`](#FunctionCall)*** `, ... ]` (may be **required**)
- A shared function or sequence of functions to call (called in order)
- ❗ If not defined `code` must be defined
- `docs`: *`string`* | `[`*`string`*`, ... ]`
- Single documentation URL or list of URLs for those who wants to learn more about the script
- E.g. `https://docs.microsoft.com/en-us/windows-server/`
- `recommend`: `"standard"` | `"strict"` | `undefined` (default)
- If not defined then the script will not be recommended
- If defined it can be either
- `standard`: Only non-breaking scripts without limiting OS functionality
- `strict`: Scripts that can break certain functionality in favor of privacy and security
### `FunctionCall`
- Describes a single call to a function by optionally providing values to its parameters.
- 👀 See [parameter substitution](./templating.md#parameter-substitution) for an example usage
#### `FunctionCall` syntax
- `function`: *`string`* (**required**)
- Name of the function to call.
- ❗ Function with same name must defined in `functions` property of [Collection](#collection)
- `parameters`: `[ parameterName:` *`parameterValue`*`, ... ]`
- Defines key value dictionary for each parameter and its value
- E.g.
```yaml
parameters:
userDefinedParameterName: parameterValue
# ...
appName: Microsoft.WindowsFeedbackHub
```
- 💡 [Expressions (templating)](./templating.md#expressions) can be used as parameter value
### `Function`
- Functions allow re-usable code throughout the defined scripts.
- Functions are templates compiled by privacy.sexy and uses special expression expressions.
- A function can be of two different types (just like [scripts](#script)):
1. Inline function: a function with an inline code.
- Must define `code` property and optionally `revertCode` but not `call`.
2. Caller function: a function that calls other functions.
- Must define `call` property but not `code` or `revertCode`.
- 👀 Read more on [Templating](./templating.md) for function expressions and [example usages](./templating.md#parameter-substitution).
#### `Function` syntax
- `name`: *`string`* (**required**)
- Name of the function that scripts will use.
- Convention is to use camelCase, and be verbs.
- E.g. `uninstallStoreApp`
- ❗ Function names must be unique
- `parameters`: `[` ***[`FunctionParameter`](#FunctionParameter)*** `, ... ]`
- List of parameters that function code refers to.
- ❗ Must be defined to be able use in [`FunctionCall`](#functioncall) or [expressions (templating)](./templating.md#expressions)
`code`: *`string`* (**required** if `call` is undefined)
- Batch file commands that will be executed
- 💡 [Expressions (templating)](./templating.md#expressions) can be used in its value
- 💡 If defined, best practice to also define `revertCode`
- ❗ If not defined `call` must be defined
- `revertCode`: *`string`*
- Code that'll undo the change done by `code` property.
- E.g. let's say `code` sets an environment variable as `setx POWERSHELL_TELEMETRY_OPTOUT 1`
- then `revertCode` should be doing `setx POWERSHELL_TELEMETRY_OPTOUT 0`
- 💡 [Expressions (templating)](./templating.md#expressions) can be used in code
- `call`: ***[`FunctionCall`](#FunctionCall)*** | `[` ***[`FunctionCall`](#FunctionCall)*** `, ... ]` (may be **required**)
- A shared function or sequence of functions to call (called in order)
- The parameter values that are sent can use [expressions (templating)](./templating.md#expressions)
- ❗ If not defined `code` must be defined
### `FunctionParameter`
- Defines a parameter that function requires optionally or mandatory.
- Its arguments are provided by a [Script](#script) through a [FunctionCall](#FunctionCall).
#### `FunctionParameter` syntax
- `name`: *`string`* (**required**)
- Name of the parameters that the function has.
- Parameter names must be defined to be used in [expressions (templating)](./templating.md#expressions).
- ❗ Parameter names must be unique and include alphanumeric characters only.
- `optional`: *`boolean`* (default: `false`)
- Specifies whether the caller [Script](#script) must provide any value for the parameter.
- If set to `false` i.e. an argument value is not optional then it expects a non-empty value for the variable;
- Otherwise it throws.
- 💡 Set it to `true` if a parameter is used conditionally;
- Or else set it to `false` for verbosity or do not define it as default value is `false` anyway.
- 💡 Can be used in conjunction with [`with` expression](./templating.md#with).
### `ScriptingDefinition`
- Defines global properties for scripting that's used throughout its parent [Collection](#collection).
#### `ScriptingDefinition` syntax
- `language:` *`string`* (**required**)
- 📖 See [ScriptingLanguage.ts](./../src/domain/ScriptingLanguage.ts) enumeration for allowed values.
- `startCode:` *`string`* (**required**)
- Code that'll be inserted on top of user created script.
- Global variables such as `$homepage`, `$version`, `$date` can be used using [parameter substitution](./templating.md#parameter-substitution) code syntax such as `Welcome to {{ $homepage }}!`
- `endCode:` *`string`* (**required**)
- Code that'll be inserted at the end of user created script.
- Global variables such as `$homepage`, `$version`, `$date` can be used using [parameter substitution](./templating.md#parameter-substitution) code syntax such as `Welcome to {{ $homepage }}!`

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 KiB

72
docs/presentation.md Normal file
View File

@@ -0,0 +1,72 @@
# Presentation layer
- Consists of Vue.js components and other UI-related code.
- Desktop application is created using [Electron](https://www.electronjs.org/).
- Event driven as in components simply listens to events from the state and act accordingly.
## Structure
- [`/src/` **`presentation/`**](./../src/presentation/): Contains all presentation related code including Vue and Electron configurations
- [**`bootstrapping/`**](./../src/presentation/bootstrapping/): Registers Vue global objects including components and plugins.
- [**`components/`**](./../src/presentation/components/): Contains all Vue components and their helper classes.
- [**`Shared/`**](./../src/presentation/components/Shared): Contains Vue components and component helpers that are shared across other components.
- [**`assets/`**](./../src/presentation/assets/styles/): Contains assets that will be processed by webpack.
- [**`fonts/`**](./../src/presentation/assets/fonts/): Contains fonts
- [**`styles/`**](./../src/presentation/assets/styles/): Contains shared styles used throughout different components.
- [**`components/`**](./../src/presentation/assets/styles/components): Contains styles that are reusable and tightly coupled a Vue/HTML component.
- [**`vendors-extensions/`**](./../src/presentation/assets/styles/third-party-extensions): Contains styles that override third-party components used.
- [**`main.scss`**](./../src/presentation/assets/styles/main.scss): Primary Sass file, passes along all other styles, should be the only file used from other components.
- [**`main.ts`**](./../src/presentation/main.ts): Application entry point that mounts and starts Vue application.
- [**`electron/`**](./../src/presentation/electron/): Electron configuration for the desktop application.
- [**`main.ts`**](./../src/presentation/main.ts): Main process of Electron, started as first thing when app starts.
- [**`/public/`**](./../public/): Contains static assets that will directly be copied and not go through webpack.
- [**`/vue.config.js`**](./../vue.config.js): Global Vue CLI configurations loaded by `@vue/cli-service`
- [**`/postcss.config.js`**](./../postcss.config.js): PostCSS configurations that are used by Vue CLI internally
- [**`/babel.config.js`**](./../babel.config.js): Babel configurations for polyfills used by `@vue/cli-plugin-babel`
## Application data
- Components and should use [ApplicationFactory](./../src/application/ApplicationFactory.ts) singleton to reach the application domain.
- [Application.ts](../src/domain/Application.ts) domain model is the stateless application representation including
- available scripts, collections as defined in [collection files](./collection-files.md)
- package information as defined in [`package.json`](./../package.json)
- 📖 See [Application data | Application layer](./presentation.md#application-data) where application data is parsed and compiled.
## Application state
- Stateful components mutate or/and react to state changes in [ApplicationContext](./../src/application/Context/ApplicationContext.ts).
- Stateless components that does not handle state extends `Vue`
- Stateful components that depends on the collection state such as user selection, search queries and more extends [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts)
- The single source of truth is a singleton of the state created and made available to presentation layer by [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts)
- `StatefulVue` includes abstract `handleCollectionState` that is fired once the component is loaded and also each time [collection](./collection-files.md) is changed.
- Do not forget to subscribe from events when component is destroyed or if needed [collection](./collection-files.md) is changed.
- 💡 `events` in base class [`StatefulVue`](./../src/presentation/components/Shared/StatefulVue.ts) makes lifecycling easier
- 📖 See [Application state | Application layer](./presentation.md#application-state) where the state is implemented using using state pattern.
## Modals
- [Dialog.vue](./../src/presentation/components/Shared/Dialog.vue) is a shared component that can be used to show modal windows
- Simply wrap the content inside of its slot and call `.show()` method on its reference.
- Example:
```html
<Dialog ref="testDialog">
<div>Hello world</div>
</Dialog>
<div @click="$refs.testDialog.show()">Show dialog</div>
```
## Sass naming convention
- Use lowercase for variables/functions/mixins e.g.
- Variable: `$variable: value;`
- Function: `@function function() {}`
- Mixin: `@mixin mixin() {}`
- Use - for a phrase/compound word e.g.
- Variable: `$some-variable: value;`
- Function: `@function some-function() {}`
- Mixin: `@mixin some-mixin() {}`
- Grouping and name variables from generic to specific e.g.
- ✅ `$border-blue`, `$border-blue-light`, `$border-blue-lightest`, `$border-red`
- ❌ `$blue-border`, `$light-blue-border`, `$lightest-blue-border`, `$red-border`

88
docs/templating.md Normal file
View File

@@ -0,0 +1,88 @@
# Templating
## Benefits of templating
- Generating scripts by sharing code to increase best-practice usage and maintainability.
- Creating self-contained scripts without depending on each other that can be easily shared.
- Use of pipes for writing cleaner code and letting pipes do dirty work.
## Expressions
- Expressions in the language are defined inside mustaches (double brackets, `{{` and `}}`).
- Expression syntax is inspired mainly by [Go Templates](https://pkg.go.dev/text/template).
- Expressions are used in and enabled by functions where they can be used.
- In script definition parts of a function, see [`Function`](./collection-files.md#Function).
- When doing a call as argument values, see [`FunctionCall`](./collection-files.md#Function).
### Parameter substitution
A simple function example:
```yaml
function: EchoArgument
parameters:
- name: 'argument'
code: Hello {{ $argument }} !
```
It would print "Hello world" if it's called in a [script](./collection-files.md#script) as following:
```yaml
script: Echo script
call:
function: EchoArgument
parameters:
argument: World
```
A function can call other functions such as:
```yaml
-
function: CallerFunction
parameters:
- name: 'value'
call:
function: EchoArgument
parameters:
argument: {{ $value }}
-
function: EchoArgument
parameters:
- name: 'argument'
code: Hello {{ $argument }} !
```
### with
- Skips the block if the variable is absent or empty.
- Binds its context (`.`) value of provided argument for the parameter if provided one.
- A block is defined as `{{ with $parameterName }} Parameter value is {{ . }} here {{ end }}`.
- The parameters used for `with` condition should be declared as optional, otherwise `with` block becomes redundant.
- Example:
```yaml
function: FunctionThatOutputsConditionally
parameters:
- name: 'argument'
optional: true
code: |-
{{ with $argument }}
Value is: {{ . }}
{{ end }}
```
### Pipes
- Pipes are set of functions available for handling text in privacy.sexy.
- Allows stacking actions one after another also known as "chaining".
- Just like [Unix pipelines](https://en.wikipedia.org/wiki/Pipeline_(Unix)), the concept is simple: each pipeline's output becomes the input of the following pipe.
- Pipes are provided and defined by the compiler and consumed by collection files.
- Pipes can be combined with [parameter substitution](#parameter-substitution) and [with](#with).
- ❗ Pipe names must be camelCase without any space or special characters.
- **Existing pipes**
- `inlinePowerShell`: Converts a multi-lined PowerShell script to a single line.
- `escapeDoubleQuotes`: Escapes `"` characters to be used inside double quotes (`"`)
- **Example usages**
- `{{ with $code }} echo "{{ . | inlinePowerShell }}" {{ end }}`
- `{{ with $code }} echo "{{ . | inlinePowerShell | escapeDoubleQuotes }}" {{ end }}`

43
docs/tests.md Normal file
View File

@@ -0,0 +1,43 @@
# Tests
- There are two different types of tests executed:
1. [Unit tests](#unit-tests)
2. [Integration tests](#integration-tests)
- 💡 You can use path/module alias `@/tests` in import statements.
## Unit tests
- Tests each component in isolation
- Defined in [`./tests/unit`](./../tests/unit)
- They follow same folder structure as [`./src`](./../src)
### Naming
- Each test suite first describe the system under test
- E.g. tests for class `Application` is categorized under `Application`
- Tests for specific methods are categorized under method name (if applicable)
- E.g. test for `run()` is categorized under `run`
### Act, arrange, assert
- Tests use act, arrange and assert (AAA) pattern when applicable
- **Arrange**
- Should set up the test case
- Starts with comment line `// arrange`
- **Act**
- Should cover the main thing to be tested
- Starts with comment line `// act`
- **Assert**
- Should elicit some sort of response
- Starts with comment line `// assert`
### Stubs
- Stubs are defined in [`./tests/stubs`](./../tests/unit/stubs)
- They implement dummy behavior to be functional
## Integration tests
- Tests functionality of a component in combination with others (not isolated)
- Ensure dependencies to third parties work as expected
- Defined in [`./tests/integration`](./../tests/integration)

View File

@@ -0,0 +1 @@
<mxfile host="Electron" modified="2021-01-31T12:32:01.751Z" agent="5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.1.8 Chrome/87.0.4280.88 Electron/11.1.1 Safari/537.36" etag="OTbSPW1ZOLwiPL6mt-j9" version="14.1.8" type="device"><diagram id="rhL8jzEM8kVVyiS98U7u" name="Page-1">3VtZd6JKF/01/dhZjA6PREjCXRbGFpM2L70QCYIoLsUI/PpvnwKcMD3cazrJl6wEqfHU3vvsKoz5Infm6e3KWU5ZPPGiL5IwSb/I+hdJUsUmflNBVhQoDaEo8FfBpCgS9wWDIPfKwqrZJph466OGSRxHSbA8LnTjxcJzk6MyZ7WKt8fNnuPoeNal43u1goHrRPXSx2CSTIvSlirsy++8wJ9WM4tCWTN3qsZlwXrqTOLtQZFsfJE7qzhOilfztONFhF2FS9Hv5pXaXWArb5H8Tofr+9ZNO9J+6A+Ljvr89N2aP5tflSq4JKtW7E0AQHkbr5Jp7McLJzL2pdereLOYeDSsgLt9m24cL1EoojD0kiQr2XQ2SYyiaTKPylovDZLv1P1KLe9GBzV6Wo7Mb7LqZpGssoNOdDs6rNt343dVv3WyimdeJ47iFV+f3OZfqKkDWGK6jjcr1/sJapUQnZXvJT9pJxXtCNGDCUp6br147iFSNFh5kZMEL8eSc0rl+rt2e3LxouT3T7iW3oXrHW9HrO1J/IC8yZfmjXfVVisnO2iwjINFsj4Y+Z4K0KD0TrnMzdI51ZP0/nlrSVRPBFNMv5fPbh3/QVHyu7rHgXcIV5L6m/bxeWSofCj7KMd9caJNOdP9yltj8Zg7XtSEcEzzdhok3mDpcFy2OCkcU/ocRNEBxhPVa02Uc+i3pLHcaFCPeJFUOjuzFVbBeqvES38KXlnbaB6nT5lN2/2eL1c7+/Rgv69OMxdHW268Z2qJR6n1m5klHmeW9B6pJb1Xav07h28fm7YoH5n2L9tLzebbm7zc+ixHxPcU1MWPDP/JPaSaV2vLZRS4l7DqI+OtWfezSt/nyGjwr3KEg/Li62ck/b6Lq8cuvnsYO7Rx6YyNN9/MxtXPkjwf6flK/pQHJLmWdHo8d4LLHo3G4mTyfBZ3UWjKbe8Njkbtk6Rq15NKUs4klfpWSaXUgDYXzysHiGzcZLPyLgr4c8v1XPcc4OOWqqjCGwDePDmLNs4A3vqbLtaoAe69eOXJ5hWgxT8H+tlrnAd60myPBeEyO0TrBNtmHdvmGWilt4K2WYN25S3jdZDE5eCfGl75zAb8V+Ft1a3CWCRB8hmxPfWFdwe3XQM3ma48ZxIs/P8DeN/dGsT6KX5Of165rO2OBU/2GufAFbyW0GpdBlwcTo7BFZQ6uOqVeAZe6a3grZ/X8DKY/OoZ6aNCLKniVfvDgazWQF4nTvKzI9qf42vo9H0ZFE9MQKze/XhHCP/K6euSGJ6+mXoORPHcu6lvh2H9mOUcviEiRLEfuJ8HULG+Nf1dQHdr2AOazamXG0eR5xKqH1efHw/N+lZUA289dZb0MpjzTywcQkUrh5QjLQr8BcoSeptoV9p1xl50T48UJHVZH8dJEs/RIKKKa8ed+ZyYowMXfaEJn0xbL4tPVtBBy6lunoOUqLwu49GnSUIfydAICenGnSyUq8CNF88BKF9duZhRusHe6uBC5VDHDZIuXn91FpOv4xV+U5FKh54budH88bDxwvUPaoKDUOtqWZ0pL/pk3aa/UpxyryhXap38fenl6a9vkp+ffvmP6f/qTOKxtxOB1Gr9GDjr9QXpl9TWVVP9PQlI5zUgvZkI6tv85xeB+EsRjBdb/AbFKX7wCtsyFdNbausLsS7LyhHlcuOqVT+QSO0zht9+K7Lr55HPT7bwS7Kf45XvLb6uvZg+TXDTAC83y4C/Z7v+Gi+TYB7k/ER2wZzfvUtSsS/XqK/0cUh9VfZfqH/Y3Hrj5vegr7fv2awhLwLh8cyf5n7J/CWIPS+Z8+Qe8V/RzamUteJWulm/gJzrlM58nfs7S3rKrpXxY7pxcyFw7r4Jrh6/dOWJPMlUmWXqizt3X1iobVmnnU/mbmDeTZZPd9/i+4GZWfYoMG+nkfM4iSe6ELBwKJnBteQ8Psj9eVtBm62paz4v103RCkzMfX/r+k/zaD1Gj/G8vXkamMV9R8wmj2l0P/gnmswfNmPp28wMldZIirKRlEbm7dNyfLttmwHL+uE/N0wwMLtFs6Qs9Om1unt9Z7bN0Mh6HfPlPkwXB33Vb7OH62/hLCjLEnfxsH6yi1i8+UM2zniUd9fTya3vPyFK2zawfkVkuulbubGxwijs2qbUBS7WQBC6oZtbgSBYgSJaobthoZl27SGVSyzQUqujCMweJqhPcfWZrW0se5Z17f6G5SMZ2KDtKLcGGq6mYOpMxb1gzY0MV8nKtOoKPA2fdajdKMOcVC4yiSVWpsiWbSbMZhjbxNgzxDFCHKZIYzEepylYmZAjnhx1PuJRmO6jD9aUz1LiqBsaQq8jpKjLMJZv6RjH9uWubaTd0M+tx3MxaRTTpmcPJawb8/Zlby4kWBvKZqqpu2jLtpbEUo4jxwBz2kOxWLshW4GWsUDJe3bfZ/kM8ZBmGOZkSq+j5bQ+FjJoiWL1wYO76el+jv4y4tiygaaijYR+GBu42po0sk1wxfEtr4hzoG27wIjpmkj4WzraZVgvjU9zow/TXQXrABY+8Qeeh4SJivi2TGcJHz830MYgvMCvoIBrzkcP2Fq8DeFPPDDU9WX0zxnVvcqpkHfDmQAN4DpUvYArdzv6/i02b/ttcyakPYo3NGl9W8xHvFPcWyg+QY5izQblGcadIXcFgc+n+xwP8CsWmhymLBBIu+grEB8CcEW8Ptqwck0zWgv0CDz1IepGGLt/Hs8O8BwoWyuc+Wifs9wKGdeARtio4C4j3Vvh0IfuVHALfg1gPEOsBtbaV0x9RPFluE8pZ4ABrn3oxkQe+FuKE30zWgt+gP1MfY1bU+8Tf9Ay8kDvS6RDi17nlAsjhWvtkdY7pHFIY4h1poInmluxOhrmdIUe8gXYiozj7UNrTCy4nAms0KqAssQKSQt96Jj0MiIfkICpwmwXGoWOwdPrsRJOrgz8ZCt/CLkubZYjZ0n3AmLJMJZq6W5i0Rj5CJgMEYNJmMiESY+0w/EeIUcpTkMs8sYAf8CNuAk06Arj5CbnGXy/ih/4Jx3JRR4b4hkdKtxrMi3t6S7laT7KMa+tCUUu+6RB4lXqwc8QP7h3eU739D7mIe0apPuUUUz6kDREeKo9e5T0qL3OuEYseFGXvIzy5/bVvCFNy/C3jPN2W3ohjYs1kkd0aT2hKUKLaW+gKD3ySfJpvQ//MEhjyG3kAvyD8XgE0qxI8XA/DYeUx7S2DJiCY7STXo0HOsB6uIZd1ZKXCTiBRkzu9z19BLwoj42kyEsT+qdYfLHUYIo4Ea+m0N6CeAXue1inRdjkM65dC+OAb8xtSow8PSM9ukmP+1c/ezVXqd4eCZQnaC+McoPvNSzTuIfhWuwPpF/eZkQ5grWT12jEPfj0aayUv87dpPBt4piwYrTPUR5R/iiv40T+oEHPtA/McuSpCK1k2DtoPInZ/4RYM+FAuSgSLvBZeBe45X7F84G4zfg+m1VtuYbLMu20n1/1IzzIO7G/kW/tvL+o2/Xf9ava0rqrGE777eYF5zx/4Iamfj0lbjAW4uvnZZ7Bi4wyV3gcx/WYAzGU9dcN2+7THqLynON7Vz8d5aSZ4UE8/dN4hAMcgAnXu0px4QwjHuC2679fB28LXWrJHhPe73DMPaaFXgn7Au+BdgbvPTZFjgAdySjXDB/RWbVu0jr5vQLfOq2vtFPUL+Kgmyst9/ZGcDrXM5wcLcxH5wHSqkjnLkv/Fv4Rd3WshDpW7BQr9V9j1flbWGEs7rczn2so9zOce6CxmVLstxo8XeBeWJwrNRWemvL9Jx8mHMP8aQo/ynCu86trNU9RT35J50BXIo/r2eRptNe78B/yf9pvyZ/orGls6ZxSxK3RtYxBK2OqYtCKmIr85vtOEdNTwwxadFLvtBf34fblCUroyniiyRV6hrrMnz8l+Uo9fuNJlurPoY0zz6GNP34Oxe3+v8qKTwHv/zVPNv4H</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because one or more lines are too long

BIN
img/architecture/gitops.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

BIN
img/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

38575
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +1,80 @@
{ {
"name": "privacy.sexy", "name": "privacy.sexy",
"version": "0.4.3", "version": "0.11.1",
"private": true, "private": true,
"description": "Enforce privacy & security best-practices on Windows and macOS, because privacy is sexy 🍑🍆",
"author": "undergroundwires",
"scripts": { "scripts": {
"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:serve": "vue-cli-service electron:serve",
"lint:md": "markdownlint **/*.md --ignore node_modules",
"lint:md:consistency": "remark . --frail --use remark-preset-lint-consistent",
"lint:md:relative-urls": "remark . --frail --use remark-validate-links",
"lint:vue": "vue-cli-service lint --no-fix", "lint:vue": "vue-cli-service lint --no-fix",
"lint:yaml": "yamllint **/*.yaml --ignore=node_modules/**/*.yaml", "lint:yaml": "yamllint **/*.yaml --ignore=node_modules/**/*.yaml",
"lint:md": "markdownlint **/*.md --ignore node_modules", "postinstall": "electron-builder install-app-deps",
"lint:md:relative-urls": "remark . --frail --use remark-validate-links", "postuninstall": "electron-builder install-app-deps"
"lint:md:consistency": "remark . --frail --use remark-preset-lint-consistent"
}, },
"main": "background.js",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.26", "@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-brands-svg-icons": "^5.12.0", "@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-regular-svg-icons": "^5.12.0", "@fortawesome/free-regular-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.12.0", "@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/vue-fontawesome": "^0.1.9", "@fortawesome/vue-fontawesome": "^2.0.6",
"ace-builds": "^1.4.7", "@juggle/resize-observer": "^3.3.1",
"file-saver": "^2.0.2", "ace-builds": "^1.4.13",
"inversify": "^5.0.1", "core-js": "^3.18.3",
"cross-fetch": "^3.1.4",
"electron-progressbar": "^2.0.1",
"file-saver": "^2.0.5",
"install": "^0.13.0",
"liquor-tree": "^0.2.70", "liquor-tree": "^0.2.70",
"v-tooltip": "^2.0.2", "npm": "^8.1.1",
"vue": "^2.6.11", "v-tooltip": "2.1.3",
"vue-class-component": "^7.1.0", "vue": "^2.6.14",
"vue-js-modal": "^2.0.0-rc.3", "vue-class-component": "^7.2.6",
"vue-property-decorator": "^8.3.0" "vue-js-modal": "^2.0.1",
"vue-property-decorator": "^9.1.2"
}, },
"devDependencies": { "devDependencies": {
"@types/ace": "0.0.42", "@types/ace": "0.0.47",
"@types/chai": "^4.2.7", "@types/chai": "^4.2.22",
"@types/file-saver": "^2.0.1", "@types/file-saver": "^2.0.3",
"@types/mocha": "^5.2.7", "@types/mocha": "^9.0.0",
"@vue/cli-plugin-typescript": "^4.4.0", "@vue/cli-plugin-babel": "^4.5.14",
"@vue/cli-plugin-unit-mocha": "^4.1.1", "@vue/cli-plugin-typescript": "^4.5.14",
"@vue/cli-service": "^4.1.1", "@vue/cli-plugin-unit-mocha": "^4.5.14",
"@vue/test-utils": "1.0.0-beta.30", "@vue/cli-service": "^4.5.14",
"chai": "^4.2.0", "@vue/test-utils": "1.2.2",
"chai": "^4.3.4",
"electron": "^15.3.0",
"electron-devtools-installer": "^3.2.0",
"electron-log": "^4.4.1",
"electron-updater": "^4.3.9",
"js-yaml-loader": "^1.2.2", "js-yaml-loader": "^1.2.2",
"markdownlint-cli": "^0.23.1", "markdownlint-cli": "^0.29.0",
"remark-cli": "^8.0.0", "raw-loader": "^4.0.2",
"remark-lint-no-dead-urls": "^1.0.2", "remark-cli": "^10.0.0",
"remark-preset-lint-consistent": "^3.0.0", "remark-lint-no-dead-urls": "^1.1.0",
"remark-validate-links": "^10.0.0", "remark-preset-lint-consistent": "^5.1.0",
"sass": "^1.24.0", "remark-validate-links": "^11.0.1",
"sass-loader": "^8.0.0", "sass": "^1.43.3",
"typescript": "^3.7.4", "sass-loader": "10.2.0",
"vue-template-compiler": "^2.6.11", "tslib": "^2.3.1",
"typescript": "^4.4.4",
"vue-cli-plugin-electron-builder": "^2.1.1",
"vue-template-compiler": "^2.6.14",
"yaml-lint": "^1.2.4" "yaml-lint": "^1.2.4"
},
"homepage": "https://privacy.sexy",
"repository": {
"type": "git",
"url": "https://github.com/undergroundwires/privacy.sexy.git"
} }
} }

BIN
public/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Privacy is sexy 🍑🍆 - Enforce privacy & security on Windows</title> <title>Privacy is sexy 🍑🍆 - Enforce privacy & security on Windows and macOS</title>
<meta name="robots" content="index,follow" /> <meta name="robots" content="index,follow" />
<meta name="description" content="Web tool to generate scripts for enforcing privacy & security best-practices such as stopping data collection of Windows and different softwares on it."/> <meta name="description" content="Web tool to generate scripts for enforcing privacy & security best-practices such as stopping data collection of Windows and different softwares on it."/>
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">

2
public/robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow:

View File

@@ -1,80 +0,0 @@
<template>
<div id="app">
<div class="wrapper">
<TheHeader class="row" />
<TheSearchBar class="row" />
<TheScripts class="row"/>
<TheCodeArea class="row" theme="xcode" />
<TheCodeButtons class="row code-buttons" />
<TheFooter />
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
import { ApplicationState, IApplicationState } from '@/application/State/ApplicationState';
import TheHeader from '@/presentation/TheHeader.vue';
import TheFooter from '@/presentation/TheFooter.vue';
import TheCodeArea from '@/presentation/TheCodeArea.vue';
import TheCodeButtons from '@/presentation/TheCodeButtons.vue';
import TheSearchBar from '@/presentation/TheSearchBar.vue';
import TheScripts from '@/presentation/Scripts/TheScripts.vue';
@Component({
components: {
TheHeader,
TheCodeArea,
TheCodeButtons,
TheScripts,
TheSearchBar,
TheFooter,
},
})
export default class App extends Vue {
}
</script>
<style lang="scss">
@import "@/presentation/styles/colors.scss";
@import "@/presentation/styles/fonts.scss";
* {
box-sizing: border-box;
}
body {
background: $light-gray;
font-family: $main-font;
color: $slate;
}
#app {
margin-right: auto;
margin-left: auto;
max-width: 1500px;
.wrapper {
margin: 0% 2% 0% 2%;
background-color: white;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.06);
padding: 2%;
display:flex;
flex-direction: column;
.row {
margin-bottom: 10px;
}
.code-buttons {
padding-bottom: 10px;
}
}
}
@import "@/presentation/styles/tooltip.scss";
@import "@/presentation/styles/tree.scss";
</style>

View File

@@ -0,0 +1,21 @@
import { IApplication } from '@/domain/IApplication';
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
import { IApplicationFactory } from './IApplicationFactory';
import { parseApplication } from './Parser/ApplicationParser';
export type ApplicationGetter = () => IApplication;
const ApplicationGetter: ApplicationGetter = parseApplication;
export class ApplicationFactory implements IApplicationFactory {
public static readonly Current: IApplicationFactory = new ApplicationFactory(ApplicationGetter);
private readonly getter: AsyncLazy<IApplication>;
protected constructor(costlyGetter: ApplicationGetter) {
if (!costlyGetter) {
throw new Error('undefined getter');
}
this.getter = new AsyncLazy<IApplication>(() => Promise.resolve(costlyGetter()));
}
public getApp(): Promise<IApplication> {
return this.getter.getValue();
}
}

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

@@ -0,0 +1,54 @@
// Because we cannot do "T extends enum" 😞 https://github.com/microsoft/TypeScript/issues/30611
export type EnumType = number | string;
export type EnumVariable<T extends EnumType, TEnumValue extends EnumType> = { [key in T]: TEnumValue };
export interface IEnumParser<TEnum> {
parseEnum(value: string, propertyName: string): TEnum;
}
export function createEnumParser<T extends EnumType, TEnumValue extends EnumType>(
enumVariable: EnumVariable<T, TEnumValue>): IEnumParser<TEnumValue> {
return {
parseEnum: (value, propertyName) => parseEnumValue(value, propertyName, enumVariable),
};
}
function parseEnumValue<T extends EnumType, TEnumValue extends EnumType>(
value: string,
enumName: string,
enumVariable: EnumVariable<T, TEnumValue>): TEnumValue {
if (!value) {
throw new Error(`undefined ${enumName}`);
}
if (typeof value !== 'string') {
throw new Error(`unexpected type of ${enumName}: "${typeof value}"`);
}
const casedValue = getEnumNames(enumVariable)
.find((enumValue) => enumValue.toLowerCase() === value.toLowerCase());
if (!casedValue) {
throw new Error(`unknown ${enumName}: "${value}"`);
}
return enumVariable[casedValue as keyof typeof enumVariable];
}
export function getEnumNames<T extends EnumType, TEnumValue extends EnumType>(
enumVariable: EnumVariable<T, TEnumValue>): string[] {
return Object
.values(enumVariable)
.filter((enumMember) => typeof enumMember === 'string') as string[];
}
export function getEnumValues<T extends EnumType, TEnumValue extends EnumType>(
enumVariable: EnumVariable<T, TEnumValue>): TEnumValue[] {
return getEnumNames(enumVariable)
.map((level) => enumVariable[level]) as TEnumValue[];
}
export function assertInRange<T extends EnumType, TEnumValue extends EnumType>(
value: TEnumValue,
enumVariable: EnumVariable<T, TEnumValue>) {
if (value === undefined) {
throw new Error('undefined enum value');
}
if (!(value in enumVariable)) {
throw new RangeError(`enum value "${value}" is out of range`);
}
}

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

@@ -0,0 +1,60 @@
import { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
import { ICategoryCollectionState } from './State/ICategoryCollectionState';
import { CategoryCollectionState } from './State/CategoryCollectionState';
import { IApplication } from '@/domain/IApplication';
import { OperatingSystem } from '@/domain/OperatingSystem';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { assertInRange } from '@/application/Common/Enum';
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
export class ApplicationContext implements IApplicationContext {
public readonly contextChanged = new EventSource<IApplicationContextChangedEvent>();
public collection: ICategoryCollection;
public currentOs: OperatingSystem;
public get state(): ICategoryCollectionState {
return this.states[this.collection.os];
}
private readonly states: StateMachine;
public constructor(
public readonly app: IApplication,
initialContext: OperatingSystem) {
validateApp(app);
assertInRange(initialContext, OperatingSystem);
this.states = initializeStates(app);
this.changeContext(initialContext);
}
public changeContext(os: OperatingSystem): void {
if (this.currentOs === os) {
return;
}
this.collection = this.app.getCollection(os);
if (!this.collection) {
throw new Error(`os "${OperatingSystem[os]}" is not defined in application`);
}
const event: IApplicationContextChangedEvent = {
newState: this.states[os],
oldState: this.states[this.currentOs],
};
this.contextChanged.notify(event);
this.currentOs = os;
}
}
function validateApp(app: IApplication) {
if (!app) {
throw new Error('undefined app');
}
}
function initializeStates(app: IApplication): StateMachine {
const machine = new Map<OperatingSystem, ICategoryCollectionState>();
for (const collection of app.collections) {
machine[collection.os] = new CategoryCollectionState(collection);
}
return machine;
}

View File

@@ -0,0 +1,31 @@
import { ApplicationContext } from './ApplicationContext';
import { IApplicationContext } from '@/application/Context/IApplicationContext';
import { OperatingSystem } from '@/domain/OperatingSystem';
import { Environment } from '../Environment/Environment';
import { IApplication } from '@/domain/IApplication';
import { IEnvironment } from '../Environment/IEnvironment';
import { IApplicationFactory } from '../IApplicationFactory';
import { ApplicationFactory } from '../ApplicationFactory';
export async function buildContext(
factory: IApplicationFactory = ApplicationFactory.Current,
environment = Environment.CurrentEnvironment): Promise<IApplicationContext> {
if (!factory) { throw new Error('undefined factory'); }
if (!environment) { throw new Error('undefined environment'); }
const app = await factory.getApp();
const os = getInitialOs(app, environment);
return new ApplicationContext(app, os);
}
function getInitialOs(app: IApplication, environment: IEnvironment): OperatingSystem {
const currentOs = environment.os;
const supportedOsList = app.getSupportedOsList();
if (supportedOsList.includes(currentOs)) {
return currentOs;
}
supportedOsList.sort((os1, os2) => {
const getPriority = (os: OperatingSystem) => app.getCollection(os).totalScripts;
return getPriority(os2) - getPriority(os1);
});
return supportedOsList[0];
}

View File

@@ -0,0 +1,16 @@
import { ICategoryCollectionState } from './State/ICategoryCollectionState';
import { OperatingSystem } from '@/domain/OperatingSystem';
import { IEventSource } from '@/infrastructure/Events/IEventSource';
import { IApplication } from '@/domain/IApplication';
export interface IApplicationContext {
readonly app: IApplication;
readonly state: ICategoryCollectionState;
readonly contextChanged: IEventSource<IApplicationContextChangedEvent>;
changeContext(os: OperatingSystem): void;
}
export interface IApplicationContextChangedEvent {
readonly newState: ICategoryCollectionState;
readonly oldState: ICategoryCollectionState;
}

View File

@@ -0,0 +1,23 @@
import { UserFilter } from './Filter/UserFilter';
import { IUserFilter } from './Filter/IUserFilter';
import { ApplicationCode } from './Code/ApplicationCode';
import { UserSelection } from './Selection/UserSelection';
import { IUserSelection } from './Selection/IUserSelection';
import { ICategoryCollectionState } from './ICategoryCollectionState';
import { IApplicationCode } from './Code/IApplicationCode';
import { ICategoryCollection } from '../../../domain/ICategoryCollection';
import { OperatingSystem } from '@/domain/OperatingSystem';
export class CategoryCollectionState implements ICategoryCollectionState {
public readonly os: OperatingSystem;
public readonly code: IApplicationCode;
public readonly selection: IUserSelection;
public readonly filter: IUserFilter;
public constructor(readonly collection: ICategoryCollection) {
this.selection = new UserSelection(collection, []);
this.code = new ApplicationCode(this.selection, collection.scripting);
this.filter = new UserFilter(collection);
this.os = collection.os;
}
}

View File

@@ -0,0 +1,39 @@
import { CodeChangedEvent } from './Event/CodeChangedEvent';
import { CodePosition } from './Position/CodePosition';
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { IUserSelection } from '@/application/Context/State/Selection/IUserSelection';
import { UserScriptGenerator } from './Generation/UserScriptGenerator';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { IApplicationCode } from './IApplicationCode';
import { IUserScriptGenerator } from './Generation/IUserScriptGenerator';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
export class ApplicationCode implements IApplicationCode {
public readonly changed = new EventSource<ICodeChangedEvent>();
public current: string;
private scriptPositions = new Map<SelectedScript, CodePosition>();
constructor(
userSelection: IUserSelection,
private readonly scriptingDefinition: IScriptingDefinition,
private readonly generator: IUserScriptGenerator = new UserScriptGenerator()) {
if (!userSelection) { throw new Error('userSelection is null or undefined'); }
if (!scriptingDefinition) { throw new Error('scriptingDefinition is null or undefined'); }
if (!generator) { throw new Error('generator is null or undefined'); }
this.setCode(userSelection.selectedScripts);
userSelection.changed.on((scripts) => {
this.setCode(scripts);
});
}
private setCode(scripts: ReadonlyArray<SelectedScript>): void {
const oldScripts = Array.from(this.scriptPositions.keys());
const code = this.generator.buildCode(scripts, this.scriptingDefinition);
this.current = code.code;
this.scriptPositions = code.scriptPositions;
const event = new CodeChangedEvent(code.code, oldScripts, code.scriptPositions);
this.changed.notify(event);
}
}

View File

@@ -0,0 +1,64 @@
import { ICodeChangedEvent } from './ICodeChangedEvent';
import { SelectedScript } from '../../Selection/SelectedScript';
import { IScript } from '@/domain/IScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
export class CodeChangedEvent implements ICodeChangedEvent {
public readonly code: string;
public readonly addedScripts: ReadonlyArray<IScript>;
public readonly removedScripts: ReadonlyArray<IScript>;
public readonly changedScripts: ReadonlyArray<IScript>;
private readonly scripts: Map<IScript, ICodePosition>;
constructor(
code: string,
oldScripts: ReadonlyArray<SelectedScript>,
scripts: Map<SelectedScript, ICodePosition>) {
ensureAllPositionsExist(code, Array.from(scripts.values()));
this.code = code;
const newScripts = Array.from(scripts.keys());
this.addedScripts = selectIfNotExists(newScripts, oldScripts);
this.removedScripts = selectIfNotExists(oldScripts, newScripts);
this.changedScripts = getChangedScripts(oldScripts, newScripts);
this.scripts = new Map<IScript, ICodePosition>();
scripts.forEach((position, selection) => {
this.scripts.set(selection.script, position);
});
}
public isEmpty(): boolean {
return this.scripts.size === 0;
}
public getScriptPositionInCode(script: IScript): ICodePosition {
return this.scripts.get(script);
}
}
function ensureAllPositionsExist(script: string, positions: ReadonlyArray<ICodePosition>) {
const totalLines = script.split(/\r\n|\r|\n/).length;
for (const position of positions) {
if (position.endLine > totalLines) {
throw new Error(`script end line (${position.endLine}) is out of range.` +
`(total code lines: ${totalLines}`);
}
}
}
function getChangedScripts(
oldScripts: ReadonlyArray<SelectedScript>,
newScripts: ReadonlyArray<SelectedScript>): ReadonlyArray<IScript> {
return newScripts
.filter((newScript) => oldScripts.find((oldScript) => oldScript.id === newScript.id
&& oldScript.revert !== newScript.revert ))
.map((selection) => selection.script);
}
function selectIfNotExists(
selectableContainer: ReadonlyArray<SelectedScript>,
test: ReadonlyArray<SelectedScript>) {
return selectableContainer
.filter((script) => !test.find((oldScript) => oldScript.id === script.id))
.map((selection) => selection.script);
}

View File

@@ -0,0 +1,11 @@
import { IScript } from '@/domain/IScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
export interface ICodeChangedEvent {
readonly code: string;
addedScripts: ReadonlyArray<IScript>;
removedScripts: ReadonlyArray<IScript>;
changedScripts: ReadonlyArray<IScript>;
isEmpty(): boolean;
getScriptPositionInCode(script: IScript): ICodePosition;
}

View File

@@ -1,11 +1,25 @@
import { ICodeBuilder } from './ICodeBuilder';
const NewLine = '\n'; const NewLine = '\n';
const TotalFunctionSeparatorChars = 58; const TotalFunctionSeparatorChars = 58;
export class CodeBuilder { export abstract class CodeBuilder implements ICodeBuilder {
private readonly lines = new Array<string>(); private readonly lines = new Array<string>();
// Returns current line starting from 0 (no lines), or 1 (have single line)
public get currentLine(): number {
return this.lines.length;
}
public appendLine(code?: string): CodeBuilder { public appendLine(code?: string): CodeBuilder {
this.lines.push(code); if (!code) {
this.lines.push('');
return this;
}
const lines = code.match(/[^\r\n]+/g);
for (const line of lines) {
this.lines.push(line);
}
return this; return this;
} }
@@ -15,7 +29,7 @@ export class CodeBuilder {
} }
public appendCommentLine(commentLine?: string): CodeBuilder { public appendCommentLine(commentLine?: string): CodeBuilder {
this.lines.push(`:: ${commentLine}`); this.lines.push(`${this.getCommentDelimiter()} ${commentLine}`);
return this; return this;
} }
@@ -23,9 +37,8 @@ export class CodeBuilder {
if (!name) { throw new Error('name cannot be empty or null'); } if (!name) { throw new Error('name cannot be empty or null'); }
if (!code) { throw new Error('code cannot be empty or null'); } if (!code) { throw new Error('code cannot be empty or null'); }
return this return this
.appendLine()
.appendCommentLineWithHyphensAround(name) .appendCommentLineWithHyphensAround(name)
.appendLine(`echo --- ${name}`) .appendLine(this.writeStandardOut(`--- ${name}`))
.appendLine(code) .appendLine(code)
.appendTrailingHyphensCommentLine(); .appendTrailingHyphensCommentLine();
} }
@@ -42,10 +55,13 @@ export class CodeBuilder {
return this return this
.appendTrailingHyphensCommentLine() .appendTrailingHyphensCommentLine()
.appendCommentLine(firstHyphens + sectionName + secondHyphens) .appendCommentLine(firstHyphens + sectionName + secondHyphens)
.appendTrailingHyphensCommentLine(); .appendTrailingHyphensCommentLine(TotalFunctionSeparatorChars);
} }
public toString(): string { public toString(): string {
return this.lines.join(NewLine); return this.lines.join(NewLine);
} }
protected abstract getCommentDelimiter(): string;
protected abstract writeStandardOut(text: string): string;
} }

View File

@@ -0,0 +1,14 @@
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ICodeBuilder } from './ICodeBuilder';
import { BatchBuilder } from './Languages/BatchBuilder';
import { ShellBuilder } from './Languages/ShellBuilder';
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
export class CodeBuilderFactory extends ScriptingLanguageFactory<ICodeBuilder> implements ICodeBuilderFactory {
constructor() {
super();
this.registerGetter(ScriptingLanguage.shellscript, () => new ShellBuilder());
this.registerGetter(ScriptingLanguage.batchfile, () => new BatchBuilder());
}
}

View File

@@ -0,0 +1,9 @@
export interface ICodeBuilder {
currentLine: number;
appendLine(code?: string): ICodeBuilder;
appendTrailingHyphensCommentLine(totalRepeatHyphens: number): ICodeBuilder;
appendCommentLine(commentLine?: string): ICodeBuilder;
appendCommentLineWithHyphensAround(sectionName: string, totalRepeatHyphens: number): ICodeBuilder;
appendFunction(name: string, code: string): ICodeBuilder;
toString(): string;
}

View File

@@ -0,0 +1,5 @@
import { ICodeBuilder } from './ICodeBuilder';
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
export interface ICodeBuilderFactory extends IScriptingLanguageFactory<ICodeBuilder> {
}

View File

@@ -0,0 +1,7 @@
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
export interface IUserScript {
code: string;
scriptPositions: Map<SelectedScript, ICodePosition>;
}

View File

@@ -0,0 +1,9 @@
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { IUserScript } from './IUserScript';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
export interface IUserScriptGenerator {
buildCode(
selectedScripts: ReadonlyArray<SelectedScript>,
scriptingDefinition: IScriptingDefinition): IUserScript;
}

View File

@@ -0,0 +1,16 @@
import { CodeBuilder } from '@/application/Context/State/Code/Generation/CodeBuilder';
export class BatchBuilder extends CodeBuilder {
protected getCommentDelimiter(): string {
return '::';
}
protected writeStandardOut(text: string): string {
return `echo ${escapeForEcho(text)}`;
}
}
function escapeForEcho(text: string) {
return text
.replace(/&/g, '^&')
.replace(/%/g, '%%');
}

View File

@@ -0,0 +1,15 @@
import { CodeBuilder } from '@/application/Context/State/Code/Generation/CodeBuilder';
export class ShellBuilder extends CodeBuilder {
protected getCommentDelimiter(): string {
return '#';
}
protected writeStandardOut(text: string): string {
return `echo '${escapeForEcho(text)}'`;
}
}
function escapeForEcho(text: string) {
return text
.replace(/'/g, '\'\\\'\'');
}

View File

@@ -0,0 +1,71 @@
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { IUserScriptGenerator } from './IUserScriptGenerator';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { CodePosition } from '../Position/CodePosition';
import { IUserScript } from './IUserScript';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { ICodeBuilder } from './ICodeBuilder';
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
import { CodeBuilderFactory } from './CodeBuilderFactory';
export class UserScriptGenerator implements IUserScriptGenerator {
constructor(private readonly codeBuilderFactory: ICodeBuilderFactory = new CodeBuilderFactory()) {
}
public buildCode(
selectedScripts: ReadonlyArray<SelectedScript>,
scriptingDefinition: IScriptingDefinition): IUserScript {
if (!selectedScripts) { throw new Error('undefined scripts'); }
if (!scriptingDefinition) { throw new Error('undefined definition'); }
let scriptPositions = new Map<SelectedScript, ICodePosition>();
if (!selectedScripts.length) {
return { code: '', scriptPositions };
}
let builder = this.codeBuilderFactory.create(scriptingDefinition.language);
builder = initializeCode(scriptingDefinition.startCode, builder);
for (const selection of selectedScripts) {
scriptPositions = appendSelection(selection, scriptPositions, builder);
}
const code = finalizeCode(builder, scriptingDefinition.endCode);
return { code, scriptPositions };
}
}
function initializeCode(startCode: string, builder: ICodeBuilder): ICodeBuilder {
if (!startCode) {
return builder;
}
return builder
.appendLine(startCode)
.appendLine();
}
function finalizeCode(builder: ICodeBuilder, endCode: string): string {
if (!endCode) {
return builder.toString();
}
return builder.appendLine()
.appendLine(endCode)
.toString();
}
function appendSelection(
selection: SelectedScript,
scriptPositions: Map<SelectedScript, ICodePosition>,
builder: ICodeBuilder): Map<SelectedScript, ICodePosition> {
const startPosition = builder.currentLine + 1; // Because first line will be empty to separate scripts
builder = appendCode(selection, builder);
const endPosition = builder.currentLine - 1;
builder.appendLine();
const position = new CodePosition(startPosition, endPosition);
scriptPositions.set(selection, position);
return scriptPositions;
}
function appendCode(selection: SelectedScript, builder: ICodeBuilder): ICodeBuilder {
const name = selection.revert ? `${selection.script.name} (revert)` : selection.script.name;
const scriptCode = selection.revert ? selection.script.code.revert : selection.script.code.execute;
return builder
.appendLine()
.appendFunction(name, scriptCode);
}

View File

@@ -0,0 +1,7 @@
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import { IEventSource } from '@/infrastructure/Events/IEventSource';
export interface IApplicationCode {
readonly changed: IEventSource<ICodeChangedEvent>;
readonly current: string;
}

View File

@@ -0,0 +1,24 @@
import { ICodePosition } from './ICodePosition';
export class CodePosition implements ICodePosition {
public get totalLines(): number {
return this.endLine - this.startLine;
}
constructor(
public readonly startLine: number,
public readonly endLine: number) {
if (startLine < 0) {
throw new Error('Code cannot start in a negative line');
}
if (endLine < 0) {
throw new Error('Code cannot end in a negative line');
}
if (endLine === startLine) {
throw new Error('Empty code');
}
if (endLine < startLine) {
throw new Error('End line cannot be less than start line');
}
}
}

View File

@@ -0,0 +1,5 @@
export interface ICodePosition {
readonly startLine: number;
readonly endLine: number;
readonly totalLines: number;
}

View File

@@ -1,5 +1,5 @@
import { IFilterResult } from './IFilterResult'; import { IFilterResult } from './IFilterResult';
import { IScript } from '@/domain/Script'; import { IScript } from '@/domain/IScript';
import { ICategory } from '@/domain/ICategory'; import { ICategory } from '@/domain/ICategory';
export class FilterResult implements IFilterResult { export class FilterResult implements IFilterResult {

View File

@@ -0,0 +1,10 @@
import { IEventSource } from '@/infrastructure/Events/IEventSource';
import { IFilterResult } from './IFilterResult';
export interface IUserFilter {
readonly currentFilter: IFilterResult | undefined;
readonly filtered: IEventSource<IFilterResult>;
readonly filterRemoved: IEventSource<void>;
setFilter(filter: string): void;
removeFilter(): void;
}

View File

@@ -0,0 +1,52 @@
import { IScript } from '@/domain/IScript';
import { FilterResult } from './FilterResult';
import { IFilterResult } from './IFilterResult';
import { IUserFilter } from './IUserFilter';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
export class UserFilter implements IUserFilter {
public readonly filtered = new EventSource<IFilterResult>();
public readonly filterRemoved = new EventSource<void>();
public currentFilter: IFilterResult | undefined;
constructor(private collection: ICategoryCollection) {
}
public setFilter(filter: string): void {
if (!filter) {
throw new Error('Filter must be defined and not empty. Use removeFilter() to remove the filter');
}
const filterLowercase = filter.toLocaleLowerCase();
const filteredScripts = this.collection.getAllScripts().filter(
(script) => isScriptAMatch(script, filterLowercase));
const filteredCategories = this.collection.getAllCategories().filter(
(category) => category.name.toLowerCase().includes(filterLowercase));
const matches = new FilterResult(
filteredScripts,
filteredCategories,
filter,
);
this.currentFilter = matches;
this.filtered.notify(matches);
}
public removeFilter(): void {
this.currentFilter = undefined;
this.filterRemoved.notify();
}
}
function isScriptAMatch(script: IScript, filterLowercase: string) {
if (script.name.toLowerCase().includes(filterLowercase)) {
return true;
}
if (script.code.execute.toLowerCase().includes(filterLowercase)) {
return true;
}
if (script.code.revert) {
return script.code.revert.toLowerCase().includes(filterLowercase);
}
return false;
}

View File

@@ -0,0 +1,13 @@
import { IUserFilter } from './Filter/IUserFilter';
import { IUserSelection } from './Selection/IUserSelection';
import { IApplicationCode } from './Code/IApplicationCode';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { OperatingSystem } from '@/domain/OperatingSystem';
export interface ICategoryCollectionState {
readonly code: IApplicationCode;
readonly filter: IUserFilter;
readonly selection: IUserSelection;
readonly collection: ICategoryCollection;
readonly os: OperatingSystem;
}

View File

@@ -0,0 +1,20 @@
import { SelectedScript } from './SelectedScript';
import { IScript } from '@/domain/IScript';
import { ICategory } from '@/domain/ICategory';
import { IEventSource } from '@/infrastructure/Events/IEventSource';
export interface IUserSelection {
readonly changed: IEventSource<ReadonlyArray<SelectedScript>>;
readonly selectedScripts: ReadonlyArray<SelectedScript>;
areAllSelected(category: ICategory): boolean;
isAnySelected(category: ICategory): boolean;
removeAllInCategory(categoryId: number): void;
addOrUpdateAllInCategory(categoryId: number, revert: boolean): void;
addSelectedScript(scriptId: string, revert: boolean): void;
addOrUpdateSelectedScript(scriptId: string, revert: boolean): void;
removeSelectedScript(scriptId: string): void;
selectOnly(scripts: ReadonlyArray<IScript>): void;
isSelected(scriptId: string): boolean;
selectAll(): void;
deselectAll(): void;
}

View File

@@ -0,0 +1,14 @@
import { BaseEntity } from '@/infrastructure/Entity/BaseEntity';
import { IScript } from '@/domain/IScript';
export class SelectedScript extends BaseEntity<string> {
constructor(
public readonly script: IScript,
public readonly revert: boolean,
) {
super(script.id);
if (revert && !script.canRevert()) {
throw new Error('cannot revert an irreversible script');
}
}
}

View File

@@ -0,0 +1,141 @@
import { SelectedScript } from './SelectedScript';
import { IUserSelection } from './IUserSelection';
import { InMemoryRepository } from '@/infrastructure/Repository/InMemoryRepository';
import { IScript } from '@/domain/IScript';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { IRepository } from '@/infrastructure/Repository/IRepository';
import { ICategory } from '@/domain/ICategory';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
export class UserSelection implements IUserSelection {
public readonly changed = new EventSource<ReadonlyArray<SelectedScript>>();
private readonly scripts: IRepository<string, SelectedScript>;
constructor(
private readonly collection: ICategoryCollection,
selectedScripts: ReadonlyArray<SelectedScript>) {
this.scripts = new InMemoryRepository<string, SelectedScript>();
if (selectedScripts && selectedScripts.length > 0) {
for (const script of selectedScripts) {
this.scripts.addItem(script);
}
}
}
public areAllSelected(category: ICategory): boolean {
if (this.selectedScripts.length === 0) {
return false;
}
const scripts = category.getAllScriptsRecursively();
if (this.selectedScripts.length < scripts.length) {
return false;
}
return scripts.every((script) => this.selectedScripts.some((selected) => selected.id === script.id));
}
public isAnySelected(category: ICategory): boolean {
if (this.selectedScripts.length === 0) {
return false;
}
return this.selectedScripts.some((s) => category.includes(s.script));
}
public removeAllInCategory(categoryId: number): void {
const category = this.collection.findCategory(categoryId);
const scriptsToRemove = category.getAllScriptsRecursively()
.filter((script) => this.scripts.exists(script.id));
if (!scriptsToRemove.length) {
return;
}
for (const script of scriptsToRemove) {
this.scripts.removeItem(script.id);
}
this.changed.notify(this.scripts.getItems());
}
public addOrUpdateAllInCategory(categoryId: number, revert: boolean = false): void {
const category = this.collection.findCategory(categoryId);
const scriptsToAddOrUpdate = category.getAllScriptsRecursively()
.filter((script) =>
!this.scripts.exists(script.id)
|| this.scripts.getById(script.id).revert !== revert,
);
if (!scriptsToAddOrUpdate.length) {
return;
}
for (const script of scriptsToAddOrUpdate) {
const selectedScript = new SelectedScript(script, revert);
this.scripts.addOrUpdateItem(selectedScript);
}
this.changed.notify(this.scripts.getItems());
}
public addSelectedScript(scriptId: string, revert: boolean): void {
const script = this.collection.findScript(scriptId);
if (!script) {
throw new Error(`Cannot add (id: ${scriptId}) as it is unknown`);
}
const selectedScript = new SelectedScript(script, revert);
this.scripts.addItem(selectedScript);
this.changed.notify(this.scripts.getItems());
}
public addOrUpdateSelectedScript(scriptId: string, revert: boolean): void {
const script = this.collection.findScript(scriptId);
const selectedScript = new SelectedScript(script, revert);
this.scripts.addOrUpdateItem(selectedScript);
this.changed.notify(this.scripts.getItems());
}
public removeSelectedScript(scriptId: string): void {
this.scripts.removeItem(scriptId);
this.changed.notify(this.scripts.getItems());
}
public isSelected(scriptId: string): boolean {
return this.scripts.exists(scriptId);
}
/** Get users scripts based on his/her selections */
public get selectedScripts(): ReadonlyArray<SelectedScript> {
return this.scripts.getItems();
}
public selectAll(): void {
for (const script of this.collection.getAllScripts()) {
if (!this.scripts.exists(script.id)) {
const selection = new SelectedScript(script, false);
this.scripts.addItem(selection);
}
}
this.changed.notify(this.scripts.getItems());
}
public deselectAll(): void {
const selectedScriptIds = this.scripts.getItems().map((script) => script.id);
for (const scriptId of selectedScriptIds) {
this.scripts.removeItem(scriptId);
}
this.changed.notify([]);
}
public selectOnly(scripts: readonly IScript[]): void {
if (!scripts || scripts.length === 0) {
throw new Error('Scripts are empty. Use deselectAll() if you want to deselect everything');
}
// Unselect from selected scripts
if (this.scripts.length !== 0) {
this.scripts.getItems()
.filter((existing) => !scripts.some((script) => existing.id === script.id))
.map((script) => script.id)
.forEach((scriptId) => this.scripts.removeItem(scriptId));
}
// Select from unselected scripts
const unselectedScripts = scripts.filter((script) => !this.scripts.exists(script.id));
for (const toSelect of unselectedScripts) {
const selection = new SelectedScript(toSelect, false);
this.scripts.addItem(selection);
}
this.changed.notify(this.scripts.getItems());
}
}

View File

@@ -0,0 +1,54 @@
import { OperatingSystem } from '@/domain/OperatingSystem';
import { DetectorBuilder } from './DetectorBuilder';
import { IBrowserOsDetector } from './IBrowserOsDetector';
export class BrowserOsDetector implements IBrowserOsDetector {
private readonly detectors = BrowserDetectors;
public detect(userAgent: string): OperatingSystem | undefined {
if (!userAgent) {
return undefined;
}
for (const detector of this.detectors) {
const os = detector.detect(userAgent);
if (os !== undefined) {
return os;
}
}
return undefined;
}
}
// Reference: https://github.com/keithws/browser-report/blob/master/index.js#L304
const BrowserDetectors =
[
define(OperatingSystem.KaiOS, (b) =>
b.mustInclude('KAIOS')),
define(OperatingSystem.ChromeOS, (b) =>
b.mustInclude('CrOS')),
define(OperatingSystem.BlackBerryOS, (b) =>
b.mustInclude('BlackBerry')),
define(OperatingSystem.BlackBerryTabletOS, (b) =>
b.mustInclude('RIM Tablet OS')),
define(OperatingSystem.BlackBerry, (b) =>
b.mustInclude('BB10')),
define(OperatingSystem.Android, (b) =>
b.mustInclude('Android').mustNotInclude('Windows Phone')),
define(OperatingSystem.Android, (b) =>
b.mustInclude('Adr').mustNotInclude('Windows Phone')),
define(OperatingSystem.iOS, (b) =>
b.mustInclude('like Mac OS X')),
define(OperatingSystem.Linux, (b) =>
b.mustInclude('Linux').mustNotInclude('Android').mustNotInclude('Adr')),
define(OperatingSystem.Windows, (b) =>
b.mustInclude('Windows').mustNotInclude('Windows Phone')),
define(OperatingSystem.WindowsPhone, (b) =>
b.mustInclude('Windows Phone')),
define(OperatingSystem.macOS, (b) =>
b.mustInclude('OS X').mustNotInclude('Android').mustNotInclude('like Mac OS X')),
];
function define(os: OperatingSystem, applyRules: (builder: DetectorBuilder) => DetectorBuilder): IBrowserOsDetector {
const builder = new DetectorBuilder(os);
applyRules(builder);
return builder.build();
}

View File

@@ -0,0 +1,53 @@
import { IBrowserOsDetector } from './IBrowserOsDetector';
import { OperatingSystem } from '@/domain/OperatingSystem';
export class DetectorBuilder {
private readonly existingPartsInUserAgent = new Array<string>();
private readonly notExistingPartsInUserAgent = new Array<string>();
constructor(private readonly os: OperatingSystem) { }
public mustInclude(str: string): DetectorBuilder {
return this.add(str, this.existingPartsInUserAgent);
}
public mustNotInclude(str: string): DetectorBuilder {
return this.add(str, this.notExistingPartsInUserAgent);
}
public build(): IBrowserOsDetector {
if (!this.existingPartsInUserAgent.length) {
throw new Error('Must include at least a part');
}
return {
detect: (agent) => this.detect(agent),
};
}
private detect(userAgent: string): OperatingSystem {
if (!userAgent) {
throw new Error('User agent is null or undefined');
}
if (this.existingPartsInUserAgent.some((part) => !userAgent.includes(part))) {
return undefined;
}
if (this.notExistingPartsInUserAgent.some((part) => userAgent.includes(part))) {
return undefined;
}
return this.os;
}
private add(part: string, array: string[]): DetectorBuilder {
if (!part) {
throw new Error('part is empty or undefined');
}
if (this.existingPartsInUserAgent.includes(part)) {
throw new Error(`part ${part} is already included as existing part`);
}
if (this.notExistingPartsInUserAgent.includes(part)) {
throw new Error(`part ${part} is already included as not existing part`);
}
array.push(part);
return this;
}
}

View File

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

View File

@@ -0,0 +1,80 @@
import { BrowserOsDetector } from './BrowserOs/BrowserOsDetector';
import { IBrowserOsDetector } from './BrowserOs/IBrowserOsDetector';
import { IEnvironment } from './IEnvironment';
import { OperatingSystem } from '@/domain/OperatingSystem';
interface IEnvironmentVariables {
readonly window: Window & typeof globalThis;
readonly process: NodeJS.Process;
readonly navigator: Navigator;
}
export class Environment implements IEnvironment {
public static readonly CurrentEnvironment: IEnvironment = new Environment({
window,
process,
navigator,
});
public readonly isDesktop: boolean;
public readonly os: OperatingSystem;
protected constructor(
variables: IEnvironmentVariables,
browserOsDetector: IBrowserOsDetector = new BrowserOsDetector()) {
if (!variables) {
throw new Error('variables is null or empty');
}
this.isDesktop = isDesktop(variables);
this.os = this.isDesktop ?
getDesktopOsType(getProcessPlatform(variables))
: browserOsDetector.detect(getUserAgent(variables));
}
}
function getUserAgent(variables: IEnvironmentVariables): string {
if (!variables.window || !variables.window.navigator) {
return undefined;
}
return variables.window.navigator.userAgent;
}
function getProcessPlatform(variables: IEnvironmentVariables): string {
if (!variables.process || !variables.process.platform) {
return undefined;
}
return variables.process.platform;
}
function getDesktopOsType(processPlatform: string): OperatingSystem | undefined {
// https://nodejs.org/api/process.html#process_process_platform
if (processPlatform === 'darwin') {
return OperatingSystem.macOS;
} else if (processPlatform === 'win32') {
return OperatingSystem.Windows;
} else if (processPlatform === 'linux') {
return OperatingSystem.Linux;
}
return undefined;
}
function isDesktop(variables: IEnvironmentVariables): boolean {
// More: https://github.com/electron/electron/issues/2288
// Renderer process
if (variables.window
&& variables.window.process
&& variables.window.process.type === 'renderer') {
return true;
}
// Main process
if (variables.process
&& variables.process.versions
&& Boolean(variables.process.versions.electron)) {
return true;
}
// Detect the user agent when the `nodeIntegration` option is set to true
if (variables.navigator
&& variables.navigator.userAgent
&& variables.navigator.userAgent.includes('Electron')) {
return true;
}
return false;
}

View File

@@ -0,0 +1,6 @@
import { OperatingSystem } from '@/domain/OperatingSystem';
export interface IEnvironment {
readonly isDesktop: boolean;
readonly os: OperatingSystem;
}

View File

@@ -0,0 +1,5 @@
import { IApplication } from '@/domain/IApplication';
export interface IApplicationFactory {
getApp(): Promise<IApplication>;
}

View File

@@ -1,21 +1,38 @@
import { Category } from '../../domain/Category'; import { IApplication } from '@/domain/IApplication';
import { Application } from '../../domain/Application'; import { IProjectInformation } from '@/domain/IProjectInformation';
import applicationFile from 'js-yaml-loader!./../application.yaml'; import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { parseCategory } from './CategoryParser'; import { parseCategoryCollection } from './CategoryCollectionParser';
import WindowsData from 'js-yaml-loader!@/application/collections/windows.yaml';
import MacOsData from 'js-yaml-loader!@/application/collections/macos.yaml';
import { CollectionData } from 'js-yaml-loader!@/*';
import { parseProjectInformation } from '@/application/Parser/ProjectInformationParser';
import { Application } from '@/domain/Application';
export function parseApplication(): Application { export function parseApplication(
const categories = new Array<Category>(); parser = CategoryCollectionParser,
if (!applicationFile.actions || applicationFile.actions.length <= 0) { processEnv: NodeJS.ProcessEnv = process.env,
throw new Error('Application does not define any action'); collectionsData = PreParsedCollections): IApplication {
} validateCollectionsData(collectionsData);
for (const action of applicationFile.actions) { const information = parseProjectInformation(processEnv);
const category = parseCategory(action); const collections = collectionsData.map((collection) => parser(collection, information));
categories.push(category); const app = new Application(information, collections);
}
const app = new Application(
applicationFile.name,
applicationFile.repositoryUrl,
process.env.VUE_APP_VERSION,
categories);
return app; return app;
} }
export type CategoryCollectionParserType
= (file: CollectionData, info: IProjectInformation) => ICategoryCollection;
const CategoryCollectionParser: CategoryCollectionParserType
= (file, info) => parseCategoryCollection(file, info);
const PreParsedCollections: readonly CollectionData []
= [ WindowsData, MacOsData ];
function validateCollectionsData(collections: readonly CollectionData[]) {
if (!collections.length) {
throw new Error('no collection provided');
}
if (collections.some((collection) => !collection)) {
throw new Error('undefined collection provided');
}
}

View File

@@ -0,0 +1,40 @@
import { Category } from '@/domain/Category';
import { CollectionData } from 'js-yaml-loader!@/*';
import { parseCategory } from './CategoryParser';
import { OperatingSystem } from '@/domain/OperatingSystem';
import { createEnumParser } from '../Common/Enum';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { CategoryCollection } from '@/domain/CategoryCollection';
import { IProjectInformation } from '@/domain/IProjectInformation';
import { CategoryCollectionParseContext } from './Script/CategoryCollectionParseContext';
import { ScriptingDefinitionParser } from './ScriptingDefinition/ScriptingDefinitionParser';
export function parseCategoryCollection(
content: CollectionData,
info: IProjectInformation,
osParser = createEnumParser(OperatingSystem)): ICategoryCollection {
validate(content);
const scripting = new ScriptingDefinitionParser()
.parse(content.scripting, info);
const context = new CategoryCollectionParseContext(content.functions, scripting);
const categories = new Array<Category>();
for (const action of content.actions) {
const category = parseCategory(action, context);
categories.push(category);
}
const os = osParser.parseEnum(content.os, 'os');
const collection = new CategoryCollection(
os,
categories,
scripting);
return collection;
}
function validate(content: CollectionData): void {
if (!content) {
throw new Error('content is null or undefined');
}
if (!content.actions || content.actions.length <= 0) {
throw new Error('content does not define any action');
}
}

View File

@@ -1,26 +1,26 @@
import { YamlCategory, YamlScript } from 'js-yaml-loader!./application.yaml'; import { CategoryData, ScriptData, CategoryOrScriptData } from 'js-yaml-loader!@/*';
import { Script } from '@/domain/Script'; import { Script } from '@/domain/Script';
import { Category } from '../../domain/Category'; import { Category } from '@/domain/Category';
import { parseDocUrls } from './DocumentationParser'; import { parseDocUrls } from './DocumentationParser';
import { ICategoryCollectionParseContext } from './Script/ICategoryCollectionParseContext';
import { parseScript } from './Script/ScriptParser';
let categoryIdCounter: number = 0; let categoryIdCounter: number = 0;
interface ICategoryChildren { interface ICategoryChildren {
subCategories: Category[]; subCategories: Category[];
subScripts: Script[]; subScripts: Script[];
} }
export function parseCategory(category: YamlCategory): Category { export function parseCategory(category: CategoryData, context: ICategoryCollectionParseContext): Category {
if (!category.children || category.children.length <= 0) { if (!context) { throw new Error('undefined context'); }
throw Error('Category has no children'); ensureValid(category);
}
const children: ICategoryChildren = { const children: ICategoryChildren = {
subCategories: new Array<Category>(), subCategories: new Array<Category>(),
subScripts: new Array<Script>(), subScripts: new Array<Script>(),
}; };
for (const categoryOrScript of category.children) { for (const data of category.children) {
parseCategoryChild(categoryOrScript, children, category); parseCategoryChild(data, children, category, context);
} }
return new Category( return new Category(
/*id*/ categoryIdCounter++, /*id*/ categoryIdCounter++,
@@ -31,30 +31,41 @@ export function parseCategory(category: YamlCategory): Category {
); );
} }
function parseCategoryChild( function ensureValid(category: CategoryData) {
categoryOrScript: any, children: ICategoryChildren, parent: YamlCategory) { if (!category) {
if (isCategory(categoryOrScript)) { throw Error('category is null or undefined');
const subCategory = parseCategory(categoryOrScript as YamlCategory); }
children.subCategories.push(subCategory); if (!category.children || category.children.length === 0) {
} else if (isScript(categoryOrScript)) { throw Error(`category has no children: "${category.category}"`);
const yamlScript = categoryOrScript as YamlScript; }
const script = new Script( if (!category.category || category.category.length === 0) {
/* name */ yamlScript.name, throw Error('category has no name');
/* code */ yamlScript.code,
/* docs */ parseDocUrls(yamlScript),
/* is recommended? */ yamlScript.recommend);
children.subScripts.push(script);
} else {
throw new Error(`Child element is neither a category or a script.
Parent: ${parent.category}, element: ${categoryOrScript}`);
} }
} }
function parseCategoryChild(
function isScript(categoryOrScript: any): boolean { data: CategoryOrScriptData,
return categoryOrScript.code && categoryOrScript.code.length > 0; children: ICategoryChildren,
parent: CategoryData,
context: ICategoryCollectionParseContext) {
if (isCategory(data)) {
const subCategory = parseCategory(data as CategoryData, context);
children.subCategories.push(subCategory);
} else if (isScript(data)) {
const scriptData = data as ScriptData;
const script = parseScript(scriptData, context);
children.subScripts.push(script);
} else {
throw new Error(`Child element is neither a category or a script.
Parent: ${parent.category}, element: ${JSON.stringify(data)}`);
}
} }
function isCategory(categoryOrScript: any): boolean { function isScript(data: any): boolean {
return categoryOrScript.category && categoryOrScript.category.length > 0; return (data.code && data.code.length > 0)
|| data.call;
}
function isCategory(data: any): boolean {
return data.category && data.category.length > 0;
} }

View File

@@ -1,34 +1,46 @@
import { YamlDocumentable } from 'js-yaml-loader!./application.yaml'; import { DocumentableData, DocumentationUrlsData } from 'js-yaml-loader!@/*';
export function parseDocUrls(documentable: YamlDocumentable): ReadonlyArray<string> { export function parseDocUrls(documentable: DocumentableData): ReadonlyArray<string> {
if (!documentable) {
throw new Error('documentable is null or undefined');
}
const docs = documentable.docs; const docs = documentable.docs;
if (!docs) { if (!docs || !docs.length) {
return []; return [];
} }
const result = new DocumentationUrls(); let result = new DocumentationUrlContainer();
if (docs instanceof Array) { result = addDocs(docs, result);
for (const doc of docs) {
if (typeof doc !== 'string') {
throw new Error('Docs field (documentation url) must be an array of strings');
}
result.add(doc);
}
} else if (typeof docs === 'string') {
result.add(docs);
} else {
throw new Error('Docs field (documentation url) must a string or array of strings');
}
return result.getAll(); return result.getAll();
} }
class DocumentationUrls { function addDocs(docs: DocumentationUrlsData, urls: DocumentationUrlContainer): DocumentationUrlContainer {
if (docs instanceof Array) {
urls.addUrls(docs);
} else if (typeof docs === 'string') {
urls.addUrl(docs);
} else {
throw new Error('Docs field (documentation url) must a string or array of strings');
}
return urls;
}
class DocumentationUrlContainer {
private readonly urls = new Array<string>(); private readonly urls = new Array<string>();
public add(url: string) { public addUrl(url: string) {
validateUrl(url); validateUrl(url);
this.urls.push(url); this.urls.push(url);
} }
public addUrls(urls: readonly any[]) {
for (const url of urls) {
if (typeof url !== 'string') {
throw new Error('Docs field (documentation url) must be an array of strings');
}
this.addUrl(url);
}
}
public getAll(): ReadonlyArray<string> { public getAll(): ReadonlyArray<string> {
return this.urls; return this.urls;
} }

View File

@@ -0,0 +1,12 @@
import { IProjectInformation } from '@/domain/IProjectInformation';
import { ProjectInformation } from '@/domain/ProjectInformation';
export function parseProjectInformation(
environment: NodeJS.ProcessEnv): IProjectInformation {
return new ProjectInformation(
environment.VUE_APP_NAME,
environment.VUE_APP_VERSION,
environment.VUE_APP_REPOSITORY_URL,
environment.VUE_APP_HOMEPAGE_URL,
);
}

View File

@@ -0,0 +1,22 @@
import { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { ILanguageSyntax } from '@/domain/ScriptCode';
import { FunctionData } from 'js-yaml-loader!@/*';
import { IScriptCompiler } from './Compiler/IScriptCompiler';
import { ScriptCompiler } from './Compiler/ScriptCompiler';
import { ICategoryCollectionParseContext } from './ICategoryCollectionParseContext';
import { SyntaxFactory } from './Syntax/SyntaxFactory';
import { ISyntaxFactory } from './Syntax/ISyntaxFactory';
export class CategoryCollectionParseContext implements ICategoryCollectionParseContext {
public readonly compiler: IScriptCompiler;
public readonly syntax: ILanguageSyntax;
constructor(
functionsData: ReadonlyArray<FunctionData> | undefined,
scripting: IScriptingDefinition,
syntaxFactory: ISyntaxFactory = new SyntaxFactory()) {
if (!scripting) { throw new Error('undefined scripting'); }
this.syntax = syntaxFactory.create(scripting.language);
this.compiler = new ScriptCompiler(functionsData, this.syntax);
}
}

View File

@@ -0,0 +1,62 @@
import { ExpressionPosition } from './ExpressionPosition';
import { IExpression } from './IExpression';
import { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
import { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
import { FunctionParameterCollection } from '@/application/Parser/Script/Compiler/Function/Parameter/FunctionParameterCollection';
import { FunctionCallArgumentCollection } from '../../Function/Call/Argument/FunctionCallArgumentCollection';
import { IExpressionEvaluationContext } from './ExpressionEvaluationContext';
import { ExpressionEvaluationContext } from '@/application/Parser/Script/Compiler/Expressions/Expression/ExpressionEvaluationContext';
export type ExpressionEvaluator = (context: IExpressionEvaluationContext) => string;
export class Expression implements IExpression {
constructor(
public readonly position: ExpressionPosition,
public readonly evaluator: ExpressionEvaluator,
public readonly parameters: IReadOnlyFunctionParameterCollection = new FunctionParameterCollection()) {
if (!position) {
throw new Error('undefined position');
}
if (!evaluator) {
throw new Error('undefined evaluator');
}
}
public evaluate(context: IExpressionEvaluationContext): string {
if (!context) {
throw new Error('undefined context');
}
validateThatAllRequiredParametersAreSatisfied(this.parameters, context.args);
const args = filterUnusedArguments(this.parameters, context.args);
context = new ExpressionEvaluationContext(args, context.pipelineCompiler);
return this.evaluator(context);
}
}
function validateThatAllRequiredParametersAreSatisfied(
parameters: IReadOnlyFunctionParameterCollection,
args: IReadOnlyFunctionCallArgumentCollection,
) {
const requiredParameterNames = parameters
.all
.filter((parameter) => !parameter.isOptional)
.map((parameter) => parameter.name);
const missingParameterNames = requiredParameterNames
.filter((parameterName) => !args.hasArgument(parameterName));
if (missingParameterNames.length) {
throw new Error(
`argument values are provided for required parameters: "${missingParameterNames.join('", "')}"`);
}
}
function filterUnusedArguments(
parameters: IReadOnlyFunctionParameterCollection,
allFunctionArgs: IReadOnlyFunctionCallArgumentCollection): IReadOnlyFunctionCallArgumentCollection {
const specificCallArgs = new FunctionCallArgumentCollection();
for (const parameter of parameters.all) {
if (parameter.isOptional && !allFunctionArgs.hasArgument(parameter.name)) {
continue; // Optional parameter is not necessarily provided
}
const arg = allFunctionArgs.getArgument(parameter.name);
specificCallArgs.addArgument(arg);
}
return specificCallArgs;
}

View File

@@ -0,0 +1,18 @@
import { IReadOnlyFunctionCallArgumentCollection } from '../../Function/Call/Argument/IFunctionCallArgumentCollection';
import { IPipelineCompiler } from '../Pipes/IPipelineCompiler';
import { PipelineCompiler } from '../Pipes/PipelineCompiler';
export interface IExpressionEvaluationContext {
readonly args: IReadOnlyFunctionCallArgumentCollection;
readonly pipelineCompiler: IPipelineCompiler;
}
export class ExpressionEvaluationContext implements IExpressionEvaluationContext {
constructor(
public readonly args: IReadOnlyFunctionCallArgumentCollection,
public readonly pipelineCompiler: IPipelineCompiler = new PipelineCompiler()) {
if (!args) {
throw new Error('undefined args, send empty collection instead');
}
}
}

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,9 @@
import { ExpressionPosition } from './ExpressionPosition';
import { IReadOnlyFunctionParameterCollection } from '../../Function/Parameter/IFunctionParameterCollection';
import { IExpressionEvaluationContext } from './ExpressionEvaluationContext';
export interface IExpression {
readonly position: ExpressionPosition;
readonly parameters: IReadOnlyFunctionParameterCollection;
evaluate(context: IExpressionEvaluationContext): string;
}

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