Compare commits

...

140 Commits

Author SHA1 Message Date
undergroundwires
b042b36aea Add expansion/collapse animations for cards
Key changes:

- Add animation for card opening/collapse.

Other supporting changes:

- Remove card expansion panel to its own component for easier
  maintainability and better separation of concerns.
- Use real DOM element instead of &:before pseudo class for showing
  expansion arrow. This increases by maintainability by separating its
  code and concerns.

- TODO: When one card is expanded and others is also expanded then the
  transition sucks.
2024-03-31 20:07:09 +02:00
undergroundwires
be7a886225 Improve URL checks to reduce false-negatives
This commit improves the URL health checking mechanism to reduce false
negatives.

- Treat all 2XX status codes as successful, addressing issues with codes
  like `204`.
- Exclude URLs within Markdown inline code blocks.
- Send the Host header for improved handling of webpages behind proxies.
- Improve formatting and context for output messages.
- Fix the defaulting options for redirects and cookie handling.
- Add URL exclusion support for non-responsive URLs.
- Update the user agent pool to modern browsers and platforms.
- Improve CI/CD workflow to respond to modifications in the
  `test/checks/external-urls` directory, offering immediate feedback on
  potential impacts to the external URL test.
- Add support for randomizing TLS fingerprint to mimic various clients
  better, improving the effectiveness of checks. However, this is not
  fully supported by Node.js's HTTP client; see nodejs/undici#1983 for
  more details.
- Use `AbortSignal` instead of `AbortController` as more modern and
  simpler way to handle timeouts.
2024-03-13 18:26:16 +01:00
undergroundwires
4ac1425f76 Migrate to Vite 5 and adjust configurations
This commit updates the `vite` dependency to the latest version (5.1.X)
and makes necessary adjustments to accommodate deprecations and new
features introduced in Vite 5.1.X.

Changes include:

- Modify the import statement for SVG files to use `query: '?raw'` syntax
  due to the deprecation of the `as: raw` option.
- Update `moduleResolution` setting to `Bundler` in `tsconfig.json` to
  support the new TypeScript 5 option, aligning with Vite 5's migration
  guide for Rollup 4 compatibility without requiring file extensions on
  relative imports.

Plugin migrations for Vite 5 support:

- Bump `@modyfi/vite-plugin-yaml`, see @modyfi/vite-plugin-yaml#22.
- Bump `electron-vite`, see alex8088/electron-vite#335.
- Bump `vitejs/plugin-legacy`.
- Bump `vitejs/vite-plugin-vue`, see vitejs/vite-plugin-vue#290.
2024-03-13 09:49:26 +01:00
undergroundwires
a721e82a4f Bump TypeScript to 5.3 with verbatimModuleSyntax
This commit upgrades TypeScript to the latest version 5.3 and introduces
`verbatimModuleSyntax` in line with the official Vue guide
recommendatinos (vuejs/docs#2592).

By enforcing `import type` for type-only imports, this commit improves
code clarity and supports tooling optimization, ensuring imports are
only bundled when necessary for runtime.

Changes:

- Bump TypeScript to 5.3.3 across the project.
- Adjust import statements to utilize `import type` where applicable,
  promoting cleaner and more efficient code.
2024-02-27 04:20:22 +01:00
undergroundwires
98845e6cae Improve VSCode detection in configure_vscode.py
This commit improves the reliability of the `configure_vscode.py` script
on macOS by improving the detection mechanism for the Visual Studio Code
CLI command (`code`). It introduces a fallback mechanism to locate the
`code` executable in common installation path for macOS, addressing the
issue where the VSCode CLI might not be found in PATH variable.

Additionally, the commit refines error handling by providing clearer error
messages for unknown exceptions during the extension installation process.
This ensures that users are better informed about the nature of the error,
facilitating easier troubleshooting.
2024-02-24 07:53:19 +01:00
undergroundwires
19645248ab Fix tooltip falling behind elements on fade out
This commit ensures that the tooltip maintains its `z-index` during both
visibility and invisibility transitions. This prevents the tooltip from
falling behind other elements during its fade-in and fade-out
animations, providing smoother and more visually consistent user
experience.
2024-02-23 14:00:37 +01:00
undergroundwires
255c51c8a0 ci/cd: Fix cross-platform git command compability
By explicitly setting the shell to bash in GitHub actions workflow, this
commit fixes the failure of automated releases on Windows. Previously,
the default PowerShell environment on Windows runners led to syntax
incompatibilities, causing the release process to fail with an error
when executing git checkout commands.

This changes allows successful application publishing on Windows by
avoiding syntax issues due to PowerShell interpreting commands
differently, fixing the following error encountered:

```
Run git checkout "$(git rev-list "0.13.0"..master | tail -1)"
  git checkout "$(git rev-list "0.13.0"..master | tail -1)"
  shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"
fatal: empty string is not a valid pathspec. please use . instead if you meant to match all paths
Error: Process completed with exit code 1.
```
2024-02-22 21:08:16 +01:00
undergroundwires-bot
bbf3490e9c ⬆️ bump everywhere to 0.13.0 2024-02-21 13:41:49 +00:00
undergroundwires
c7fa4b6d02 Update meta title and description
This commit changes outdated meta description which suggested
privacy.sexy is only for Windows.

It also changes title to use `Maximize your privacy` instead of using
the word "enforce".
2024-02-21 00:34:39 +01:00
undergroundwires
17152c84dc win: add host blocking category #26
- Introduce new category for host blocking.
- Add new scripts to block tracking hosts Windows connects to.
- Relocate Dropbox host blocking under new category.
- Update comments in `BlockViaHostsFile` function for clarity.
2024-02-20 12:10:46 +01:00
undergroundwires
894687c0e0 win: relocate service disabling and improve docs
This commit improves the organization of service disabling scripts by
relocating the "Disable OS services" section. It improves documentation
and script/category titles to enhance clarity and accessibility for the
divers user base of privacy.sexy, including those with non-technical
backgrounds.

Key changes:

- Move "Disable OS services" to "Remove bloatware" to simplify
  navigation and prepare for new categories (for #26).
- Rename "Disable OS services" to "Disable non-essential services"
  for better understanding.
- Relocate "Disable NetBios for all interfaces" to "Security
  improvements" due to its relevance to security rather than bloatware.
- Improve documentation.
- Simplify script names by removing technical jargon, making them more
  more accessible.
2024-02-19 21:12:34 +01:00
undergroundwires
fb08f03765 Add UI animations for expand/collapse actions
This commit improves the user experience by adding smooth transitions
for expanding and collapsing tree node items and documentation sections.
The introduction of these animations makes the interface feel more
dynamic and responsive to user interactions.

Key changes:

- Implement a new `ExpandCollapseTransition` component to wrap UI
  elements requiring expand/collapse animations.
- Utiliz the `ExpandCollapseTransition` in tree view nodes and
  documentation sections to animate visibility changes.
- Refactor CSS to remove obsolete transition mixins, leveraging Vue's
  transition system for consistency and maintainability.
2024-02-18 22:38:32 +01:00
undergroundwires
faa7a38a7d Apply global styles for visual consistency
This commit centralizes the styling of key UI elements across the
project to ensure:

- Consistent look and feel.
- Enhanced code reusability.
- Simpified maintenance, improving development speed.

It establishes a uniform foundation that can be leveraged across
different parts of the project, even enabling the styling to be shared
across different websites (supporting issue #49).

Key changes:

- Apply the following shared styles globally:
  * Styling of code, blockquotes, superscripts, horizontal rules and
    anchors.
  * Vertical and horizontal spacing.
- Segregate base styling into dedicated SCSS files for clearer structure
  and increased maintainability.
- Remove custom styling from affected components, enabling global style
  reuse for visual uniformity, reduced redundancy, and enhanced
  semantics.

Other supporting changes:

- Rename `globals.scss` to `base.scss` for better clarity.
- Add `.editorconfig` for `.scss` files to ensure consistent whitespace
  usage.
- Remove `2` file from the project root, that was included in the source
  code by mistake.
- Remove unused font-face imports
2024-02-17 23:09:58 +01:00
undergroundwires
d5bbc321f9 Change fonts for improved readability
Key changes:

- Change main font to Roboto Slab for enhanced readability.
- Change code font to 'Source Code Pro' for consistent monospace code
  rendering.
- Import and set code font explicitly for uniform appearance across
  platforms.
- Update Slabo 27px (logo font) version from v6 to v14.
- Update Yesteryear (cursive font) version from v8 to v18.
- Drop support for historic browser-specific formats, retaining only
  WOFF2 for modern and TTF for legacy browsers.
- Use `font-display: swap` to improve perceived load times and minimize
  layout shifts.

Supporting changes:

- Simplify font-weight usage to 'normal' and 'bold' for consistency.
- Adjust inline code padding for better scalability and prevent
  overflow.
- Introduce `$font-main` as main font variable.
- Remove specification of main font as it's best practice to rely on the
  default font defined on `body` style.
- Specify font in code area to ensure it uses the code font consistently
  as the rest of the application.
- Remove local font search through `local` to simplify the import logic
  and prioritize consistency over performance.
- Import bold font explicitly (`font-weight: 700`) for smooth and
  consistent rendering.
- Move `font-family` definitions to `_typography.scss` to better adhere
  to the common standards and conventions.
- Refactor font variables to have `font-family-` prefix instead of
  `font-` to improve clarity and differentiation between `font-size`
  variables.
- Rename 'artistic' font to 'cursive' for preciseness and clarity.
- Use smaller font sizes to match the new main font size, as Roboto Slab
  is relatively larger.
- Add missing fallbacks for serif fonts to improve fault tolerance.
- Change padding slightly on toggle switch for revert buttons to align
  well with new main font and its sizing.
2024-02-16 11:27:31 +01:00
undergroundwires
ebd82853dd Remove 'preview' label from Linux options
Since the 0.12.0 release, Linux support has undergone extensive testing
and all reported issues have been addressed. This change removes the
'preview' label from all UI elements related to Linux, signifying that
Linux support is mature and fully integrated.

- The 'preview' text next to Linux in the operating system selection
  and other related UI elements has been omitted.
- Users can now select Linux without the implication of it being an
  experimental feature, encouraging trust and wider adoption.
2024-02-15 21:28:09 +01:00
undergroundwires
6142f3a297 Extend search by including documentation content
This commit broadens the search functionality within privacy.sexy by
including documentation text in the search scope. Users can now find
scripts and categories not only by their names but also by content in
their documentation. This improvement aims to make the discovery of
relevant scripts and information more intuitive and comprehensive.

Key changes:

- Documentation text is now searchable, enhancing the ability to
  discover scripts and categories based on content details.

Other supporting changes:

- Remove interface prefixes (`I`) from related interfaces to adhere to
  naming conventions, enhancing code readability.
- Refactor filtering to separate actual filtering logic from filter
  state management, improving the structure for easier maintenance.
- Improve test coverage to ensure relability of existing and new search
  capabilities.
- Test coverage expanded to ensure the reliability of the new search
  capabilities.
2024-02-14 12:10:49 +01:00
undergroundwires
63366a4ec2 win, mac, linux: add privacy.sexy cleanup scripts
Introduce scripts across Windows, macOS and Linux to allow privacy.sexy
users to erase their script usage traces, improving privacy protection.

Key changes:

- Add category to clear privacy.sexy data.
- Add scripts for deleting privacy.sexy's script execution history and
  activity logs.

Supporting changes:

- Update documentation to highlight the new capability for users to
  clear privacy.sexy-generated data.
- Add shared functions for directory cleanup for Linux and macOS.
- Add code annotations to hint unified approach across all supported
  operating systems.
2024-02-12 13:05:01 +01:00
undergroundwires
55fa7eae71 Add 'Revert All Selection' feature #68
This commit introduces 'Revert: None - Selected' toggle, enabling users
to revert all reversible scripts with a single action, improving user
safety and control over script effects.

This feature addresses user-reported concerns about the ease of
reverting script changes. This feature should enhance the user experience
by streamlining the revert process along with providing essential
information about script reversibility.

Key changes:

- Add buttons to revert all selected scripts or setting all selected
  scripts to non-revert state.
- Add tooltips with detailed explanations about consequences of
  modifying revert states, includinginformation about irreversible
  script changes.

Supporting changes:

- Align items on top menu vertically for better visual consistency.
- Rename `SelectionType` to `RecommendationStatusType` for more clarity.
- Rename `IReverter` to `Reverter` to move away from `I` prefix
  convention.
- The `.script` CSS class was duplicated in `TheScriptsView.vue` and
  `TheScriptsArea.vue`, leading to style collisions in the development
  environment. The class has been renamed to component-specific classes
  to avoid such issues in the future.
2024-02-11 22:47:34 +01:00
undergroundwires
a54e16488c Change slogan and refactor project info naming
The project's slagon has been updated back to "Privacy is sexy" from
"Now you have the choice" for enhanced brand clarity and memorability.

This change also reflects the community's preference and aligns with the
project's established identity.

This commit also refactors naming and structure of project information
(metadata) struct to enhance clarity and maintainability in relation to
changing the slogan.

Key changes include:

- Update UI components to display the revised slogan.
- Remove period from project slogan in code area for consistency with a
  explanatory comment for future maintainability.
- Refactor header container and class names for clarity.
- Standardize project metadata usage in `TheCodeArea.vue` to ensure
  consistency.
- Improve code clarity by renaming `IProjectInformation` to
  `ProjectDetails` and `ProjectInformation` to `GitHubProjectDetails`.
- Organize `ProjectDetails` under a dedicated `Project` directory within
  the domain layer for better structure.

These changes are expected to improve the project's appeal and
streamline future maintenance and development efforts.
2024-02-10 18:50:56 +01:00
undergroundwires
b9c89b701f Render bracket references as superscript text
This commit improves markdown rendering to convert reference labels
(e.g., `[1]`) to superscripts, improving document readability without
cluttering the text. This improvement applies documentation of all
scripts and categories.

Changes:

- Implement superscript conversion for reference labels within markdown
  content, ensuring a cleaner presentation of textual references.
- Enable HTML content within markdown, necessary for inserting `<sup>`
  elements due to limitations in `markdown-it`, see
  markdown-it/markdown-it#999 for details.
- Refactor markdown rendering process for improved testability and
  adherence to the Single Responsibility Principle.
- Create `_typography.scss` with font size definitions, facilitating
  better control over text presentation.
- Adjust external URL indicator icon sizing for consistency, aligning
  images with the top of the text to maintain a uniform appearence.
- Use normal font-size explicitly for documentation text to ensure
  consistency.
- Remove text size specification in `markdown-styles` mixin, using `1em`
  for spacing to simplify styling.
- Rename font sizing variables for clarity, distinguishing between
  absolute and relative units.
- Change `font-size-relative-smaller` to be `80%`, browser default for
  `font-size: smaller;` CSS style and use it with `<sup>` elements.
- Improve the logic for converting plain URLs to hyperlinks, removing
  trailing whitespace for cleaner link generation.
- Fix plain URL to hyperlink (autolinking) logic removing trailing
  whitespace from the original markdown content. This was revealed by
  tests after separating its logic.
- Increase test coverage with more tests.
- Add types for `markdown-it` through `@types/markdown-it` package for
  better editor support and maintainability.
- Simplify implementation of adding custom anchor attributes in
  `markdown-it` using latest documentation.
2024-02-09 16:25:05 +01:00
undergroundwires
311fcb1813 Improve UI code styling for all platforms
This commit standardizes the visual styling of inline code and code
blocks, ensuring consistency across macOS, Android, Linux and Windows
platforms.

The discrepancies observed in font rendering on macOS, which caused the
inline code font to appear larger, have been addressed. This behavior
was only observed on macOS using different browsers such as Firefox,
Safari, Chromium-based browsers including Electron.

Key changes:

- Standardize font size relative to the parent element.
- Remove font-weight for uniformity, especially when the specific weight
  is not included with the application.
- Add a consistent background color to inline codes, aligning their look
  with code blocks.
- Refactor code styling into a separate SCSS file for improved
  modularity and maintainability.
- Update the documentation to reflect these visual design choices for
  privacy.sexy's UI.

These changes enhance the overall user experience by providing a
consistent look and feel for code elements within the UI, regardless of
the user's platform or browser.
2024-02-06 12:35:51 +01:00
undergroundwires
aa4205ff7a Remove playful emojis (🍑🍆)
Improve title, documentation and metadata readability by removing
emojis.

Rationale:

- Visual clutter.
- Inconsistent look across different browsers
- Informal tone.
2024-02-02 15:38:17 +01:00
undergroundwires
937f4593d1 Change 'revert' button to title case
- Switch 'revert' button text to title case for consistency and more
  formal and professional look.
- Update related styles to reflect the new case usage.
- Adjust tests to match the new button label casing.
- Remove reduntant visibility switch between to elements to simpify the
  DOM and style rules.
2024-02-01 17:20:11 +01:00
undergroundwires
4da306b9f7 Normalize and improve font sizes
This commit standardizes font sizes across components for a uniform
look. The icon sizes, font weights and line heights are also adjusted
accordingly for better standardization and simplicity.

- Introduce variables for standard font sizes, enhancing
  maintainability.
- Remove explicit pixel values, replaced with scalable units based on
  root size.
- Remove workaround for line-height adoptation of bigger font-size.
- Use consistent small font-size for the code area.
- Adjust checkbox tick to scale with font size.
2024-01-31 19:54:11 +01:00
undergroundwires
a5ffed4cd6 Add markdown support for script/category names
Add markdown rendering for script and category titles to improve the
presentation of textual content.

- Introduce reusable `MarkdownText` for markdown rendering.
- Incorporate markdown styling into dedicated SCSS file for clarity.
- Define explicit font sizes for consistent visual experience.
- Apply `MarkdownText` usage across UI for unified markdown rendering.
- Streamline related styles and layout for improved maintainability
- Set font sizes explicitly for better consistency and to avoid
  unexpected inheritence.

This enhancement enables richer text formatting and improves the user
interface's flexibility in displaying content.
2024-01-30 16:36:55 +01:00
undergroundwires
6ab6dacd1b Limit tooltip width for improved readability
Tooltip content now has a maximum width set to accommodate an optimal
character count per line, enhancing readability and interface
cleanliness.

This limit is grounded in typographic research suggesting that 50-75
characters per line is ideal for text readability, with tooltips being
targeted to the lower end of this spectrum to maintain brevity and
clarity.
2024-01-29 15:46:54 +01:00
undergroundwires
d277139dd5 Expand script names to take full available width
This commit improves consistency in the UI by ensuring that all nodes in
the tree component expand to take full available width. This approach
eliminates layout shifts that were previously observed when toggling
documentation.
2024-01-28 09:08:37 +01:00
undergroundwires
7af8daa341 Improve selection type documentation
- Refine tooltip documentation with clearer information.
- Introduce privacy ranking indicator for intuitive user guidance.
- Adopt a consistent format throughout documentation.
- Switch from emojis to icons to maintain visual uniformity.
2024-01-26 15:40:20 +01:00
undergroundwires
d67100ad5e Update screenshot to v0.12.10 2024-01-25 12:51:51 +01:00
undergroundwires
10829d65aa win: add Dropbox telemetry blocking #125, #118 2024-01-24 19:07:55 +01:00
undergroundwires
cd425502ae win: add disabling Windows Copilot #263, #266
This commit implements scripts to disable Windows Copilot (Copilot in
Windows), addressing issues #263 and #266.

Changes include:

- Add category and scripts to disable Windows copilot.
- Incorporate a restart explorer suggestion across all taskbar
  modification scripts to ensure consistency in user experience.
2024-01-22 09:57:12 +01:00
undergroundwires
541f9aa5ee win: improve search privacy scripts #117
- Add disabling bing search suggestions, resolving #117.
- Fix revert codes to align with default OS configurations.
- Implement message for recommended explorer.exe restart.
- Simplify script names for ease of understanding.
- Provide detailed documentation for each script change.
- Correct `BingSearchEnabled` registry path from HKLM to HKCU.
- Improve categorization of search privacy scripts.
2024-01-21 16:33:04 +01:00
undergroundwires
c6ebba85fb win: add disabling clipboard features #251, #247
This commit adds scripts to secure clipboard by disabling clipboard
synchronization and history. These changes aim to prevent sensitive data
like passwords and credit card details from being inadvertently stored
or shared via the cloud.
2024-01-19 17:16:16 +01:00
undergroundwires-bot
f94a1ffe11 ⬆️ bump everywhere to 0.12.10 2024-01-18 11:23:59 +00:00
undergroundwires
6ada8d425c Improve script error dialogs #304
- Include the script's directory path #304.
- Exclude Windows-specific instructions on non-Windows OS.
- Standardize language across dialogs for consistency.

Other supporting changes:

- Add script diagnostics data collection from main process.
- Document script file storage and execution tamper protection in
  SECURITY.md.
- Remove redundant comment in `NodeReadbackFileWriter`.
- Centralize error display for uniformity and simplicity.
- Simpify `WindowVariablesValidator` to omit checks when not on the
  renderer process.
- Improve and centralize Electron environment detection.
- Use more emphatic language (don't worry) in error messages.
2024-01-17 23:59:05 +01:00
undergroundwires
f03fc24098 Add AD detection on desktop app #264, #304
This commit addresses issues #264 and #304, where users were not
receiving error messages when script execution failed due to
antivirus intervention, particularly with Microsoft Defender.
Now, desktop app users will see a detailed error message with
guidance on next steps if script saving or execution fails due
to antivirus removal.

Key changes:

- Implement a check to detect failure in file writing,
  including reading the written file back. This method effectively
  detects antivirus interventions, as the read operation triggers
  an antivirus scan, leading to file deletion by the antivirus.
- Introduce a specific error message for scenarios where an
  antivirus intervention is detected.
2024-01-16 22:26:28 +01:00
undergroundwires
756c736e21 Add Windows save instructions UI and fix URL #296
- Add Windows instruction dialog when saving scripts for Windows.
- Fix incorrect macOS download URL given for Linux instructions.
- Refactor UI rendering, eleminating the use of `v-html` and JavaScript
  variables to hold HTML code.
2024-01-15 22:38:39 +01:00
undergroundwires
e09db0f1bd Show save/execution error dialogs on desktop #264
This commit introduces system-native error dialogs on desktop
application for code save or execution failures, addressing user confusion
described in issue #264.

This commit adds informative feedback when script execution or saving
fails.

Changes:

- Implement support for system-native error dialogs.
- Refactor `CodeRunner` and `Dialog` interfaces and their
  implementations to improve error handling and provide better type
  safety.
- Introduce structured error handling, allowing UI to display detailed
  error messages.
- Replace error throwing with an error object interface for controlled
  handling. This ensures that errors are propagated to the renderer
  process without being limited by Electron's error object
  serialization limitations as detailed in electron/electron#24427.
- Add logging for dialog actions to aid in troubleshooting.
- Rename `fileName` to `defaultFilename` in `saveFile` functions
  to clarify its purpose.
- Centralize message assertion in `LoggerStub` for consistency.
- Introduce `expectTrue` in tests for clearer boolean assertions.
- Standardize `filename` usage across the codebase.
- Enhance existing test names and organization for clarity.
- Update related documentation.
2024-01-14 22:35:53 +01:00
undergroundwires
c546a33eff Show native save dialogs in desktop app #50, #264
This commit introduces native operating system file dialogs in the
desktop application replacing the existing web-based dialogs.

It lays the foundation for future enhancements such as:

- Providing error messages when saving or executing files, addressing
  #264.
- Creating system restore points, addressing #50.

Documentation updates:

- Update `desktop-vs-web-features.md` with added functionality.
- Update `README.md` with security feature highlights.
- Update home page documentation to emphasize security features.

Other supporting changes include:

- Integrate IPC communication channels for secure Electron dialog API
  interactions.
- Refactor `IpcRegistration` for more type-safety and simplicity.
- Introduce a Vue hook to encapsulate dialog functionality.
- Improve errors during IPC registration for easier troubleshooting.
- Move `ClientLoggerFactory` for consistency in hooks organization and
  remove `LoggerFactory` interface for simplicity.
- Add tests for the save file dialog in the browser context.
- Add `Blob` polyfill in tests to compensate for the missing
  `blob.text()` function in `jsdom` (see jsdom/jsdom#2555).

Improve environment detection logic:

- Treat test environment as browser environments to correctly activate
  features based on the environment. This resolves issues where the
  environment is misidentified as desktop, but Electron preloader APIs
  are missing.
- Rename `isDesktop` environment identification variable to
  `isRunningAsDesktopApplication` for better clarity and to avoid
  confusion with desktop environments in web/browser/test environments.
- Simplify `BrowserRuntimeEnvironment` to consistently detect
  non-desktop application environments.
- Improve environment detection for Electron main process
  (electron/electron#2288).
2024-01-13 18:04:23 +01:00
undergroundwires
da4be500da win: add missing extension apps, improve docs #279
This commit adds missing extension apps seen since Windows 11 22H2 and
improves documentation scripts and category of extension app removal.

Addition of new extension apps found since Windows 11 22H2:

- HEVC Video Extensions (`Microsoft.HEVCVideoExtension`)
- Raw Image Extension (`Microsoft.RawImageExtension`)

Documentation improvements:

- Fix links that are not correctly archived.
- Add cautionary notes for all extension app removal scripts.
- Add security implications associated with these extensions.
2024-01-10 21:59:55 +01:00
undergroundwires
b404a91ada Fix invisible script execution on Windows #264
This commit addresses an issue in the privacy.sexy desktop application
where scripts executed as administrator on Windows were running in the
background. This was observed in environments like Windows Pro VMs on
Azure, where operations typically run with administrative privileges.

Previously, the application used the `"$path"` shell command to execute
scripts. This mechanism failed to activate the logic for requesting
admin privileges if the app itself was running as an administrator.
To resolve this, the script execution process has been modified to
explicitly ask for administrator privileges using the `VerbAs` method.
This ensures that the script always runs in a new `cmd.exe` window,
enhancing visibility and user interaction.

Other supporting changes:

- Rename the generated script file from `run-{timestamp}-{extension}` er
  to `{timestamp}-privacy-script-{extension}` for clearer identification
  and better file sorting.
- Refactor `ScriptFileCreator` to parameterize file extension and
  script name.
- Rename `OsTimestampedFilenameGenerator` to
  `TimestampedFilenameGenerator` to better reflect its new and more
  scoped functionality after refactoring mentioned abvoe.
- Remove `setAppName()` due to ineffective behavior in Windows.
- Update `SECURITY.md` to highlight that the app doesn't require admin
  rights for standard operations.
- Add `.editorconfig` settings for PowerShell scripts.
- Add a integration test for script execution logic. Improve environment
  detection for more reliable test execution.
- Disable application logging during unit/integration tests to keep test
  outputs clean and focused.
2024-01-09 20:44:06 +01:00
undergroundwires
728584240c Fix touch, cursor and accessibility in slider
This commit improves the horizontal slider between the generated code
area and the script list. It enhances interaction, accessibility and
performance. It provides missing touch responsiveness, improves
accessibility by using better HTML semantics, introduces throttling and
refactors cursor handling during drag operations with added tests.

These changes provides smoother user experience, better support for
touch devices, reduce load during interactions and ensure the
component's behavior is intuitive and accessible across different
devices and interactions.

- Fix horizontal slider not responding to touch events.
- Improve slider handle to be a `<button>` for improved accessibility
  and native browser support, improving user interaction and keyboard
  support.
- Add throttling in the slider for performance optimization, reducing
  processing load during actions.
- Fix losing dragging state cursor on hover over page elements such as
  input boxes and buttons during dragging.
- Separate dragging logic into its own compositional hook for clearer
  separation of concerns.
- Refactor global cursor mutation process.
- Increase robustness in global cursor changes by preserving and
  restoring previous cursor style to prevent potential side-effects.
- Use Vue 3.2 feature for defining cursor CSS style in `<style>`
  section.
- Expand unit test coverage for horizontal slider, use MouseEvent and
  type cast it to PointerEvent as MouseEvent is not yet supported by
  `jsdom` (see jsdom/jsdom#2527).
2024-01-08 23:08:10 +01:00
undergroundwires
3b1a89ce86 Fix script execution for Linux VSCode development
This commit improves the VSCode configuration script for Linux-based
development environments.

It fixes a script execution failure in the deskto version during
development when using VSCode installed via Snap or Flatpak. It resolves
the following error encountered during script execution in development
mode (`npm run electron:dev`):

`symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0:
 undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE`

Changes:

- Add a setting in VSCode configuration script to workaround script
  execution errors in sandboxed VSCode installations on Linux (see
  see microsoft/vscode#179274).
- Migrate the configuration script to Python for cross-platform
  compatibility and simplicity.
- Refactor the script for better extensibility.
- Automate installation of recommended VSCode extensions.
- Recommend VSCode Pylint extension for Python linting.
- Standardize Python development settings in `.editorconfig`.
2024-01-07 14:02:40 +01:00
undergroundwires
c84a1bb74c Fix script deletion during execution on desktop
This commit fixes an issue seen on certain Windows environments (Windows
10 22H2 and 11 23H2 Pro Azure VMs) where scripts were being deleted
during execution due to temporary directory usage. To resolve this,
scripts are now stored in a persistent directory, enhancing reliability
for long-running scripts and improving auditability along with
troubleshooting.

Key changes:

- Move script execution logic to the `main` process from `preloader` to
  utilize Electron's `app.getPath`.
- Improve runtime environment detection for non-browser environments to
  allow its usage in Electron main process.
- Introduce a secure module to expose IPC channels from the main process
  to the renderer via the preloader process.

Supporting refactorings include:

- Simplify `CodeRunner` interface by removing the `tempScriptFolderName`
  parameter.
- Rename `NodeSystemOperations` to `NodeElectronSystemOperations` as it
  now wraps electron APIs too, and convert it to class for simplicity.
- Rename `TemporaryFileCodeRunner` to `ScriptFileCodeRunner` to reflect
  its new functinoality.
- Rename `SystemOperations` folder to `System` for simplicity.
- Rename `HostRuntimeEnvironment` to `BrowserRuntimeEnvironment` for
  clarity.
- Refactor main Electron process configuration to align with latest
  Electron documentation/recommendations.
- Refactor unit tests `BrowserRuntimeEnvironment` to simplify singleton
  workaround.
- Use alias imports like `electron/main` and `electron/common` for
  better clarity.
2024-01-06 18:47:58 +01:00
undergroundwires
bf7fb0732c Bump ESLint Typescript dependencies to latest
- Bump all ESLint dependencies related to TypeScript to their latest
  version. This was made possible by the resolution of compatibility
  issues with `@vue/eslint-config-airbnb-with-typescript`.
  See vuejs/eslint-config-airbnb#58 for details.
- Refactor code to comply with the latest linting configuration.
- Improve documentation in the ESLint configuration file to better
  describe the functionality and limitations of
  `@vue/typescript/recommended`.
  See vuejs/eslint-config-typescript#67 for details.
- Document functionality and limitation of `@vue/typescript/recommended`
  more clearly in ESLint configuration file.
2024-01-05 14:18:50 +01:00
undergroundwires
dc30825232 Fix macOS detection in desktop app and Chromium
This commit addresses an issue where macOS was incorrectly identified as
iPadOS in Chromium-based browsers. The root cause was related to touch
support detection being inaccurately triggered on Chromium browsers,
leading to misidentification.

The bug caused two issues:

1. Desktop version: Script execution on macOS did not work as the
   desktop app wrongly assumed that it was running on iPadOS.
2. Web and desktop version: The UI didn't default to macOS, presuming an
   iPadOS environment.

This bug was exclusive to Chromium browsers on macOS. Firefox and Safari
didn't exhibit this behavior, as they handle touch event browser API
as differently and initially expected.

Key changes:

- Improve touch support detection to accurately differentiate between
  macOS and iPadOS by removing an identification method used that is not
  reliable for Chromium-based browsers.
- Update user agent detection to correctly identify Electron-based
  applications as macOS even without needing the information from the
  preloader context.
2024-01-03 11:00:34 +01:00
undergroundwires
40f5eb8334 Fix handling special chars in script paths
This commit improves the handling of paths with spaces or special
characters during script execution in the desktop application.

Key improvements:

- Paths are now quoted for macOS/Linux, addressing issues with
  whitespace or single quotes.
- Windows paths are enclosed in double quotes to handle special
  characters.

Other supporting changes:

- Add more documentation for terminal execution commands.
- Refactor terminal script file execution into a dedicated file for
  improved separation of concerns.
- Refactor naming of `RuntimeEnvironment` to align with naming
  conventions (no interface with I prefix) and for clarity.
- Refactor `TemporaryFileCodeRunner` to simplify it by removing the `os`
  parameter and handling OS-specific logic within the filename generator
  instead.
- Refactor `fileName` to `filename` for consistency.
2024-01-02 16:16:31 +01:00
undergroundwires
fac72edd55 win: improve store app docs and add research #279
This commit improves documentation for removal of Windows store apps
along with adding related research.

1. Improve Store app removal documentation:
   The documentation for scripts that remove Store apps has been
   enhanced. It now includes information on the default preinstallation
   status of these apps across various Windows versions. This update
   covers Windows 10 (from version 19H2 to 23H2) and Windows 11 (from
   version 21H2 to 23H2), enabling users to identify potentially
   preinstalled apps that might affect privacy.

2. Add research documentation:
   A detailed research documentation on Windows Store apps has been
   introduced for Windows 10 (versions 1909 to 22H2) and Windows 11
   (versions 21H2 to 23H2). This includes lists of preinstalled Store
   apps, complete with package information. This research aids in
   understanding which default apps are present in different Windows
   versions and their status regarding removal. The documentation also
   includes the PowerShell script used for this research, serving as a
   resource for future updates and expansion.
2024-01-01 17:44:09 +01:00
undergroundwires
cdc32d1f12 Improve desktop script runs with timestamps & logs
Improve script execution in the desktop app by introducing timestamped
filenames and detailed logging. These changes aim to facilitate easier
debugging, auditing and overall better user experience.

Key changes:

- Add timestamps in filenames for temporary files to aid in
  troubleshooting and auditing.
- Add application logging throughout the script execution process to
  enhance troubleshooting capabilities.

Other supporting changes:

- Refactor `TemporaryFileCodeRunner` with subfunctions for improved
  readability, maintenance, reusability and extensibility.
- Refactor unit tests for `TemporaryFileCodeRunner` for improved
  granularity and simplicity.
- Create centralized definition of supported operating systems by
  privacy.sexy to ensure robust and consistent test case creation.
- Simplify the `runCode` method by removing the file extension
  parameter; now handled internally by `FileNameGenerator`.
2023-12-31 14:28:58 +01:00
undergroundwires
8f4b34f8f1 win: fix language dependent delete script #149
This commit addresses the language dependency of the `takeown /d y`
command in non-English Windows versions by using the `choice` utility.
This utility dynamically determines the equivalent of 'yes' in the
current system language, resolving issues encountered in the delete
script.

Other solution options such as enumerating language equivalents,
adjusting script culture settings, using side-effects of the `copy`
command, and parsing `takeown` help documentation proved either
impractical or unreliable.

The `choice` command has been successfully tested in both English and
German environments, ensuring reliable execution across various locales.
This change replaces the previous `takeown` usage in the script,
its reliability across diverse Windows locales.
2023-12-30 17:12:21 +01:00
undergroundwires
86fde6d7dc Fix button inconsistencies and macOS layout shifts
This commit fixes layout shifts experienced in macOS Safari when
hovering over top menu items. Instead of making text bold — which was
causing layout shifts — the hover effect now changes the text color.
This ensures a consistent UI across different browsers and platforms.

Additionally, this commit fixes the styling of the privacy button
located in the bottom right corner. Previously styled as an `<a>`
element, it is now correctly represented as a `<button>`.

Furthermore, the commit enhances HTML conformity and accessibility by
correctly using `<button>` and `<a>` tags instead of relying on click
interactions on `<span>` elements.

This commit introduces `FlatButton` Vue component and a new
`flat-button` mixin. These centralize button usage and link styles,
aligning the hover/touch reactions of buttons across the application,
thereby creating a more consistent user interface.
2023-12-29 17:26:40 +01:00
undergroundwires
2f06043559 Bump Node.js environment to 18.x
- Bump Node.js to version 18. This change is necessary as Node.js v16
  will reach end-of-life on 2023-09-11. It also ensure compatibility
  with dependencies requiring minimum of Node.js v18, such as `vite`,
  `@vitejs`plugin-legacy` and `icon-gen`.
- Bump `setup-node` action to v4.
- Recommend using the `nvm` tool for managing Node.js versions in the
  documentation.
- Update documentation to point to code reference for required Node.js
  version. This removes duplication of information, and keeps the code
  as single source of truth for required Node.js version.
- Refactor code to adopt the `node:` protocol for Node API imports as
  per Node.js 18 standards. This change addresses ambiguities and aligns
  with Node.js best practices (nodejs/node#38343). Currently, there is
  no ESLint rule to enforce this protocol, as noted in
  import-js/eslint-plugin-import#2717.
- Replace `cross-fetch` dependency with the native Node.js fetch API
  introduced in Node.js 18. Adjust type casting for async iterable read
  streams to align with the latest Node.js APIs, based on discussions in
  DefinitelyTyped/DefinitelyTyped#65542.
2023-12-28 11:57:38 +01:00
undergroundwires
fc9dd234e9 Improve documentation for contribution guidelines
- Improve `CONTRIBUTING.md` with clearer, more structured guidelines.
- Introduce a centralized 'Script Guidelines' document for consistent
  reference.
- Remove repetitive information across documents, providing links to the
  primary source.
- Simplify language across related documentation for better
  accessibility and readability.
2023-12-20 18:53:08 +01:00
undergroundwires
645c333787 Fix unresponsive circle icon in revert button
This commit fixes a UI bug where the circle icon of the revertbutton was
unresponsive to clicks. The solution involves replacing the
pseudo-element (`:before`) with an actual HTML element, enabling direct
event binding.

Additional improvements include:

- Removal of redundant `z-index` properties to simplify click event
  handling and reduce complexity.
- Programmatic toggle of `isChecked` on click, providing more controlled
  and explicit behavior and avoiding issues with native checkbox
  behavior, especially when overlaid on a pseudo-element.
2023-12-19 10:44:54 +01:00
undergroundwires
efa05f42bc Improve security by isolating code execution more
This commit enhances application security against potential attacks by
isolating dependencies that access the host system (like file
operations) from the renderer process. It narrows the exposed
functionality to script execution only, adding an extra security layer.

The changes allow secure and scalable API exposure, preparing for future
functionalities such as desktop notifications for script errors (#264),
improved script execution handling (#296), and creating restore points
(#50) in a secure and repeatable way.

Changes include:

- Inject `CodeRunner` into Vue components via dependency injection.
- Move `CodeRunner` to the application layer as an abstraction for
  better domain-driven design alignment.
- Refactor `SystemOperations` and related interfaces, removing the `I`
  prefix.
- Update architecture documentation for clarity.
- Update return types in `NodeSystemOperations` to match the Node APIs.
- Improve `WindowVariablesProvider` integration tests for better error
  context.
- Centralize type checks with common functions like `isArray` and
  `isNumber`.
- Change `CodeRunner` to use `os` parameter, ensuring correct window
  variable injection.
- Streamline API exposure to the renderer process:
  - Automatically bind function contexts to prevent loss of original
    context.
  - Implement a way to create facades (wrapper/proxy objects) for
    increased security.
2023-12-18 17:30:56 +01:00
undergroundwires
940febc3e8 Fix CSP for Vue, Ace, Vite, Safari compatibility
Relax Content Security Policy (CSP) to ensure essential functionality
of Vue, Ace and Vite legacy along with functioning developer experience
with macOS Safari.
2023-12-17 18:08:23 +01:00
undergroundwires-bot
3f62bb2d6e ⬆️ bump everywhere to 0.12.9 2023-12-16 03:56:16 +00:00
undergroundwires
e95b2ba217 win: add scripts to postpone auto-updates #272
This commit adds Windows update postponement techniques.

This provides users more control over the update process, aiming to
prevent automatic re-enabling of updates without user consent.

These scripts are tested and validated on Windows 10 (22H2 onwards) and
Windows 11 (22H3 onwards), introducing registry modifications for
sustained pause durations.
2023-12-16 04:10:02 +01:00
undergroundwires
20633972e9 Fix touch-enabled Chromium highlight on tree nodes
This commit resolves issues with the touch highlight behavior on tree
nodes in touch-enabled Chromium browsers (such as Google Chrome).

The fix addresses two issues:

1. Dual color transition issue during tapping actions on tree nodes.
2. Not highlighting full visible width of the node on keyboard focus.

Other changes include:

- Create `InteractableNode.vue` to centralize click styling and logic.
- Remove redundant click/hover/touch styling from `LeafTreeNode.vue` and
  `HierarchicalTreeNode.vue`.
2023-12-15 08:00:46 +01:00
undergroundwires
3457fe18cf Fix OS switching not working on tree view UI
This commit resolves a rendering bug in the tree view component.
Previously, updating the tree collection prior to node updates led to
rendering errors due to the presence of non-existent nodes in the new
collection.

Changes:

- Implement manual control over the rendering process in tree view. This
  includes clearing the rendering queue and currently rendered nodes
  before updates, aligning the rendering process with the updated
  collection.
- Add Cypress E2E tests to test switching between all operating systems
  and script views, ensuring no uncaught errors and preventing
  regression.
- Replace hardcoded operating system lists in the download URL list view
  with a unified `getSupportedOsList()` method from the application,
  reducing duplication and simplifying future updates.
- Rename `initial-nodes` to `nodes` in `TreeView.vue` to reflect their
  mutable nature.
- Centralize the function for getting operating system names into
  `OperatingSystemNames.ts`, improving reusability in E2E tests.
2023-12-14 09:51:42 +01:00
undergroundwires
fe3de498c8 win: improve disabling of Application Experience
This commit improves disabling of Application Experience component by
improving the categorization, documentation, existing scripts and adding
new scripts. It renames the scripts to be more user-friendly but still
technically accurate.

- Rename scripts to make them easier for non-technical users to
  understand.
- Improve existing documentation and add more documentation.
- Add new scripts for:
  - 'Disable "MareBackup" task'
  - 'Disable "SdbinstMergeDbTask" task'
  - 'Disable "PcaPatchDbTask" task'
- Improve `CompatTelRunner.exe` disabling to soft-delete the file.
2023-12-13 09:14:01 +01:00
undergroundwires
15134ea04b Fix tree view alignment and padding issues
This commit addresses issues with the tree view not fully utilizing the
available width (appearing squeezed on the left) on bigger screens, and
inconsistent padding during searches.

The changes centralize padding and script tree rendering logic to
enforce consistency and prevent regression.

Changes:

- Fix tree view width utilization.
- Refactor SCSS variables for better IDE support.
- Unify padding and tree background color logic for consistent padding
  and coloring around the tree component.
- Fix no padding around the tree in tree view.
- Centralize color SCSS variable for script background for consistent
  application theming.
2023-12-12 03:44:02 +01:00
undergroundwires
a9851272ae Fix touch state not being activated in iOS Safari
This commit resolves the issue with the `:active` pseudo-class not
activating in mobile Safari on iOS devices. It introduces a workaround
specifically for mobile Safari on iOS/iPadOS to enable the `:active`
pseudo-class. This ensures a consistent and responsive user interface
in response to touch states on mobile Safari.

Other supporting changes:

- Introduce new test utility functions such as `createWindowEventSpies`
  and `formatAssertionMessage` to improve code reusability and
  maintainability.
- Improve browser detection:
  - Add detection for iPadOS and Windows 10 Mobile.
  - Add touch support detection to correctly determine iPadOS vs macOS.
  - Fix misidentification of some Windows 10 Mobile platforms as Windows
    Phone.
  - Improve test coverage and refactor tests.
2023-12-11 05:24:27 +01:00
undergroundwires
916c9d62d9 Fix tooltip overflow on smaller screens
This commit addresses three main issues related to tooltips on devices
with smaller screens:

1. Fix tooltip overflow: On mobile devices, tooltips associated with
   script selection options (None, Standard, Strict, All) were
   overflowing due to inherited `white-space: nowrap` styling. This
   styling caused tooltips to render beyond screen limits. The fix
   involves applying `white-space: initial` to the tooltip overlay,
   preventing this style propagation and resolving the overflow issue.
2. Corrects tooltip arrow placement: Previously, when tooltips shifted
   from their default top position to the bottom on smaller screens,
   their arrows did not reposition accordingly. This issue was caused by
   using an incorrect reference for tooltip placement calculation. By
   updating the reference used to the one from `useFloating` function,
   the tooltip arrow now correctly aligns with the adjusted position.
3. Uniform margin handling: Enhances the margin settings around tooltips
   to maintain a consistent gap between the tooltip and the document
   edges, visible particularly on smaller screens.

Additionaly, the `DevToolkit` component has been improved for easier
testing. It is now non-interactable (except for its buttons) to prevent
it from getting in the way when testing on smaller screens. A new close
button has been added, allowing developers/testers to completely hide
the DevToolkit if desired.
2023-12-10 19:53:19 +01:00
undergroundwires
47b4823bc5 win: improve disabling update healing #272
This commit strengthens user control over the Windows Update Medic
Service (`WaaSMedicSvc`) and related components. These changes aim to
provide users with more control over Windows updates and telemetry data
shared with Microsoft, addressing privacy concerns.

Updates include:

- Soft deletion of various Windows Update Medic Service files and
  remediation files to prevent automatic re-enabling of Windows updates.
- Termination of `upfc.exe` to stop it from reactivating Windows Update
  Medic Service, thereby allowing users to maintain their desired update
  settings.
- Improving documentation with cautionary notes to guide users through
  poential impacts of these changes on system stability and update
  integrity.
- Including rationale behind the exclusion of `sedsvc`.
- Better documentation and output messages of `DisableService` function.
2023-12-09 19:30:33 +01:00
undergroundwires
c72f9f5016 win: discourage XboxIdentityProvider #64, #79 #181
Recommending the script that removes "Xbox Identity Provider" app
(`Microsoft.XboxIdentityProvider`) at the "Standard" level has led to
unforeseen consequences for Windows users using Xbox sign-in.

This commit introduces additional documentation and reduces the
recommendation level to mitigate these issues.

- Change recommendation level from "Standard" to "Strict".
- Improve documentation to outline the impact of uninstalling the "Xbox
  Identity Provider" app.
- Update script title to warn users about the breaking behavior.
2023-12-08 13:11:12 +01:00
undergroundwires
e747ee5cbc win: document and discourage admin shares #249
- Reduce recommendation level from "Standard" to "Strict" due to its
  potential breaking behavior.
- Add detailed documentation.
- Simplify script title for broader accessibility while maintaining
  technical accuracy.
- Note potential impact on remote system management in the script title.
- Adjust revert code align with recent Windows OS version.
2023-12-07 12:59:37 +01:00
undergroundwires
ba5b29a35d Improve security and privacy with strict meta tags
This commit introduces two meta tags to strengthen the application's
security posture and enhance user privacy, following best practices and
OWASP recommendations.

- Add Content-Security-Policy (CSP) to strictly to strictly control
  which resources the application is allowed, mitigating the risk of
  code injection attacks such as Cross-Site Scripting (XSS).
- Add `referrer` meta tag to prevent the users' browser from sending the
  page's address, or referrer, when navigating to another site, thereby
  enhancing user privacy.
2023-12-06 15:08:58 +01:00
undergroundwires
daa6230fc9 win: fix Win 11 Windows Security app removal #195
This commit fixes the issue of Windows Security app not being removed in
Windows 11. It addresses the problem by extending the app uninstallation
process to cover the new app package specific to Windows 11. It improves
the overall design of templated functions for store app removal to
implement the fix.

- Improve Windows Security removal script:
  - Add support for removing `Microsoft.SecHealthUI` in Windows 11.
  - Revise script documentation for clarity and correct typos.
- Redesign uninstallion of Store apps:
  - Change `UninstallSystemApp` to `UninstallNonRemovableStoreApp` for
    wider usage. This change is due to `Microsoft.SecHealthUI` being
    non-removable yet not a system app.
  - Refactor app data cleanup into two distinct functions
    (`ClearStoreAppDataBeforeUninstallation` and
    `ClearStoreAppDataAfterUninstallation`) for better clarity and
    maintainability. This also helps in testing by allowing easier
    reordering of operations.
  - Seperate between simple non-removable app uninstallation and
    uninstallation with cleanup in separate functions, highlighting that
    the latter is more invasive and should be used cautiously. This
    addresses permission issues encountered with `SecHealthUI` app
    removal during cleanup on Windows 11.
  - Separate uninstalling app and uninstalling app with cleanup to
    different functions, document that cleanup should no longer be
    prefered as it's invasive and too aggresive. Cleanup logic
    introduces permission issues/errors for `SecHealthUI` in Windows 11.
  - Extend app soft-deletion to include the default Windows app folder,
    this ensures that the cleanup covers any kind of Store apps (not
    only system apps).
2023-12-05 17:35:03 +01:00
undergroundwires
4765752ee3 Improve security and reliability of macOS updates
This commit introduces several improvements to the macOS update process,
primarily focusing on enhancing security and reliability:

- Add data integrity checks to ensure downloaded updates haven't been
  tampered with.
- Optimize update progress logging in `streamWithProgress` by limiting
  amount of logs during the download process.
- Improve resource management by ensuring proper closure of file
  read/write streams.
- Add retry logic with exponential back-off during file access to handle
  occassionally seen file system preparation delays on macOS.
- Improve decision-making based on user responses.
- Improve clarity and informativeness of log messages.
- Update error dialogs for better user guidance when updates fail to
  download, unexpected errors occur or the installer can't be opened.
- Add handling for unexpected errors during the update process.
- Move to asynchronous functions for more efficient operation.
- Move to scoped imports for better code clarity.
- Update `Readable` stream type to a more modern variant in Node.
- Refactor `ManualUpdater` for improved separation of concerns.
- Document the secure update process, and log directory locations.
- Rename files to more accurately reflect their purpose.
- Add `.DS_Store` in `.gitignore` to avoid unintended files in commits.
2023-12-04 18:28:43 +01:00
undergroundwires
25e23c89c3 win: fix revert and improve docs for SAM enum #255
- Rename script for simplicity.
- Add documentation.
- Fix default value not matching default OS state.
- Fix wrong registry path.
2023-12-03 17:07:49 +01:00
undergroundwires
08dbfead7c Centralize log file and refactor desktop logging
- Migrate to `electron-log` v5.X.X, centralizing log files to adhere to
  best-practices.
- Add critical event logging in the log file.
- Replace `ElectronLog` type with `LogFunctions` for better abstraction.
- Unify log handling in `desktop-runtime-error` by removing
  `renderer.log` due to `electron-log` v5 changes.
- Update and extend logger interfaces, removing 'I' prefix and adding
  common log levels to abstract `electron-log` completely.
- Move logger interfaces to the application layer as it's cross-cutting
  concern, meanwhile keeping the implementations in the infrastructure
  layer.
- Introduce `useLogger` hook for easier logging in Vue components.
- Simplify `WindowVariables` by removing nullable properties.
- Improve documentation to clearly differentiate between desktop and web
  versions, outlining specific features of each.
2023-12-02 11:50:25 +01:00
undergroundwires
8f5d7ed3cf win: improve documentation for "Get Help" app #280
- Update script name to mention breaking behavior.
- Add documentation to explain what the app does and how it impacts
  system functionality.
2023-12-01 14:49:24 +01:00
undergroundwires
807ae6a8f8 win: fix logic for terminating processes
This commit fixes and improves the process termination functionality in
related functions.

`KillProcessWhenItStarts` shared function:

- Fix registry key values configured by removing unnecessary single
  quotes.
- Rename to `TerminateExecutableOnLaunch` for clarity.
- Rename parameter `processName` to `executableNameWithExtension` for
  clarity.
- Add code comments.
- Document the function.
- Rename `%windir` to `%WINDIR%` for consistency in environment variable
  naming across scripts.
- Integrate `KillProcess` for robustness.
- Suppress errors in revert code to prevent false negatives.

`KillProcess` shared function to be able to support the termination:

- Rename to `TerminateRunningProcess` for clarity.
- Rename parameters for clarity and consistency:
  - `processName` to `executableNameWithExtension`.
  - `processStartPath` to `revertExecutablePath`.
  - `processStartArgs` to `revertExecutableArgs`.
- Make revert logic optional.
- Add code comments.
2023-11-30 08:15:24 +01:00
undergroundwires
5a7d7d88ff mac: improve clearing privacy permissions
- Improve the service permissions reset logic:
  - Implement more intuitive and user-friendly messages.
  - Ensure graceful handling when `tccutil` is unavailable.
  - Avoid treating unsupported service IDs as errors.
  - Introduce atemplated shared function.
- Rename 'Clear all privacy permissions for applications' to
  'Clear application privacy permissions' to enhance clarity.
- Add additional documentation.
- Introduce support for missing service permissions.
- Fix a bug where clearing "contacts" permissions inadvertently affected
  "full disk access" permissions.
- Move the option to clear all application permissions to top for
  improved accessibility.
- Standardize naming across scripts to maintain consistency and clarity.
2023-11-29 13:07:41 +01:00
undergroundwires
40ae8a8add win: improve docs and category of jump lists #146
- Add more documentation and improve existing documetation.
- Rename 'Clear most recently used (MRU) lists' to 'Clear recent
  activity logs' for simplicity.
- Move 'clearing recent activity logs' outside of 'Clear
  third-application data' to directy under 'Privacy cleanup' as these
  recent activities are not always necessarily from third-party
  applications.
- Fix dead link.

Co-authored-by: NerdyGamerB0i <85419060+NerdyGamerB0i@users.noreply.github.com>
2023-11-28 12:17:21 +01:00
undergroundwires-bot
6488e81901 ⬆️ bump everywhere to 0.12.8 2023-11-27 10:32:33 +00:00
undergroundwires
d328f08952 Fix incorrect URL rendering in documentation texts
This commit addresses incorrect URL rendering within documentation text
by improving auto-linkified URL labels, handling `+` symbols as spaces,
enhancing readability of encoded path segments and manually updating
some of the documetation.

Key improvements:

- Parse `+` as whitespace in URLs for accurate script labeling.
- Interpret multiple whitespaces as single for robustness.
- Decode path segments for clearer links.
- Refactor markdown renderer.
- Expand unit tests for comprehensive coverage.

Documentation has been updated to fix inline URL references and improve
linkification across several scripts, ensuring more readable and
user-friendly content.

Affected files and documentation sections have been adjusted
accordingly, including script and category names for consistency and
clarity.

Some of the script/category documentation changing fixing URL rendering
includes:

- 'Disable sending information to Customer Experience Improvement
  Program':
  - Fix reference URLs being inlined.
- 'Disable "Secure boot" button in "Windows Security"':
  - Fix rendering issue due to auto-linkification of `markdown-it`.
- 'Clear Internet Explorer DOMStore':
  - Fix rendering issue due to auto-linkification of `markdown-it`.
- 'Disable "Windows Defender Firewall" service':
  - Fix rendering issue due to auto-linkification of `markdown-it`.
  - Convert YAML comments to markdown comments visible by users.
  - Add breaking behavior to script name, changing script name to.
- 'Disable Microsoft Defender Firewall services and drivers':
  - Remove information about breaking behavior to avoid duplication and
    be consistent with the documentation of the rest of the collections.
- Use consistent styling for warning texts starting with `Caution:`.
- Rename 'Remove extensions' category to 'Remove extension apps' for
  consistency with names of its sibling categories.
2023-11-27 05:17:58 +01:00
undergroundwires
bcad357017 linux: fix Firefox settings not reverting #282
Improve the revert process for Firefox settings by extending
modifications to also include `prefs.js`.

- Validate profile directories similarly to execution script.
- Check and warn if Firefox is running during revert to prevent
  `prefs.js` from being overriden.
- Clarify output messages for execution and revert scripts.
- Add flowchart diagram for visual documentation.
- Improve documentation for consistency and precision.
- Update `.gitignore` to account for temporary draw.io files.
2023-11-26 01:20:21 +01:00
undergroundwires
9845a7cd68 Fix rendering of inline code blocks for docs
Styling of codeblocks:

- Uniform margins as other documentation elements.
- Add small margin for inline code-blocks.
- Use different background color for inline code-blocks.
- Introduce `inline-code` and `code-block` mixins for clarity in
  styling.

Overflowing of codeblocks:

- Improve flex layout of the tree component to be handle overflowing
  content and providing maximum available width. To be able to correctly
  provide maximum available width in card content, card expansion layout
  is changed so both close button and the content gets their full width.
- Other refactorings to support this:
  - Introduce separate Vue component for checkboxes of nodes for better
    separation of concerns and improved maintainability.
  - Refactor `LeafTreeNode` to make it simpler, separating layout concerns
    from other styling.
  - `ScriptsTree.vue`: Prefer `<div>`s instead of `<span>`s as they
    represent large content.
  - Remove unnecessary `<div>`s and use `<template>`s to reduce HTML
    complexity.
  - Update script documentation to not include unnecessary left padding
    on script code blocks.
  - Refactor SCSS variable names in `DocumentationText.vue` for clarity.
2023-11-25 11:03:33 +01:00
undergroundwires
7c632f7388 win: fix system app removal affecting updates #287
This commit fixes an issue where removing systems apps could disrupt
Windows Cumulative updates as reported in #287.

The fix involves removing the `EndOfLife` registry key after the app is
removed. Keeping the key at
`HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\EndOfLife`
was identified as the cause for update failures in #287.

This commit also refactors the registry key creation/removal logic to be
owned by separate functions for easier readability and reusability.
2023-11-24 14:52:52 +01:00
undergroundwires
1442f62633 Fix spacing in documentation for readability
This commit improves the readability of the script/category
documentations by refining the vertical and horizontal spacing. The
adjustments aim to create more visually consistent layout.

Styling changes include:

- Add more and consistent spacing between text parts (such as lists,
  tables, paragraphs etc.).
- Remove top/bottom spacing at the start and end of the text.
- Add more horizontal spacing (padding on left) for lists.
- Improve blockquote styling with a border and similar spacing as other
  parts.
2023-11-23 07:39:11 +01:00
undergroundwires
7f7a84e3ba win: discourage IntelliCode disabling #267, #286
This commit fixes issues #267 and #286 where users reported that
disabling IntelliCode data collection causes Visual Studio 2022 to hang
or become unresponsive.

The script has been updated to remove its recommendation status and
include a warning about these issues. As Microsoft did not respond to
inconsistencies with the official documentation in
MicrosoftDocs/intellicode#510, this commit prevents further disruptions
for privacy.sexy users.
2023-11-22 11:59:35 +01:00
undergroundwires
dee3279f85 win: fix persistent update disabling /w tasks #272
This patch improves the existing functionality for disabling Windows
Updates. It ensures that the disabling of automatic updates is more
persistent, addressing previous shortcomings.

This commit introduces the "Disable Windows Update scheduled tasks"
category, enabling users to persistently turn off automatic background
updates.

Supporting changes include:

- Improve `DisableScheduledTask`:
  - Add the ability to elevate privileges.
  - Add the ability to disable tasks upon script reversion to match the
    correct default operating system state.
  - Fix warning output not being correctly formatted upon script
    reversion.
- Add the ability to disable tasks upon script reversion in
  `DisableScheduledTask` to match the correct default operating system
  state.
- Add a comment to clarify the rationale behind not disabling certain
  Windows services.
- Ensure consistent casing (all uppercase) for Windows environment
  variables in documentation.
- Ensure consistent and right casing of Windows folder names in scripts
  and their documentation.
2023-11-21 05:07:43 +01:00
undergroundwires
094dbb01b8 win: fix and improve Store app categorization #190
- Remove incorrect categories and flatten their children.
- Simplify user interface by removing "installed" and "provisioned" app
  categories, listing the apps directly.
- Indent comments to be easily collapse parent category in IDE.
- Improve some of the existing documentation.
2023-11-20 11:26:14 +01:00
undergroundwires
e299d40fa1 Fix layout jumps/shifts and overflow on modals
This commit improves the user interface in modal display.

- Prevent layout shifts caused by background scrollbars when modals are
  active.
- Fix unintended overflow of modals on small screens, preventing parts
  of the modal from being cut off on the right side.
- Refactor DOM manipulation, enhancing modularity, reusability,
  extensibility, and separation of concerns.
- Centralize viewport test scenarios for different sizes in a single
  definition for E2E tests.
2023-11-19 23:51:25 +01:00
undergroundwires
cb42f11b97 Fix code highlighting and optimize category select
This commit introduces a batched debounce mechanism for managing user
selection state changes. It effectively reduces unnecessary processing
during rapid script checking, preventing multiple triggers for code
compilation and UI rendering.

Key improvements include:

- Enhanced performance, especially noticeable when selecting large
  categories. This update resolves minor UI freezes experienced when
  selecting categories with numerous scripts.
- Correction of a bug where the code area only highlighted the last
  selected script when multiple scripts were chosen.

Other changes include:

- Timing functions:
  - Create a `Timing` folder for `throttle` and the new
    `batchedDebounce` functions.
  - Move these functions to the application layer from the presentation
    layer, reflecting their application-wide use.
  - Refactor existing code for improved clarity, naming consistency, and
    adherence to new naming conventions.
  - Add missing unit tests.
- `UserSelection`:
  - State modifications in `UserSelection` now utilize a singular object
    inspired by the CQRS pattern, enabling batch updates and flexible
    change configurations, thereby simplifying change management.
- Remove the `I` prefix from related interfaces to align with new coding
  standards.
- Refactor related code for better testability in isolation with
  dependency injection.
- Repository:
  - Move repository abstractions to the application layer.
  - Improve repository abstraction to combine `ReadonlyRepository` and
    `MutableRepository` interfaces.
- E2E testing:
  - Introduce E2E tests to validate the correct batch selection
    behavior.
  - Add a specialized data attribute in `TheCodeArea.vue` for improved
    testability.
  - Reorganize shared Cypress functions for a more idiomatic Cypress
    approach.
  - Improve test documentation with related information.
- `SelectedScript`:
  - Create an abstraction for simplified testability.
  - Introduce `SelectedScriptStub` in tests as a substitute for the
    actual object.
2023-11-18 22:23:27 +01:00
undergroundwires
4531645b4c Refactor to Vue 3 recommended ESLint rules
These updates ensure better adherence to Vue 3 standards and improve
overall code quality and readability.

- Update ESLint configuration from Vue 2.x to Vue 3 rules.
- Switch from "essential" to strictest "recommended" ESLint ruleset.
- Adjust ESLint script to treat warnings as errors by using
  `--max-warnings=0` flag. This enforces stricter code quality controls
  provided by Vue 3 rules.
2023-11-17 13:57:13 +01:00
undergroundwires
bf3426f91b Fix card list UI layout shifts (jumps) on load
This commit fixes layout shifts that occur on card list part of the page
when the page is initially loaded.

- Resolve issue where card list starts with minimal width, leading
  to jumps in UI until correct width is calculated on medium and
  big screens.
- Dispose of existing `ResizeObserver` properly before creating a new
  one. This prevents leaks and incorrect width calculations if
  `containerElement` changes.
- Throttle resize events to minimize width/height calculation changes,
  enhancing performance and reducing the chances for layout shifts.

Supporting CI/CD improvements:

- Enable artifact upload in CI/CD even if E2E tests fail.
- Distinguish uploaded artifacts by operating system for clarity.
2023-11-16 16:06:33 +01:00
undergroundwires
3864f04218 win: improve disabling of scheduled tasks
This commit:

- Reduces false-positive error messages when disabling scheduled tasks.
  E.g., `ERROR: The specified task name ... does not exist in the system.`
- Centralizes and unifies the logic for disabling scheduled tasks.
- Adds additional documentation, including the existence status of tasks
  on default installations.
- Updates and improves the scripts that disable scheduled tasks.
- Improves consistency of headers in documentation text by removing the
  top margin introduces by headers.

Introduces `DisableScheduledTask` templating function:

- It provides a unified way of disabling scheduled tasks.
- It displays user-friendly messages if a task cannot be found.
- It can now handle multiple tasks found matching a pattern.
- The script now exits with the correct error code.
- It skips enable/disable actions if it's not necessary.

Improve existing scripts:

- 'Disable Google update services':
  - Rename to 'Disable Google background automatic updates'.
  - Add missing scheduled tasks observed in newer versions of Chrome.
  - Change the recommendation for disabling certain tasks to `Strict`,
    as they may interfere with Google Credential Provider as
    side-effect.
  - Separate into more categories/scripts for better granularity and
    documentation.
- 'Disable Adobe Acrobat update services':
  - Rename to 'Disable Adobe background automatic updates'.
  - Separate into more categories/scripts for enhanced granularity and
    documentation.
  - Remove end-of-life `Adobe Flash Player Updater` scheduled task and
    `adobeflashplayerupdatesvc`.
- 'Disable Dropbox automatic update services':
  - Rename to 'Disable Dropbox background automatic updates'.
  - Seperate into more categories/scripts.
- 'Disable Webcam Telemetry (`devicecensus.exe`)':
  - Rename to 'Disable census data collection'.
  - Add the disabling of the "Device User" task under it.
- 'Disable `devicecensus.exe` (telemetry) process':
  - Rename to 'Disable device and configuration data collection tool'.
- 'Disable Nvidia telemetry services':
  - Rename to 'Disable Nvidia telemetry scheduled tasks'.
  - Converted into a category for better granularity.
  - Improve documentation.
- 'Disable Defender tasks':
  - Rename to 'Disable Defender scheduled tasks'.
- 'Disable "Windows Defender ExploitGuard" task':
  - Rename to 'Disable "ExploitGuard MDM policy Refresh" task'.
- 'Remove Nvidia telemetry tasks':
  - Rename to 'Remove Nvidia telemetry packages', as "tasks" often
    refers to scheduled tasks.
- 'Disable Microsoft Office Subscription Heartbeat'
  - Rename to 'Disable "Microsoft Office Subscription Heartbeat" task'.
  - Remove disabling of the undocumented `Office 16 Subscription
    Heartbeat` task.
- 'Disable OneDrive scheduled tasks':
  - Improve documentation.
  - Add disabling of 'OneDrive Per-Machine Standalone Update' task.
- 'Disable Customer Experience Improvement Program'
  - Rename to 'Disable "Customer Experience Improvement Program"
    scheduled tasks' for clarity.
2023-11-15 21:30:42 +01:00
undergroundwires
e541a35e86 Fix mobile layout overflow caused by tooltips
This commit fixes an issue where tooltips create unwanted horizontal
overflow on mobile devices.

An overlay has been added to contain the tooltip within the viewport,
ensuring it doesn't disrupt the page layout.

The changes include adjustments to CSS visibility and pointer event
handling for the tooltip container and its children.

Changes:

- Introduce an overlay that spans the entire viewport for the tooltip
  container.
- Add CSS rules to ensure the tooltip and its children maintain correct
  pointer events and overflow behavior.
- Add a Cypress end-to-end test that verifies the absence of the
  unintended horizontal overflow on small screens.
- Uploads videos/screenshots as artifacts during CI/CD to provide easier
  troubleshooting. This change is supported by creating
  `cypress-dirs.json` to be able to share directory information with
  CI/CD runners and cypress configuration file.
2023-11-14 13:46:53 +01:00
undergroundwires
bd383ed273 Fix icon tooltip alignment on instructions modal
This commit fixes a UI misalignment issue for toolips in the download
instructions modal.

The existing margin on icons caused tooltips to be misaligned upon hover
or touch.

Changes include:

- Introduce wrapper elements to encapsulate the margin, ensuring
  tooltips align with the corresponding icons.
- Extract the information incon into a separate Vue component to adhere
  to the single-responsibility principle and improve maintainability.
- Remove redundant newline at the end of 'Open terminal' tooltip to
  reduce the visual clutter.
2023-11-13 19:02:14 +01:00
undergroundwires
949fac1a7c Refactor to enforce strictNullChecks
This commit applies `strictNullChecks` to the entire codebase to improve
maintainability and type safety. Key changes include:

- Remove some explicit null-checks where unnecessary.
- Add necessary null-checks.
- Refactor static factory functions for a more functional approach.
- Improve some test names and contexts for better debugging.
- Add unit tests for any additional logic introduced.
- Refactor `createPositionFromRegexFullMatch` to its own function as the
  logic is reused.
- Prefer `find` prefix on functions that may return `undefined` and
  `get` prefix for those that always return a value.
2023-11-12 22:54:00 +01:00
undergroundwires
7ab16ecccb Refactor watch sources for reliability
This commit changes `WatchSource` signatures into `Readonly<Ref>`s.

It provides two important benefits:

1. Eliminates the possibility of `undefined` states, that's result of
   using `WatchSource`s. This previously required additional null checks.
   By using `Readonly<Ref>`, the state handling becomes simpler and less
   susceptible to null errors.
2. Optimizes performance by using references:
   - Avoids the reactive layer of `computed` references when not needed.
   - The `watch` syntax, such as `watch(() => ref.value)`, can introduce
     side effects. For example, it does not account for `triggerRef` in
     scenarios where the value remains unchanged, preventing the watcher
     from running (vuejs/core#9579).
2023-11-11 13:55:21 +01:00
undergroundwires
58cd551a30 Refactor user selection state handling using hook
This commit introduces `useUserSelectionState` compositional hook. it
centralizes and allows reusing the logic for tracking and mutation user
selection state across the application.

The change aims to increase code reusability, simplify the code, improve
testability, and adhere to the single responsibility principle. It makes
the code more reliable against race conditions and removes the need for
tracking deep changes.

Other supporting changes:

- Introduce `CardStateIndicator` component for displaying the card state
  indicator icon, improving the testability and separation of concerns.
- Refactor `SelectionTypeHandler` to use functional code with more clear
  interfaces to simplify the code. It reduces complexity, increases
  maintainability and increase readability by explicitly separating
  mutating functions.
- Add new unit tests and extend improving ones to cover the new logic
  introduced in this commit. Remove the need to mount a wrapper
  component to simplify and optimize some tests, using parameter
  injection to inject dependencies intead.
2023-11-10 13:16:53 +01:00
undergroundwires
7770a9b521 Refactor DI for simplicity and type safety
This commit improves the dependency injection mechanism by introducing a
custom `injectKey` function.

Key improvements are:

- Enforced type consistency during dependency registration and
  instantiation.
- Simplified injection process, abstracting away the complexity with a
  uniform API, regardless of the dependency's lifetime.
- Eliminated the possibility of `undefined` returns during dependency
  injection, promoting fail-fast behavior.
- Removed the necessity for type casting to `symbol` for injection keys
  in unit tests by using existing types.
- Consalidated imports, combining keys and injection functions in one
  `import` statement.
2023-11-09 13:17:38 +01:00
undergroundwires
aab0f7ea46 Remove duplicated index.html file
This commit removes the redundant `index.html` file from the
`src/presentation/public` directory. This file was initially created
there with Vue CLI before migration to Vite. The existence of this file
is now unnecessary as Vite requires `index.html` to be at the project
root.

The deletion of this duplicate file simplifies the project and
eliminates potential confusion regarding the entry point of the
application.

Changes:

- Update `docs/presentation.md` to clarify the location of `index.html`.
- Remove the `src/presentation/public/index.html` file, which was
  duplicate of the project root `index.html`.

These changes ensure compliance with Vite's configuration and project
structure clarity.
2023-11-08 17:06:53 +01:00
undergroundwires-bot
ea41f4f503 ⬆️ bump everywhere to 0.12.7 2023-11-07 01:06:52 +00:00
undergroundwires
af7219f6e1 Fix tree node check states not being updated
This commit fixes a bug where the check states of tree nodes were not
correctly updated upon selecting predefined groups like "Standard",
"Strict", "None" and "All".

It resolves the issue by manually triggering of updates for mutated
array containing selected scripts.

It enhances test coverage to prevent regression and verify the correct
behavior of state updates.

This bug was introduced in commit
4995e49c46, which optimized reactivity by
removing deep state tracking.
2023-11-07 01:14:38 +01:00
undergroundwires
8ccaec7af6 Fix unresponsive copy button on instructions modal
This commit fixes the bug where the "Copy" button does not copy when
clicked on download instructions modal (on Linux and macOS).

This commit also introduces several improvements to the UI components
related to copy action and their interaction with the clipboard feature.

It adds more tests to avoid regression of the bugs and improves
maintainability, testability and adherence to Vue's reactive principles.

Changes include:

- Fix non-responsive copy button in the download instructions modal by
  triggering a `click` event in `AppIcon.vue`.
- Improve `TheCodeButtons.vue`:
  - Remove redundant `getCurrentCode` function.
  - Separate components for each button for better separation of
    concerns and higher testability.
  - Use the `gap` property in the flexbox layout, replacing the less
    explicit sibling combinator approach.
- Add `useClipboard` compositional hook for more idiomatic Vue approach
  to interacting with the clipboard.
- Add `useCurrentCode` compositional hook to handle current code state
  more effectively with unified logic.
- Abstract clipboard operations to an interface to isolate
  responsibilities.
- Switch clipboard implementation to the `navigator.clipboard` API,
  moving away from the deprecated `document.execCommand`.
- Move clipboard logic to the presentation layer to conform to
  separation of concerns and domain-driven design principles.
- Improve `IconButton.vue` component to increase reusability with
  consistent sizing.
2023-11-06 21:55:43 +01:00
undergroundwires
b2ffc90da7 Add winget download instructions 2023-11-05 17:05:17 +01:00
undergroundwires-bot
72e4d0b896 ⬆️ bump everywhere to 0.12.6 2023-11-04 12:14:46 +00:00
undergroundwires
5bb13e34f8 win: fix store revert for multiple installs #260
This commit improves the revert script for store apps to handle
scenarios where `Get-AppxPackage` returns multiple packages. Instead of
relying on a single package result, the script now iterates over all
found packages and attempts installation using the `AppxManifest.xml`
for each. This ensures that even if multiple versions or instances of a
package are found, the script will robustly handle and attempt to install
each one until successful.

Other changes:

- Add better message with suggestion if the revert code fails, as
  discussed in #270.
- Improve robustness of finding manifest path by using `Join-Path`
  instead of basic string concatenation. This resolves wrong paths being
  built due to missing `\` in file path.
- Add check for null or empty `InstallLocation` before accessing
  manifest path. It prevents errors when accessing `AppxManifest.xml`,
  enhancing script robustness and reliability.
- Improve error handling in manifest file existence check with try-catch
  block to catch and log exceptions, ensuring uninterrupted script
  execution in edge cases such as when the script lacks access to read
  the directory.
- Add verification of package installation before attempting to install
  the package for increased robustness.
- Add documentation for revertCode.
2023-11-03 15:24:15 +01:00
undergroundwires
0466b86f10 win, linux: unify & improve Firefox clean-up #273
This commit unifies some of the logic, documentation and naming for
Firefox clean-up with improvements on both Linux and Windows platforms.

Windows:

- 'Clear browsing history and cache':
  - Not recommend.
  - Align script name and logic with Linux implementation.
  - New documentation and not including the script in recommendation
    provides safety against unintended data loss as discussed in #273.
- 'Clear Firefox user profiles, settings, and data':
  - Rename to 'Clear all Firefox user information and preferences' for
    improved clarity.
  - Add more documentation.

Linux:

- Replace `DeleteFromFirefoxProfiles` with
  `DeleteFilesFromFirefoxProfiles`.
- Migrate implementation to Python:
  - Add more user-friendly outputs.
  - Exclude removing directory itself for additional safety.

Both Linux and Windows:

- Improve documentation for:
  - 'Clear Firefox user profiles, settings, and data'
  - 'Clear Firefox history'
2023-11-02 13:18:54 +01:00
undergroundwires
ca81f68ff1 Migrate to Vue 3.0 #230
- Migrate from "Vue 2.X" to "Vue 3.X"
- Migrate from "Vue Test Utils v1" to "Vue Test Utils v2"

Changes in detail:

- Change `inserted` to `mounted`.
- Change `::v-deep` to `:deep`.
- Change to Vue 3.0 `v-modal` syntax.
- Remove old Vue 2.0 transition name, keep the ones for Vue 3.0.
- Use new global mounting API `createApp`.
- Change `destroy` to `unmount`.
- Bootstrapping:
  - Move `provide`s for global dependencies to a bootsrapper from
    `App.vue`.
  - Remove `productionTip` setting (not in Vue 3).
  - Change `IVueBootstrapper` for simplicity and Vue 3 compatible API.
  - Add missing tests.
- Remove `.text` access on `VNode` as it's now internal API of Vue.
- Import `CSSProperties` from `vue` instead of `jsx` package.
- Shims:
  - Remove unused `shims-tsx.d.ts`.
  - Remove `shims-vue.d.ts` that's missing in quickstart template.
- Unit tests:
  - Remove old typing workaround for mounting components.
  - Rename `propsData` to `props`.
  - Remove unneeded `any` cast workarounds.
  - Move stubs and `provide`s under `global` object.

Other changes:

- Add `dmg-license` dependency explicitly due to failing electron builds
  on macOS (electron-userland/electron-builder#6520,
  electron-userland/electron-builder#6489). This was a side-effect of
  updating dependencies for this commit.
2023-11-01 13:39:39 +01:00
undergroundwires
4995e49c46 Improve UI performance by optimizing reactivity
- Replace `ref`s with `shallowRef` when deep reactivity is not needed.
- Replace `readonly`s with `shallowReadonly` where the goal is to only
  prevent `.value` mutation.
- Remove redundant `ref` in `SizeObserver.vue`.
- Remove redundant nested `ref` in `TooltipWrapper.vue`.
- Remove redundant `events` export from `UseCollectionState.ts`.
- Remove redundant `computed` from `UseCollectionState.ts`.
- Remove `timestamp` from `TreeViewFilterEvent` that becomes unnecessary
  after using `shallowRef`.
- Add missing unit tests for `UseTreeViewFilterEvent`.
- Add missing stub for `FilterChangeDetails`.
2023-10-31 13:57:57 +01:00
undergroundwires
77123d8c92 win: change system app removal to hard delete #260
This commit changes the system app removal functionality in privacy.sexy
to perform a hard delete, while preserving the soft-delete logic for
handling residual files.

It improves in-code documentation to facilitate a clearer understanding
of the code execution flow, as the logic for removing system apps has
grown in complexity and length.

Transitioning to a hard-delete approach resolves issues related to
residual links to soft-deleted apps:

- Resolves issue with Edge remaining in the installed apps list (#236).
- Resolves issue with Edge remaining in the programs list (#194).
- Resolves issue with Edge shortcuts persisting in the start menu (#73).

Other changes:

- `RunPowerShell`:
  - Introduce `codeComment` and `revertCodeComment` parameters for
    improved in-code documentation.
- `CommentCode`:
  - Simplify naming to `Comment`.
  - Rename `comment` to `codeComment` for clarity.
  - Add functionality to comment on revert with the `revertCodeComment`
    parameter.
2023-10-30 12:39:10 +01:00
undergroundwires
e72c1c13ea win: improve file delete
This commit unifies the way the files are being deleted by introducing
the `DeleteFiles` function. It refactors existing scripts that are
deleting files to use the new function, to improve their documentation
and increase their safety.

Script changes:

- 'Clear Software Reporter Tool logs':
  - Rename to: 'Clear Google's "Software Reporter Tool" logs'
- 'Clear credentials in Windows Credential Manager':
  - Migrate code to PowerShell, removing the need to delete files.
  - Improve error messages and robustness of the implementation.
- 'Clear Nvidia residual telemetry files':
  - Extract to two scripts for more granularity and better
    documentation:
      1. 'Disable Nvidia telemetry components'
      2. 'Disable Nvidia telemetry drivers'
  - Change the logic so instead of clearing directory contents and
    deleting drivers, it conducts a soft delete for reversibility to
    prioritize user safety.
- 'Remove OneDrive residual files':
  - Improve documentation
- 'Clear primary Windows telemetry file':
  - Rename to 'Clear diagnostics tracking logs'.
  - Add missing file paths seen on modern versions of Windows.
  - Add more documentation.
- 'Clear Windows Update History (`WUAgent`) system logs':
  - Rename to 'Clear Windows update files'.
  - Add more documentation.
- 'Clear Cryptographic Services diagnostic traces':
  - Rename to 'Clear "Cryptographic Services" diagnostic traces'.
  - Add more documentation.

Other changes:

- Improve `DeleteGlob`:
  - Add iteration callbacks for its reusability.
  - Improve its documentation.
  - Make recursion optional.
  - Improve sanity check (verification) logic for given glob when
    granting permissions.
  - Fix granting permissions using wrong variable to find out parent
    directory.
- Improve `IterateGlob`:
  - Use `Get-Item` to get results. This fixes `DeleteDirectory` not
    being able to delete directory itself but just its contents.
  - Introduce and use `recurse` parameter to provide optional recursive
    search logic (to search in subdirectories) using `Get-ChildItem`.
  - Fix wrong PowerShell syntax for `$revert` variable value for
    `revertCode`: replace `true` with `$true`.
  - Order iterated paths based on their length to process the deepest
    item first.
  - Improve handling of missing files with correct/informative outputs
    when granting permissions.
- Improve `SoftDeleteFiles`:
  - Introduce and use `recurse` parameter for explicitness.
  - Fix undefined `$backupFilePath` by replacing it with correct
    `$originalFilePath`.
  - Improve documentation.
- Ensure consistent use of instructive language in code comments.
2023-10-29 18:42:41 +01:00
undergroundwires
e775d68a9b linux: fix string formatting of Firefox configs
This commit fixes some configurations being set wrong values to wrong
YAML notation used for string values.
2023-10-28 13:58:41 +02:00
undergroundwires
f8e5f1a5a2 Fix incorrect tooltip position after window resize
This commit fixes an issue where the tooltip position becomes inaccurate
after resizing the window.

The solution uses `autoUpdate` functionality of `floating-ui` to update
the position automatically on resize events. This function depends on
browser APIs: `IntersectionObserver` and `ResizeObserver`. The official
documentation recommends polyfilling those to support old browsers.

Polyfilling `ResizeObserver` is already part of the codebase, used by
`SizeObserver.vue`. This commit refactors polyfill logic to be reusable
across different components, and reuses it on `TooltipWrapper.vue`.

Polyfilling `IntersectionObserver` is ignored due to this API being
older and more widely supported.
2023-10-27 20:58:07 +02:00
undergroundwires
f4a74f058d win: improve soft file/app delete security #260
This commit improves soft file delete logic:

- Unify logic for soft deleting single files and system apps.
- Rename `RenameSystemFile` templating function to `SoftDeleteFiles` so
  new name gives clarity to:
   - It's not necessarily single file being renamed but can be multiple
     files.
   - It's not necessarily system files being renamed, but can also work
     without granting extra permissions.
- Grant permissions for only files that will be backed up, skipping
  unnecessarily granting permissions to folders/other files. Both
  `SeRestorePrivilege` and `SeTakeownershipPrivileges` are claimed and
  revoked as necessary.
- Make granting permissions optional through `grantPermissions`
  parameter. Do not take permissions if not needed.
- Restore permissions to system default after file is renamed. Before
  both deletion of system apps and renaming system files did not restore
  their original permissions. This might leave user computers
  vulnerable, which is fixed in this commit. It ensures that the
  system's original security posture is preserved.
- Deleting system apps is now independent of `Get-AppxPackage`,
  improving its robustness and enabling their execution once system apps
  are hard-deleted (#260)
- Introduce common way to share glob iteration logic of how the
  directories are being cleaned up. It reuses most of the logic from
  former `DeleteGlob` with some improvements:
  - Simplify call to `Get-ChildItem` by avoiding `-Filter` parameter.
  - Improve reliability of getting parent directory in `DeleteGlob`
    sanity check to use .NET's `[System.IO.Path]` methods.
2023-10-26 18:35:39 +02:00
undergroundwires
80821fca07 Fix compiler failing with nested with expression
The previous implementation of `WithParser` used regex, which struggles
with parsing nested structures correctly. This commit improves
`WithParser` to track and parse all nested `with` expressions.

Other improvements:

- Throw meaningful errors when syntax is wrong. Replacing the prior
  behavior of silently ignoring such issues.
- Remove `I` prefix from related interfaces to align with newer code
  conventions.
- Add more unit tests for `with` expression.
- Improve documentation for templating.
- `ExpressionRegexBuilder`:
  - Use words `capture` and `match` correctly.
  - Fix minor issues revealed by new and improved tests:
     - Change regex for matching anything except surrounding
       whitespaces. The new regex ensures that it works even without
       having any preceeding text.
     - Change regex for capturing pipelines. The old regex was only
       matching (non-greedy) first character of the pipeline in tests,
       new regex matches the full pipeline.
- `ExpressionRegexBuilder.spec.ts`:
  - Ensure consistent way to define `describe` and `it` blocks.
  - Replace `expectRegex` tests, regex expectations test internal
    behavior of the class, not the external.
  - Simplified tests by eliminating the need for UUID suffixes/prefixes.
2023-10-25 19:39:12 +02:00
undergroundwires
dfd4451561 win: improve script environment robustness #221
This commit ensures the script functions as expected, even when invoked
from unexpected environments.

Using `setlocal` initializes a distinct environment for privacy.sexy.
It's strategically placed after the admin privilege check to avoid
unnecessary setup in case of a relaunch. The script concludes with
`endlocal` right before the exit, maintaining a clean environment
throughout its execution and ensuring no unintentional global
environment modifications.

Changes:

- Enhance script's environment robustness.
- Add descriptive comments for script start/end sequences.
2023-10-24 16:56:54 +02:00
undergroundwires
8570b02dde win: prevent updates from reinstalling apps #260
This commit addresses the issue of unwanted applications being
reinstalled during a Windows update. By adding a specific registry
entry, this commit ensures that Windows apps, once removed, do not
return with subsequent updates.

This change ensures more control over the applications present on a
Windows system, particularly after an update, enhancing user experience
and systeam cleanliness.
2023-10-23 16:52:52 +02:00
undergroundwires
d6da406c61 Centralize Electron entry file path configuration
This commit refactors configuration to use centrally defined Electron
entry file path to improve maintainability and reduce duplication.

- Replace the hardcoded file path in the `main` field of `package.json`
  with a reference to the `ELECTRON_ENTRY` environment variable, managed
  by `electron-vite`.
- Update `electron-vite` to version 1.0.28, enabling the use of
  `ELECTRON_ENTRY` environment variable feature (details in
  alex8088/electron-vite#270).
2023-10-22 15:03:58 +02:00
undergroundwires
060e789662 win: improve directory cleanup security
This commit improves the security, reliability, and robustness of
directory cleanup operations on Windows.

The focus is shifted from deleting entire directories to purging their
contents, addressing potential unintended side effects. Previously,
numerous directories were removed, which could destabilize system
behavior.

This improvement has crucial security implications. The prior approach
involved changing ownership and assigning permissions to the directory
itself, leading to an altered and potentially less secure OS security
posture.

Directory removal improvements include:

- Output user-friendly messages.
- Improved ownership and permission handling for file deletion.
- Explicit shared functions for enhanced reliability/security.
- Centralized way to delete glob (wildcard) patterns in Windows.
Notable script improvements:

- 'Clear Steam dumps, logs, and traces':
  - Convert the script to a category to provide more granularity.
  - Improve cache cleaning, ensuring the entire cache directory is
    cleared, not just the log files.
- 'Clear "Temporary Internet Files" (browser cache)':
  - Add more documentation.
  - Grant necessary permissions to folders, fixing errors due to
    lack of permissions before.
- 'Clear Windows Update Medic Service logs':
  - Remove redundant permission grants, as they are unnecessary in
    recent Windows versions.
- 'Clear Server-initiated Healing Events system logs',
  'Clear Windows Update events logs':
  - Merge due to identical functionalities.
  - Add more documentation.
- 'Clear Defender scan (protection) history':
  - Remove the execution with `TrustedInstallerPrivileges`, uniformly
    using `grantPermissions` as with other scripts. This addresses the
    false-positive alerts from Microsoft Defender, as discussed in #264.
- 'Clear "Temporary Internet Files" (browser cache)':
  - Retain `INetCache` and `Temporary Internet Files` directories,
    purging only their contents. This approach aims to resolve the issue
    mentioned in #145, where the absence of these folders could prevent
    Microsoft Office applications from launching.
2023-10-21 17:41:37 +02:00
undergroundwires
e40b9a3cf5 win: fix Microsoft Advertising app removal #200
This commit fixes the issue where the Microsoft Advertising app fails to
be removed using the standard script. The problem is due to Microsoft
Advertising SDK (`Microsoft.Advertising.Xaml`) acting as a framework
package. Such packages are automatically installed when a specific
application requires them, and they cannot be individually removed if
there are applications that depend on them. The only way to effectively
remove this library is by uninstalling the dependent applications.

Key findings:

- On Windows 11 22H2, the issue does not arise as the package does not
  exist.
- On Windows 10 22H2, the user is prompted to delete dependent
  applications, like MSN Weather and Mail And Calendar apps. Once these
  apps are removed, the Microsoft Advertising app is automatically
  removed.

Given the nuances and potential for confusion, this script is removed.
This means that the app will no longer be removed directly but will be
handled as part of the removal of its dependencies.
2023-10-20 16:04:25 +02:00
undergroundwires
237d9944f9 Fix YAML error for site release in CI/CD
Fix the syntax error in the GitHub action script that was caused by
improper multi-line YAML notation. This correction ensures the action
can successfully parse and execute.
2023-10-19 12:33:26 +02:00
undergroundwires
79b46bf210 Improve performance of rendering during search
Optimize the tree view rendering during searches by enhancing the render
queue ordering. This update changes the rendering order to prioritize
visible nodes, leading to faster appearance of these nodes during
searches. The ordering logic now ignores the depth in the hierarchy and
instead focused on the node order. The collapsed check for the node
itself is removed, ensuring that visible collapsed parents are first
while their invisible children are rendered later.
2023-10-18 16:44:49 +02:00
undergroundwires
98a26f9ae4 win: improve system app uninstall /w fallback #260
This commit improves soft deletion of system apps. Before if the package
was missing, it failed to recover or delete system apps. Now, it works
even though if `Get-AppxPackage` returns null (i.e. package is
non-existing), so it can be executed even after a hard delete. This
allows safely introducing hard-delete of system apps (as discussed in
 #260) with still keeping a robust soft-delete as complement.

Before, the script was dependent on `Get-AppxPackage.InstallLocation`,
however a system app can only be located in one of these folders:

- C:\Windows\SystemApps\{PackageFamilyName}
- C:\Windows\{ShortAppName}

To ensure resilience, this commit adjust the script to rename the files
within these directories if Get-AppxPackage fails, this provides a
fallback.
2023-10-17 13:56:32 +02:00
undergroundwires
dbe3c5cfb9 win: improve system app uninstall cleanup #73
- Add documentation about folders.
- Add more user-friendly logging.
- Continue uninstallation if single folder fails (remove throw).
- Continue uninstallation if renaming single file fails.
- Add handling of `Metadata` folder as suggested in #73.
2023-10-16 18:42:29 +02:00
undergroundwires
25d7f7b2a4 Bump dependencies to latest
This commit updates various dependencies to their latest versions.

Other changes include:

- Moved the following from `devDependencies` to `dependencies`:
  - `electron-log`
  - `electron-updater`
- Remove `npm` dependency.
- Code changes:
  - Add type casting in several places to align with the latest
    `typescript` version.
  - Adopt to new return type of `setTimeout`.
- Dependencies not upgraded due to
  `@vue/eslint-config-airbnb-with-typescript` not supporting
  `@eslint-typescript` V6 (see vuejs/eslint-config-airbnb#58):
  - `vue/eslint-config-typescript`
  - `@typescript-eslint/eslint-plugin`
  - `@typescript-eslint/parser`
- Enable video recording for cypress as it's disabled by default since
  13.X.X.
2023-10-16 02:06:19 +02:00
undergroundwires-bot
b76e99ac0f ⬆️ bump everywhere to 0.12.5 2023-10-14 14:17:25 +00:00
undergroundwires
67c3677621 win, linux, mac: fix typos and improve naming
- Use instruction format such as "do this, do that" to provide clear,
  direct instructions. This format minimize confusion and is easy to
  follow. They are specific and leave no room for interpretation,
  stating precisely what needs to be done without ambiguity.
- Fix typos and grammar issues.
- Improve consistency in script and category names.
- Revise sentences for more natural English language flow.
- Change brand name casing to match official branding.
- Change title case (all words start capitalized) to sentence case.
- Prioritize consistency over variations.
- Add minor documentation to explain scripts where the names are not
  clear.
- Add naming guidelines.
2023-10-13 20:14:33 +02:00
undergroundwires
bab6316e76 win: fix and improve AppCompat disabling #255
- Introduce a new parent category: 'Disable Application Compatibility
  framework" for better categorization.
- Move following existing scripts under the new category:
  - Disable Application Impact Telemetry (AIT)
  - Disable steps recorder
  - Disable Inventory Collector
  - Program Compatibility Assistant Service
- Add new scripts new scripts within the same category:
  - Disable Application Compatibility Engine
  - Disable "Program Compatibility Assistant (PCA)" feature
  - Disable "Program Compatibility Assistant Service" (`PcaSvc`)
- Add missing revert codes for:
  - 'Disable steps recorder'
- Fix revert codes for scripts:
  - 'Disable Inventory Collector'
  - 'Disable Application Impact Telemetry (AIT)' (as pointed in #255).
- Add extensive documentation for all related scripts.
- Rename scripts for clarity:
  - 'Disable Inventory Collector' > 'Disable "Inventory Collector"
    task'.
  - 'Program Compatibility Assistant Service' > 'Disable "Program
    Compatibility Assistant Service" (`PcaSvc`) service'.
  - 'Disable steps recorder' > 'Disable Steps Recorder (collects
    screenshots, mouse/keyboard input and UI data)'.
2023-10-12 14:49:35 +02:00
undergroundwires
48730bca05 Implement new UI component for icons #230
- Introduce `AppIcon.vue`, offering improved performance over the
  previous `fort-awesome` dependency. This implementation reduces bundle
  size by 67.31KB (tested for web using `npm run build -- --mode prod`).
- Migrate Font Awesome 5 icons to Font Awesome 6.

This commit facilitates migration to Vue 3.0 (#230) and ensures no Vue
component remains tightly bound to a specific Vue version, enhancing
code portability.

Font Awesome license is not included because Font Awesome revokes its
right:

> "Attribution is no longer required as of Font Awesome 3.0"
>
> Sources:
>
> - https://fontawesome.com/v4/license/ (archived: https://web.archive.org/web/20231003213441/https://fontawesome.com/v4/license/, https://archive.ph/Yy9j5)
> - https://github.com/FortAwesome/Font-Awesome/wiki (archived: https://web.archive.org/web/20231003214646/https://github.com/FortAwesome/Font-Awesome/wiki, https://archive.ph/C6sXv)

This commit removes following third-party production dependencies:

- `@fortawesome/vue-fontawesome`
- `@fortawesome/free-solid-svg-icons`
- `@fortawesome/free-regular-svg-icons`
- `@fortawesome/free-brands-svg-icons`
- `@fortawesome/fontawesome-svg-core`
2023-10-11 18:38:19 +02:00
undergroundwires
698b570ee6 Fix working directory in CI/CD web release
This commit fixes the CI/CD website release process which was failing
due to an incorrect working directory setting. The `working-directory`
is now correctly set within the action workflow, ensuring the `npm run
install-deps` command runs in project root directory where
`package.json` exists.
2023-10-10 15:37:59 +02:00
undergroundwires
a3f11dff18 win: improve app reversion and docs #260
This commit prepares for #260, aiming for a hard delete of system apps,
and necessitating a more reliable app reversion method.

- Improve documentation:
  - Add existence status for latest OS versions.
  - Add command for quick future testing.
  - Use archive links.
  - Document categories.
  - Add documentation to list of default apps to give context about why
    the package is here.
  - Fix wrong store URL for Cortana app.
  - Unify documentation of excluded apps.
- Fix categorization:
  - Categorize uninstallation of Windows store apps.
  - Remove "Zune" category (flatten children apps) to be able to align
    with latest branding.
  - Categorize uninstallation of Candy Crush apps.
  - Categorize uninstallation of OOBE apps.
- Rename:
  - "Uninstall Windows store apps" to "Uninstall Windows apps" as these
    apps are not necessarily store apps.
  - "Xbox Game Bar Plugin appcache" to "Xbox Game Bar Plugin".
  - "Groove Music" to "Windows Media Player".
  - "Movies and TV" to "Movies & TV".
  - "Your Phone" to "Phone Link".
  - "Cred Dialog Host" to "Credentials Dialog Host".
  - "Windows Voice Recorder" to "Windows Sound Recorder".
  - "Remote Desktop" to "Microsoft Remote Desktop"
  - "Microsoft To Do" to "Microsoft To Do: Lists, Tasks & Reminders".
  - "People Hub app (People Experience Host)" to "People Hub app".
  - "My Office" to "Microsoft 365 (Office)".
  - "iHeartRadio" to "iHeart: Radio, Music, Podcasts".
  - "Duolingo" to "Duolingo - Language Lessons".
  - "Photoshop Express" to "Adobe Photoshop Express".
  - "Spotify" to "Spotify - Music and Podcasts".
  - "Windows Alarms and Clock" to "Windows Clock".
  - "OOBE Network Captive Port" to "OOBE Network Captive Portal".
  - "Secure Assessment Browser app (breaks Microsoft Intune/Graph)" to
    "Take a Test app".
  - "Windows 10 Family Safety / Parental Controls" > "Microsoft Family
    Safety / Parental control".
  - "People / People Bar App on taskbar (People Experience Host)" > "My
    People"
  - "MSN News" > "Microsoft News"
  - "Minecraft for Windows 10" > "Minecraft for Windows"
  - "Snip & Sketch" > "Snipping Tool"
  - "Bio enrollment" > "Hello setup UI"
- Fix package names for:
  - `AdobeSystemIncorporated.AdobePhotoshop` >
    `AdobeSystemsIncorporated.AdobePhotoshopExpress`
2023-10-09 16:21:26 +02:00
undergroundwires
5e359c2fb8 win: fix and improve network data usage reset #265
Fix `Clear (Reset) Network Data Usage` trying to delete other files from
Windows system directory.

Changes:

- Precisely target the deletion of `C:\System32\sru\SRUDB.dat`.
- Improve documentation.
- Handle explicitly and better if `DPS` service is missing.
- Rename script from `Clear (Reset) Network Data Usage` to `Clear System
  Resource Usage Monitor (SRUM) data` for clearer representation.
- Migrate script from batchfile to PowerShell for better
  maintainability and readability.
- Add user-friendly output messages.
- Improve script logic to avoid unnecessary service start/stop when the
  file doesn't exist.
2023-10-08 15:55:06 +02:00
undergroundwires
2147eae687 Add developer toolkit UI component
The commit adds a new a UI component that's enabled in development mode.
This component, initially, provides a button that wen clicked, logs all
the script and category names to the console. It helps revising names
used throughout the application.

By having this component in a conditionally rendered component, it's
excluded from the production builds.
2023-10-07 15:14:53 +02:00
undergroundwires
286295128d win: relocate and document SecHealthUI #190
- Move removal of `SecHealthUI` app to "Privacy over security" category.
- Emphasize disruptive behavior in the script name.
- Add comprehensive documentation
2023-10-06 14:02:11 +02:00
undergroundwires
8501495c17 win: improve Edge & OneDrive shortcut removal #73
- Add script to remove Edge shortcuts upon uninstallation.
- Unify OneDrive shortcut removal logic with Edge's, introducing revert
  feature to the OneDrive removal script.
- Add more extensive documentation.
- Rename "Delete OneDrive shortcuts" to "Remove OneDrive shortcuts" to
  have consistent naming.
2023-10-05 11:50:21 +02:00
undergroundwires
888c9166fc win: add removal of Edge assocations #64
This commit introduces scripts for cleaning up file and URL associations
related to Microsoft Edge, enhancing the uninstallation process. The
changes adress the issues detailed in #64, improving system reliability,
integrity and security by preventing lingering associations.

Changes include:

- Introduce scripts to clear Edge browser file and URL associations.
- Provide extensive documentation for related scripts.
- Ensure thorough cleanup of URL, file, OpenWith menu, and toast
  associations.
- Recommend removing Microsoft Edge (Legacy) Dev Tools Client app on
  Strict to align with other Edge legacy removal recommendations.
2023-10-04 11:22:47 +02:00
undergroundwires
e5f6edf405 linux: fix obsolete Firefox DPI script #239
- Replace obsolete "Firefox First party isolation" with "Firefox state
  partitioning".
- Add comprehensive documentation for the new scripts.
- Introduce enabling dynamic First-Party Isolation (dFPI)
- Disable deprecated First-Party Isolation (FPI) to avoid conflicts with
  dFPI.
- Add script to enable Firefox network partitioning to cover
  functionality of older FPI script.
2023-10-03 12:36:06 +02:00
undergroundwires
e8a52f717d win, linux: improve VSCode setting robustness #196
This commit enhances the robustness of setting VSCode configurations,
ensuring consistent and reliable operation even in edge cases, such as
when the settings file is empty. This commit also uniforms behavior of
Linux and Windows modification of VSCode settings.

On Windows:

- Move parameters to on top of scripts to be able to easily test the
  scripts using PowerShell without compiling.
- Add a check to exit the script with an error message if the attempt to
  parse the JSON content fails.
- Omit the `OutString` cmdlet from the pipeline in the script for
  converting JSON file content to a PowerShell object. `Out-String` is
  unnecessary in this context because `Get-Content` already outputs the
  file content as a string array, which `ConvertFrom-Json` effectively.
  Additionally, using `Out-String` could potentially introduce issues by
  concatenating file content into a single string, causing
  `ConvertFrom-Json` to fail when processing pretty-printed JSON. By
  removing `Out-String`, the script is streamlined and potential errors
  are avoided.
- Add logic to handle empty settings file. Add an additional check for
  empty settings file, if the file is empty, the script writes a default
  empty JSON object (`{}`) to the file. The operation is logged to
  ensure transparency, notifying the user of the action taken. This
  change removes fails due to empty setting files.
- When reverting, do not fail if the setting file is missing because it
  means that default settings are already in-place.
- When reverting, show informative message if the key does not exist or
  does not have the value set by privacy.sexy and do not take any
  further action.
- If the desired value is already set, show a message for it and skip
  updating the setting file.

On Linux:

- Handles empty `settings.json` similarly to Windows.
- Add more user friendly error if JSON file cannot be parsed.
2023-10-02 14:33:55 +02:00
undergroundwires
d45750428c win: fix and improve temp dir cleanup #176, #89
This commit improve cleanup of temporary directories on Windows,
addressing issues #176 and #89.

Changes include:

- Fix side-effects caused by this script by clearing the contents of
  directories rather than deleting the directories themselves.
- Add the removal of Prefetch directory contents, which stores temporary
  files and can enhance privacy and free up disk space when cleared.
- Remove the command `del /f /q %localappdata%\Temp\*` due to its
  redundancy.
- Improve the granularity and documentation of cleanup scripts, and
  moving the `Clear temporary Windows files` category up in the hierarchy
  for better structure and clarity.

Co-authored-by: iam-py-test <84232764+iam-py-test@users.noreply.github.com>
2023-10-01 17:42:25 +02:00
undergroundwires
cf55ca9e28 Add Scoop download instructions #174
- Add "Further Installation Options" section.
- Move releases page reference to the new section to keep Get Started
  simple.

Co-authored-by: MrEddX <101912712+Zliced13@users.noreply.github.com>
2023-09-29 14:03:07 +02:00
undergroundwires
3e5239f7d3 Add SAST security checks with SECURITY.md #178
This commit incorporates Static Analysis Security Testing (SAST) using
CodeQL. This integration will enforce consistent security assessments
with every change and on a predetermined schedule.

This commit also involves a restructure of security checks. The existing
security-checks workflow is renamed to better reflect its functionality
related to dependency audits.

These changes will enhance the project's resilience against potential
vulnerabilities in both the codebase and third-party dependencies.

Changes include:

- Remove older LGTM badge that's replaced by SAST checks.
- Rename `checks.security.yaml` to `checks.security.dependencies.yaml`,
  reinforcing the focus on dependency audits.
- Update `README.md`, ensuring the clear representation of security
  check statuses, including new SAST integration.
- Add new `SECURITY.md`, establishing the protocol for reporting
  vulnerabilities and outlining the project's commitment to robust
  security testing.
- Enhance `docs/tests.md` with detailed information on the newly
  integrated security checks.
- Add reference to SECURITY.md in README.md.
2023-09-28 15:19:09 +02:00
undergroundwires
7669985f8e Fix Docker build and improve checks #220
This commit improves multiple aspects of Docker builds:

- Enable artifact output validation for Dockerfile.
- Correct the path references in Dockerfile for the distribution
  directory.
- Add Dockerfile specific indentation rules to `.editorconfig`.
- Use `npm run install-deps` for dependency installation, enhancing
  build reliability.
- Add automation script `verify-web-server-status.js` to verify running
  web server on given URL.
- Introduce automated build verification for Dockerfile:
  - On macOS, install Docker with colima as the container runtime
    because default agents do not include Docker and Docker runtime is
    not installed due to licensing issues (see actions/runner-images#17).
  - On Windows, there's no Linux container support (actions/runner#904,
    actions/runner-images#1143), so keep the checks for macOS and Ubuntu
    only.
2023-09-27 19:53:40 +02:00
undergroundwires-bot
5047c9b6e7 ⬆️ bump everywhere to 0.12.4 2023-09-26 11:45:04 +00:00
957 changed files with 52696 additions and 24842 deletions

View File

@@ -1,7 +1,33 @@
[*.{js,jsx,ts,tsx,vue,sh}] root = true # Top-most EditorConfig file
[*]
end_of_line = lf
[*.{js,jsx,ts,tsx,vue,sh,scss}]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
max_line_length = 100 max_line_length = 100
[{Dockerfile}]
indent_style = space
indent_size = 4
[*.py]
indent_size = 4 # PEP 8 (the official Python style guide) recommends using 4 spaces per indentation level
indent_style = space
max_line_length = 100
[*.ps1]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
[*.{scss}] # SASS guidelines: https://archive.today/2024.02.16-232553/https://sass-guidelin.es/
indent_style = space
indent_size = 2 # Recommended by SASS guidelines
max_line_length = 100 # Recommended by SASS guidelines
trim_trailing_whitespace = true
insert_final_newline = true

View File

@@ -9,14 +9,15 @@ module.exports = {
es2022: true, // add globals and sets parserOptions.ecmaVersion to 2022 es2022: true, // add globals and sets parserOptions.ecmaVersion to 2022
}, },
extends: [ extends: [
// Vue specific rules, eslint-plugin-vue // Vue specific base rules, `eslint-plugin-vue`
'plugin:vue/essential', 'plugin:vue/vue3-recommended',
// Extends eslint-config-airbnb // Extends `eslint-config-airbnb`
'@vue/eslint-config-airbnb-with-typescript', '@vue/eslint-config-airbnb-with-typescript',
// Extends @typescript-eslint/recommended // - Sets base parser and plugin options.
// Uses the recommended rules from the @typescript-eslint/eslint-plugin // - Includes `plugin:@typescript-eslint/recommended`. But incompatible with
// `strict-type-checked` and `stylistic-type-checked`, see https://github.com/vuejs/eslint-config-typescript/issues/67.
'@vue/typescript/recommended', '@vue/typescript/recommended',
], ],
rules: { rules: {

View File

@@ -5,71 +5,56 @@ labels: enhancement
--- ---
<!-- <!--
Thank you for suggesting an script to make privacy better. 🤗 Thank you for contributing to privacy.sexy! 🌟
Please fill in as much of the template below as you're able. For guidance, see our script guidelines: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md.
You could alternatively send a PR directly (see CONTRIBUTING.md). Consider submitting a PR for faster implementation: https://github.com/undergroundwires/privacy.sexy/blob/master/CONTRIBUTING.md#extend-scripts.
--> -->
### OS ### Operating system
<!-- <!--
Which OS will the new script configure? Specify the OS: Windows, macOS, or Linux.
One of the supported OSes: "Windows", "macOS" or "Linux".
--> -->
### Name ### Name
<!-- <!--
The name of the script. Suggest a name for the script.
It should start with an imperative noun such as "disable", "turn off" , "clear"... Naming conventions: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#name.
E.g. "Disable webcam telemetry"
--> -->
### Script code ### Code
<!-- <!--
Code that will be executed when script is selected. Provide or explain the code to execute when the script runs.
Try to keep it as simple and backwards-compatible as possible. Code guidelines: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#code.
Allowed languages:
- Windows: PowerShell (ps1) or batchfile
- 💡 Prioritize the one that's simpler, batchfile if similar.
- macOS: bash (sh)
- Linux: bash (sh) or Python 3
- 💡 Prioritize the one that's simpler, bash if similar.
--> -->
### Revert code ### Revert code
<!-- <!--
If applicable, add code that will revert the script code to its original (OS default) state. Include code to revert changes to the default state.
It may require additional time, but it's much appreciated by the community. Leave blank for non-reversible scripts.
Leave blank if the script is nonreversible (e.g. when clearing data without backup).
--> -->
### Suggested category ### Category
<!-- <!--
If applicable, suggest one more multiple suitable parent category of script. Suggest a category for the script.
A category is the item where the script will be presented under. If unsure, leave blank for maintainers to decide.
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 ### Recommendation level
<!-- <!--
If applicable, suggest recommending the script or not recommending at all. Suggest a recommendation level: STANDARD (non-breaking), STRICT (limits functionality), or NONE (for advanced users).
A script should be only recommended if it'll be safe for your grandmother to run. If unsure, leave blank for maintainers to decide.
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 ### Documentation/References
<!-- <!--
If applicable, refer to documentation that should show up on the script description. Provide any relevant documentation or references.
Sources (URLs) should be as high quality as possible e.g. vendor documentation is favored over user forums. Prefer high-quality sources such as vendor documentation.
Documentation guidelines: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#documentation.
--> -->

View File

@@ -8,4 +8,5 @@ runs:
- -
name: Run `npm ci` with retries name: Run `npm ci` with retries
shell: bash shell: bash
run: npm run install-deps -- --ci --root-directory "${{ inputs.working-directory }}" run: npm run install-deps -- --ci
working-directory: ${{ inputs.working-directory }}

View File

@@ -3,6 +3,6 @@ runs:
steps: steps:
- -
name: Setup node name: Setup node
uses: actions/setup-node@v2 uses: actions/setup-node@v4
with: with:
node-version: 16.x node-version: 18.x

View File

@@ -1,4 +1,4 @@
name: build-checks name: checks.build
on: on:
push: push:
@@ -21,7 +21,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node
@@ -49,7 +49,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node
@@ -68,3 +68,33 @@ jobs:
- -
name: Verify bundled desktop build artifacts name: Verify bundled desktop build artifacts
run: npm run check:verify-build-artifacts -- --electron-bundled run: npm run check:verify-build-artifacts -- --electron-bundled
build-docker:
strategy:
matrix:
os: [ macos, ubuntu ] # Windows runners do not support Linux containers
fail-fast: false # Allows to see results from other combinations
runs-on: ${{ matrix.os }}-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Install Docker on macOS
if: matrix.os == 'macos' # macOS runner is missing Docker
run: |-
# Install Docker
brew install docker
# Docker on macOS misses daemon due to licensing, so install colima as runtime
brew install colima
# Start the daemon
colima start
-
name: Build Docker image
run: docker build -t undergroundwires/privacy.sexy:latest .
-
name: Run Docker image on port 8080
run: docker run -d -p 8080:80 --rm --name privacy.sexy undergroundwires/privacy.sexy:latest
-
name: Check server is up and returns HTTP 200
run: node ./scripts/verify-web-server-status.js --url http://localhost:8080

View File

@@ -15,7 +15,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

View File

@@ -3,6 +3,9 @@ name: checks.external-urls
on: on:
schedule: schedule:
- cron: '0 0 * * 0' # at 00:00 on every Sunday - cron: '0 0 * * 0' # at 00:00 on every Sunday
push:
paths:
- tests/checks/external-urls/**
jobs: jobs:
run-check: run-check:
@@ -10,7 +13,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

View File

@@ -18,7 +18,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

View File

@@ -14,7 +14,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node
@@ -42,7 +42,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

View File

@@ -1,4 +1,4 @@
name: security-checks name: checks.security.dependencies
on: on:
push: push:
@@ -13,7 +13,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

View File

@@ -0,0 +1,42 @@
name: checks.security.sast
on:
push:
pull_request:
schedule:
- cron: '0 0 * * 0' # at 00:00 on every Sunday
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [
javascript # analyzes code written in JavaScript, TypeScript and both.
]
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
-
name: Autobuild
uses: github/codeql-action/autobuild@v2
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{ matrix.language }}"

View File

@@ -14,12 +14,13 @@ jobs:
runs-on: ${{ matrix.os }}-latest runs-on: ${{ matrix.os }}-latest
steps: steps:
- -
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
ref: master # otherwise it defaults to the version tag missing bump commit ref: master # otherwise it defaults to the version tag missing bump commit
fetch-depth: 0 # fetch all history fetch-depth: 0 # fetch all history
- -
name: Checkout to bump commit name: Checkout to bump commit
shell: bash
run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)" run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)"
- -
name: Setup node name: Setup node

View File

@@ -10,7 +10,7 @@ jobs:
steps: steps:
- -
name: "Infrastructure: Checkout" name: "Infrastructure: Checkout"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
path: aws path: aws
repository: undergroundwires/aws-static-site-with-cd repository: undergroundwires/aws-static-site-with-cd
@@ -75,7 +75,7 @@ jobs:
working-directory: aws working-directory: aws
- -
name: "App: Checkout" name: "App: Checkout"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
path: app path: app
ref: master # otherwise we don't get version bump commit ref: master # otherwise we don't get version bump commit
@@ -102,7 +102,7 @@ jobs:
- -
name: "App: Deploy to S3" name: "App: Deploy to S3"
shell: bash shell: bash
run: >- run: |-
declare web_output_dir declare web_output_dir
if ! web_output_dir=$(cd app && node scripts/print-dist-dir.js --web); then if ! web_output_dir=$(cd app && node scripts/print-dist-dir.js --web); then
echo 'Error: Could not determine distribution directory.' echo 'Error: Could not determine distribution directory.'

View File

@@ -14,7 +14,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node
@@ -24,3 +24,41 @@ jobs:
- -
name: Run e2e tests name: Run e2e tests
run: npm run test:cy:run run: npm run test:cy:run
-
name: Output artifact directories
id: artifacts
if: always() # Run even if previous steps fail because test run video is always captured
shell: bash
run: |-
declare -r dirs_json_file='cypress-dirs.json'
if [ ! -f "${dirs_json_file}" ]; then
echo "${dirs_json_file} does not exist"
exit 1
fi
SCREENSHOTS_DIR=$(jq -r '.screenshots' "${dirs_json_file}")
VIDEOS_DIR=$(jq -r '.videos' "${dirs_json_file}")
for dir in "${SCREENSHOTS_DIR}" "${VIDEOS_DIR}"; do
if [ "${dir}" = 'null' ] || [ -z "${dir}" ]; then
echo "One or more directories are null or not specified in cypress-dirs.json"
exit 1
fi
done
echo "SCREENSHOTS_DIR=${SCREENSHOTS_DIR}" >> "${GITHUB_OUTPUT}"
echo "VIDEOS_DIR=${VIDEOS_DIR}" >> "${GITHUB_OUTPUT}"
-
name: Upload screenshots
if: failure() # Run only if previous steps fail because screenshots will be generated only if E2E test failed
uses: actions/upload-artifact@v3
with:
name: e2e-screenshots-${{ matrix.os }}
path: ${{ steps.artifacts.outputs.SCREENSHOTS_DIR }}
-
name: Upload videos
if: always() # Run even if previous steps fail because test run video is always captured
uses: actions/upload-artifact@v3
with:
name: e2e-videos-${{ matrix.os }}
path: ${{ steps.artifacts.outputs.VIDEOS_DIR }}

View File

@@ -16,7 +16,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Setup node name: Setup node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

View File

@@ -14,7 +14,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- -
name: Set-up node name: Set-up node
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node

15
.gitignore vendored
View File

@@ -1,5 +1,16 @@
node_modules # Application build artifacts
/dist-*/ /dist-*/
.vs
# npm
node_modules
# Visual Studio Code
.vscode/**/* .vscode/**/*
!.vscode/extensions.json !.vscode/extensions.json
# draw.io
*.bkp
*.dtmp
# macOS
.DS_Store

View File

@@ -16,7 +16,8 @@
// Scripting // Scripting
"timonwong.shellcheck", // Lints bash files. "timonwong.shellcheck", // Lints bash files.
"ms-vscode.powershell", // Lints PowerShell files. "ms-vscode.powershell", // Lints PowerShell files.
"ms-python.python", // Lints Python files. "ms-python.python", // Python IntelliSense, debugging, and basic linting.
"ms-python.pylint", // Lints Python files
// Distribution // Distribution
"ms-azuretools.vscode-docker" // Adds Docker support. "ms-azuretools.vscode-docker" // Adds Docker support.
] ]

View File

@@ -1,5 +1,183 @@
# Changelog # Changelog
## 0.13.0 (2024-02-11)
* win: add disabling clipboard features #251, #247 | [c6ebba8](https://github.com/undergroundwires/privacy.sexy/commit/c6ebba85fb1b362be0d81d3078f19db71e0528b2)
* win: improve search privacy scripts #117 | [541f9aa](https://github.com/undergroundwires/privacy.sexy/commit/541f9aa5ee1b5f4885063b65beaf6cd873f0d786)
* win: add disabling Windows Copilot #263, #266 | [cd42550](https://github.com/undergroundwires/privacy.sexy/commit/cd425502ae882bba9642dc2171c2b5771946b5a9)
* win: add Dropbox telemetry blocking #125, #118 | [10829d6](https://github.com/undergroundwires/privacy.sexy/commit/10829d65aa3fb0df937bb8829244e6290bb748c7)
* Improve selection type documentation | [7af8daa](https://github.com/undergroundwires/privacy.sexy/commit/7af8daa3411b24efb6385c7876a49bd372753f38)
* Expand script names to take full available width | [d277139](https://github.com/undergroundwires/privacy.sexy/commit/d277139dd50eeb4e4057b0a7d8fc4ac2d70785de)
* Limit tooltip width for improved readability | [6ab6dac](https://github.com/undergroundwires/privacy.sexy/commit/6ab6dacd1be2d7bf1863b07b121d86f2a379ac67)
* Add markdown support for script/category names | [a5ffed4](https://github.com/undergroundwires/privacy.sexy/commit/a5ffed4cd60d9d058d5374145c1176b10fad1660)
* Normalize and improve font sizes | [4da306b](https://github.com/undergroundwires/privacy.sexy/commit/4da306b9f79b0bb7a64bb197fb246258cf435b8d)
* Change 'revert' button to title case | [937f459](https://github.com/undergroundwires/privacy.sexy/commit/937f4593d1a91081ab6b1bcb8f85d03879d7cf07)
* Remove playful emojis (🍑🍆) | [aa4205f](https://github.com/undergroundwires/privacy.sexy/commit/aa4205ff7af7d05cfb5e82bf541b521d49bbd1c8)
* Improve UI code styling for all platforms | [311fcb1](https://github.com/undergroundwires/privacy.sexy/commit/311fcb18133d1343f6a9ae5bd7a25795a1d12c49)
* Render bracket references as superscript text | [b9c89b7](https://github.com/undergroundwires/privacy.sexy/commit/b9c89b701fc77d20dcc706419a8659ad156c4fc2)
* Change slogan and refactor project info naming | [a54e164](https://github.com/undergroundwires/privacy.sexy/commit/a54e16488ce32219bcf811b5da85f06584b293fb)
* Add 'Revert All Selection' feature #68 | [55fa7ea](https://github.com/undergroundwires/privacy.sexy/commit/55fa7eae71031357d6f03f0d349a09cd446270d3)
* win, mac, linux: add privacy.sexy cleanup scripts | [63366a4](https://github.com/undergroundwires/privacy.sexy/commit/63366a4ec2533a376849d692211e9972b56ab4a8)
* Extend search by including documentation content | [6142f3a](https://github.com/undergroundwires/privacy.sexy/commit/6142f3a2973d20493f784f323f3be57fa8deaeef)
* Remove 'preview' label from Linux options | [ebd8285](https://github.com/undergroundwires/privacy.sexy/commit/ebd82853ddc56f1cc2fc9be3fe0b3001b07f0186)
* Change fonts for improved readability | [d5bbc32](https://github.com/undergroundwires/privacy.sexy/commit/d5bbc321f902dc60618ffdfda0d583a4a433f7af)
* Apply global styles for visual consistency | [faa7a38](https://github.com/undergroundwires/privacy.sexy/commit/faa7a38a7d16390f27e4a3e51017b81665cf85ca)
* Add UI animations for expand/collapse actions | [fb08f03](https://github.com/undergroundwires/privacy.sexy/commit/fb08f037651e1a7d453b9a6af724cbccecc5b903)
* win: relocate service disabling and improve docs | [894687c](https://github.com/undergroundwires/privacy.sexy/commit/894687c0e0375a24f40bcd720ea69c9b2aa62a58)
* win: add host blocking category #26 | [17152c8](https://github.com/undergroundwires/privacy.sexy/commit/17152c84dc639e75560998a6feddfd46e0f713ce)
* Update meta title and description | [c7fa4b6](https://github.com/undergroundwires/privacy.sexy/commit/c7fa4b6d020ac6fd3bf72bb4e57022dffb1ba921)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.10...0.13.0)
## 0.12.10 (2024-01-17)
* Fix CSP for Vue, Ace, Vite, Safari compatibility | [940febc](https://github.com/undergroundwires/privacy.sexy/commit/940febc3e80cfd0c01b5cc8282ebaab6b024d1b5)
* Improve security by isolating code execution more | [efa05f4](https://github.com/undergroundwires/privacy.sexy/commit/efa05f42bc53c44a352152b7c272bc0bda363070)
* Fix unresponsive circle icon in revert button | [645c333](https://github.com/undergroundwires/privacy.sexy/commit/645c33378769969c525a1552c65f8d0005e25fcf)
* Improve documentation for contribution guidelines | [fc9dd23](https://github.com/undergroundwires/privacy.sexy/commit/fc9dd234e9c749247f42289432ebb92dbe0a5f64)
* Bump Node.js environment to 18.x | [2f06043](https://github.com/undergroundwires/privacy.sexy/commit/2f0604355988a421690bb275375c3df280af7ee6)
* Fix button inconsistencies and macOS layout shifts | [86fde6d](https://github.com/undergroundwires/privacy.sexy/commit/86fde6d7dc61bbeeb3088cd24e37451181cc4e01)
* win: fix language dependent delete script #149 | [8f4b34f](https://github.com/undergroundwires/privacy.sexy/commit/8f4b34f8f156476f56fb7dde8e7c762f4455518b)
* Improve desktop script runs with timestamps & logs | [cdc32d1](https://github.com/undergroundwires/privacy.sexy/commit/cdc32d1f12c938966238c9569c91b64b23cd6f26)
* win: improve store app docs and add research #279 | [fac72ed](https://github.com/undergroundwires/privacy.sexy/commit/fac72edd551264320ed97194e7ecb3fcc34139f7)
* Fix handling special chars in script paths | [40f5eb8](https://github.com/undergroundwires/privacy.sexy/commit/40f5eb8334b27e958eee63e2141ded7d5861d960)
* Fix macOS detection in desktop app and Chromium | [dc30825](https://github.com/undergroundwires/privacy.sexy/commit/dc30825232a1355a325e364c8cd9fde78ffa3b1a)
* Bump ESLint Typescript dependencies to latest | [bf7fb07](https://github.com/undergroundwires/privacy.sexy/commit/bf7fb0732c52745521c1a89b963bdbf3394d9e63)
* Fix script deletion during execution on desktop | [c84a1bb](https://github.com/undergroundwires/privacy.sexy/commit/c84a1bb74ccb7a53bd493684b63a9e04f40e0b8b)
* Fix script execution for Linux VSCode development | [3b1a89c](https://github.com/undergroundwires/privacy.sexy/commit/3b1a89ce863c18c32be7d0b22dba566f692d81d1)
* Fix touch, cursor and accessibility in slider | [7285842](https://github.com/undergroundwires/privacy.sexy/commit/728584240cae6b3857abca4d3ddaaa7f6bb4a66e)
* Fix invisible script execution on Windows #264 | [b404a91](https://github.com/undergroundwires/privacy.sexy/commit/b404a91ada509e19a287d026d55db0035ff6233b)
* win: add missing extension apps, improve docs #279 | [da4be50](https://github.com/undergroundwires/privacy.sexy/commit/da4be500da7b0b5897a8b3e0525d9e50c9159fe0)
* Show native save dialogs in desktop app #50, #264 | [c546a33](https://github.com/undergroundwires/privacy.sexy/commit/c546a33eff7506550c7bcf03bb1f227a7c091816)
* Show save/execution error dialogs on desktop #264 | [e09db0f](https://github.com/undergroundwires/privacy.sexy/commit/e09db0f1bd73503204d8e5375a9cfe693f174a57)
* Add Windows save instructions UI and fix URL #296 | [756c736](https://github.com/undergroundwires/privacy.sexy/commit/756c736e21d713b8d2651cf2a9d7cf0678badde0)
* Add AD detection on desktop app #264, #304 | [f03fc24](https://github.com/undergroundwires/privacy.sexy/commit/f03fc2409832ddf904bc6bd4e19274a8d40745dc)
* Improve script error dialogs #304 | [6ada8d4](https://github.com/undergroundwires/privacy.sexy/commit/6ada8d425c4a7df88490756187c84b5c57ed1dcc)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.9...0.12.10)
## 0.12.9 (2023-12-16)
* win: improve docs and category of jump lists #146 | [40ae8a8](https://github.com/undergroundwires/privacy.sexy/commit/40ae8a8addaeb834ee26eabd330fda5cbb495324)
* mac: improve clearing privacy permissions | [5a7d7d8](https://github.com/undergroundwires/privacy.sexy/commit/5a7d7d88ff2f3e8862b18c94d062f692ee4b690b)
* win: fix logic for terminating processes | [807ae6a](https://github.com/undergroundwires/privacy.sexy/commit/807ae6a8f8ca724d781169f3ecb40f43ccd3fe10)
* win: improve documentation for "Get Help" app #280 | [8f5d7ed](https://github.com/undergroundwires/privacy.sexy/commit/8f5d7ed3cfa57f66dded9b72374006c9b6df2ce9)
* Centralize log file and refactor desktop logging | [08dbfea](https://github.com/undergroundwires/privacy.sexy/commit/08dbfead7ca7b55fe85f7dded01f2d4b88906c72)
* win: fix revert and improve docs for SAM enum #255 | [25e23c8](https://github.com/undergroundwires/privacy.sexy/commit/25e23c89c3f86897d5661a24a774997c924d3b2d)
* Improve security and reliability of macOS updates | [4765752](https://github.com/undergroundwires/privacy.sexy/commit/4765752ee3a36301b3d97317c570432424de8460)
* win: fix Win 11 Windows Security app removal #195 | [daa6230](https://github.com/undergroundwires/privacy.sexy/commit/daa6230fc96f2cf7210bc8c165106c0d5544e5fb)
* Improve security and privacy with strict meta tags | [ba5b29a](https://github.com/undergroundwires/privacy.sexy/commit/ba5b29a35dd7665aeea430aec4aaa8ff5ca811de)
* win: document and discourage admin shares #249 | [e747ee5](https://github.com/undergroundwires/privacy.sexy/commit/e747ee5cbc7cf5f0fe28a87fe7d02457d777373e)
* win: discourage XboxIdentityProvider #64, #79 #181 | [c72f9f5](https://github.com/undergroundwires/privacy.sexy/commit/c72f9f501680c1d880a0b560d02451a9e31063b4)
* win: improve disabling update healing #272 | [47b4823](https://github.com/undergroundwires/privacy.sexy/commit/47b4823bc5e487188b12cbea67db2525260af497)
* Fix tooltip overflow on smaller screens | [916c9d6](https://github.com/undergroundwires/privacy.sexy/commit/916c9d62d9fce27c3cd3feaf90c66df584d4f04a)
* Fix touch state not being activated in iOS Safari | [a985127](https://github.com/undergroundwires/privacy.sexy/commit/a9851272ae14eb1b374767b0eed3eb68e6dd1560)
* Fix tree view alignment and padding issues | [15134ea](https://github.com/undergroundwires/privacy.sexy/commit/15134ea04bc46e8cb13977d75b788f5ff71c800e)
* win: improve disabling of Application Experience | [fe3de49](https://github.com/undergroundwires/privacy.sexy/commit/fe3de498c8a1394efd6517d436797a08f938bb57)
* Fix OS switching not working on tree view UI | [3457fe1](https://github.com/undergroundwires/privacy.sexy/commit/3457fe18cf8193883f45b50ecbc9638c91ace2fb)
* Fix touch-enabled Chromium highlight on tree nodes | [2063397](https://github.com/undergroundwires/privacy.sexy/commit/20633972e9b56bdc102357129e74df30a95cefa9)
* win: add scripts to postpone auto-updates #272 | [e95b2ba](https://github.com/undergroundwires/privacy.sexy/commit/e95b2ba2179e40c0033a51b0087871dbfdc32d78)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.8...0.12.9)
## 0.12.8 (2023-11-27)
* Remove duplicated `index.html` file | [aab0f7e](https://github.com/undergroundwires/privacy.sexy/commit/aab0f7ea4680f377c610066bd0e99011eed8b506)
* Refactor DI for simplicity and type safety | [7770a9b](https://github.com/undergroundwires/privacy.sexy/commit/7770a9b5211d7208cfb2bfa5f737d46dc90b7946)
* Refactor user selection state handling using hook | [58cd551](https://github.com/undergroundwires/privacy.sexy/commit/58cd551a304a03e42637e6858982f8c5dfd9f598)
* Refactor watch sources for reliability | [7ab16ec](https://github.com/undergroundwires/privacy.sexy/commit/7ab16ecccb31b2d54e5b634520a8246fbbc248c1)
* Refactor to enforce strictNullChecks | [949fac1](https://github.com/undergroundwires/privacy.sexy/commit/949fac1a7cbc962ed63058e6a896695cfb4d35c8)
* Fix icon tooltip alignment on instructions modal | [bd383ed](https://github.com/undergroundwires/privacy.sexy/commit/bd383ed273ca95c10ea1cce765c0aa6836ec508c)
* Fix mobile layout overflow caused by tooltips | [e541a35](https://github.com/undergroundwires/privacy.sexy/commit/e541a35e86c0eff83f84dd002b46de7c55ebbcac)
* win: improve disabling of scheduled tasks | [3864f04](https://github.com/undergroundwires/privacy.sexy/commit/3864f042180f62afe469fdfe36010b018f84f4b3)
* Fix card list UI layout shifts (jumps) on load | [bf3426f](https://github.com/undergroundwires/privacy.sexy/commit/bf3426f91b6b7dbcad58d58507222559a8d14242)
* Refactor to Vue 3 recommended ESLint rules | [4531645](https://github.com/undergroundwires/privacy.sexy/commit/4531645b4c0c5143f15240652368bb9b9ddb48a4)
* Fix code highlighting and optimize category select | [cb42f11](https://github.com/undergroundwires/privacy.sexy/commit/cb42f11b9785e74719338a0a80a50d81dfccb4b6)
* Fix layout jumps/shifts and overflow on modals | [e299d40](https://github.com/undergroundwires/privacy.sexy/commit/e299d40fa1d71d921d4dac37e469fe299c9da3af)
* win: fix and improve Store app categorization #190 | [094dbb0](https://github.com/undergroundwires/privacy.sexy/commit/094dbb01b83bce9925fafab778b922f64390c2be)
* win: fix persistent update disabling /w tasks #272 | [dee3279](https://github.com/undergroundwires/privacy.sexy/commit/dee3279f85c99a9c62201a093b1afa41ec2412ec)
* win: discourage IntelliCode disabling #267, #286 | [7f7a84e](https://github.com/undergroundwires/privacy.sexy/commit/7f7a84e3ba259fade22d4838563d16129a1585e6)
* Fix spacing in documentation for readability | [1442f62](https://github.com/undergroundwires/privacy.sexy/commit/1442f626335e30e3a8d74e4e13e561c41f073ef8)
* win: fix system app removal affecting updates #287 | [7c632f7](https://github.com/undergroundwires/privacy.sexy/commit/7c632f738853b32fd90952bb4ca1ac924f962eb0)
* Fix rendering of inline code blocks for docs | [9845a7c](https://github.com/undergroundwires/privacy.sexy/commit/9845a7cd68a9920c96da739b58238bb1fdb1251d)
* linux: fix Firefox settings not reverting #282 | [bcad357](https://github.com/undergroundwires/privacy.sexy/commit/bcad357017d9f29ce77e706ca943107dd9caefb6)
* Fix incorrect URL rendering in documentation texts | [d328f08](https://github.com/undergroundwires/privacy.sexy/commit/d328f0895244d998e885ad8df335b6444b9ac66b)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.7...0.12.8)
## 0.12.7 (2023-11-07)
* Add winget download instructions | [b2ffc90](https://github.com/undergroundwires/privacy.sexy/commit/b2ffc90da70367b9e65c82556e8f440f865ceb98)
* Fix unresponsive copy button on instructions modal | [8ccaec7](https://github.com/undergroundwires/privacy.sexy/commit/8ccaec7af6ea3ecfd46bab5c13b90f71d55e32c1)
* Fix tree node check states not being updated | [af7219f](https://github.com/undergroundwires/privacy.sexy/commit/af7219f6e12ab4a65ce07190f691cf3234e87e35)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.6...0.12.7)
## 0.12.6 (2023-11-03)
* Bump dependencies to latest | [25d7f7b](https://github.com/undergroundwires/privacy.sexy/commit/25d7f7b2a479e51e092881cc2751e67a7d3f179f)
* win: improve system app uninstall cleanup #73 | [dbe3c5c](https://github.com/undergroundwires/privacy.sexy/commit/dbe3c5cfb91ba8a1657838b69117858843c8fbc8)
* win: improve system app uninstall /w fallback #260 | [98a26f9](https://github.com/undergroundwires/privacy.sexy/commit/98a26f9ae47af2668aa53f39d1768983036048ce)
* Improve performance of rendering during search | [79b46bf](https://github.com/undergroundwires/privacy.sexy/commit/79b46bf21004d96d31551439e5db5d698a3f71f3)
* Fix YAML error for site release in CI/CD | [237d994](https://github.com/undergroundwires/privacy.sexy/commit/237d9944f900f5172366868d75219224ff0542b0)
* win: fix Microsoft Advertising app removal #200 | [e40b9a3](https://github.com/undergroundwires/privacy.sexy/commit/e40b9a3cf53c341f2e84023a9f0e9680ac08f3fa)
* win: improve directory cleanup security | [060e789](https://github.com/undergroundwires/privacy.sexy/commit/060e7896624309aebd25e8b190c127282de177e8)
* Centralize Electron entry file path configuration | [d6da406](https://github.com/undergroundwires/privacy.sexy/commit/d6da406c61e5b9f5408851d1302d6d7398157a2e)
* win: prevent updates from reinstalling apps #260 | [8570b02](https://github.com/undergroundwires/privacy.sexy/commit/8570b02dde14ffad64863f614682c3fc1f87b6c2)
* win: improve script environment robustness #221 | [dfd4451](https://github.com/undergroundwires/privacy.sexy/commit/dfd44515613f38abe5a806bda36f44e7b715b50b)
* Fix compiler failing with nested `with` expression | [80821fc](https://github.com/undergroundwires/privacy.sexy/commit/80821fca0769e5fd2c6338918fbdcea12fbe83d2)
* win: improve soft file/app delete security #260 | [f4a74f0](https://github.com/undergroundwires/privacy.sexy/commit/f4a74f058db9b5bcbcbe438785db5ec88ecc1657)
* Fix incorrect tooltip position after window resize | [f8e5f1a](https://github.com/undergroundwires/privacy.sexy/commit/f8e5f1a5a2afa1f18567e6d965359b6a1f082367)
* linux: fix string formatting of Firefox configs | [e775d68](https://github.com/undergroundwires/privacy.sexy/commit/e775d68a9b4a5f9e893ff0e3500dade036185193)
* win: improve file delete | [e72c1c1](https://github.com/undergroundwires/privacy.sexy/commit/e72c1c13ea2d73ebfc7a8da5a21254fdfc0e5b59)
* win: change system app removal to hard delete #260 | [77123d8](https://github.com/undergroundwires/privacy.sexy/commit/77123d8c929d23676a9cb21d7b697703fd1b6e82)
* Improve UI performance by optimizing reactivity | [4995e49](https://github.com/undergroundwires/privacy.sexy/commit/4995e49c469211404dac9fcb79b75eb121f80bce)
* Migrate to Vue 3.0 #230 | [ca81f68](https://github.com/undergroundwires/privacy.sexy/commit/ca81f68ff1c3bbe5b22981096ae9220b0b5851c7)
* win, linux: unify & improve Firefox clean-up #273 | [0466b86](https://github.com/undergroundwires/privacy.sexy/commit/0466b86f1013341c966a9bbf6513990337b16598)
* win: fix store revert for multiple installs #260 | [5bb13e3](https://github.com/undergroundwires/privacy.sexy/commit/5bb13e34f8de2e2a7ba943ff72b12c0569435e62)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.5...0.12.6)
## 0.12.5 (2023-10-13)
* Fix Docker build and improve checks #220 | [7669985](https://github.com/undergroundwires/privacy.sexy/commit/7669985f8e1446e726a95626ecf35b3ce6b60a16)
* Add SAST security checks with SECURITY.md #178 | [3e5239f](https://github.com/undergroundwires/privacy.sexy/commit/3e5239f7d35e57749c01adf3dbbcd365aebb39c8)
* Add Scoop download instructions #174 | [cf55ca9](https://github.com/undergroundwires/privacy.sexy/commit/cf55ca9e28b064fa7a516077a9da23e3a8e3f534)
* win: fix and improve temp dir cleanup #176, #89 | [d457504](https://github.com/undergroundwires/privacy.sexy/commit/d45750428cca010daf2721b33a8ae3a01b28813b)
* win, linux: improve VSCode setting robustness #196 | [e8a52f7](https://github.com/undergroundwires/privacy.sexy/commit/e8a52f717dc799b34ceeb1c27c2b8219391dff6a)
* linux: fix obsolete Firefox DPI script #239 | [e5f6edf](https://github.com/undergroundwires/privacy.sexy/commit/e5f6edf405bcec7c29ea4d7932d1910620fa15f8)
* win: add removal of Edge assocations #64 | [888c916](https://github.com/undergroundwires/privacy.sexy/commit/888c9166fc66a2094137fa8be739cc21bafef5f6)
* win: improve Edge & OneDrive shortcut removal #73 | [8501495](https://github.com/undergroundwires/privacy.sexy/commit/8501495c170af61913288a63dbd369db5bbc5003)
* win: relocate and document SecHealthUI #190 | [2862951](https://github.com/undergroundwires/privacy.sexy/commit/286295128d0179358e0c6b7b6415d752175a1aed)
* Add developer toolkit UI component | [2147eae](https://github.com/undergroundwires/privacy.sexy/commit/2147eae687b82d05bc43bb4605d9068f148bb92a)
* win: fix and improve network data usage reset #265 | [5e359c2](https://github.com/undergroundwires/privacy.sexy/commit/5e359c2fb82a08e6acf7159b70ca86a8234b359b)
* win: improve app reversion and docs #260 | [a3f11df](https://github.com/undergroundwires/privacy.sexy/commit/a3f11dff187c821a00910c20dac05e285cda9073)
* Fix working directory in CI/CD web release | [698b570](https://github.com/undergroundwires/privacy.sexy/commit/698b570ee6e300d6703015464f4345b5e706f1cb)
* Implement new UI component for icons #230 | [48730bc](https://github.com/undergroundwires/privacy.sexy/commit/48730bca0506120bca4bf3a23545d59f2b1a9009)
* win: fix and improve AppCompat disabling #255 | [bab6316](https://github.com/undergroundwires/privacy.sexy/commit/bab6316e7625230cf4a4cf67c3aca417347db75c)
* win, linux, mac: fix typos and improve naming | [67c3677](https://github.com/undergroundwires/privacy.sexy/commit/67c3677621b201525a813e8a26f07d607176e89b)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.4...0.12.5)
## 0.12.4 (2023-09-25)
* win: fix Windows spotlight revert, docs, recommend | [659fea7](https://github.com/undergroundwires/privacy.sexy/commit/659fea7afcabcd0ea273cfdcc8c4bae190c126f3)
* win: fix Edge telemetry disabling for v116+ #242 | [6d301f9](https://github.com/undergroundwires/privacy.sexy/commit/6d301f99616ed49975876803d0098eafe4d3cb2e)
* win: fix, improve disabling automatic updates #252 | [6e9b65d](https://github.com/undergroundwires/privacy.sexy/commit/6e9b65d8b1b481c1471dde90876c37838b4ac4e5)
* win: refactor `update.mode` key for VSCode #215 | [c27172c](https://github.com/undergroundwires/privacy.sexy/commit/c27172c32e7c316b7cb0f44cab611eed89ca034e)
* Fix wrong action path in website CI deployment | [a1f2497](https://github.com/undergroundwires/privacy.sexy/commit/a1f24973813ccbdd7e1f06c64e1912a991a6bb64)
* Fix compiler bug with nested optional arguments | [53222fd](https://github.com/undergroundwires/privacy.sexy/commit/53222fd83c2846089746a217482195806f960d18)
* Fix no spacing after lists in documentation text | [f810ed0](https://github.com/undergroundwires/privacy.sexy/commit/f810ed0c147c2a46cae3b70b635ed81128646fff)
* Rewrite tooltip UI for efficiency and Vue 3.0 #230 | [8b930fc](https://github.com/undergroundwires/privacy.sexy/commit/8b930fc57c8ee6691ed6165bcb27d97e64a1a0c0)
* win: fix uninstallation of newer Edge #236 | [60dde11](https://github.com/undergroundwires/privacy.sexy/commit/60dde11311a2409537f5965f370b0daaaec53339)
* win: fix delivery optimization side-effects #173 | [203daeb](https://github.com/undergroundwires/privacy.sexy/commit/203daeb4a2fca0a0295cbc2a736394f9f87725e6)
* win: fix Defender scan artifacts removal #246 | [cb21a97](https://github.com/undergroundwires/privacy.sexy/commit/cb21a970b6b867e1476a5eb8a72b9a7fdd53a744)
* Fix outdated and broken links in README #161 | [0303ef2](https://github.com/undergroundwires/privacy.sexy/commit/0303ef2fd98b36306523e2a0c5f5ae812a4c6c99)
* Fix loss of tree node state when switching views | [8f188ac](https://github.com/undergroundwires/privacy.sexy/commit/8f188acd3c2d93e40c89569c74bc5cff992f0052)
* Fix slow appearance of nodes on tree view | [bd2082e](https://github.com/undergroundwires/privacy.sexy/commit/bd2082e8c574db065bb4462f30ea3ace2cb028cb)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.12.3...0.12.4)
## 0.12.3 (2023-09-09) ## 0.12.3 (2023-09-09)
* linux: use user.js over prefs.js for Firefox #232 | [dae6d11](https://github.com/undergroundwires/privacy.sexy/commit/dae6d114daab6857d773071211eb57619b136281) * linux: use user.js over prefs.js for Firefox #232 | [dae6d11](https://github.com/undergroundwires/privacy.sexy/commit/dae6d114daab6857d773071211eb57619b136281)

View File

@@ -1,6 +1,6 @@
# Contributing # Contributing
Love your input! Contributing to this project should be as easy and transparent as possible, whether it's: Love your input ❤️! Contributing to this project should be as easy and transparent as possible, whether it's:
- reporting a bug, - reporting a bug,
- discussing the current state of the code, - discussing the current state of the code,
@@ -16,7 +16,7 @@ Your pull requests are actively welcomed. We collaborate using [GitHub flow](htt
The steps: The steps:
1. Fork the repo and create your branch from master. 1. Fork the repository and create your branch from `master`.
2. If you've added code that requires testing, add tests. See [tests.md](./docs/tests.md). 2. If you've added code that requires testing, add tests. See [tests.md](./docs/tests.md).
3. If you've done a major change, update the documentation. See [docs/](./docs/). 3. If you've done a major change, update the documentation. See [docs/](./docs/).
4. Ensure the test suite passes. See [development.md | Testing](./docs/development.md#testing) for commands. 4. Ensure the test suite passes. See [development.md | Testing](./docs/development.md#testing) for commands.
@@ -37,15 +37,44 @@ Automated pipelines will run to control your PR and they will publish your code
## Extend scripts ## Extend scripts
Here's quick information for you who want to add more scripts. If you're interested in adding new scripts to privacy.sexy:
You have two alternatives: 1. Read [guidelines for a good script](./docs/script-guidelines.md)
2. Choose one of two ways to contribute:
1. [Create an issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose) requesting the addition of a new script. This allows other contributors to develop and add it for you. This will take longer time.
2. Submit a pull request with your script. This is the faster route to seeing your script included in the project. Add your scripts to the appropriate OS directory in the [collections](src/application/collections/) (for syntax guidance, see [collection-files.md](docs/collection-files.md)) folder, and follow the [pull request process](#pull-request-process).
1. [Create an issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose) and ask for someone else to add the script for you. ## Commit conventions
2. Or send a PR yourself. This would make it faster to get your code into the project. You need to add scripts to related OS in [collections](src/application/collections/) folder. Then you'd sent a pull request, see [pull request process](#pull-request-process).
- 📖 If you're unsure about the syntax, check [collection-files.md](docs/collection-files.md). - Adhere to the 50/72 rule:
- 📖 If you wish to use templates, use [templating.md](./docs/templating.md). - Commit titles should not exceed 50 characters.
- Limit description lines to 72 characters, except for code blocks or inline codes.
- Avoid including delta (such as `git diff` information) or a list of changed files in the commit message. This information is redundant as it's already part of the commit.
- Focus on explaining the WHY and HOW of the changes, rather than WHAT changes are.
- Begin the commit message with a concise summary of what the commit accomplishes.
- Use imperative language in the commit title. For example, use "add" instead of "added".
- Commit prefixes:
- Prefix bug fixes with `fix:` or `Fix ...`.
- For commits affecting scripts of specific operating systems:
- Prefix the commit title with an OS-specific tag such as `win:` for Windows scripts, `mac:` for macOS scripts, and `linux:` for Linux scripts.
- Combine prefixes for commits affecting more than one operating system, e.g., `win, mac: ...`.
## Versioning
We base versioning on the release's content rather than strictly following semantic versioning.
There are two main types of releases:
1. **Patch Releases:** These focus on minor UI improvements, bug fixes, refactorings, dependency updates, and documentation updates. For scripts, they involve adjusting recommendation levels, enhancing functionality, and dividing scripts for more precise control. Patch releases may ship minor feature additions if they are essential for fixing a bug. For these updates, we increment the patch number in the `MAJOR.MINOR.PATCH`.
2. **Feature Releases:** These releases bring significant updates that change how users interact with privacy.sexy. They include major UI enhancements, the introduction of new scripts, and features. For these updates, we increment the minor number in the `MAJOR.MINOR.PATCH`.
Maintainers tag specific commits with a version number to trigger a release, and [bump-everywhere](https://github.com/undergroundwires/bump-everywhere) automates the release process including updating version numbers throughout the project.
## Refactoring
Opportunistic refactoring is welcome. If you're adding a feature or fixing a bug, feel free to also clean up and optimize the related code. Your contributions should leave the code in a better state than when you found it.
## License ## License
By contributing, you agree that your [GNU General Public License v3.0](./LICENSE) will be the license for your contributions. By contributing to this project, you agree that your contributions are licensed under the [GNU Affero General Public License](./LICENSE) as currently specified. Additionally, you expressly consent to the project maintainers having full authority to modify the licensing terms or relicense your contributions under different terms in the future.

View File

@@ -1,13 +1,16 @@
# Build # Build
FROM node:lts-alpine as build-stage FROM node:lts-alpine AS build-stage
WORKDIR /app WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . . COPY . .
RUN npm run build RUN npm run install-deps
RUN npm run build \
&& npm run check:verify-build-artifacts -- --web
RUN mkdir /dist \
&& dist_directory=$(node 'scripts/print-dist-dir.js' --web) \
&& cp -a "${dist_directory}/." '/dist'
# Production stage # Production stage
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 /dist /usr/share/nginx/html
EXPOSE 80 EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,6 +1,6 @@
# privacy.sexy — Now you have the choice # privacy.sexy — Privacy is sexy
> Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy 🍑🍆 > Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.
<!-- markdownlint-disable MD033 --> <!-- markdownlint-disable MD033 -->
<p align="center"> <p align="center">
@@ -16,14 +16,6 @@
src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat"
/> />
</a> </a>
<!-- Code quality -->
<br />
<a href="https://lgtm.com/projects/g/undergroundwires/privacy.sexy/context:javascript" target="_blank" rel="noopener noreferrer">
<img
alt="Language grade: JavaScript/TypeScript"
src="https://img.shields.io/lgtm/grade/javascript/g/undergroundwires/privacy.sexy.svg?logo=lgtm&logoWidth=18"
/>
</a>
<a href="https://codeclimate.com/github/undergroundwires/privacy.sexy/maintainability" target="_blank" rel="noopener noreferrer"> <a href="https://codeclimate.com/github/undergroundwires/privacy.sexy/maintainability" target="_blank" rel="noopener noreferrer">
<img <img
alt="Maintainability" alt="Maintainability"
@@ -50,6 +42,20 @@
src="https://github.com/undergroundwires/privacy.sexy/workflows/e2e-tests/badge.svg" src="https://github.com/undergroundwires/privacy.sexy/workflows/e2e-tests/badge.svg"
/> />
</a> </a>
<!-- Security checks -->
<br />
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.security.sast.yaml" target="_blank" rel="noopener noreferrer">
<img
alt="Status of dependency security checks"
src="https://github.com/undergroundwires/privacy.sexy/workflows/checks.security.sast/badge.svg"
/>
</a>
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.security.dependencies.yaml" target="_blank" rel="noopener noreferrer">
<img
alt="Status of Static Analysis Security Testing (SAST)"
src="https://github.com/undergroundwires/privacy.sexy/workflows/checks.security.dependencies/badge.svg"
/>
</a>
<!-- Checks --> <!-- Checks -->
<br /> <br />
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.quality.yaml" target="_blank" rel="noopener noreferrer"> <a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.quality.yaml" target="_blank" rel="noopener noreferrer">
@@ -58,16 +64,10 @@
src="https://github.com/undergroundwires/privacy.sexy/workflows/quality-checks/badge.svg" src="https://github.com/undergroundwires/privacy.sexy/workflows/quality-checks/badge.svg"
/> />
</a> </a>
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.security.yaml" target="_blank" rel="noopener noreferrer">
<img
alt="Security checks status"
src="https://github.com/undergroundwires/privacy.sexy/workflows/security-checks/badge.svg"
/>
</a>
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.build.yaml" target="_blank" rel="noopener noreferrer"> <a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.build.yaml" target="_blank" rel="noopener noreferrer">
<img <img
alt="Build checks status" alt="Status of build checks"
src="https://github.com/undergroundwires/privacy.sexy/workflows/build-checks/badge.svg" src="https://github.com/undergroundwires/privacy.sexy/workflows/checks.build/badge.svg"
/> />
</a> </a>
<a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.desktop-runtime-errors.yaml" target="_blank" rel="noopener noreferrer"> <a href="https://github.com/undergroundwires/privacy.sexy/actions/workflows/checks.desktop-runtime-errors.yaml" target="_blank" rel="noopener noreferrer">
@@ -122,11 +122,11 @@
## Get started ## Get started
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy). - 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
- 🖥️ **Offline**: Check [releases page](https://github.com/undergroundwires/privacy.sexy/releases), or download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.3/privacy.sexy-Setup-0.12.3.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.3/privacy.sexy-0.12.3.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.3/privacy.sexy-0.12.3.AppImage). - 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.0/privacy.sexy-Setup-0.13.0.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.0/privacy.sexy-0.13.0.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.0/privacy.sexy-0.13.0.AppImage). For more options, see [here](#additional-install-options).
Online version does not require to run any software on your computer. Offline version has more functions such as running the scripts directly. For a detailed comparison of features between the desktop and web versions of privacy.sexy, see [Desktop vs. Web Features](./docs/desktop-vs-web-features.md).
💡 You should apply your configuration from time to time (more than once). It would strengthen your privacy and security control because privacy.sexy and its scripts get better and stronger in every new version. 💡 Regularly applying your configuration with privacy.sexy is recommended, especially after each new release and major operating system updates. Each version updates scripts to enhance stability, privacy, and security.
[![privacy.sexy application](img/screenshot.png?raw=true )](https://privacy.sexy) [![privacy.sexy application](img/screenshot.png?raw=true )](https://privacy.sexy)
@@ -137,6 +137,7 @@ Online version does not require to run any software on your computer. Offline ve
- **Transparent**. Have full visibility into what the tweaks do as you enable them. - **Transparent**. Have full visibility into what the tweaks do as you enable them.
- **Reversible**. Revert if something feels wrong. - **Reversible**. Revert if something feels wrong.
- **Accessible**. No need to run any compiled software on your computer with web version. - **Accessible**. No need to run any compiled software on your computer with web version.
- **Secure**: Security is a top priority at privacy.sexy with [comprehensive safeguards](./SECURITY.md#security-practices) in place.
- **Open**. What you see as code in this repository is what you get. The application itself, its infrastructure and deployments are open-source and automated thanks to [bump-everywhere](https://github.com/undergroundwires/bump-everywhere). - **Open**. What you see as code in this repository is what you get. The application itself, its infrastructure and deployments are open-source and automated thanks to [bump-everywhere](https://github.com/undergroundwires/bump-everywhere).
- **Tested**. A lot of tests. Automated and manual. Community-testing and verification. Stability improvements comes before new features. - **Tested**. A lot of tests. Automated and manual. Community-testing and verification. Stability improvements comes before new features.
- **Extensible**. Effortlessly [extend scripts](./CONTRIBUTING.md#extend-scripts) with a custom designed [templating language](./docs/templating.md). - **Extensible**. Effortlessly [extend scripts](./CONTRIBUTING.md#extend-scripts) with a custom designed [templating language](./docs/templating.md).
@@ -150,6 +151,25 @@ Online version does not require to run any software on your computer. Offline ve
**Contribute 👷**. Contributions of any type are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) as the starting point. It includes useful information like [how to add new scripts](./CONTRIBUTING.md#extend-scripts). **Contribute 👷**. Contributions of any type are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) as the starting point. It includes useful information like [how to add new scripts](./CONTRIBUTING.md#extend-scripts).
## Additional Install Options
- Check the [releases page](https://github.com/undergroundwires/privacy.sexy/releases) for all available versions.
- Other unofficial channels (not maintained by privacy.sexy) for Windows include:
- [Scoop 🥄](https://scoop.sh/#/apps?q=privacy.sexy&s=2&d=1&o=true) (latest version):
```powershell
scoop bucket add extras
scoop install privacy.sexy
```
- [winget 🪟](https://winget.run/pkg/undergroundwires/privacy.sexy) (may be outdated):
```powershell
winget install -e --id undergroundwires.privacy.sexy
```
With winget, updates require manual submission; the auto-update feature within privacy.sexy will notify you of new releases post-installation.
## Development ## Development
Refer to [development.md](./docs/development.md) for Docker usage and reading more about setting up your development environment. Refer to [development.md](./docs/development.md) for Docker usage and reading more about setting up your development environment.
@@ -157,3 +177,9 @@ Refer to [development.md](./docs/development.md) for Docker usage and reading mo
Check [architecture.md](./docs/architecture.md) for an overview of design and how different parts and layers work together. You can refer to [application.md](./docs/application.md) for a closer look at application layer codebase and [presentation.md](./docs/presentation.md) for code related to GUI layer. [collection-files.md](./docs/collection-files.md) explains the YAML files that are the core of the application and [templating.md](./docs/templating.md) documents how to use templating language in those files. In [ci-cd.md](./docs/ci-cd.md), you can read more about the pipelines that automates maintenance tasks and ensures you get what see. Check [architecture.md](./docs/architecture.md) for an overview of design and how different parts and layers work together. You can refer to [application.md](./docs/application.md) for a closer look at application layer codebase and [presentation.md](./docs/presentation.md) for code related to GUI layer. [collection-files.md](./docs/collection-files.md) explains the YAML files that are the core of the application and [templating.md](./docs/templating.md) documents how to use templating language in those files. In [ci-cd.md](./docs/ci-cd.md), you can read more about the pipelines that automates maintenance tasks and ensures you get what see.
[docs/](./docs/) folder includes all other documentation. [docs/](./docs/) folder includes all other documentation.
## Security
Security is a top priority at privacy.sexy.
An extensive commitment to security verification ensures this priority.
For any security concerns or vulnerabilities, please consult the [Security Policy](./SECURITY.md).

70
SECURITY.md Normal file
View File

@@ -0,0 +1,70 @@
# Security Policy
Security is a top priority at privacy.sexy.
Please report any discovered vulnerabilities responsibly.
## Reporting a Vulnerability
Efforts to responsibly disclose findings are greatly appreciated. To report a security vulnerability, follow these steps:
- For general vulnerabilities, [open an issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose) using the bug report template.
- For sensitive matters, [contact the developer directly](https://undergroundwires.dev).
## Security Report Handling
Upon receiving a security report, the process involves:
- Confirming the report and identifying affected components.
- Assessing the impact and severity of the issue.
- Fixing the vulnerability and planning a release to address it.
- Keeping the reporter informed about progress.
## Security Practices
### Application Security
privacy.sexy adopts a defense in depth strategy to protect users on multiple layers:
- **Link Protection:**
privacy.sexy ensures each external link has special attributes for your privacy and security.
These attributes block the new site from accessing the privacy.sexy page, increasing your online safety and privacy.
- **Content Security Policies (CSP):**
privacy.sexy actively follows security guidelines from the Open Web Application Security Project (OWASP) at strictest level.
This approach protects against attacks like Cross Site Scripting (XSS) and data injection.
- **Host System Access Control:**
The desktop application segregates and isolates code sections based on their access levels through sandboxing.
This provides a critical defense mechanism, prevents attackers from introducing harmful code into the app, known as injection attacks.
- **Auditing and Transparency:**
The desktop application improves security and transparency by logging application activities and retaining files of executed scripts
This facilitates detailed auditability and effective troubleshooting, contributing to the integrity and reliability of the application.
Recognizing that some users prefer not to keep these records, privacy.sexy provides specialized scripts for deletion of these logs.
- **Privilege Management:**
The desktop application operates without persistent administrative or `sudo` privileges, reinforcing its security posture. It requests
elevation of privileges for system modifications with explicit user consent and logs every action taken with high privileges. This
approach actively minimizes potential security risks by limiting privileged operations and aligning with the principle of least privilege.
- **Secure Script Execution/Storage:**
Before executing any script, the desktop application stores a copy to allow antivirus software to perform scans. This safeguards against
any unwanted modifications. Furthermore, the application incorporates integrity checks for tamper protection. If the script file differs from
the user's selected script, the application will not execute or save the script, ensuring the processing of authentic scripts.
Recognizing that some users prefer not to keep these records, privacy.sexy provides specialized scripts for deletion of these scripts.
### Update Security and Integrity
privacy.sexy benefits from automated update processes including security tests. Automated deployments from source code ensure immediate and secure updates, mirroring the latest source code. This aligns the deployed application with the expected source code, enhancing transparency and trust. For more details, see [CI/CD Documentation](./docs/ci-cd.md).
Every desktop update undergoes a thorough verification process. Updates are cryptographically signed to ensure authenticity and integrity, preventing tampered versions from reaching your device. Version checks are conducted to prevent downgrade attacks.
### Testing
privacy.sexy's testing approach includes a mix of automated and community-driven tests.
Details on testing practices are available in the [Testing Documentation](./docs/tests.md).
## Support
For help or any questions, [submit a GitHub issue](https://github.com/undergroundwires/privacy.sexy/issues/new/choose). Addressing security concerns is a priority, and we ensure the necessary support.
Support privacy.sexy's commitment to security by [making a donation ❤️](https://github.com/sponsors/undergroundwires). Your contributions aid in maintaining and enhancing the project's security features.
---
Active contribution to the safety and security of privacy.sexy is thanked. This collaborative effort keeps the project resilient and trustworthy for all.

5
cypress-dirs.json Normal file
View File

@@ -0,0 +1,5 @@
{
"base": "tests/e2e",
"videos": "tests/e2e/videos",
"screenshots": "tests/e2e/videos"
}

View File

@@ -1,15 +1,31 @@
import { defineConfig } from 'cypress'; import { defineConfig } from 'cypress';
import ViteConfig from './vite.config'; import ViteConfig from './vite.config';
import cypressDirs from './cypress-dirs.json' assert { type: 'json' };
const CYPRESS_BASE_DIR = 'tests/e2e/';
export default defineConfig({ export default defineConfig({
fixturesFolder: `${CYPRESS_BASE_DIR}/fixtures`, fixturesFolder: `${cypressDirs.base}/fixtures`,
screenshotsFolder: `${CYPRESS_BASE_DIR}/screenshots`, screenshotsFolder: cypressDirs.screenshots,
videosFolder: `${CYPRESS_BASE_DIR}/videos`,
video: true,
videosFolder: cypressDirs.videos,
e2e: { e2e: {
baseUrl: `http://localhost:${ViteConfig.server.port}/`, baseUrl: `http://localhost:${getApplicationPort()}/`,
specPattern: `${CYPRESS_BASE_DIR}/**/*.cy.{js,jsx,ts,tsx}`, // Default: cypress/e2e/**/*.cy.{js,jsx,ts,tsx} specPattern: `${cypressDirs.base}/**/*.cy.{js,jsx,ts,tsx}`, // Default: cypress/e2e/**/*.cy.{js,jsx,ts,tsx}
supportFile: `${CYPRESS_BASE_DIR}/support/e2e.ts`, supportFile: `${cypressDirs.base}/support/e2e.ts`,
}, },
/*
Disabling Chrome's web security to allow for faster DOM queries to access DOM earlier than
`cy.get()`. It bypasses the usual same-origin policy constraints
*/
chromeWebSecurity: false,
}); });
function getApplicationPort(): number {
const port = ViteConfig.server?.port;
if (port === undefined) {
throw new Error('Unknown application port');
}
return port;
}

View File

@@ -27,13 +27,14 @@ Application uses highly decoupled models & services in different DDD layers:
**Domain layer**: **Domain layer**:
- Serves as the system's core and central truth. - Serves as the system's core and central truth.
- Facilitates communication between the application and presentation layers through the domain model. - It should be independent of other layers and encapsulate the core business concepts.
**Infrastructure layer**: **Infrastructure layer**:
- Manages technical implementations without dependencies on other layers or domain knowledge. - Provides technical implementations.
- Depends on the application and domain layers in terms of interfaces and contracts but should not include business logic.
![DDD + vue.js](./../img/architecture/app-ddd.png) ![DDD + vue.js](./../img/architecture/app-ddd.drawio.png)
### Application state ### Application state

View File

@@ -1,176 +1,164 @@
# Collection files # 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/) privacy.sexy is a data-driven application that reads YAML files.
- 💡 Best practices This document details the structure and syntax of the YAML files located in [`application/collections`](./../src/application/collections/), which form the backbone of the application's data model.
- 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) Related documentation:
- 📖 Types in code: [`collection.yaml.d.ts`](./../src/application/collections/collection.yaml.d.ts)
- 📖 [`collection.yaml.d.ts`](./../src/application/collections/collection.yaml.d.ts) outlines code types.
- 📖 [Script Guidelines](./script-guidelines.md) provide guidance on script creation including best-practices.
## Objects ## Objects
### `Collection` ### `Collection`
- A collection simply defines: - Defines categories, scripts, and OS-specific details in a tree structure.
- different categories and their scripts in a tree structure - Allows defining common [functions](#function) for code reuse.
- 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 #### `Collection` syntax
- `os:` *`string`* (**required**) - `os:` *`string`* **(required)**
- Operating system that the [Collection](#collection) is written for. - Operating system for the collection.
- 📖 See [OperatingSystem.ts](./../src/domain/OperatingSystem.ts) enumeration for allowed values. - 📖 See [`OperatingSystem.ts`](./../src/domain/OperatingSystem.ts) for possible values.
- `actions: [` ***[`Category`](#category)*** `, ... ]` **(required)** - `actions: [` ***[`Category`](#category)*** `, ... ]` **(required)**
- Each [category](#category) is rendered as different cards in card presentation. - Renders each parent category as cards in the user interface.
- ❗ A [Collection](#collection) must consist of at least one category. - ❗ A [Collection](#collection) must consist of at least one category.
- `functions: [` ***[`Function`](#function)*** `, ... ]` - `functions: [` ***[`Function`](#function)*** `, ... ]`
- Functions are optionally defined to re-use the same code throughout different scripts. - Optional for code reuse.
- `scripting:` ***[`ScriptingDefinition`](#scriptingdefinition)*** **(required)** - `scripting:` ***[`ScriptingDefinition`](#scriptingdefinition)*** **(required)**
- Defines the scripting language that the code of other action uses. - Sets the scripting language for all inline code used within the collection.
### `Category` ### `Category`
- Category has a parent that has tree-like structure where it can have subcategories or subscripts. Represents a logical group of scripts and subcategories.
- It's a logical grouping of different scripts and other categories.
#### `Category` syntax #### `Category` syntax
- `category:` *`string`* (**required**) - `category:` *`string`* **(required)**
- Name of the category - Name of the category.
- ❗ Must be unique throughout the [Collection](#collection) - ❗ Must be unique throughout the [collection](#collection).
- `children: [` ***[`Category`](#category)*** `|` [***`Script`***](#script) `, ... ]` (**required**) - `children: [` ***[`Category`](#category)*** `|` [***`Script`***](#script) `, ... ]` **(required)**
- ❗ Category must consist of at least one subcategory or script. - ❗ Category must consist of at least one subcategory or script.
- Children can be combination of scripts and subcategories. - Children can be combination of scripts and subcategories.
- `docs`: *`string`* | `[`*`string`*`, ... ]` - `docs`: *`string`* | `[`*`string`*`, ... ]`
- Documentation pieces related to the category. - Markdown-formatted documentation related to the category.
- Rendered as markdown.
### `Script` ### `Script`
- Script represents a single tweak. Represents an individual tweak.
- A script can be of two different types (just like [functions](#function)):
1. Inline script; a script with an inline code Types (like [functions](#function)):
- Must define `code` property and optionally `revertCode` but not `call`
2. Caller script; a script that calls other functions 1. Inline script:
- Must define `call` property but not `code` or `revertCode` - Direct code.
- 🙏 For any new script, please add `revertCode` and `docs` values if possible. - ❗ Requires `code` and optional `revertCode`.
2. Caller script:
- Calls other [functions](#function).
- ❗ Requires `call`, but not `code` or `revertCode`.
📖 For detailed guidelines, see [Script Guidelines](./script-guidelines.md).
#### `Script` syntax #### `Script` syntax
- `name`: *`string`* (**required**) - `name`: *`string`* **(required)**
- Name of the script - Script name.
- ❗ Must be unique throughout the [Collection](#collection) - ❗ Must be unique throughout the [Collection](#collection).
- E.g. `Disable targeted ads` - `code`: *`string`* **(conditionally required)**
- `code`: *`string`* (may be **required**) - Code to execute when the user selects the script.
- Batch file commands that will be executed - 💡 If defined, it's best practice to also define `revertCode`.
- 💡 If defined, best practice to also define `revertCode` - ❗ Cannot co-exist with `call`, define either `code` with optional `revertCode` or `call`.
- ❗ If not defined `call` must be defined, do not define if `call` is defined. - `revertCode`: *`string`*
- `revertCode`: `string` - Reverts changes made by `code`.
- Code that'll undo the change done by `code` property. - ❗ Cannot co-exist with `call`, define `revertCode` with `code` or `call`.
- E.g. let's say `code` sets an environment variable as `setx POWERSHELL_TELEMETRY_OPTOUT 1` - `call`: ***[`FunctionCall`](#functioncall)*** | `[` ***[`FunctionCall`](#functioncall)*** `, ... ]` **(conditionally required)**
- then `revertCode` should be doing `setx POWERSHELL_TELEMETRY_OPTOUT 0` - A shared function or sequence of functions to call (called in order).
-Do not define if `call` is defined. -Cannot co-exist with `code` or `revertCode`, define `code` with optional `revertCode` or `call`.
- `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`*`, ... ]` - `docs`: *`string`* | `[`*`string`*`, ... ]`
- Documentation pieces related to the script. - Markdown-formatted documentation related to the script.
- Rendered as markdown. - `recommend`: *`"standard"`* | *`"strict"`* | *`undefined`* (default: `undefined`)
- `recommend`: `"standard"` | `"strict"` | `undefined` (default) - Sets recommendation level.
- If not defined then the script will not be recommended - Application will not recommend the script if `undefined`.
- If defined it can be either
- `standard`: Only non-breaking scripts without limiting OS functionality 📖 For detailed guidelines, see [Script Guidelines](./script-guidelines.md).
- `strict`: Scripts that can break certain functionality in favor of privacy and security
### `FunctionCall` ### `FunctionCall`
- Describes a single call to a function by optionally providing values to its parameters. Specifies a function call. It may require providing argument values to its parameters.
- 👀 See [parameter substitution](./templating.md#parameter-substitution) for an example usage
#### `FunctionCall` syntax #### `FunctionCall` syntax
- `function`: *`string`* (**required**) - `function`: *`string`* **(required)**
- Name of the function to call. - Name of the function to call.
- ❗ Function with same name must defined in `functions` property of [Collection](#collection) - ❗ Function with same name must defined in `functions` property of [Collection](#collection).
- `parameters`: `[ parameterName:` *`parameterValue`*`, ... ]` - `parameters`: `[` *`parameterName: parameterValue`* `, ... ]`
- Defines key value dictionary for each parameter and its value - Key-value pairs representing function parameters and their corresponding argument values.
- E.g. - 📖 See [parameter substitution](./templating.md#parameter-substitution) for an example usage.
- 💡 You can use [expressions (templating)](./templating.md#expressions) when providing argument values for parameters.
```yaml
parameters:
userDefinedParameterName: parameterValue
# ...
appName: Microsoft.WindowsFeedbackHub
```
- 💡 [Expressions (templating)](./templating.md#expressions) can be used as parameter value
### `Function` ### `Function`
- Functions allow re-usable code throughout the defined scripts. - Enables reusable code in scripts.
- Functions are templates compiled by privacy.sexy and uses special expression expressions. - Functions are templates compiled by privacy.sexy and uses special expression expressions.
- A function can be of two different types (just like [scripts](#script)): - A function can be of two different types (like [scripts](#script)):
1. Inline function: a function with an inline code. 1. Inline function: a function with an inline code.
- Must define `code` property and optionally `revertCode` but not `call`. - ❗ Requires `code` and optionally `revertCode`, but not `call`.
2. Caller function: a function that calls other functions. 2. Caller function: a function that calls other functions.
- Must define `call` property but not `code` or `revertCode`. - ❗ Requires `call`, but not `code` or `revertCode`.
- 👀 Read more on [Templating](./templating.md) for function expressions and [example usages](./templating.md#parameter-substitution). - 📖 Read about function expressions in [Templating](./templating.md) with [example usages](./templating.md#parameter-substitution).
#### `Function` syntax #### `Function` syntax
- `name`: *`string`* (**required**) - `name`: *`string`* **(required)**
- Name of the function that scripts will use. - Name of the function that scripts will use.
- Convention is to use camelCase, and be verbs. - ❗ Function names must be unique.
- E.g. `uninstallStoreApp` - ❗ Function names must follow camelCase and start with verbs (e.g., `uninstallStoreApp`).
- ❗ Function names must be unique - `parameters`: `[` ***[`FunctionParameter`](#functionparameter)*** `, ... ]` **(conditionally required)**
- `parameters`: `[` ***[`FunctionParameter`](#functionparameter)*** `, ... ]` - Lists parameters used.
- List of parameters that function code refers to. - ❗ Required to be able use in [`FunctionCall`](#functioncall) or [expressions (templating)](./templating.md#expressions).
- ❗ Must be defined to be able use in [`FunctionCall`](#functioncall) or [expressions (templating)](./templating.md#expressions) - `code`: *`string`* **(conditionally required)**
`code`: *`string`* (**required** if `call` is undefined) - Code to execute when the user selects the script.
- Batch file commands that will be executed - 💡 You can use [expressions (templating)](./templating.md#expressions) in its value.
- 💡 [Expressions (templating)](./templating.md#expressions) can be used in its value - 💡 If defined, it's best practice to also define `revertCode`.
- 💡 If defined, best practice to also define `revertCode` - ❗ Cannot co-exist with `call`, define either `code` with optional `revertCode` or `call`.
- ❗ If not defined `call` must be defined
- `revertCode`: *`string`* - `revertCode`: *`string`*
- Code that'll undo the change done by `code` property. - Reverts changes made by `code`.
- E.g. let's say `code` sets an environment variable as `setx POWERSHELL_TELEMETRY_OPTOUT 1` - 💡 You can use [expressions (templating)](./templating.md#expressions) in its value.
- then `revertCode` should be doing `setx POWERSHELL_TELEMETRY_OPTOUT 0` - ❗ Cannot co-exist with `call`, define `revertCode` with `code` or `call`.
- 💡 [Expressions (templating)](./templating.md#expressions) can be used in code - `call`: ***[`FunctionCall`](#functioncall)*** | `[` ***[`FunctionCall`](#functioncall)*** `, ... ]` **(conditionally required)**
- `call`: ***[`FunctionCall`](#functioncall)*** | `[` ***[`FunctionCall`](#functioncall)*** `, ... ]` (may be **required**) - A shared function or sequence of functions to call (called in order).
- A shared function or sequence of functions to call (called in order) - 💡 You can use [expressions (templating)](./templating.md#expressions) in argument values provided for parameters.
- The parameter values that are sent can use [expressions (templating)](./templating.md#expressions) - ❗ Cannot co-exist with `code` or `revertCode`, define `code` with optional `revertCode` or `call`.
- ❗ If not defined `code` must be defined
### `FunctionParameter` ### `FunctionParameter`
- Defines a parameter that function requires optionally or mandatory. - Defines a single parameter that may require an argument value optionally or mandatory.
- Its arguments are provided by a [Script](#script) through a [FunctionCall](#functioncall). - A [`FunctionCall`](#functioncall) provides argument values by a caller.
- A caller can be a [Script](#script) or [Function](#function).
#### `FunctionParameter` syntax #### `FunctionParameter` syntax
- `name`: *`string`* (**required**) - `name`: *`string`* **(required)**
- Name of the parameters that the function has. - Name of the parameter that the function has.
- Parameter names must be defined to be used in [expressions (templating)](./templating.md#expressions). - ❗ Required for [expressions (templating)](./templating.md#expressions).
-Parameter names must be unique and include alphanumeric characters only. -Must be unique and consists of alphanumeric characters.
- `optional`: *`boolean`* (default: `false`) - `optional`: *`boolean`* (default: `false`)
- Specifies whether the caller [Script](#script) must provide any value for the parameter. - Indicates the caller must provide and argument 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; - 💡 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. - E.g., in a [`with` expression](./templating.md#with).
- 💡 Set it to `true` if a parameter is used conditionally; - 💡 Set it to `true` if you will use its argument value conditionally;
- Or else set it to `false` for verbosity or do not define it as default value is `false` anyway. - 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` ### `ScriptingDefinition`
- Defines global properties for scripting that's used throughout its parent [Collection](#collection). Sets global scripting properties for a [Collection](#collection).
#### `ScriptingDefinition` syntax #### `ScriptingDefinition` syntax
- `language:` *`string`* (**required**) - `language:` *`string`* **(required)**
- 📖 See [ScriptingLanguage.ts](./../src/domain/ScriptingLanguage.ts) enumeration for allowed values. - 📖 See [`ScriptingLanguage.ts`](./../src/domain/ScriptingLanguage.ts) enumeration for allowed values.
- `startCode:` *`string`* (**required**) - `startCode:` *`string`* **(required)**
- Code that'll be inserted on top of user created script. - Prepends the given code to the generated script file.
- Global variables such as `$homepage`, `$version`, `$date` can be used using [parameter substitution](./templating.md#parameter-substitution) code syntax such as `Welcome to {{ $homepage }}!` - 💡 You can use global variables such as `$homepage`, `$version`, `$date` via [parameter substitution](./templating.md#parameter-substitution) code syntax such as `Welcome to {{ $homepage }}!`.
- `endCode:` *`string`* (**required**) - `endCode:` *`string`* **(required)**
- Code that'll be inserted at the end of user created script. - Appends to the given code to the generated script file.
- Global variables such as `$homepage`, `$version`, `$date` can be used using [parameter substitution](./templating.md#parameter-substitution) code syntax such as `Welcome to {{ $homepage }}!` - 💡 You can use global variables such as `$homepage`, `$version`, `$date` via [parameter substitution](./templating.md#parameter-substitution) code syntax such as `Welcome to {{ $homepage }}!`.

View File

@@ -0,0 +1,99 @@
# Desktop vs. Web Features
This table highlights differences between the desktop and web versions of `privacy.sexy`.
| Feature | Desktop | Web |
| ------- | ------- | --- |
| [Usage without installation](#usage-without-installation) | 🔴 Not available | 🟢 Available |
| [Offline usage](#offline-usage) | 🟢 Available | 🟡 Partially available |
| [Auto-updates](#auto-updates) | 🟢 Available | 🟢 Available |
| [Logging](#logging) | 🟢 Available | 🔴 Not available |
| [Script execution](#script-execution) | 🟢 Available | 🔴 Not available |
| [Error handling](#error-handling) | 🟢 Advanced | 🟡 Limited |
| [Native dialogs](#native-dialogs) | 🟢 Available | 🔴 Not available |
| [Secure script execution/storage](#secure-script-executionstorage) | 🟢 Available | 🔴 Not available |
## Feature descriptions
### Usage without installation
You can use the web version directly in a browser without installation.
The desktop version requires download and installation.
> **Note for Linux users:** On Linux, privacy.sexy is available as an `AppImage`, a portable format that doesn't need traditional installation.
> This allows Linux users to use the desktop version without full installation, akin to the web version.
### Offline usage
The web version, once loaded, supports offline use.
Desktop version inherently allows offline usage.
### Auto-updates
Both the desktop and web versions of privacy.sexy provide timely access to the latest features and security improvements. The updates are automatically deployed from source code, reflecting the latest changes for enhanced security and reliability. For more details, see [CI/CD documentation](./ci-cd.md).
The desktop version ensures secure delivery through cryptographic signatures and version checks.
[Security is a top priority](./../SECURITY.md#update-security-and-integrity) at privacy.sexy.
> **Note for macOS users:** On macOS, the desktop version's auto-update process involves manual steps due to Apple's code signing costs.
> Users get notified about updates but might need to complete the installation manually.
> Consider [donating](https://github.com/sponsors/undergroundwires) to help improve this process ❤️.
### Logging
The desktop version supports logging of activities to aid in troubleshooting.
This feature is not available in the web version.
Log file locations vary by operating system:
- macOS: `$HOME/Library/Logs/privacy.sexy`
- Linux: `$HOME/.config/privacy.sexy/logs`
- Windows: `%APPDATA%\privacy.sexy\logs`
> 💡 privacy.sexy provides scripts to securely erase these logs.
### Script execution
The desktop version of privacy.sexy enables direct script execution, providing a seamless and integrated experience.
This direct execution capability isn't available in the web version due to inherent browser restrictions.
**Script execution history:**
For enhanced auditability and easier troubleshooting, the desktop version keeps a record of executed scripts in designated directories.
These locations vary based on the operating system:
- macOS: `$HOME/Library/Application Support/privacy.sexy/runs`
- Linux: `$HOME/.config/privacy.sexy/runs`
- Windows: `%APPDATA%\privacy.sexy\runs`
> 💡 privacy.sexy provides scripts to securely erase your script execution history.
### Error handling
The desktop version of privacy.sexy features advanced error handling capabilities.
It employs robust and reliable execution strategies, including self-healing mechanisms, and provides guidance and troubleshooting information to resolve issues effectively.
In contrast, the web version has more basic error handling due to browser limitations and the nature of web applications.
### Native dialogs
The desktop version uses native dialogs, offering more features and reliability compared to the browser's file system dialogs.
These native dialogs provide a more integrated and user-friendly experience, aligning with the operating system's standard interface and functionalities.
### Secure script execution/storage
**Integrity checks:**
The desktop version of privacy.sexy implements robust integrity checks for both script execution and storage.
Featuring tamper protection, the application actively verifies the integrity of script files before executing or saving them.
If the actual contents of a script file do not align with the expected contents, the application refuses to execute or save the script.
This proactive approach ensures only unaltered and verified scripts undergo processing, thereby enhancing both security and reliability.
Due to browser constraints, this feature is absent in the web version.
**Error handling:**
In scenarios where script execution or storage encounters failure, the desktop application initiates automated troubleshooting and self-healing processes.
It also guides users through potential issues with filesystem or third-party software, such as antivirus interventions.
Specifically, the application is capable of identifying when antivirus software blocks or removes a script, providing users with tailored error messages
and detailed resolution steps. This level of proactive error handling and user guidance enhances the application's security and reliability,
offering a feature not achievable in the web version due to browser limitations.

View File

@@ -13,8 +13,11 @@ See [ci-cd.md](./ci-cd.md) for more information.
### Prerequisites ### Prerequisites
- Install Node >16.x. - Install Node.js:
- Refer to [action.yml](./../.github/actions/setup-node/action.yml) for the minimum required version compatible with the automated workflows.
- 💡 Recommended: Use [`nvm`](https://github.com/nvm-sh/nvm) CLI to install and switch between Node.js versions.
- Install dependencies using `npm install` (or [`npm run install-deps`](#utility-scripts) for more options). - Install dependencies using `npm install` (or [`npm run install-deps`](#utility-scripts) for more options).
- For Visual Studio Code users, running the configuration script is recommended to optimize the IDE settings, as detailed in [utility scripts](#utility-scripts).
### Testing ### Testing
@@ -60,6 +63,7 @@ See [ci-cd.md](./ci-cd.md) for more information.
1. Build: `docker build -t undergroundwires/privacy.sexy:latest .` 1. Build: `docker build -t undergroundwires/privacy.sexy:latest .`
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy undergroundwires/privacy.sexy:latest` 2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy undergroundwires/privacy.sexy:latest`
3. Application should be available at [`http://localhost:8080`](http://localhost:8080)
### Building ### Building
@@ -76,19 +80,21 @@ See [ci-cd.md](./ci-cd.md) for more information.
- [**`npm run install-deps [-- <options>]`**](../scripts/npm-install.js): - [**`npm run install-deps [-- <options>]`**](../scripts/npm-install.js):
- Manages NPM dependency installation, it offers capabilities like doing a fresh install, retries on network errors, and other features. - Manages NPM dependency installation, it offers capabilities like doing a fresh install, retries on network errors, and other features.
- For example, you can run `npm run install-deps -- --fresh` to do clean installation of dependencies. - For example, you can run `npm run install-deps -- --fresh` to do clean installation of dependencies.
- [**`./scripts/configure-vscode.sh`**](../scripts/configure-vscode.sh): - [**`python ./scripts/configure_vscode.py`**](../scripts/configure_vscode.py):
- This script checks and sets the necessary configurations for VSCode in `settings.json` file. - Optimizes Visual Studio Code settings and installs essential extensions, enhancing the development environment.
#### Automation scripts #### Automation scripts
- [**`node scripts/print-dist-dir.js [-- <options>]`**](../scripts/print-dist-dir.js): - [**`node scripts/print-dist-dir.js [<options>]`**](../scripts/print-dist-dir.js):
- Determines the absolute path of a distribution directory based on CLI arguments and outputs its absolute path. - Determines the absolute path of a distribution directory based on CLI arguments and outputs its absolute path.
- Primarily used by automation scripts.
- [**`npm run check:verify-build-artifacts [-- <options>]`**](../scripts/verify-build-artifacts.js): - [**`npm run check:verify-build-artifacts [-- <options>]`**](../scripts/verify-build-artifacts.js):
- Verifies the existence and content of build artifacts. Useful for ensuring that the build process is generating the expected output. - Verifies the existence and content of build artifacts. Useful for ensuring that the build process is generating the expected output.
- [**`node scripts/verify-web-server-status.js --url [URL]`**](../scripts/verify-web-server-status.js):
- Checks if a specified server is up with retries and returns an HTTP 200 status code.
## Recommended extensions ## Recommended extensions
You should use EditorConfig to follow project style. You should use EditorConfig to follow project style.
For Visual Studio Code, [`.vscode/extensions.json`](./../.vscode/extensions.json) includes list of recommended extensions. For Visual Studio Code, [`.vscode/extensions.json`](./../.vscode/extensions.json) includes list of recommended extensions.
You can use [VSCode configuration script](#utility-scripts) to automatically install those.

View File

@@ -11,6 +11,8 @@ The presentation layer uses an event-driven architecture for bidirectional react
## Structure ## Structure
- [`/src/` **`presentation/`**](./../src/presentation/): Contains Vue and Electron code. - [`/src/` **`presentation/`**](./../src/presentation/): Contains Vue and Electron code.
- [**`main.ts`**](./../src/presentation/main.ts): Starts Vue app.
- [**`index.html`**](./../src/presentation/index.html): The `index.html` entry file, located at the root of the project as required by Vite
- [**`bootstrapping/`**](./../src/presentation/bootstrapping/): Registers Vue components and plugins. - [**`bootstrapping/`**](./../src/presentation/bootstrapping/): Registers Vue components and plugins.
- [**`components/`**](./../src/presentation/components/): Contains Vue components and helpers. - [**`components/`**](./../src/presentation/components/): Contains Vue components and helpers.
- [**`Shared/`**](./../src/presentation/components/Shared): Contains shared Vue components and helpers. - [**`Shared/`**](./../src/presentation/components/Shared): Contains shared Vue components and helpers.
@@ -20,8 +22,7 @@ The presentation layer uses an event-driven architecture for bidirectional react
- [**`fonts/`**](./../src/presentation/assets/fonts/): Contains fonts. - [**`fonts/`**](./../src/presentation/assets/fonts/): Contains fonts.
- [**`styles/`**](./../src/presentation/assets/styles/): Contains shared styles. - [**`styles/`**](./../src/presentation/assets/styles/): Contains shared styles.
- [**`components/`**](./../src/presentation/assets/styles/components): Contains styles coupled to Vue components. - [**`components/`**](./../src/presentation/assets/styles/components): Contains styles coupled to Vue components.
- [**`main.scss`**](./../src/presentation/assets/styles/main.scss): Main Sass file, imported by other components as single entrypoint. - [**`main.scss`**](./../src/presentation/assets/styles/main.scss): Main Sass file, imported by other components as single entrypoint..
- [**`main.ts`**](./../src/presentation/main.ts): Starts Vue app.
- [**`electron/`**](./../src/presentation/electron/): Contains Electron code. - [**`electron/`**](./../src/presentation/electron/): Contains Electron code.
- [`/main/` **`index.ts`**](./../src/presentation/main.ts): Main entry for Electron, managing application windows and lifecycle events. - [`/main/` **`index.ts`**](./../src/presentation/main.ts): Main entry for Electron, managing application windows and lifecycle events.
- [`/preload/` **`index.ts`**](./../src/presentation/main.ts): Script executed before the renderer, securing Node.js features for renderer use. - [`/preload/` **`index.ts`**](./../src/presentation/main.ts): Script executed before the renderer, securing Node.js features for renderer use.
@@ -31,7 +32,12 @@ The presentation layer uses an event-driven architecture for bidirectional react
## Visual design best-practices ## Visual design best-practices
Add visual clues for clickable items. It should be as clear as possible that they're interactable at first look without hovering. They should also have different visual state when hovering/touching on them that indicates that they are being clicked, which helps with accessibility. - **Clickables**:
Add visual clues for clickable items.
It should be as clear as possible that they're interactable at first look without hovering.
They should also have different visual state when hovering/touching on them that indicates that they are being clicked, which helps with accessibility.
- **Borders**:
privacy.sexy prefers sharper edges in its design language.
## Application data ## Application data
@@ -70,26 +76,30 @@ To add a new dependency:
1. **Define its symbol**: Define an associated symbol for every dependency in [`injectionSymbols.ts`](./../src/presentation/injectionSymbols.ts). Symbols are grouped into: 1. **Define its symbol**: Define an associated symbol for every dependency in [`injectionSymbols.ts`](./../src/presentation/injectionSymbols.ts). Symbols are grouped into:
- **Singletons**: Shared across components, instantiated once. - **Singletons**: Shared across components, instantiated once.
- **Transients**: Factories yielding a new instance on every access. - **Transients**: Factories yielding a new instance on every access.
2. **Provide the dependency**: Modify the [`provideDependencies`](./../src/presentation/bootstrapping/DependencyProvider.ts) function to include the new dependency. [`App.vue`](./../src/presentation/components/App.vue) calls this function within its `setup()` hook to register the dependencies. 2. **Provide the dependency**:
3. **Inject the dependency**: Use Vue's `inject` method alongside the defined symbol to incorporate the dependency into components. Modify the [`provideDependencies`](./../src/presentation/bootstrapping/DependencyProvider.ts) function to include the new dependency.
- For singletons, invoke the factory method: `inject(symbolKey)()`. [`App.vue`](./../src/presentation/components/App.vue) calls this function within its `setup()` hook to register the dependencies.
- For transients, directly inject: `inject(symbolKey)`. 3. **Inject the dependency**: Use `injectKey` to inject a dependency. Pass a selector function to `injectKey` that retrieves the appropriate symbol from the provided dependencies.
- Example usage: `injectKey((keys) => keys.useCollectionState)`;
## Shared UI components ## Shared UI components
Shared UI components promote consistency and simplifies the creation of the front-end. Shared UI components ensure consistency and streamline front-end development.
In order to maintain portability and easy maintainability, the preference is towards using homegrown components over third-party ones or comprehensive UI frameworks like Quasar. We use homegrown components over third-party solutions or comprehensive UI frameworks like Quasar to maintain portability and easy maintenance.
Shared components include: Shared components include:
- [ModalDialog.vue](./../src/presentation/components/Shared/Modal/ModalDialog.vue) is utilized for rendering modal windows. - [ModalDialog.vue](./../src/presentation/components/Shared/Modal/ModalDialog.vue): Renders modal windows.
- [TooltipWrapper.vue](./../src/presentation/components/Shared/TooltipWrapper.vue) acts as a wrapper for rendering tooltips. - [TooltipWrapper.vue](./../src/presentation/components/Shared/TooltipWrapper.vue): Provides tooltip functionality for improved information accessibility.
- [FlatButton.vue](./../src/presentation/components/Shared/FlatButton.vue): Creates flat-style buttons for a unified and consistent user interface.
## Desktop builds ## Desktop builds
Desktop builds uses `electron-vite` to bundle the code, and `electron-builder` to build and publish the packages. Desktop builds uses `electron-vite` to bundle the code, and `electron-builder` to build and publish the packages.
Host system access is strictly controlled. The [`preloader`](./../src/presentation/electron/preload/) isolates logic that interacts with the host system. These functionalities are then securely exposed to the renderer process (Vue application) using context-bridging. [`ApiContextBridge.ts`](./../src/presentation/electron/preload/ContextBridging/ApiContextBridge.ts) handles the configuration of the exposed APIs, ensuring a secure bridge between the Electron and Vue layers.
## Styles ## Styles
### Style location ### Style location

24
docs/research/README.md Normal file
View File

@@ -0,0 +1,24 @@
# Research Documentation
Welcome to the research section of privacy.sexy.
This area houses in-depth technical research and analyses, serving as a resource for developers, contributors, and technology enthusiasts.
**Structure:**
This folder organizes research into topic-specific subdirectories like `windows`, `linux`, etc.
Each contains materials relevant to its subject.
**Contents:**
These documents offer comprehensive insights into the respective topics, supporting development and contributions.
**Contributing:**
Contributions to our research documentation are welcome.
If your research aligns with privacy.sexy goals, please consider adding it here.
See [`CONTRIBUTING.md`](./../../CONTRIBUTING.md) on more information about how to contribute.
**Usage:**
This information is available for educational and research purposes.
We support knowledge sharing and aim to enhance understanding of privacy and security technologies.

View File

@@ -0,0 +1,84 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
InputApp cw5n1h2txyewy System True
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned False
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.Messaging 8wekyb3d8bbwe Provisioned False
Microsoft.Microsoft3DViewer 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdge 8wekyb3d8bbwe System True
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.MixedReality.Portal 8wekyb3d8bbwe Provisioned False
Microsoft.MSPaint 8wekyb3d8bbwe Provisioned False
Microsoft.Office.OneNote 8wekyb3d8bbwe Provisioned False
Microsoft.OneConnect 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.PPIProjection cw5n1h2txyewy System True
Microsoft.Print3D 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SkypeApp kzf8qxf38zg5c Provisioned False
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.Wallet 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.Cortana cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.SecHealthUI cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxApp 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,85 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
Microsoft.549981C3F5F10 8wekyb3d8bbwe Provisioned False
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned False
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.Microsoft3DViewer 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdge 8wekyb3d8bbwe System True
Microsoft.MicrosoftEdge.Stable 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.MixedReality.Portal 8wekyb3d8bbwe Provisioned False
Microsoft.MSPaint 8wekyb3d8bbwe Provisioned False
Microsoft.Office.OneNote 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SkypeApp kzf8qxf38zg5c Provisioned False
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.VCLibs.140.00 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.Wallet 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.Search cw5n1h2txyewy System True
Microsoft.Windows.SecHealthUI cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxApp 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
MicrosoftWindows.Client.CBS cw5n1h2txyewy System True
MicrosoftWindows.UndockedDevKit cw5n1h2txyewy System True
NcsiUwpApp 8wekyb3d8bbwe System True
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,85 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
Microsoft.549981C3F5F10 8wekyb3d8bbwe Provisioned False
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned False
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.Microsoft3DViewer 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdge 8wekyb3d8bbwe System True
Microsoft.MicrosoftEdge.Stable 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.MixedReality.Portal 8wekyb3d8bbwe Provisioned False
Microsoft.MSPaint 8wekyb3d8bbwe Provisioned False
Microsoft.Office.OneNote 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SkypeApp kzf8qxf38zg5c Provisioned False
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.VCLibs.140.00 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.Wallet 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.Search cw5n1h2txyewy System True
Microsoft.Windows.SecHealthUI cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxApp 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
MicrosoftWindows.Client.CBS cw5n1h2txyewy System True
MicrosoftWindows.UndockedDevKit cw5n1h2txyewy System True
NcsiUwpApp 8wekyb3d8bbwe System True
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,85 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
Microsoft.549981C3F5F10 8wekyb3d8bbwe Provisioned False
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned False
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.Microsoft3DViewer 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdge 8wekyb3d8bbwe System True
Microsoft.MicrosoftEdge.Stable 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.MixedReality.Portal 8wekyb3d8bbwe Provisioned False
Microsoft.MSPaint 8wekyb3d8bbwe Provisioned False
Microsoft.Office.OneNote 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SkypeApp kzf8qxf38zg5c Provisioned False
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.VCLibs.140.00 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.Wallet 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.Search cw5n1h2txyewy System True
Microsoft.Windows.SecHealthUI cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxApp 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
MicrosoftWindows.Client.CBS cw5n1h2txyewy System True
MicrosoftWindows.UndockedDevKit cw5n1h2txyewy System True
NcsiUwpApp 8wekyb3d8bbwe System True
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,88 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
Microsoft.549981C3F5F10 8wekyb3d8bbwe Provisioned False
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingNews 8wekyb3d8bbwe Provisioned False
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned True
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GamingApp 8wekyb3d8bbwe Provisioned False
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.MicrosoftEdge 8wekyb3d8bbwe System True
Microsoft.MicrosoftEdge.Stable 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.OneDriveSync 8wekyb3d8bbwe Installed False
Microsoft.Paint 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.PowerAutomateDesktop 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SecHealthUI 8wekyb3d8bbwe Provisioned True
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.Todos 8wekyb3d8bbwe Provisioned False
Microsoft.UI.Xaml.2.4 8wekyb3d8bbwe Provisioned False
Microsoft.VCLibs.140.00 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.Search cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsNotepad 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsTerminal 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
MicrosoftWindows.Client.CBS cw5n1h2txyewy System True
MicrosoftWindows.Client.WebExperience cw5n1h2txyewy Provisioned False
MicrosoftWindows.UndockedDevKit cw5n1h2txyewy System True
NcsiUwpApp 8wekyb3d8bbwe System True
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,91 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
Clipchamp.Clipchamp yxz26nhyzhsrt Provisioned False
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
Microsoft.549981C3F5F10 8wekyb3d8bbwe Provisioned False
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingNews 8wekyb3d8bbwe Provisioned False
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned True
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GamingApp 8wekyb3d8bbwe Provisioned False
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.HEVCVideoExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.MicrosoftEdge 8wekyb3d8bbwe System True
Microsoft.MicrosoftEdge.Stable 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.Paint 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.PowerAutomateDesktop 8wekyb3d8bbwe Provisioned False
Microsoft.RawImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SecHealthUI 8wekyb3d8bbwe Provisioned True
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.Todos 8wekyb3d8bbwe Provisioned False
Microsoft.VCLibs.140.00 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.PrintQueueActionCenter cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsNotepad 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsTerminal 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
MicrosoftCorporationII.QuickAssist 8wekyb3d8bbwe Provisioned False
MicrosoftWindows.Client.CBS cw5n1h2txyewy System True
MicrosoftWindows.Client.Core cw5n1h2txyewy System True
MicrosoftWindows.Client.WebExperience cw5n1h2txyewy Provisioned False
MicrosoftWindows.UndockedDevKit cw5n1h2txyewy System True
NcsiUwpApp 8wekyb3d8bbwe System True
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,91 @@
Name PublisherId Category NonRemovable
---- ----------- -------- ------------
1527c705-839a-4832-9118-54d4Bd6a0c89 cw5n1h2txyewy System True
c5e2524a-ea46-4f67-841f-6a9465d9d515 cw5n1h2txyewy System True
Clipchamp.Clipchamp yxz26nhyzhsrt Provisioned False
E2A4F912-2574-4A75-9BB0-0D023378592B cw5n1h2txyewy System True
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE cw5n1h2txyewy System True
Microsoft.549981C3F5F10 8wekyb3d8bbwe Provisioned False
Microsoft.AAD.BrokerPlugin cw5n1h2txyewy System True
Microsoft.AccountsControl cw5n1h2txyewy System True
Microsoft.AsyncTextService 8wekyb3d8bbwe System True
Microsoft.BingNews 8wekyb3d8bbwe Provisioned False
Microsoft.BingWeather 8wekyb3d8bbwe Provisioned False
Microsoft.BioEnrollment cw5n1h2txyewy System True
Microsoft.CredDialogHost cw5n1h2txyewy System True
Microsoft.DesktopAppInstaller 8wekyb3d8bbwe Provisioned True
Microsoft.ECApp 8wekyb3d8bbwe System True
Microsoft.GamingApp 8wekyb3d8bbwe Provisioned False
Microsoft.GetHelp 8wekyb3d8bbwe Provisioned False
Microsoft.Getstarted 8wekyb3d8bbwe Provisioned False
Microsoft.HEIFImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.HEVCVideoExtension 8wekyb3d8bbwe Provisioned False
Microsoft.LockApp cw5n1h2txyewy System True
Microsoft.MicrosoftEdge.Stable 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftEdgeDevToolsClient 8wekyb3d8bbwe System True
Microsoft.MicrosoftOfficeHub 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftSolitaireCollection 8wekyb3d8bbwe Provisioned False
Microsoft.MicrosoftStickyNotes 8wekyb3d8bbwe Provisioned False
Microsoft.Paint 8wekyb3d8bbwe Provisioned False
Microsoft.People 8wekyb3d8bbwe Provisioned False
Microsoft.PowerAutomateDesktop 8wekyb3d8bbwe Provisioned False
Microsoft.RawImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.ScreenSketch 8wekyb3d8bbwe Provisioned False
Microsoft.SecHealthUI 8wekyb3d8bbwe Provisioned True
Microsoft.StorePurchaseApp 8wekyb3d8bbwe Provisioned False
Microsoft.Todos 8wekyb3d8bbwe Provisioned False
Microsoft.VCLibs.140.00 8wekyb3d8bbwe Provisioned False
Microsoft.VP9VideoExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebMediaExtensions 8wekyb3d8bbwe Provisioned False
Microsoft.WebpImageExtension 8wekyb3d8bbwe Provisioned False
Microsoft.Win32WebViewHost cw5n1h2txyewy System True
Microsoft.Windows.Apprep.ChxApp cw5n1h2txyewy System True
Microsoft.Windows.AssignedAccessLockApp cw5n1h2txyewy System True
Microsoft.Windows.CallingShellApp cw5n1h2txyewy System True
Microsoft.Windows.CapturePicker cw5n1h2txyewy System True
Microsoft.Windows.CloudExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.ContentDeliveryManager cw5n1h2txyewy System True
Microsoft.Windows.NarratorQuickStart 8wekyb3d8bbwe System True
Microsoft.Windows.OOBENetworkCaptivePortal cw5n1h2txyewy System True
Microsoft.Windows.OOBENetworkConnectionFlow cw5n1h2txyewy System True
Microsoft.Windows.ParentalControls cw5n1h2txyewy System True
Microsoft.Windows.PeopleExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.Photos 8wekyb3d8bbwe Provisioned False
Microsoft.Windows.PinningConfirmationDialog cw5n1h2txyewy System True
Microsoft.Windows.PrintQueueActionCenter cw5n1h2txyewy System True
Microsoft.Windows.SecureAssessmentBrowser cw5n1h2txyewy System True
Microsoft.Windows.ShellExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.StartMenuExperienceHost cw5n1h2txyewy System True
Microsoft.Windows.XGpuEjectDialog cw5n1h2txyewy System True
Microsoft.WindowsAlarms 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCalculator 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsCamera 8wekyb3d8bbwe Provisioned False
microsoft.windowscommunicationsapps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsFeedbackHub 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsMaps 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsNotepad 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsSoundRecorder 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsStore 8wekyb3d8bbwe Provisioned False
Microsoft.WindowsTerminal 8wekyb3d8bbwe Provisioned False
Microsoft.Xbox.TCUI 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGameCallableUI cw5n1h2txyewy System True
Microsoft.XboxGameOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxGamingOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.XboxIdentityProvider 8wekyb3d8bbwe Provisioned False
Microsoft.XboxSpeechToTextOverlay 8wekyb3d8bbwe Provisioned False
Microsoft.YourPhone 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneMusic 8wekyb3d8bbwe Provisioned False
Microsoft.ZuneVideo 8wekyb3d8bbwe Provisioned False
MicrosoftCorporationII.QuickAssist 8wekyb3d8bbwe Provisioned False
MicrosoftWindows.Client.CBS cw5n1h2txyewy System True
MicrosoftWindows.Client.Core cw5n1h2txyewy System True
MicrosoftWindows.Client.FileExp cw5n1h2txyewy System True
MicrosoftWindows.Client.WebExperience cw5n1h2txyewy Provisioned False
MicrosoftWindows.UndockedDevKit cw5n1h2txyewy System True
NcsiUwpApp 8wekyb3d8bbwe System True
Windows.CBSPreview cw5n1h2txyewy System True
windows.immersivecontrolpanel cw5n1h2txyewy System True
Windows.PrintDialog cw5n1h2txyewy System True

View File

@@ -0,0 +1,46 @@
# Research on Windows
In this section, we maintain a structured approach to our research on Windows.
The use of `01` prefixed file names aids in organizing and retrieving search results effectively.
## Apps
The PowerShell script below serves as a method for gathering detailed information about Windows packages.
```ps1
$allPackages = @()
$provisionedPackages = Get-AppxProvisionedPackage -Online
foreach ($installedPackage in Get-AppxPackage -AllUsers) {
if ($installedPackage.IsFramework -eq $true) {
continue
}
$allPackages += [PSCustomObject]@{
Name = $installedPackage.Name
PublisherId = $installedPackage.PublisherId
Category = if ($installedPackage.SignatureKind -eq "System") {
'System'
} elseif ($provisionedPackages | Where-Object { $_.DisplayName -eq $installedPackage.Name }) {
'Provisioned'
} else {
'Installed'
}
NonRemovable = $installedPackage.NonRemovable
}
}
foreach ($provisionedPackage in $provisionedPackages) {
if ($allPackages | Where-Object { $_.Name -eq $provisionedPackage.DisplayName }) {
continue
}
$allPackages += [PSCustomObject]@{
Name = $provisionedPackage.DisplayName
PublisherId = $provisionedPackage.PackageName -split '_' | Select-Object -Last 1
Category = 'Provisioned'
NonRemovable = $false
}
}
$allPackages `
| Sort-Object Name `
| Select-Object Name, PublisherId, Category, NonRemovable `
| Format-Table `
| Out-File -FilePath "$([System.Environment]::GetFolderPath('Desktop'))\apps.txt"
```

57
docs/script-guidelines.md Normal file
View File

@@ -0,0 +1,57 @@
# privacy.sexy Script Guidelines
Create a script for privacy.sexy by submitting a PR or creating an issue (details in [Extend Scripts](./../CONTRIBUTING.md#extend-scripts)).
As scripts are central to privacy.sexy and reach a global audience, their design is critical.
Key attributes of a good script:
- ✅ Well-referenced [documentation](#documentation).
- ✅ Utilizes [shared functions](#shared-functions).
- ✅ Has a [simple name](#name).
## Name
- Choose a title that is easy to understand for all users, regardless of technical skill, yet remains technically accurate.
- Focus on privacy implications, avoiding complex or overly technical jargon.
- Maintain consistency in naming, avoiding linguistic variations.
- Use action-oriented language for clarity and directness. Use an instruction format like "do this, do that" for clear, direct guidance.
- Respect the official casing of brand names.
- Choose clear and uncomplicated language.
- It should start with an imperative noun.
- Start with action verbs like `Clear`, `Disable`, `Remove`, `Configure`, `Minimize`, `Maximize`. While exceptions exist, these prefixes help maintain naming consistency.
- The scripts that modify hosts file should start with `Block ..`.
- Favor the terms:
- `Disable` over `Turn off`, `Stop`, `Prevent`
- `Configure` over `Set up`
- `Clear` over `Erase`, `Clean`
- `Minimize` over `Limit`, `Reduce`
- `Maximize` over `Extend`, `Delay`, `Postpone`, `Prolong`
- `Remove` over `Uninstall`
- Structure your phrases for clarity, examples:
- Prefer `Disable XX telemetry` over `Disable telemetry in XX`
- Prefer `Clear XX data` over `Clear data from XX`, or `Clear data of XX`.
- Use sentence case rather than Title Case.
## Documentation
- Use credible and reputable sources for references.
- Use archived links by using [archive.org](https://archive.org) or [archive.today](https://archive.today).
- Format archive.today links fully, for example: `https://archive.today/YYYYMMDDhhmmss/https://privacy.sexy`.
- Explain the default behavior if the script is not executed.
## Shared functions
Use existing shared functions when possible, like `DisableService` for disabling services,.
- 📖 Learn about templates in [templating.md](./templating.md).
- 📖 For syntax, see [collection-files.md](collection-files.md).
## Code
- Prefer [shared functions](#shared-functions); avoid custom code unless necessary.
- Keep code simple and compatible with older systems.
- Focus on reliability, ensuring the script is error-resistant, works on different locales and handles unexpected situations.
- Language selection:
- Windows: Use batch when simpler, otherwise PowerShell.
- macOS/Linux: Use bash when simpler, otherwise Python.
- Provide revert code to restore original/default settings when applicable.

View File

@@ -2,21 +2,69 @@
## Benefits of templating ## Benefits of templating
- Generating scripts by sharing code to increase best-practice usage and maintainability. - **Code sharing:** Share code across scripts for consistent practices and easier maintenance.
- Creating self-contained scripts without cross-dependencies. - **Script independence:** Generate self-contained scripts, eliminating the need for external code.
- Use of pipes for writing cleaner code and letting pipes do dirty work. - **Cleaner code:** Use pipes for complex operations, resulting in more readable and streamlined code.
## Expressions ## Expressions
- Expressions start and end with mustaches (double brackets, `{{` and `}}`). **Syntax:**
- E.g. `Hello {{ $name }} !`
- Syntax is close to [Go Templates ❤️](https://pkg.go.dev/text/template) but not the same. Expressions are enclosed within `{{` and `}}`.
- Functions enables usage of expressions. Example: `Hello {{ $name }}!`.
- In script definition parts of a function, see [`Function`](./collection-files.md#Function). They are a core component of templating, enhancing scripts with dynamic capabilities and functionality.
- When doing a call as argument values, see [`FunctionCall`](./collection-files.md#Function).
- Expressions inside expressions (nested templates) are supported. **Syntax similarity:**
- An expression can output another expression that will also be compiled.
- E.g. following would compile first [with expression](#with), and then [parameter substitution](#parameter-substitution) in its output. The syntax shares similarities with [Go Templates ❤️](https://pkg.go.dev/text/template), but with some differences:
**Function definitions:**
You can use expressions in function definition.
Refer to [Function](./collection-files.md#function) for more details.
Example usage:
```yaml
name: GreetFunction
parameters:
- name: name
code: Hello {{ $name }}!
```
If you assign `name` the value `world`, invoking `GreetFunction` would result in `Hello world!`.
**Function arguments:**
You can also use expressions in arguments in nested function calls.
Refer to [`Function | collection-files.md`](./collection-files.md#functioncall) for more details.
Example with nested function calls:
```yaml
-
name: PrintMessageFunction
parameters:
- name: message
code: echo "{{ $message }}"
-
name: GreetUserFunction
parameters:
- name: userName
call:
name: PrintMessageFunction
parameters:
argument: 'Hello, {{ $userName }}!'
```
Here, if `userName` is `Alice`, invoking `GreetUserFunction` would execute `echo "Hello, Alice!"`.
**Nested templates:**
You can nest expressions inside expressions (also called "nested templates").
This means that an expression can output another expression where compiler will compile both.
For example, following would compile first [with expression](#with), and then [parameter substitution](#parameter-substitution) in its output:
```go ```go
{{ with $condition }} {{ with $condition }}
@@ -26,55 +74,70 @@
### Parameter substitution ### Parameter substitution
A simple function example: Parameter substitution dynamically replaces variable references with their corresponding values in the script.
**Example function:**
```yaml ```yaml
function: EchoArgument name: DisplayTextFunction
parameters: parameters:
- name: 'argument' - name: 'text'
code: Hello {{ $argument }} ! code: echo {{ $text }}
``` ```
It would print "Hello world" if it's called in a [script](./collection-files.md#script) as following: Invoking `DisplayTextFunction` with `text` set to `"Hello, world!"` would result in `echo "Hello, World!"`.
```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 ### with
Skips its "block" if the variable is absent or empty. Its "block" is between `with` start (`{{ with .. }}`) and end (`{{ end }`}) expressions. The `with` expression enables conditional rendering and provides a context variable for simpler code.
E.g. `{{ with $parameterName }} Hi, I'm a block! {{ end }}` would only output `Hi, I'm a block!` if `parameterName` has any value..
It binds its context (value of the provided parameter value) as arbitrary `.` value. It allows you to use the argument value of the given parameter when it is provided and not empty such as: **Optional block rendering:**
If the provided variable is falsy (`false`, `null`, or empty), the compiler skips the enclosed block of code.
A "block" lies between the with start (`{{ with .. }}`) and end (`{{ end }}`) expressions, defining its boundaries.
Example:
```go
{{ with $optionalVariable }}
Hello
{{ end }}
```
This would display `Hello` if `$optionalVariable` is truthy.
**Parameter declaration:**
You should set `optional: true` for the argument if you use it like `{{ with $argument }} .. {{ end }}`.
Declare parameters used for `with` condition as optional such as:
```yaml
name: ConditionalOutputFunction
parameters:
- name: 'data'
optional: true
code: |-
{{ with $data }}
Data is: {{ . }}
{{ end }}
```
**Context variable:**
`with` statement binds its context (value of the provided parameter value) as arbitrary `.` value.
`{{ . }}` syntax gives you access to the context variable.
This is optional to use, and not required to use `with` expressions.
For example:
```go ```go
{{ with $parameterName }}Parameter value is {{ . }} here {{ end }} {{ with $parameterName }}Parameter value is {{ . }} here {{ end }}
``` ```
It supports multiline text inside the block. You can have something like: **Multiline text:**
It supports multiline text inside the block. You can write something like:
```go ```go
{{ with $argument }} {{ with $argument }}
@@ -83,7 +146,9 @@ It supports multiline text inside the block. You can have something like:
{{ end }} {{ end }}
``` ```
You can also use other expressions inside its block, such as [parameter substitution](#parameter-substitution): **Inner expressions:**
You can also embed other expressions inside its block, such as [parameter substitution](#parameter-substitution):
```go ```go
{{ with $condition }} {{ with $condition }}
@@ -91,32 +156,44 @@ You can also use other expressions inside its block, such as [parameter substitu
{{ end }} {{ end }}
``` ```
💡 Declare parameters used for `with` condition as optional. Set `optional: true` for the argument if you use it like `{{ with $argument }} .. {{ end }}`. This also includes nesting `with` statements:
Example: ```go
{{ with $condition1 }}
```yaml Value of $condition1: {{ . }}
function: FunctionThatOutputsConditionally {{ with $condition2 }}
parameters: Value of $condition2: {{ . }}
- name: 'argument' {{ end }}
optional: true
code: |-
{{ with $argument }}
Value is: {{ . }}
{{ end }} {{ end }}
``` ```
### Pipes ### Pipes
- Pipes are functions available for handling text. Pipes are functions designed for text manipulation.
- Allows stacking actions one after another also known as "chaining". They allow for a sequential application of operations resembling [Unix pipelines](https://en.wikipedia.org/wiki/Pipeline_(Unix)), also known as "chaining".
- 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. Each pipeline's output becomes the input of the following pipe.
- You cannot create pipes. [A dedicated compiler](./application.md#parsing-and-compiling) provides pre-defined pipes to consume in collection files.
- You can combine pipes with other expressions such as [parameter substitution](#parameter-substitution) and [with](#with) syntax. **Pre-defined**:
- ❗ Pipe names must be camelCase without any space or special characters.
- **Existing pipes** Pipes are pre-defined by the system.
You cannot create pipes in [collection files](./collection-files.md).
[A dedicated compiler](./application.md#parsing-and-compiling) provides pre-defined pipes to consume in collection files.
**Compatibility:**
You can combine pipes with other expressions such as [parameter substitution](#parameter-substitution) and [with](#with) syntax.
For example:
```go
{{ with $script }} echo "{{ . | inlinePowerShell | escapeDoubleQuotes }}" {{ end }}
```
**Naming:**
❗ Pipe names must be camelCase without any space or special characters.
**Available pipes:**
- `inlinePowerShell`: Converts a multi-lined PowerShell script to a single line. - `inlinePowerShell`: Converts a multi-lined PowerShell script to a single line.
- `escapeDoubleQuotes`: Escapes `"` characters, allows you to use them inside double quotes (`"`). - `escapeDoubleQuotes`: Escapes `"` characters for batch command execution, allows you to use them inside double quotes (`"`).
- **Example usages**
- `{{ with $code }} echo "{{ . | inlinePowerShell }}" {{ end }}`
- `{{ with $code }} echo "{{ . | inlinePowerShell | escapeDoubleQuotes }}" {{ end }}`

View File

@@ -29,7 +29,9 @@ There are different types of tests executed:
- Evaluate individual components in isolation. - Evaluate individual components in isolation.
- Located in [`./tests/unit`](./../tests/unit). - Located in [`./tests/unit`](./../tests/unit).
- Achieve isolation using [stubs](./../tests/unit/shared/Stubs). - Achieve isolation using stubs where you place:
- Common stubs in [`./shared/Stubs`](./../tests/unit/shared/Stubs),
- Component-specific stubs in same folder as test file.
- Include Vue component tests, enabled by `@vue/test-utils`. - Include Vue component tests, enabled by `@vue/test-utils`.
#### Unit tests naming #### Unit tests naming
@@ -56,6 +58,11 @@ These checks validate various qualities like runtime execution, building process
- Use [various tools](./../package.json) and [scripts](./../scripts). - Use [various tools](./../package.json) and [scripts](./../scripts).
- Are automatically executed as [GitHub workflows](./../.github/workflows). - Are automatically executed as [GitHub workflows](./../.github/workflows).
### Security checks
- [`checks.security.sast`](./../.github/workflows/checks.security.sast.yaml): Utilizes CodeQL to conduct Static Analysis Security Testing (SAST) to ensure the secure integrity of the codebase.
- [`checks.security.dependencies`](./../.github/workflows/checks.security.dependencies.yaml): Performs audits on third-party dependencies to identify and mitigate potential vulnerabilities, safeguarding the project from exploitable weaknesses.
## Tests structure ## Tests structure
- [`package.json`](./../package.json): Defines test commands and includes tools used in tests. - [`package.json`](./../package.json): Defines test commands and includes tools used in tests.
@@ -63,21 +70,23 @@ These checks validate various qualities like runtime execution, building process
- [`./src/`](./../src/): Contains the code subject to testing. - [`./src/`](./../src/): Contains the code subject to testing.
- [`./tests/shared/`](./../tests/shared/): Contains code shared by different test categories. - [`./tests/shared/`](./../tests/shared/): Contains code shared by different test categories.
- [`bootstrap/setup.ts`](./../tests/shared/bootstrap/setup.ts): Initializes unit and integration tests. - [`bootstrap/setup.ts`](./../tests/shared/bootstrap/setup.ts): Initializes unit and integration tests.
- [`Assertions/`](./../tests/shared/Assertions/): Contains common assertion functions, prefixed with `expect`.
- [`./tests/unit/`](./../tests/unit/) - [`./tests/unit/`](./../tests/unit/)
- Stores unit test code. - Stores unit test code.
- The directory structure mirrors [`./src/`](./../src). - The directory structure mirrors [`./src/`](./../src).
- E.g., tests for [`./src/application/ApplicationFactory.ts`](./../src/application/ApplicationFactory.ts) reside in [`./tests/unit/application/ApplicationFactory.spec.ts`](./../tests/unit/application/ApplicationFactory.spec.ts). - E.g., tests for [`./src/application/ApplicationFactory.ts`](./../src/application/ApplicationFactory.ts) reside in [`./tests/unit/application/ApplicationFactory.spec.ts`](./../tests/unit/application/ApplicationFactory.spec.ts).
- [`shared/`](./../tests/unit/shared/) - [`shared/`](./../tests/unit/shared/)
- Contains shared unit test functionalities. - Contains shared unit test functionalities.
- [`Assertions/`](./../tests/unit/shared/Assertions): Contains common assertion functions, prefixed with `expect`.
- [`TestCases/`](./../tests/unit/shared/TestCases/) - [`TestCases/`](./../tests/unit/shared/TestCases/)
- Shared test cases. - Shared test cases.
- Functions that calls `it()` from [Vitest](https://vitest.dev/) should have `it` prefix. - Functions that calls `it()` from [Vitest](https://vitest.dev/) should have `it` prefix.
- [`Stubs/`](./../tests/unit/shared/Stubs): Maintains stubs for component isolation, equipped with basic functionalities and, when necessary, spying or mocking capabilities. - [`Stubs/`](./../tests/unit/shared/Stubs): Maintains stubs for component isolation, equipped with basic functionalities and, when necessary, spying or mocking capabilities.
- [`./tests/integration/`](./../tests/integration/): Contains integration test files. - [`./tests/integration/`](./../tests/integration/): Contains integration test files.
- [`cypress.config.ts`](./../cypress.config.ts): Cypress (E2E tests) configuration file. - [`cypress.config.ts`](./../cypress.config.ts): Cypress (E2E tests) configuration file.
- [`cypress-dirs.json`](./../cypress-dirs.json): A central definition of directories used by Cypress, designed for reuse across different configurations.
- [`./tests/e2e/`](./../tests/e2e/): Base Cypress folder, includes tests with `.cy.ts` extension. - [`./tests/e2e/`](./../tests/e2e/): Base Cypress folder, includes tests with `.cy.ts` extension.
- [`/support/e2e.ts`](./../tests/e2e/support/e2e.ts): Support file, runs before every single spec file.
- [`/tsconfig.json`]: TypeScript configuration for file Cypress code, improves IDE support, recommended to have by official documentation. - [`/tsconfig.json`]: TypeScript configuration for file Cypress code, improves IDE support, recommended to have by official documentation.
- *(git ignored)* `/videos`: Asset folder for videos taken during tests. - *(git ignored)* `/videos`: Asset folder for videos taken during tests.
- *(git ignored)* `/screenshots`: Asset folder for Screenshots taken during tests. - *(git ignored)* `/screenshots`: Asset folder for Screenshots taken during tests.
- [`/support/e2e.ts`](./../tests/e2e/support/e2e.ts): Support file, runs before every single test file.
- [`/support/interactions/`](./../tests/e2e/support/interactions/): Contains reusable functions for simulating user interactions, enhancing test readability and maintainability.

View File

@@ -1,6 +1,6 @@
/* eslint-disable no-template-curly-in-string */ /* eslint-disable no-template-curly-in-string */
const { join } = require('path'); const { join } = require('node:path');
const { electronBundled, electronUnbundled } = require('./dist-dirs.json'); const { electronBundled, electronUnbundled } = require('./dist-dirs.json');
module.exports = { module.exports = {

View File

@@ -1,22 +1,28 @@
import { resolve } from 'path'; import { resolve } from 'node:path';
import { mergeConfig, UserConfig } from 'vite'; import { mergeConfig, type UserConfig } from 'vite';
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'; import { defineConfig, externalizeDepsPlugin } from 'electron-vite';
import { getAliasesFromTsConfig, getClientEnvironmentVariables } from './vite-config-helper'; import { getAliases, getClientEnvironmentVariables } from './vite-config-helper';
import { createVueConfig } from './vite.config'; import { createVueConfig } from './vite.config';
import distDirs from './dist-dirs.json' assert { type: 'json' }; import distDirs from './dist-dirs.json' assert { type: 'json' };
const MAIN_ENTRY_FILE = resolvePathFromProjectRoot('src/presentation/electron/main/index.ts'); const MAIN_ENTRY_FILE = resolvePathFromProjectRoot('src/presentation/electron/main/index.ts');
const PRELOAD_ENTRY_FILE = resolvePathFromProjectRoot('src/presentation/electron/preload/index.ts'); const PRELOAD_ENTRY_FILE = resolvePathFromProjectRoot('src/presentation/electron/preload/index.ts');
const WEB_INDEX_HTML_PATH = resolvePathFromProjectRoot('src/presentation/index.html'); const WEB_INDEX_HTML_PATH = resolvePathFromProjectRoot('src/presentation/index.html');
const DIST_DIR = resolvePathFromProjectRoot(distDirs.electronUnbundled); const ELECTRON_DIST_SUBDIRECTORIES = {
main: resolveElectronDistSubdirectory('main'),
preload: resolveElectronDistSubdirectory('preload'),
renderer: resolveElectronDistSubdirectory('renderer'),
};
process.env.ELECTRON_ENTRY = resolve(ELECTRON_DIST_SUBDIRECTORIES.main, 'index.cjs');
export default defineConfig({ export default defineConfig({
main: getSharedElectronConfig({ main: getSharedElectronConfig({
distDirSubfolder: 'main', distDirSubfolder: ELECTRON_DIST_SUBDIRECTORIES.main,
entryFilePath: MAIN_ENTRY_FILE, entryFilePath: MAIN_ENTRY_FILE,
}), }),
preload: getSharedElectronConfig({ preload: getSharedElectronConfig({
distDirSubfolder: 'preload', distDirSubfolder: ELECTRON_DIST_SUBDIRECTORIES.preload,
entryFilePath: PRELOAD_ENTRY_FILE, entryFilePath: PRELOAD_ENTRY_FILE,
}), }),
renderer: mergeConfig( renderer: mergeConfig(
@@ -25,7 +31,7 @@ export default defineConfig({
}), }),
{ {
build: { build: {
outDir: resolve(DIST_DIR, 'renderer'), outDir: ELECTRON_DIST_SUBDIRECTORIES.renderer,
rollupOptions: { rollupOptions: {
input: { input: {
index: WEB_INDEX_HTML_PATH, index: WEB_INDEX_HTML_PATH,
@@ -42,13 +48,15 @@ function getSharedElectronConfig(options: {
}): UserConfig { }): UserConfig {
return { return {
build: { build: {
outDir: resolve(DIST_DIR, options.distDirSubfolder), outDir: options.distDirSubfolder,
lib: { lib: {
entry: options.entryFilePath, entry: options.entryFilePath,
}, },
rollupOptions: { rollupOptions: {
output: { output: {
entryFileNames: '[name].cjs', // This is needed so `type="module"` works // Mark: electron-esm-support
// This is needed so `type="module"` works
entryFileNames: '[name].cjs',
}, },
}, },
}, },
@@ -58,12 +66,17 @@ function getSharedElectronConfig(options: {
}, },
resolve: { resolve: {
alias: { alias: {
...getAliasesFromTsConfig(), ...getAliases(),
}, },
}, },
}; };
} }
function resolvePathFromProjectRoot(pathSegment: string) { function resolvePathFromProjectRoot(pathSegment: string): string {
return resolve(__dirname, pathSegment); return resolve(__dirname, pathSegment);
} }
function resolveElectronDistSubdirectory(subDirectory: string): string {
const electronDistDir = resolvePathFromProjectRoot(distDirs.electronUnbundled);
return resolve(electronDistDir, subDirectory);
}

View File

@@ -1 +0,0 @@
<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: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 116 KiB

15600
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,11 @@
{ {
"name": "privacy.sexy", "name": "privacy.sexy",
"version": "0.12.3", "version": "0.13.0",
"private": true, "private": true,
"slogan": "Now you have the choice", "slogan": "Privacy is sexy",
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy 🍑🍆", "description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.",
"author": "undergroundwires", "author": "undergroundwires",
"type": "module", "type": "module",
"main": "./dist-electron-unbundled/main/index.cjs",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vue-tsc --noEmit && vite build", "build": "vue-tsc --noEmit && vite build",
@@ -25,7 +24,7 @@
"electron:preview": "electron-vite preview", "electron:preview": "electron-vite preview",
"electron:prebuild": "electron-vite build", "electron:prebuild": "electron-vite build",
"electron:build": "electron-builder", "electron:build": "electron-builder",
"lint:eslint": "eslint . --ignore-path .gitignore", "lint:eslint": "eslint . --max-warnings=0 --ignore-path .gitignore",
"lint:md": "markdownlint **/*.md --ignore node_modules", "lint:md": "markdownlint **/*.md --ignore node_modules",
"lint:md:consistency": "remark . --frail --use remark-preset-lint-consistent", "lint:md:consistency": "remark . --frail --use remark-preset-lint-consistent",
"lint:md:relative-urls": "remark . --frail --use remark-validate-links", "lint:md:relative-urls": "remark . --frail --use remark-validate-links",
@@ -35,77 +34,71 @@
}, },
"dependencies": { "dependencies": {
"@floating-ui/vue": "^1.0.2", "@floating-ui/vue": "^1.0.2",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^2.0.9",
"@juggle/resize-observer": "^3.4.0", "@juggle/resize-observer": "^3.4.0",
"ace-builds": "^1.23.4", "@types/markdown-it": "^13.0.7",
"cross-fetch": "^4.0.0", "ace-builds": "^1.30.0",
"electron-log": "^5.0.1",
"electron-progressbar": "^2.1.0", "electron-progressbar": "^2.1.0",
"electron-updater": "^6.1.4",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"markdown-it": "^13.0.1", "markdown-it": "^13.0.2",
"npm": "^9.8.1", "vue": "^3.3.7"
"vue": "^2.7.14"
}, },
"devDependencies": { "devDependencies": {
"@modyfi/vite-plugin-yaml": "^1.0.4", "@modyfi/vite-plugin-yaml": "^1.1.0",
"@rushstack/eslint-patch": "^1.3.2", "@rushstack/eslint-patch": "^1.6.1",
"@types/ace": "^0.0.48", "@types/ace": "^0.0.49",
"@types/file-saver": "^2.0.5", "@types/file-saver": "^2.0.5",
"@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^5.62.0", "@typescript-eslint/parser": "^6.17.0",
"@vitejs/plugin-legacy": "^4.1.1", "@vitejs/plugin-legacy": "^5.3.2",
"@vitejs/plugin-vue2": "^2.2.0", "@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-airbnb-with-typescript": "^7.0.0", "@vue/eslint-config-airbnb-with-typescript": "^8.0.0",
"@vue/eslint-config-typescript": "^11.0.3", "@vue/eslint-config-typescript": "^12.0.0",
"@vue/test-utils": "^1.3.6", "@vue/test-utils": "^2.4.1",
"autoprefixer": "^10.4.15", "autoprefixer": "^10.4.16",
"cypress": "^12.17.2", "cypress": "^13.3.1",
"electron": "^25.3.2", "electron": "^27.0.0",
"electron-builder": "^24.6.3", "electron-builder": "^24.6.4",
"electron-devtools-installer": "^3.2.0", "electron-devtools-installer": "^3.2.0",
"electron-icon-builder": "^2.0.1", "electron-icon-builder": "^2.0.1",
"electron-log": "^4.4.8", "electron-vite": "^2.1.0",
"electron-updater": "^6.1.4", "eslint": "^8.56.0",
"electron-vite": "^1.0.27", "eslint-plugin-cypress": "^2.15.1",
"eslint": "^8.46.0", "eslint-plugin-vue": "^9.19.2",
"eslint-plugin-cypress": "^2.14.0", "eslint-plugin-vuejs-accessibility": "^2.2.0",
"eslint-plugin-vue": "^9.6.0", "icon-gen": "^4.0.0",
"eslint-plugin-vuejs-accessibility": "^1.2.0",
"icon-gen": "^3.0.1",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"markdownlint-cli": "^0.35.0", "markdownlint-cli": "^0.37.0",
"postcss": "^8.4.28", "postcss": "^8.4.31",
"remark-cli": "^11.0.0", "remark-cli": "^12.0.0",
"remark-lint-no-dead-urls": "^1.1.0", "remark-lint-no-dead-urls": "^1.1.0",
"remark-preset-lint-consistent": "^5.1.2", "remark-preset-lint-consistent": "^5.1.2",
"remark-validate-links": "^12.1.1", "remark-validate-links": "^13.0.0",
"sass": "^1.64.1", "sass": "^1.69.3",
"start-server-and-test": "^2.0.0", "start-server-and-test": "^2.0.1",
"svgexport": "^0.4.2", "svgexport": "^0.4.2",
"terser": "^5.19.2", "terser": "^5.21.0",
"tslib": "~2.4.0", "tslib": "^2.6.2",
"typescript": "~4.6.2", "typescript": "^5.3.3",
"vite": "^4.4.9", "vite": "^5.1.6",
"vitest": "^0.34.2", "vitest": "^0.34.6",
"vue-tsc": "^1.8.8", "vue-tsc": "^1.8.19",
"yaml-lint": "^1.7.0" "yaml-lint": "^1.7.0"
}, },
"//devDependencies": { "//devDependencies": {
"terser": "Used by @vitejs/plugin-legacy for minification", "terser": "Used by `@vitejs/plugin-legacy` for minification",
"typescript": [ "@rushstack/eslint-patch": "Needed by `@vue/eslint-config-typescript` and `@vue/eslint-config-airbnb-with-typescript`"
"Cannot upgrade to 5.X.X due to unmaintained @vue/cli-plugin-typescript, https://github.com/vuejs/vue-cli/issues/7401",
"Cannot upgrade to > 4.6.X otherwise unit tests do not work, https://github.com/evanw/node-source-map-support/issues/252"
],
"tslib": "Cannot upgrade to > 2.4.X otherwise unit tests do not work, https://github.com/evanw/node-source-map-support/issues/252",
"@typescript-eslint/eslint-plugin": "Cannot upgrade to 6.X.X due to @vue/eslint-config-typescript, https://github.com/vuejs/eslint-config-typescript/pull/60",
"@typescript-eslint/parser": "Cannot upgrade to 6.X.X due to @vue/eslint-config-typescript, https://github.com/vuejs/eslint-config-typescript/pull/60"
}, },
"homepage": "https://privacy.sexy", "homepage": "https://privacy.sexy",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/undergroundwires/privacy.sexy.git" "url": "https://github.com/undergroundwires/privacy.sexy.git"
},
"optionalDependencies": {
"dmg-license": "^1.0.11"
},
"//optionalDependencies": {
"dmg-license": "Required by `electron-builder` for DMG builds on macOS, https://github.com/electron-userland/electron-builder/issues/6489, https://github.com/electron-userland/electron-builder/issues/6520"
} }
} }

View File

@@ -1,74 +0,0 @@
#!/usr/bin/env bash
# This script ensures that the '.vscode/settings.json' file exists and is configured correctly for ESLint validation on Vue and JavaScript files.
# See https://web.archive.org/web/20230801024405/https://eslint.vuejs.org/user-guide/#visual-studio-code
declare -r SETTINGS_FILE='.vscode/settings.json'
declare -ra CONFIG_KEYS=('vue' 'javascript' 'typescript')
declare -r TEMP_FILE="tmp.$$.json"
main() {
ensure_vscode_directory_exists
create_or_update_settings
}
ensure_vscode_directory_exists() {
local dir_name
dir_name=$(dirname "${SETTINGS_FILE}")
if [[ ! -d ${dir_name} ]]; then
mkdir -p "${dir_name}"
echo "🎉 Created directory: ${dir_name}"
fi
}
create_or_update_settings() {
if [[ ! -f ${SETTINGS_FILE} ]]; then
create_default_settings
else
add_or_update_eslint_validate
fi
}
create_default_settings() {
local default_validate
default_validate=$(printf '%s' "${CONFIG_KEYS[*]}" | jq -R -s -c -M 'split(" ")')
echo "{ \"eslint.validate\": ${default_validate} }" | jq '.' > "${SETTINGS_FILE}"
echo "🎉 Created default ${SETTINGS_FILE}"
}
add_or_update_eslint_validate() {
if ! jq -e '.["eslint.validate"]' "${SETTINGS_FILE}" >/dev/null; then
add_default_eslint_validate
else
update_eslint_validate
fi
}
add_default_eslint_validate() {
jq --argjson keys "$(printf '%s' "${CONFIG_KEYS[*]}" \
| jq -R -s -c 'split(" ")')" '. += {"eslint.validate": $keys}' "${SETTINGS_FILE}" > "${TEMP_FILE}"
replace_and_confirm
echo "🎉 Added default 'eslint.validate' to ${SETTINGS_FILE}"
}
update_eslint_validate() {
local existing_keys
existing_keys=$(jq '.["eslint.validate"]' "${SETTINGS_FILE}")
for key in "${CONFIG_KEYS[@]}"; do
if ! echo "${existing_keys}" | jq 'index("'"${key}"'")' >/dev/null; then
jq '.["eslint.validate"] += ["'"${key}"'"]' "${SETTINGS_FILE}" > "${TEMP_FILE}"
mv "${TEMP_FILE}" "${SETTINGS_FILE}"
echo "🎉 Updated 'eslint.validate' in ${SETTINGS_FILE} for ${key}"
else
echo "⏩️ No updated needed for ${key} ${SETTINGS_FILE}."
fi
done
}
replace_and_confirm() {
if mv "${TEMP_FILE}" "${SETTINGS_FILE}"; then
echo "🎉 Updated ${SETTINGS_FILE}"
fi
}
main

181
scripts/configure_vscode.py Executable file
View File

@@ -0,0 +1,181 @@
"""
This script configures project-level VSCode settings in '.vscode/settings.json' for
development and installs recommended extensions from '.vscode/extensions.json'.
"""
# pylint: disable=missing-function-docstring
import os
import json
from pathlib import Path
import subprocess
import sys
import re
from typing import Any, Optional
from shutil import which
VSCODE_SETTINGS_JSON_FILE: str = '.vscode/settings.json'
VSCODE_EXTENSIONS_JSON_FILE: str = '.vscode/extensions.json'
def main() -> None:
ensure_vscode_directory_exists()
ensure_setting_file_exists()
add_or_update_settings()
install_recommended_extensions()
def ensure_vscode_directory_exists() -> None:
vscode_directory_path = os.path.dirname(VSCODE_SETTINGS_JSON_FILE)
try:
os.makedirs(vscode_directory_path, exist_ok=True)
print_success(f"Created or verified directory: {vscode_directory_path}")
except OSError as error:
print_error(f"Error handling directory {vscode_directory_path}: {error}")
def ensure_setting_file_exists() -> None:
try:
if os.path.isfile(VSCODE_SETTINGS_JSON_FILE):
print_success(f"VSCode settings file exists: {VSCODE_SETTINGS_JSON_FILE}")
return
with open(VSCODE_SETTINGS_JSON_FILE, 'w', encoding='utf-8') as file:
json.dump({}, file, indent=4)
print_success(f"Created empty {VSCODE_SETTINGS_JSON_FILE}")
except IOError as error:
print_error(f"Error creating file {VSCODE_SETTINGS_JSON_FILE}: {error}")
print(f"📄 Created empty {VSCODE_SETTINGS_JSON_FILE}")
def add_or_update_settings() -> None:
configure_setting_key('eslint.validate', ['vue', 'javascript', 'typescript'])
# Set ESLint validation for specific file types.
# Details: # pylint: disable-next=line-too-long
# - https://web.archive.org/web/20230801024405/https://eslint.vuejs.org/user-guide/#visual-studio-code
configure_setting_key('terminal.integrated.env.linux', {"GTK_PATH": ""})
# Unset GTK_PATH on Linux for Electron development in sandboxed environments
# like Snap or Flatpak VSCode installations, enabling script execution.
# Details: # pylint: disable-next=line-too-long
# - https://archive.ph/2024.01.06-003914/https://github.com/microsoft/vscode/issues/179274, https://web.archive.org/web/20240106003915/https://github.com/microsoft/vscode/issues/179274
def configure_setting_key(configuration_key: str, desired_value: Any) -> None:
try:
with open(VSCODE_SETTINGS_JSON_FILE, 'r+', encoding='utf-8') as file:
settings: dict = json.load(file)
if configuration_key in settings:
actual_value = settings[configuration_key]
if actual_value == desired_value:
print_skip(f"Already configured as desired: \"{configuration_key}\"")
return
settings[configuration_key] = desired_value
file.seek(0)
json.dump(settings, file, indent=4)
file.truncate()
print_success(f"Added or updated configuration: {configuration_key}")
except json.JSONDecodeError:
print_error(f"Failed to update JSON for key {configuration_key}.")
def install_recommended_extensions() -> None:
if not os.path.isfile(VSCODE_EXTENSIONS_JSON_FILE):
print_error(
f"The extensions.json file does not exist in the path: {VSCODE_EXTENSIONS_JSON_FILE}."
)
return
with open(VSCODE_EXTENSIONS_JSON_FILE, 'r', encoding='utf-8') as file:
json_content: str = remove_json_comments(file.read())
try:
data: dict = json.loads(json_content)
extensions: list[str] = data.get("recommendations", [])
if not extensions:
print_skip(f"No recommendations found in the {VSCODE_EXTENSIONS_JSON_FILE} file.")
return
vscode_cli_path = locate_vscode_cli()
if vscode_cli_path is None:
print_error('Visual Studio Code CLI (`code`) tool not found.')
return
install_vscode_extensions(vscode_cli_path, extensions)
except json.JSONDecodeError:
print_error(f"Invalid JSON in {VSCODE_EXTENSIONS_JSON_FILE}")
def locate_vscode_cli() -> Optional[str]:
vscode_alias = which('code') # More reliable than using `code`, especially on Windows.
if vscode_alias:
return vscode_alias
potential_vscode_cli_paths = [
'/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code' # macOS VS Code may not register 'code' command in PATH
]
for vscode_cli_candidate_path in potential_vscode_cli_paths:
if Path(vscode_cli_candidate_path).is_file():
return vscode_cli_candidate_path
return None
def remove_json_comments(json_like: str) -> str:
pattern: str = r'(?:"(?:\\.|[^"\\])*"|/\*[\s\S]*?\*/|//.*)|([^:]//.*$)'
return re.sub(
pattern,
lambda m: '' if m.group(1) else m.agroup(0), json_like, flags=re.MULTILINE,
)
def install_vscode_extensions(vscode_cli_path: str, extensions: list[str]) -> None:
successful_installations = 0
for ext in extensions:
try:
result = subprocess.run(
[vscode_cli_path, "--install-extension", ext],
check=True,
capture_output=True,
text=True,
)
if "already installed" in result.stdout:
print_skip(f"Created or verified directory: {ext}")
else:
print_success(f"Installed extension: {ext}")
successful_installations += 1
print_subprocess_output(result)
except subprocess.CalledProcessError as e:
print_subprocess_output(e)
print_error(f"Failed to install extension: {ext}")
except FileNotFoundError:
print_error(' '.join([
f"Visual Studio Code CLI tool not found: {vscode_cli_path}."
f"Could not install extension: {ext}",
]))
except Exception as e: # pylint: disable=broad-except
print_error(' '.join([
f"Failed to install extension '{ext}'.",
f"Attempted using Visual Studio Code CLI at: '{vscode_cli_path}'.",
f"Encountered error: {e}",
]))
total_extensions = len(extensions)
print_installation_results(successful_installations, total_extensions)
def print_subprocess_output(result: subprocess.CompletedProcess[str]) -> None:
output = '\n'.join([text.strip() for text in [result.stdout, result.stderr] if text])
if not output:
return
formatted_output = '\t' + output.strip().replace('\n', '\n\t')
print(formatted_output)
def print_installation_results(successful_installations: int, total_extensions: int) -> None:
if successful_installations == total_extensions:
print_success(
f"Successfully installed or verified all {total_extensions} recommended extensions."
)
elif successful_installations > 0:
print_warning(
f"Partially successful: Installed or verified {successful_installations} "
f"out of {total_extensions} recommended extensions."
)
else:
print_error("Failed to install any of the recommended extensions.")
def print_error(message: str) -> None:
print(f"💀 Error: {message}", file=sys.stderr)
def print_success(message: str) -> None:
print(f"✅ Success: {message}")
def print_skip(message: str) -> None:
print(f"⏩ Skipped: {message}")
def print_warning(message: str) -> None:
print(f"⚠️ Warning: {message}", file=sys.stderr)
if __name__ == "__main__":
main()

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
import { resolve, join } from 'path'; import { resolve, join } from 'node:path';
import { rm, mkdtemp, stat } from 'fs/promises'; import { rm, mkdtemp, stat } from 'node:fs/promises';
import { spawn } from 'child_process'; import { spawn } from 'node:child_process';
import { URL, fileURLToPath } from 'url'; import { URL, fileURLToPath } from 'node:url';
class Paths { class Paths {
constructor(selfDirectory) { constructor(selfDirectory) {

View File

@@ -35,10 +35,10 @@ Note:
Example: npm run install-deps -- --fresh --non-deterministic Example: npm run install-deps -- --fresh --non-deterministic
*/ */
import { exec } from 'child_process'; import { exec } from 'node:child_process';
import { resolve } from 'path'; import { resolve } from 'node:path';
import { access, rm, unlink } from 'fs/promises'; import { access, rm, unlink } from 'node:fs/promises';
import { constants } from 'fs'; import { constants } from 'node:fs';
const MAX_RETRIES = 5; const MAX_RETRIES = 5;
const RETRY_DELAY_IN_MS = 5 /* seconds */ * 1000; const RETRY_DELAY_IN_MS = 5 /* seconds */ * 1000;

View File

@@ -12,8 +12,8 @@
* --web Path for the web application * --web Path for the web application
*/ */
import { resolve } from 'path'; import { resolve } from 'node:path';
import { readFile } from 'fs/promises'; import { readFile } from 'node:fs/promises';
const DIST_DIRS_JSON_FILE_PATH = resolve(process.cwd(), 'dist-dirs.json'); // cannot statically import because ESLint does not support it https://github.com/eslint/eslint/discussions/15305 const DIST_DIRS_JSON_FILE_PATH = resolve(process.cwd(), 'dist-dirs.json'); // cannot statically import because ESLint does not support it https://github.com/eslint/eslint/discussions/15305
const CLI_ARGUMENTS = process.argv.slice(2); const CLI_ARGUMENTS = process.argv.slice(2);

View File

@@ -13,9 +13,9 @@
* --web Verify artifacts for the web application. * --web Verify artifacts for the web application.
*/ */
import { access, readdir } from 'fs/promises'; import { access, readdir } from 'node:fs/promises';
import { exec } from 'child_process'; import { exec } from 'node:child_process';
import { resolve } from 'path'; import { resolve } from 'node:path';
const PROCESS_ARGUMENTS = process.argv.slice(2); const PROCESS_ARGUMENTS = process.argv.slice(2);
const PRINT_DIST_DIR_SCRIPT_BASE_COMMAND = 'node scripts/print-dist-dir'; const PRINT_DIST_DIR_SCRIPT_BASE_COMMAND = 'node scripts/print-dist-dir';

View File

@@ -0,0 +1,62 @@
/**
* Description:
* This script checks if a server, provided as a CLI argument, is up
* and returns an HTTP 200 status code.
* It is designed to provide easy verification of server availability
* and will retry a specified number of times.
*
* Usage:
* node ./scripts/verify-web-server-status.js --url [URL]
*
* Options:
* --url URL of the server to check
*/
import { get } from 'http';
const MAX_RETRIES = 30;
const RETRY_DELAY_IN_SECONDS = 3;
const URL_PARAMETER_NAME = '--url';
function checkServer(currentRetryCount = 1) {
const serverUrl = getServerUrl();
console.log(`Requesting ${serverUrl}...`);
get(serverUrl, (res) => {
if (res.statusCode === 200) {
console.log('🎊 Success: The server is up and returned HTTP 200.');
process.exit(0);
} else {
console.log(`Server returned HTTP status code ${res.statusCode}.`);
retry(currentRetryCount);
}
}).on('error', (err) => {
console.error('Error making the request:', err);
retry(currentRetryCount);
});
}
function retry(currentRetryCount) {
console.log(`Attempt ${currentRetryCount}/${MAX_RETRIES}:`);
console.log(`Retrying in ${RETRY_DELAY_IN_SECONDS} seconds.`);
const remainingTime = (MAX_RETRIES - currentRetryCount) * RETRY_DELAY_IN_SECONDS;
console.log(`Time remaining before timeout: ${remainingTime}s`);
if (currentRetryCount < MAX_RETRIES) {
setTimeout(() => checkServer(currentRetryCount + 1), RETRY_DELAY_IN_SECONDS * 1000);
} else {
console.log('Failure: The server at did not return HTTP 200 within the allocated time. Exiting.');
process.exit(1);
}
}
function getServerUrl() {
const urlIndex = process.argv.indexOf(URL_PARAMETER_NAME);
if (urlIndex === -1 || urlIndex === process.argv.length - 1) {
console.error(`Parameter "${URL_PARAMETER_NAME}" is not provided.`);
process.exit(1);
}
return process.argv[urlIndex + 1];
}
checkServer();

View File

@@ -14,3 +14,35 @@ export type ConstructorArguments<T> =
export type FunctionKeys<T> = { export type FunctionKeys<T> = {
[K in keyof T]: T[K] extends (...args: unknown[]) => unknown ? K : never; [K in keyof T]: T[K] extends (...args: unknown[]) => unknown ? K : never;
}[keyof T]; }[keyof T];
export function isString(value: unknown): value is string {
return typeof value === 'string';
}
export function isNumber(value: unknown): value is number {
return typeof value === 'number';
}
export function isBoolean(value: unknown): value is boolean {
return typeof value === 'boolean';
}
export function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
return typeof value === 'function';
}
export function isArray(value: unknown): value is Array<unknown> {
return Array.isArray(value);
}
export function isPlainObject(
variable: unknown,
): variable is object & Record<string, unknown> {
return Boolean(variable) // the data type of null is an object
&& typeof variable === 'object'
&& !Array.isArray(variable);
}
export function isNullOrUndefined(value: unknown): value is (null | undefined) {
return typeof value === 'undefined' || value === null;
}

View File

@@ -1,7 +1,7 @@
import { IApplication } from '@/domain/IApplication'; import type { IApplication } from '@/domain/IApplication';
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy'; import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
import { IApplicationFactory } from './IApplicationFactory';
import { parseApplication } from './Parser/ApplicationParser'; import { parseApplication } from './Parser/ApplicationParser';
import type { IApplicationFactory } from './IApplicationFactory';
export type ApplicationGetterType = () => IApplication; export type ApplicationGetterType = () => IApplication;
const ApplicationGetter: ApplicationGetterType = parseApplication; const ApplicationGetter: ApplicationGetterType = parseApplication;
@@ -12,9 +12,6 @@ export class ApplicationFactory implements IApplicationFactory {
private readonly getter: AsyncLazy<IApplication>; private readonly getter: AsyncLazy<IApplication>;
protected constructor(costlyGetter: ApplicationGetterType) { protected constructor(costlyGetter: ApplicationGetterType) {
if (!costlyGetter) {
throw new Error('missing getter');
}
this.getter = new AsyncLazy<IApplication>(() => Promise.resolve(costlyGetter())); this.getter = new AsyncLazy<IApplication>(() => Promise.resolve(costlyGetter()));
} }

View File

@@ -0,0 +1,37 @@
export interface CodeRunner {
runCode(
code: string,
fileExtension: string,
): Promise<CodeRunOutcome>;
}
export type CodeRunOutcome = SuccessfulCodeRun | FailedCodeRun;
export type CodeRunErrorType =
| 'FileWriteError'
| 'FileReadbackVerificationError'
| 'FilePathGenerationError'
| 'UnsupportedOperatingSystem'
| 'FileExecutionError'
| 'DirectoryCreationError'
| 'UnexpectedError';
interface CodeRunStatus {
readonly success: boolean;
readonly error?: CodeRunError;
}
interface SuccessfulCodeRun extends CodeRunStatus {
readonly success: true;
readonly error?: undefined;
}
export interface FailedCodeRun extends CodeRunStatus {
readonly success: false;
readonly error: CodeRunError;
}
export interface CodeRunError {
readonly type: CodeRunErrorType;
readonly message: string;
}

View File

@@ -0,0 +1 @@
export const ScriptFilename = 'privacy-script' as const;

View File

@@ -1,7 +1,5 @@
// Compares to Array<T> objects for equality, ignoring order // Compares to Array<T> objects for equality, ignoring order
export function scrambledEqual<T>(array1: readonly T[], array2: readonly T[]) { export function scrambledEqual<T>(array1: readonly T[], array2: readonly T[]) {
if (!array1) { throw new Error('missing first array'); }
if (!array2) { throw new Error('missing second array'); }
const sortedArray1 = sort(array1); const sortedArray1 = sort(array1);
const sortedArray2 = sort(array2); const sortedArray2 = sort(array2);
return sequenceEqual(sortedArray1, sortedArray2); return sequenceEqual(sortedArray1, sortedArray2);
@@ -12,8 +10,6 @@ export function scrambledEqual<T>(array1: readonly T[], array2: readonly T[]) {
// Compares to Array<T> objects for equality in same order // Compares to Array<T> objects for equality in same order
export function sequenceEqual<T>(array1: readonly T[], array2: readonly T[]) { export function sequenceEqual<T>(array1: readonly T[], array2: readonly T[]) {
if (!array1) { throw new Error('missing first array'); }
if (!array2) { throw new Error('missing second array'); }
if (array1.length !== array2.length) { if (array1.length !== array2.length) {
return false; return false;
} }

View File

@@ -1,3 +1,5 @@
import { isFunction } from '@/TypeHelpers';
/* /*
Provides a unified and resilient way to extend errors across platforms. Provides a unified and resilient way to extend errors across platforms.
@@ -20,31 +22,33 @@ export abstract class CustomError extends Error {
} }
} }
export const Environment = { interface ErrorPrototypeManipulation {
getSetPrototypeOf: () => (typeof Object.setPrototypeOf | undefined);
getCaptureStackTrace: () => (typeof Error.captureStackTrace | undefined);
}
export const PlatformErrorPrototypeManipulation: ErrorPrototypeManipulation = {
getSetPrototypeOf: () => Object.setPrototypeOf, getSetPrototypeOf: () => Object.setPrototypeOf,
getCaptureStackTrace: () => Error.captureStackTrace, getCaptureStackTrace: () => Error.captureStackTrace,
}; };
function fixPrototype(target: Error, prototype: CustomError) { function fixPrototype(target: Error, prototype: CustomError) {
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget // This is recommended by TypeScript guidelines.
const setPrototypeOf = Environment.getSetPrototypeOf(); // Source: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget
if (!functionExists(setPrototypeOf)) { // Snapshots: https://web.archive.org/web/20231111234849/https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-newtarget, https://archive.ph/tr7cX#support-for-newtarget
const setPrototypeOf = PlatformErrorPrototypeManipulation.getSetPrototypeOf();
if (!isFunction(setPrototypeOf)) {
return; return;
} }
setPrototypeOf(target, prototype); setPrototypeOf(target, prototype);
} }
function ensureStackTrace(target: Error) { function ensureStackTrace(target: Error) {
const captureStackTrace = Environment.getCaptureStackTrace(); const captureStackTrace = PlatformErrorPrototypeManipulation.getCaptureStackTrace();
if (!functionExists(captureStackTrace)) { if (!isFunction(captureStackTrace)) {
// captureStackTrace is only available on V8, if it's not available // captureStackTrace is only available on V8, if it's not available
// modern JS engines will usually generate a stack trace on error objects when they're thrown. // modern JS engines will usually generate a stack trace on error objects when they're thrown.
return; return;
} }
captureStackTrace(target, target.constructor); captureStackTrace(target, target.constructor);
} }
function functionExists(func: unknown): boolean {
// Not doing truthy/falsy check i.e. if(func) as most values are truthy in JS for robustness
return typeof func === 'function';
}

View File

@@ -1,3 +1,5 @@
import { isString } from '@/TypeHelpers';
// Because we cannot do "T extends enum" 😞 https://github.com/microsoft/TypeScript/issues/30611 // Because we cannot do "T extends enum" 😞 https://github.com/microsoft/TypeScript/issues/30611
export type EnumType = number | string; export type EnumType = number | string;
export type EnumVariable<T extends EnumType, TEnumValue extends EnumType> export type EnumVariable<T extends EnumType, TEnumValue extends EnumType>
@@ -23,7 +25,7 @@ function parseEnumValue<T extends EnumType, TEnumValue extends EnumType>(
if (!value) { if (!value) {
throw new Error(`missing ${enumName}`); throw new Error(`missing ${enumName}`);
} }
if (typeof value !== 'string') { if (!isString(value)) {
throw new Error(`unexpected type of ${enumName}: "${typeof value}"`); throw new Error(`unexpected type of ${enumName}: "${typeof value}"`);
} }
const casedValue = getEnumNames(enumVariable) const casedValue = getEnumNames(enumVariable)
@@ -40,7 +42,7 @@ export function getEnumNames
): string[] { ): string[] {
return Object return Object
.values(enumVariable) .values(enumVariable)
.filter((enumMember) => typeof enumMember === 'string') as string[]; .filter((enumMember): enumMember is string => isString(enumMember));
} }
export function getEnumValues<T extends EnumType, TEnumValue extends EnumType>( export function getEnumValues<T extends EnumType, TEnumValue extends EnumType>(
@@ -54,9 +56,6 @@ export function assertInRange<T extends EnumType, TEnumValue extends EnumType>(
value: TEnumValue, value: TEnumValue,
enumVariable: EnumVariable<T, TEnumValue>, enumVariable: EnumVariable<T, TEnumValue>,
) { ) {
if (value === undefined || value === null) {
throw new Error('absent enum value');
}
if (!(value in enumVariable)) { if (!(value in enumVariable)) {
throw new RangeError(`enum value "${value}" is out of range`); throw new RangeError(`enum value "${value}" is out of range`);
} }

View File

@@ -0,0 +1,6 @@
export interface Logger {
info(...params: unknown[]): void;
warn(...params: unknown[]): void;
error(...params: unknown[]): void;
debug(...params: unknown[]): void;
}

View File

@@ -1,6 +1,6 @@
import { ScriptingLanguage } from '@/domain/ScriptingLanguage'; import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { assertInRange } from '@/application/Common/Enum'; import { assertInRange } from '@/application/Common/Enum';
import { IScriptingLanguageFactory } from './IScriptingLanguageFactory'; import type { IScriptingLanguageFactory } from './IScriptingLanguageFactory';
type Getter<T> = () => T; type Getter<T> = () => T;
@@ -9,19 +9,16 @@ export abstract class ScriptingLanguageFactory<T> implements IScriptingLanguageF
public create(language: ScriptingLanguage): T { public create(language: ScriptingLanguage): T {
assertInRange(language, ScriptingLanguage); assertInRange(language, ScriptingLanguage);
if (!this.getters.has(language)) { const getter = this.getters.get(language);
if (!getter) {
throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`); throw new RangeError(`unknown language: "${ScriptingLanguage[language]}"`);
} }
const getter = this.getters.get(language);
const instance = getter(); const instance = getter();
return instance; return instance;
} }
protected registerGetter(language: ScriptingLanguage, getter: Getter<T>) { protected registerGetter(language: ScriptingLanguage, getter: Getter<T>) {
assertInRange(language, ScriptingLanguage); assertInRange(language, ScriptingLanguage);
if (!getter) {
throw new Error('missing getter');
}
if (this.getters.has(language)) { if (this.getters.has(language)) {
throw new Error(`${ScriptingLanguage[language]} is already registered`); throw new Error(`${ScriptingLanguage[language]} is already registered`);
} }

View File

@@ -0,0 +1,27 @@
import { PlatformTimer } from './PlatformTimer';
import type { TimeoutType, Timer } from './Timer';
export function batchedDebounce<T>(
callback: (batches: readonly T[]) => void,
waitInMs: number,
timer: Timer = PlatformTimer,
): (arg: T) => void {
let lastTimeoutId: TimeoutType | undefined;
let batches: Array<T> = [];
return (arg: T) => {
batches.push(arg);
const later = () => {
callback(batches);
batches = [];
lastTimeoutId = undefined;
};
if (lastTimeoutId !== undefined) {
timer.clearTimeout(lastTimeoutId);
}
lastTimeoutId = timer.setTimeout(later, waitInMs);
};
}

View File

@@ -0,0 +1,7 @@
import type { Timer } from './Timer';
export const PlatformTimer: Timer = {
setTimeout: (callback, ms) => setTimeout(callback, ms),
clearTimeout: (timeoutId) => clearTimeout(timeoutId),
dateNow: () => Date.now(),
};

View File

@@ -1,47 +1,29 @@
export type CallbackType = (..._: unknown[]) => void; import { PlatformTimer } from './PlatformTimer';
import type { Timer, TimeoutType } from './Timer';
export type CallbackType = (..._: readonly unknown[]) => void;
export function throttle( export function throttle(
callback: CallbackType, callback: CallbackType,
waitInMs: number, waitInMs: number,
timer: ITimer = NodeTimer, timer: Timer = PlatformTimer,
): CallbackType { ): CallbackType {
const throttler = new Throttler(timer, waitInMs, callback); const throttler = new Throttler(timer, waitInMs, callback);
return (...args: unknown[]) => throttler.invoke(...args); return (...args: unknown[]) => throttler.invoke(...args);
} }
// Allows aligning with both NodeJs (NodeJs.Timeout) and Window type (number) class Throttler {
export type TimeoutType = ReturnType<typeof setTimeout>; private queuedExecutionId: TimeoutType | undefined;
export interface ITimer {
setTimeout: (callback: () => void, ms: number) => TimeoutType;
clearTimeout: (timeoutId: TimeoutType) => void;
dateNow(): number;
}
const NodeTimer: ITimer = {
setTimeout: (callback, ms) => setTimeout(callback, ms),
clearTimeout: (timeoutId) => clearTimeout(timeoutId),
dateNow: () => Date.now(),
};
interface IThrottler {
invoke: CallbackType;
}
class Throttler implements IThrottler {
private queuedExecutionId: TimeoutType;
private previouslyRun: number; private previouslyRun: number;
constructor( constructor(
private readonly timer: ITimer, private readonly timer: Timer,
private readonly waitInMs: number, private readonly waitInMs: number,
private readonly callback: CallbackType, private readonly callback: CallbackType,
) { ) {
if (!timer) { throw new Error('missing timer'); }
if (!waitInMs) { throw new Error('missing delay'); } if (!waitInMs) { throw new Error('missing delay'); }
if (waitInMs < 0) { throw new Error('negative delay'); } if (waitInMs < 0) { throw new Error('negative delay'); }
if (!callback) { throw new Error('missing callback'); }
} }
public invoke(...args: unknown[]): void { public invoke(...args: unknown[]): void {

View File

@@ -0,0 +1,8 @@
// Allows aligning with both NodeJs (NodeJs.Timeout) and Window type (number)
export type TimeoutType = ReturnType<typeof setTimeout>;
export interface Timer {
setTimeout: (callback: () => void, ms: number) => TimeoutType;
clearTimeout: (timeoutId: TimeoutType) => void;
dateNow(): number;
}

View File

@@ -1,11 +1,11 @@
import { IApplication } from '@/domain/IApplication'; import type { IApplication } from '@/domain/IApplication';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { ICategoryCollection } from '@/domain/ICategoryCollection'; import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { EventSource } from '@/infrastructure/Events/EventSource'; import { EventSource } from '@/infrastructure/Events/EventSource';
import { assertInRange } from '@/application/Common/Enum'; import { assertInRange } from '@/application/Common/Enum';
import { CategoryCollectionState } from './State/CategoryCollectionState'; import { CategoryCollectionState } from './State/CategoryCollectionState';
import { ICategoryCollectionState } from './State/ICategoryCollectionState'; import type { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
import { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext'; import type { ICategoryCollectionState } from './State/ICategoryCollectionState';
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>; type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
@@ -26,7 +26,6 @@ export class ApplicationContext implements IApplicationContext {
public readonly app: IApplication, public readonly app: IApplication,
initialContext: OperatingSystem, initialContext: OperatingSystem,
) { ) {
validateApp(app);
this.states = initializeStates(app); this.states = initializeStates(app);
this.changeContext(initialContext); this.changeContext(initialContext);
} }
@@ -36,10 +35,8 @@ export class ApplicationContext implements IApplicationContext {
if (this.currentOs === os) { if (this.currentOs === os) {
return; return;
} }
this.collection = this.app.getCollection(os); const collection = this.app.getCollection(os);
if (!this.collection) { this.collection = collection;
throw new Error(`os "${OperatingSystem[os]}" is not defined in application`);
}
const event: IApplicationContextChangedEvent = { const event: IApplicationContextChangedEvent = {
newState: this.states[os], newState: this.states[os],
oldState: this.states[this.currentOs], oldState: this.states[this.currentOs],
@@ -49,12 +46,6 @@ export class ApplicationContext implements IApplicationContext {
} }
} }
function validateApp(app: IApplication) {
if (!app) {
throw new Error('missing app');
}
}
function initializeStates(app: IApplication): StateMachine { function initializeStates(app: IApplication): StateMachine {
const machine = new Map<OperatingSystem, ICategoryCollectionState>(); const machine = new Map<OperatingSystem, ICategoryCollectionState>();
for (const collection of app.collections) { for (const collection of app.collections) {

View File

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

View File

@@ -1,7 +1,7 @@
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { IEventSource } from '@/infrastructure/Events/IEventSource'; import type { IEventSource } from '@/infrastructure/Events/IEventSource';
import { IApplication } from '@/domain/IApplication'; import type { IApplication } from '@/domain/IApplication';
import { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from './State/ICategoryCollectionState'; import type { ICategoryCollectionState, IReadOnlyCategoryCollectionState } from './State/ICategoryCollectionState';
export interface IReadOnlyApplicationContext { export interface IReadOnlyApplicationContext {
readonly app: IApplication; readonly app: IApplication;

View File

@@ -1,26 +1,51 @@
import { ICategoryCollection } from '@/domain/ICategoryCollection'; import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { UserFilter } from './Filter/UserFilter'; import { AdaptiveFilterContext } from './Filter/AdaptiveFilterContext';
import { IUserFilter } from './Filter/IUserFilter';
import { ApplicationCode } from './Code/ApplicationCode'; import { ApplicationCode } from './Code/ApplicationCode';
import { UserSelection } from './Selection/UserSelection'; import { UserSelectionFacade } from './Selection/UserSelectionFacade';
import { IUserSelection } from './Selection/IUserSelection'; import type { FilterContext } from './Filter/FilterContext';
import { ICategoryCollectionState } from './ICategoryCollectionState'; import type { UserSelection } from './Selection/UserSelection';
import { IApplicationCode } from './Code/IApplicationCode'; import type { ICategoryCollectionState } from './ICategoryCollectionState';
import type { IApplicationCode } from './Code/IApplicationCode';
export class CategoryCollectionState implements ICategoryCollectionState { export class CategoryCollectionState implements ICategoryCollectionState {
public readonly os: OperatingSystem; public readonly os: OperatingSystem;
public readonly code: IApplicationCode; public readonly code: IApplicationCode;
public readonly selection: IUserSelection; public readonly selection: UserSelection;
public readonly filter: IUserFilter; public readonly filter: FilterContext;
public constructor(readonly collection: ICategoryCollection) { public constructor(
this.selection = new UserSelection(collection, []); public readonly collection: ICategoryCollection,
this.code = new ApplicationCode(this.selection, collection.scripting); selectionFactory = DefaultSelectionFactory,
this.filter = new UserFilter(collection); codeFactory = DefaultCodeFactory,
filterFactory = DefaultFilterFactory,
) {
this.selection = selectionFactory(collection, []);
this.code = codeFactory(this.selection.scripts, collection.scripting);
this.filter = filterFactory(collection);
this.os = collection.os; this.os = collection.os;
} }
} }
export type CodeFactory = (
...params: ConstructorParameters<typeof ApplicationCode>
) => IApplicationCode;
const DefaultCodeFactory: CodeFactory = (...params) => new ApplicationCode(...params);
export type SelectionFactory = (
...params: ConstructorParameters<typeof UserSelectionFacade>
) => UserSelection;
const DefaultSelectionFactory: SelectionFactory = (
...params
) => new UserSelectionFacade(...params);
export type FilterFactory = (
...params: ConstructorParameters<typeof AdaptiveFilterContext>
) => FilterContext;
const DefaultFilterFactory: FilterFactory = (...params) => new AdaptiveFilterContext(...params);

View File

@@ -1,13 +1,13 @@
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript';
import { IReadOnlyUserSelection } from '@/application/Context/State/Selection/IUserSelection';
import { EventSource } from '@/infrastructure/Events/EventSource'; import { EventSource } from '@/infrastructure/Events/EventSource';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition'; import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import type { ReadonlyScriptSelection } from '@/application/Context/State/Selection/Script/ScriptSelection';
import { CodeChangedEvent } from './Event/CodeChangedEvent'; import { CodeChangedEvent } from './Event/CodeChangedEvent';
import { CodePosition } from './Position/CodePosition'; import { CodePosition } from './Position/CodePosition';
import { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import { UserScriptGenerator } from './Generation/UserScriptGenerator'; import { UserScriptGenerator } from './Generation/UserScriptGenerator';
import { IApplicationCode } from './IApplicationCode'; import type { IUserScriptGenerator } from './Generation/IUserScriptGenerator';
import { IUserScriptGenerator } from './Generation/IUserScriptGenerator'; import type { ICodeChangedEvent } from './Event/ICodeChangedEvent';
import type { IApplicationCode } from './IApplicationCode';
export class ApplicationCode implements IApplicationCode { export class ApplicationCode implements IApplicationCode {
public readonly changed = new EventSource<ICodeChangedEvent>(); public readonly changed = new EventSource<ICodeChangedEvent>();
@@ -17,15 +17,12 @@ export class ApplicationCode implements IApplicationCode {
private scriptPositions = new Map<SelectedScript, CodePosition>(); private scriptPositions = new Map<SelectedScript, CodePosition>();
constructor( constructor(
userSelection: IReadOnlyUserSelection, selection: ReadonlyScriptSelection,
private readonly scriptingDefinition: IScriptingDefinition, private readonly scriptingDefinition: IScriptingDefinition,
private readonly generator: IUserScriptGenerator = new UserScriptGenerator(), private readonly generator: IUserScriptGenerator = new UserScriptGenerator(),
) { ) {
if (!userSelection) { throw new Error('missing userSelection'); } this.setCode(selection.selectedScripts);
if (!scriptingDefinition) { throw new Error('missing scriptingDefinition'); } selection.changed.on((scripts) => {
if (!generator) { throw new Error('missing generator'); }
this.setCode(userSelection.selectedScripts);
userSelection.changed.on((scripts) => {
this.setCode(scripts); this.setCode(scripts);
}); });
} }

View File

@@ -1,7 +1,7 @@
import { IScript } from '@/domain/IScript'; import type { IScript } from '@/domain/IScript';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition'; import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { SelectedScript } from '../../Selection/SelectedScript'; import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { ICodeChangedEvent } from './ICodeChangedEvent'; import type { ICodeChangedEvent } from './ICodeChangedEvent';
export class CodeChangedEvent implements ICodeChangedEvent { export class CodeChangedEvent implements ICodeChangedEvent {
public readonly code: string; public readonly code: string;
@@ -36,7 +36,18 @@ export class CodeChangedEvent implements ICodeChangedEvent {
} }
public getScriptPositionInCode(script: IScript): ICodePosition { public getScriptPositionInCode(script: IScript): ICodePosition {
return this.scripts.get(script); return this.getPositionById(script.id);
}
private getPositionById(scriptId: string): ICodePosition {
const position = [...this.scripts.entries()]
.filter(([s]) => s.id === scriptId)
.map(([, pos]) => pos)
.at(0);
if (!position) {
throw new Error('Unknown script: Position could not be found for the script');
}
return position;
} }
} }

View File

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

View File

@@ -1,4 +1,4 @@
import { ICodeBuilder } from './ICodeBuilder'; import type { ICodeBuilder } from './ICodeBuilder';
const TotalFunctionSeparatorChars = 58; const TotalFunctionSeparatorChars = 58;
@@ -16,7 +16,9 @@ export abstract class CodeBuilder implements ICodeBuilder {
return this; return this;
} }
const lines = code.match(/[^\r\n]+/g); const lines = code.match(/[^\r\n]+/g);
if (lines) {
this.lines.push(...lines); this.lines.push(...lines);
}
return this; return this;
} }

View File

@@ -1,9 +1,9 @@
import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory'; import { ScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/ScriptingLanguageFactory';
import { ScriptingLanguage } from '@/domain/ScriptingLanguage'; import { ScriptingLanguage } from '@/domain/ScriptingLanguage';
import { ICodeBuilder } from './ICodeBuilder';
import { BatchBuilder } from './Languages/BatchBuilder'; import { BatchBuilder } from './Languages/BatchBuilder';
import { ShellBuilder } from './Languages/ShellBuilder'; import { ShellBuilder } from './Languages/ShellBuilder';
import { ICodeBuilderFactory } from './ICodeBuilderFactory'; import type { ICodeBuilder } from './ICodeBuilder';
import type { ICodeBuilderFactory } from './ICodeBuilderFactory';
export class CodeBuilderFactory export class CodeBuilderFactory
extends ScriptingLanguageFactory<ICodeBuilder> extends ScriptingLanguageFactory<ICodeBuilder>

View File

@@ -1,4 +1,4 @@
import { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory'; import type { IScriptingLanguageFactory } from '@/application/Common/ScriptingLanguage/IScriptingLanguageFactory';
import { ICodeBuilder } from './ICodeBuilder'; import type { ICodeBuilder } from './ICodeBuilder';
export type ICodeBuilderFactory = IScriptingLanguageFactory<ICodeBuilder>; export type ICodeBuilderFactory = IScriptingLanguageFactory<ICodeBuilder>;

View File

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

View File

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

View File

@@ -1,12 +1,12 @@
import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript'; import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition';
import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition'; import type { IScriptingDefinition } from '@/domain/IScriptingDefinition';
import { IScriptingDefinition } from '@/domain/IScriptingDefinition'; import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript';
import { CodePosition } from '../Position/CodePosition'; import { CodePosition } from '../Position/CodePosition';
import { IUserScriptGenerator } from './IUserScriptGenerator';
import { IUserScript } from './IUserScript';
import { ICodeBuilder } from './ICodeBuilder';
import { ICodeBuilderFactory } from './ICodeBuilderFactory';
import { CodeBuilderFactory } from './CodeBuilderFactory'; import { CodeBuilderFactory } from './CodeBuilderFactory';
import type { IUserScriptGenerator } from './IUserScriptGenerator';
import type { IUserScript } from './IUserScript';
import type { ICodeBuilder } from './ICodeBuilder';
import type { ICodeBuilderFactory } from './ICodeBuilderFactory';
export class UserScriptGenerator implements IUserScriptGenerator { export class UserScriptGenerator implements IUserScriptGenerator {
constructor(private readonly codeBuilderFactory: ICodeBuilderFactory = new CodeBuilderFactory()) { constructor(private readonly codeBuilderFactory: ICodeBuilderFactory = new CodeBuilderFactory()) {
@@ -17,8 +17,6 @@ export class UserScriptGenerator implements IUserScriptGenerator {
selectedScripts: ReadonlyArray<SelectedScript>, selectedScripts: ReadonlyArray<SelectedScript>,
scriptingDefinition: IScriptingDefinition, scriptingDefinition: IScriptingDefinition,
): IUserScript { ): IUserScript {
if (!selectedScripts) { throw new Error('missing scripts'); }
if (!scriptingDefinition) { throw new Error('missing definition'); }
if (!selectedScripts.length) { if (!selectedScripts.length) {
return { code: '', scriptPositions: new Map<SelectedScript, ICodePosition>() }; return { code: '', scriptPositions: new Map<SelectedScript, ICodePosition>() };
} }
@@ -68,8 +66,19 @@ function appendSelection(
function appendCode(selection: SelectedScript, builder: ICodeBuilder): ICodeBuilder { function appendCode(selection: SelectedScript, builder: ICodeBuilder): ICodeBuilder {
const { script } = selection; const { script } = selection;
const name = selection.revert ? `${script.name} (revert)` : script.name; const name = selection.revert ? `${script.name} (revert)` : script.name;
const scriptCode = selection.revert ? script.code.revert : script.code.execute; const scriptCode = getSelectedCode(selection);
return builder return builder
.appendLine() .appendLine()
.appendFunction(name, scriptCode); .appendFunction(name, scriptCode);
} }
function getSelectedCode(selection: SelectedScript): string {
const { code } = selection.script;
if (!selection.revert) {
return code.execute;
}
if (!code.revert) {
throw new Error('Reverted script lacks revert code.');
}
return code.revert;
}

View File

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

View File

@@ -1,4 +1,4 @@
import { ICodePosition } from './ICodePosition'; import type { ICodePosition } from './ICodePosition';
export class CodePosition implements ICodePosition { export class CodePosition implements ICodePosition {
public get totalLines(): number { public get totalLines(): number {

View File

@@ -0,0 +1,35 @@
import { EventSource } from '@/infrastructure/Events/EventSource';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { FilterChange } from './Event/FilterChange';
import { LinearFilterStrategy } from './Strategy/LinearFilterStrategy';
import type { FilterResult } from './Result/FilterResult';
import type { FilterContext } from './FilterContext';
import type { FilterChangeDetails } from './Event/FilterChangeDetails';
import type { FilterStrategy } from './Strategy/FilterStrategy';
export class AdaptiveFilterContext implements FilterContext {
public readonly filterChanged = new EventSource<FilterChangeDetails>();
public currentFilter: FilterResult | undefined;
constructor(
private readonly collection: ICategoryCollection,
private readonly filterStrategy: FilterStrategy = new LinearFilterStrategy(),
) {
}
public applyFilter(filter: string): void {
if (!filter) {
throw new Error('Filter must be defined and not empty. Use clearFilter() to remove the filter');
}
const result = this.filterStrategy.applyFilter(filter, this.collection);
this.currentFilter = result;
this.filterChanged.notify(FilterChange.forApply(this.currentFilter));
}
public clearFilter(): void {
this.currentFilter = undefined;
this.filterChanged.notify(FilterChange.forClear());
}
}

View File

@@ -1,37 +1,37 @@
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult'; import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
import { FilterActionType } from './FilterActionType'; import { FilterActionType } from './FilterActionType';
import { IFilterChangeDetails, IFilterChangeDetailsVisitor } from './IFilterChangeDetails'; import type {
FilterChangeDetails, FilterChangeDetailsVisitor,
ApplyFilterAction, ClearFilterAction,
} from './FilterChangeDetails';
export class FilterChange implements IFilterChangeDetails { export class FilterChange implements FilterChangeDetails {
public static forApply(filter: IFilterResult) { public static forApply(
if (!filter) { filter: FilterResult,
throw new Error('missing filter'); ): FilterChangeDetails {
} return new FilterChange({ type: FilterActionType.Apply, filter });
return new FilterChange(FilterActionType.Apply, filter);
} }
public static forClear() { public static forClear(): FilterChangeDetails {
return new FilterChange(FilterActionType.Clear); return new FilterChange({ type: FilterActionType.Clear });
} }
private constructor( private constructor(public readonly action: ApplyFilterAction | ClearFilterAction) { }
public readonly actionType: FilterActionType,
public readonly filter?: IFilterResult,
) { }
public visit(visitor: IFilterChangeDetailsVisitor): void { public visit(visitor: FilterChangeDetailsVisitor): void {
if (!visitor) { switch (this.action.type) {
throw new Error('missing visitor');
}
switch (this.actionType) {
case FilterActionType.Apply: case FilterActionType.Apply:
visitor.onApply(this.filter); if (visitor.onApply) {
visitor.onApply(this.action.filter);
}
break; break;
case FilterActionType.Clear: case FilterActionType.Clear:
if (visitor.onClear) {
visitor.onClear(); visitor.onClear();
}
break; break;
default: default:
throw new Error(`Unknown action type: ${this.actionType}`); throw new Error(`Unknown action: ${this.action}`);
} }
} }
} }

View File

@@ -0,0 +1,23 @@
import type { FilterResult } from '@/application/Context/State/Filter/Result/FilterResult';
import type { FilterActionType } from './FilterActionType';
export interface FilterChangeDetails {
readonly action: FilterAction;
visit(visitor: FilterChangeDetailsVisitor): void;
}
export interface FilterChangeDetailsVisitor {
readonly onClear?: () => void;
readonly onApply?: (filter: FilterResult) => void;
}
export type ApplyFilterAction = {
readonly type: FilterActionType.Apply,
readonly filter: FilterResult;
};
export type ClearFilterAction = {
readonly type: FilterActionType.Clear,
};
export type FilterAction = ApplyFilterAction | ClearFilterAction;

View File

@@ -1,14 +0,0 @@
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult';
import { FilterActionType } from './FilterActionType';
export interface IFilterChangeDetails {
readonly actionType: FilterActionType;
readonly filter?: IFilterResult;
visit(visitor: IFilterChangeDetailsVisitor): void;
}
export interface IFilterChangeDetailsVisitor {
onClear(): void;
onApply(filter: IFilterResult): void;
}

View File

@@ -0,0 +1,13 @@
import type { IEventSource } from '@/infrastructure/Events/IEventSource';
import type { FilterResult } from './Result/FilterResult';
import type { FilterChangeDetails } from './Event/FilterChangeDetails';
export interface ReadonlyFilterContext {
readonly currentFilter: FilterResult | undefined;
readonly filterChanged: IEventSource<FilterChangeDetails>;
}
export interface FilterContext extends ReadonlyFilterContext {
applyFilter(filter: string): void;
clearFilter(): void;
}

View File

@@ -1,13 +0,0 @@
import { IEventSource } from '@/infrastructure/Events/IEventSource';
import { IFilterResult } from './IFilterResult';
import { IFilterChangeDetails } from './Event/IFilterChangeDetails';
export interface IReadOnlyUserFilter {
readonly currentFilter: IFilterResult | undefined;
readonly filterChanged: IEventSource<IFilterChangeDetails>;
}
export interface IUserFilter extends IReadOnlyUserFilter {
applyFilter(filter: string): void;
clearFilter(): void;
}

View File

@@ -1,16 +1,14 @@
import { IScript } from '@/domain/IScript'; import type { IScript } from '@/domain/IScript';
import { ICategory } from '@/domain/ICategory'; import type { ICategory } from '@/domain/ICategory';
import { IFilterResult } from './IFilterResult'; import type { FilterResult } from './FilterResult';
export class FilterResult implements IFilterResult { export class AppliedFilterResult implements FilterResult {
constructor( constructor(
public readonly scriptMatches: ReadonlyArray<IScript>, public readonly scriptMatches: ReadonlyArray<IScript>,
public readonly categoryMatches: ReadonlyArray<ICategory>, public readonly categoryMatches: ReadonlyArray<ICategory>,
public readonly query: string, public readonly query: string,
) { ) {
if (!query) { throw new Error('Query is empty or undefined'); } if (!query) { throw new Error('Query is empty or undefined'); }
if (!scriptMatches) { throw new Error('Script matches is undefined'); }
if (!categoryMatches) { throw new Error('Category matches is undefined'); }
} }
public hasAnyMatches(): boolean { public hasAnyMatches(): boolean {

View File

@@ -1,6 +1,6 @@
import { IScript, ICategory } from '@/domain/ICategory'; import type { IScript, ICategory } from '@/domain/ICategory';
export interface IFilterResult { export interface FilterResult {
readonly categoryMatches: ReadonlyArray<ICategory>; readonly categoryMatches: ReadonlyArray<ICategory>;
readonly scriptMatches: ReadonlyArray<IScript>; readonly scriptMatches: ReadonlyArray<IScript>;
readonly query: string; readonly query: string;

View File

@@ -0,0 +1,9 @@
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import type { FilterResult } from '../Result/FilterResult';
export interface FilterStrategy {
applyFilter(
filter: string,
collection: ICategoryCollection,
): FilterResult;
}

View File

@@ -0,0 +1,80 @@
import type { ICategory, IScript } from '@/domain/ICategory';
import type { IScriptCode } from '@/domain/IScriptCode';
import type { IDocumentable } from '@/domain/IDocumentable';
import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { AppliedFilterResult } from '../Result/AppliedFilterResult';
import type { FilterStrategy } from './FilterStrategy';
import type { FilterResult } from '../Result/FilterResult';
export class LinearFilterStrategy implements FilterStrategy {
applyFilter(filter: string, collection: ICategoryCollection): FilterResult {
const filterLowercase = filter.toLocaleLowerCase();
const filteredScripts = collection.getAllScripts().filter(
(script) => matchesScript(script, filterLowercase),
);
const filteredCategories = collection.getAllCategories().filter(
(category) => matchesCategory(category, filterLowercase),
);
return new AppliedFilterResult(
filteredScripts,
filteredCategories,
filter,
);
}
}
function matchesCategory(
category: ICategory,
filterLowercase: string,
): boolean {
return matchesAny(
() => matchName(category.name, filterLowercase),
() => matchDocumentation(category, filterLowercase),
);
}
function matchesScript(
script: IScript,
filterLowercase: string,
): boolean {
return matchesAny(
() => matchName(script.name, filterLowercase),
() => matchCode(script.code, filterLowercase),
() => matchDocumentation(script, filterLowercase),
);
}
function matchesAny(
...predicates: ReadonlyArray<() => boolean>
): boolean {
return predicates.some((predicate) => predicate());
}
function matchName(
name: string,
filterLowercase: string,
): boolean {
return name.toLowerCase().includes(filterLowercase);
}
function matchCode(
code: IScriptCode,
filterLowercase: string,
): boolean {
if (code.execute.toLowerCase().includes(filterLowercase)) {
return true;
}
if (code.revert?.toLowerCase().includes(filterLowercase)) {
return true;
}
return false;
}
function matchDocumentation(
documentable: IDocumentable,
filterLowercase: string,
): boolean {
return documentable.docs.some(
(doc) => doc.toLocaleLowerCase().includes(filterLowercase),
);
}

View File

@@ -1,56 +0,0 @@
import { IScript } from '@/domain/IScript';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { ICategoryCollection } from '@/domain/ICategoryCollection';
import { FilterResult } from './FilterResult';
import { IFilterResult } from './IFilterResult';
import { IUserFilter } from './IUserFilter';
import { IFilterChangeDetails } from './Event/IFilterChangeDetails';
import { FilterChange } from './Event/FilterChange';
export class UserFilter implements IUserFilter {
public readonly filterChanged = new EventSource<IFilterChangeDetails>();
public currentFilter: IFilterResult | undefined;
constructor(private collection: ICategoryCollection) {
}
public applyFilter(filter: string): void {
if (!filter) {
throw new Error('Filter must be defined and not empty. Use clearFilter() 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.filterChanged.notify(FilterChange.forApply(this.currentFilter));
}
public clearFilter(): void {
this.currentFilter = undefined;
this.filterChanged.notify(FilterChange.forClear());
}
}
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

@@ -1,18 +1,18 @@
import { ICategoryCollection } from '@/domain/ICategoryCollection'; import type { ICategoryCollection } from '@/domain/ICategoryCollection';
import { OperatingSystem } from '@/domain/OperatingSystem'; import { OperatingSystem } from '@/domain/OperatingSystem';
import { IReadOnlyUserFilter, IUserFilter } from './Filter/IUserFilter'; import type { IApplicationCode } from './Code/IApplicationCode';
import { IReadOnlyUserSelection, IUserSelection } from './Selection/IUserSelection'; import type { ReadonlyFilterContext, FilterContext } from './Filter/FilterContext';
import { IApplicationCode } from './Code/IApplicationCode'; import type { ReadonlyUserSelection, UserSelection } from './Selection/UserSelection';
export interface IReadOnlyCategoryCollectionState { export interface IReadOnlyCategoryCollectionState {
readonly code: IApplicationCode; readonly code: IApplicationCode;
readonly os: OperatingSystem; readonly os: OperatingSystem;
readonly filter: IReadOnlyUserFilter; readonly filter: ReadonlyFilterContext;
readonly selection: IReadOnlyUserSelection; readonly selection: ReadonlyUserSelection;
readonly collection: ICategoryCollection; readonly collection: ICategoryCollection;
} }
export interface ICategoryCollectionState extends IReadOnlyCategoryCollectionState { export interface ICategoryCollectionState extends IReadOnlyCategoryCollectionState {
readonly filter: IUserFilter; readonly filter: FilterContext;
readonly selection: IUserSelection; readonly selection: UserSelection;
} }

View File

@@ -0,0 +1,11 @@
import type { ICategory } from '@/domain/ICategory';
import type { CategorySelectionChangeCommand } from './CategorySelectionChange';
export interface ReadonlyCategorySelection {
areAllScriptsSelected(category: ICategory): boolean;
isAnyScriptSelected(category: ICategory): boolean;
}
export interface CategorySelection extends ReadonlyCategorySelection {
processChanges(action: CategorySelectionChangeCommand): void;
}

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