Compare commits

..

9 Commits
0.6.0 ... 0.6.1

Author SHA1 Message Date
undergroundwires
1cc12195a3 fixed removing onedrive does not clean start menu / quick access 2020-08-09 03:00:19 +01:00
undergroundwires
66d4d39d5b refactorings 2020-08-09 03:00:18 +01:00
undergroundwires
a5dbe66fc1 tweaks to disable webcam, speech and compatibility telemetry 2020-08-09 03:00:18 +01:00
undergroundwires
4c8be45e28 fixed mac / linux download links 2020-08-09 03:00:18 +01:00
undergroundwires
6049a2b834 moved windows connect now to security & recommended 2020-08-09 03:00:18 +01:00
undergroundwires
831c014f97 more scripts can be reverted 2020-08-09 03:00:18 +01:00
undergroundwires
5c15a7a64a fixed typo in footer 2020-08-09 03:00:18 +01:00
dependabot[bot]
e43992b278 Bump elliptic from 6.5.2 to 6.5.3 (#23)
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-08-09 03:00:18 +01:00
undergroundwires
5963d2bac5 updated documentation 2020-08-09 03:00:18 +01:00
25 changed files with 234 additions and 262 deletions

View File

@@ -1,145 +0,0 @@
name: Build & deploy
on:
release:
types: [created] # will be triggered when a NON-draft release is created and published.
jobs:
aws-deploy: # see: https://github.com/undergroundwires/aws-static-site-with-cd
runs-on: ubuntu-latest
steps:
-
name: "Infrastructure: Checkout"
uses: actions/checkout@v2
with:
path: aws
repository: undergroundwires/aws-static-site-with-cd
-
name: "Infrastructure: Create AWS user profile & session name"
run: >-
bash "scripts/configure/create-user-profile.sh" \
--profile user \
--access-key-id ${{secrets.AWS_DEPLOYMENT_USER_ACCESS_KEY_ID}} \
--secret-access-key ${{secrets.AWS_DEPLOYMENT_USER_SECRET_ACCESS_KEY}} \
--region us-east-1 \
&& \
echo "::set-env name=SESSION_NAME::${{github.actor}}-${{github.event_name}}-$(echo ${{github.sha}} | cut -c1-8)"
working-directory: aws
-
name: "Infrastructure: Deploy IAM stack"
run: >-
bash "scripts/deploy/deploy-stack.sh" \
--template-file stacks/iam-stack.yaml \
--stack-name privacysexy-iam-stack \
--capabilities CAPABILITY_IAM \
--parameter-overrides "WebStackName=privacysexy-web-stack DnsStackName=privacysexy-dns-stack \
CertificateStackName=privacysexy-cert-stack RootDomainName=privacy.sexy" \
--region us-east-1 --role-arn ${{secrets.AWS_IAM_STACK_DEPLOYMENT_ROLE_ARN}} \
--profile user --session ${{ env.SESSION_NAME }}
working-directory: aws
-
name: "Infrastructure: Deploy DNS stack"
run: >-
bash "scripts/deploy/deploy-stack.sh" \
--template-file stacks/dns-stack.yaml \
--stack-name privacysexy-dns-stack \
--parameter-overrides "RootDomainName=privacy.sexy" \
--region us-east-1 \
--role-arn ${{secrets.AWS_DNS_STACK_DEPLOYMENT_ROLE_ARN}} \
--profile user --session ${{ env.SESSION_NAME }}
working-directory: aws
-
name: "Infrastructure: Deploy certificate stack"
run: >-
bash "scripts/deploy/deploy-stack.sh" \
--template-file stacks/certificate-stack.yaml \
--stack-name privacysexy-cert-stack \
--capabilities CAPABILITY_IAM \
--parameter-overrides "IamStackName=privacysexy-iam-stack RootDomainName=privacy.sexy DnsStackName=privacysexy-dns-stack" \
--region us-east-1 \
--role-arn ${{secrets.AWS_CERTIFICATE_STACK_DEPLOYMENT_ROLE_ARN}} \
--profile user --session ${{ env.SESSION_NAME }}
working-directory: aws
-
name: "Infrastructure: Deploy web stack"
run: >-
bash "scripts/deploy/deploy-stack.sh" \
--template-file stacks/web-stack.yaml \
--stack-name privacysexy-web-stack \
--parameter-overrides "CertificateStackName=privacysexy-cert-stack DnsStackName=privacysexy-dns-stack \
RootDomainName=privacy.sexy UseDeepLinks=true" \
--capabilities CAPABILITY_IAM \
--region us-east-1 \
--role-arn ${{secrets.AWS_WEB_STACK_DEPLOYMENT_ROLE_ARN}} \
--profile user --session ${{ env.SESSION_NAME }}
working-directory: aws
-
name: "App: Checkout"
uses: actions/checkout@v2
with:
path: site
ref: master # otherwise we don't get version bump commit
-
name: "App: Setup node"
uses: actions/setup-node@v1
with:
node-version: '14.x'
-
name: "App: Install dependencies"
run: npm ci
working-directory: site
-
name: "App: Run tests"
run: npm run test:unit
working-directory: site
-
name: "App: Build"
run: npm run build
working-directory: site
-
name: "App: Deploy to S3"
run: >-
bash "aws/scripts/deploy/deploy-to-s3.sh" \
--folder site/dist \
--web-stack-name privacysexy-web-stack --web-stack-s3-name-output-name S3BucketName \
--storage-class ONEZONE_IA \
--role-arn ${{secrets.AWS_S3_SITE_DEPLOYMENT_ROLE_ARN}} \
--region us-east-1 \
--profile user --session ${{ env.SESSION_NAME }}
-
name: "App: Invalidate CloudFront cache"
run: >-
bash "aws/scripts/deploy/invalidate-cloudfront-cache.sh" \
--paths "/*" \
--web-stack-name privacysexy-web-stack --web-stack-cloudfront-arn-output-name CloudFrontDistributionArn \
--role-arn ${{secrets.AWS_CLOUDFRONT_SITE_DEPLOYMENT_ROLE_ARN}} \
--region us-east-1 \
--profile user --session ${{ env.SESSION_NAME }}
desktop-deploy:
runs-on: windows-latest
steps:
-
name: Set GitHub PAT token # https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#github-personal-access-token
run: set GH_TOKEN=TOKEN-GOES-HERE
-
name: Checkout
uses: actions/checkout@v2
with:
ref: master # otherwise it defaults to the version tag missing bump commit
fetch-depth: 0 # fetch all history
- name: Checkout to bump commit
run: git checkout "$(git rev-list "${{ github.event.release.tag_name }}"..master | tail -1)"
-
name: Setup node
uses: actions/setup-node@v1
with:
node-version: '14.x'
-
name: Install dependencies
run: npm ci
-
name: Run tests
run: npm run test:unit
-
name: Upload Release to GitHub # https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/recipes.html#upload-release-to-github
run: npm run electron:build -- -p always

View File

@@ -1,5 +1,17 @@
# Changelog
## 0.6.0 (2020-07-26)
* fixed dead links in documentation | [commit](https://github.com/undergroundwires/privacy.sexy/commit/25ce236a7737decaf2eb9b8c29a4c4f34d43f770)
* runs tests on each push on the repository | [commit](https://github.com/undergroundwires/privacy.sexy/commit/73c426844a0330718a9ab7de12b61ca05e853323)
* code area now shows "how" before "why" | [commit](https://github.com/undergroundwires/privacy.sexy/commit/4ff4b52202b1c5dbfe2b80580bbe7d93132ab05c)
* support for desktop versions #20 | [commit](https://github.com/undergroundwires/privacy.sexy/commit/5a27f9d86c96be88bb52aa69a84a7e057ac072be)
* reworked on footer & removed github icon | [commit](https://github.com/undergroundwires/privacy.sexy/commit/8ab062454db1d8504fb2df4fbb39a7002bafeb09)
* updated dependencies to latest | [commit](https://github.com/undergroundwires/privacy.sexy/commit/c335ab33ff612a19af1278bdcc88a14779e8bb91)
* updated documentation | [commit](https://github.com/undergroundwires/privacy.sexy/commit/81dfbbef7a8786751fa7693010c80561c5ac6bce)
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.5.0...0.6.0)
## 0.5.0 (2020-07-19)
* added ability to revert (#21) | [commit](https://github.com/undergroundwires/privacy.sexy/commit/9c063d59defa6297c64f50b49403e8bd10620de9)

View File

@@ -21,7 +21,7 @@
- 🙏 DO
- Document your changes in the pull request
- ❗ DON'T
- Do not update the versions, current version is only [set by the maintainer](./docs/gitops.png) and updated automatically by [bump-everywhere](https://github.com/undergroundwires/bump-everywhere)
- Do not update the versions, current version is only [set by the maintainer](./img/gitops.png) and updated automatically by [bump-everywhere](https://github.com/undergroundwires/bump-everywhere)
## Guidelines

View File

@@ -15,7 +15,9 @@
## Get started
- Online version: [https://privacy.sexy](https://privacy.sexy)
- Or download latest desktop version for [Windows](https://github.com/undergroundwires/privacy-sexy/releases/download/0.5.0/privacy.sexy-Setup-0.5.0.exe), [Linux](https://github.com/undergroundwires/privacy-sexy/releases/download/0.5.0/privacy.sexy-0.5.0.dmg), [macOS](https://github.com/undergroundwires/privacy-sexy/releases/download/0.5.0/privacy.sexy-0.5.0-mac.zip)
- or download latest desktop version for [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.6.0/privacy.sexy-Setup-0.6.0.exe), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.6.0/privacy.sexy-0.6.0.AppImage), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.6.0/privacy.sexy-0.6.0.dmg)
![privacy.sexy application](img/app.png)
## Why
@@ -46,14 +48,14 @@
- Development: `npm run serve` to compile & hot-reload for development.
- Production: `npm run build` to prepare files for distribution.
- Or run using Docker:
1. Build: `docker build -t undergroundwires/privacy.sexy:0.5.0 .`
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.5.0 undergroundwires/privacy.sexy:0.5.0`
1. Build: `docker build -t undergroundwires/privacy.sexy:0.6.0 .`
2. Run: `docker run -it -p 8080:80 --rm --name privacy.sexy-0.6.0 undergroundwires/privacy.sexy:0.6.0`
## Architecture
### Application
- Powered by **TypeScript** + **Vue.js** 💪
- Powered by **TypeScript**, **Vue.js** and **Electron** 💪
- and driven by **Domain-driven design**, **Event-driven architecture**, **Data-driven programming** concepts.
- Application uses highly decoupled models & services in different DDD layers.
- **Domain layer** is where the application is modelled with validation logic.
@@ -66,11 +68,11 @@
- The [state](src/application/State/ApplicationState.ts) is a mutable singleton & event producer.
- The application is defined & controlled in a [single YAML file](src/application/application.yaml) (see [Data-driven programming](https://en.wikipedia.org/wiki/Data-driven_programming))
![DDD + vue.js](docs/app-ddd.png)
![DDD + vue.js](img/app-ddd.png)
### AWS Infrastructure
[![AWS solution](docs/aws-solution.png)](https://github.com/undergroundwires/aws-static-site-with-cd)
[![AWS solution](img/aws-solution.png)](https://github.com/undergroundwires/aws-static-site-with-cd)
- It uses infrastructure from the following repository: [aws-static-site-with-cd](https://github.com/undergroundwires/aws-static-site-with-cd)
- Runs on AWS 100% serverless and automatically provisioned using [GitHub Actions](.github/workflows/).
@@ -82,4 +84,4 @@
- Versioning, tagging, creation of `CHANGELOG.md` and releasing is automated using [bump-everywhere](https://github.com/undergroundwires/bump-everywhere) action
- Everything that's merged in the master goes directly to production.
[![CI/CD to AWS with GitHub Actions](docs/gitops.png)](.github/workflows/)
[![CI/CD to AWS with GitHub Actions](img/gitops.png)](.github/workflows/)

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
img/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

1
img/gitops.drawio Normal file

File diff suppressed because one or more lines are too long

BIN
img/gitops.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

8
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "privacy.sexy",
"version": "0.5.0",
"version": "0.6.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -4901,9 +4901,9 @@
}
},
"elliptic": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
"integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
"dev": true,
"requires": {
"bn.js": "^4.4.0",

View File

@@ -1,6 +1,6 @@
{
"name": "privacy.sexy",
"version": "0.5.0",
"version": "0.6.0",
"author": "undergroundwires",
"description": "Enforce privacy & security best-practices on Windows, because privacy is sexy 🍑🍆",
"private": true,

View File

@@ -8,19 +8,11 @@ export class DetectorBuilder {
constructor(private readonly os: OperatingSystem) { }
public mustInclude(str: string): DetectorBuilder {
if (!str) {
throw new Error('part to include is empty or undefined');
}
this.existingPartsInUserAgent.push(str);
return this;
return this.add(str, this.existingPartsInUserAgent);
}
public mustNotInclude(str: string): DetectorBuilder {
if (!str) {
throw new Error('part to not include is empty or undefined');
}
this.notExistingPartsInUserAgent.push(str);
return this;
return this.add(str, this.notExistingPartsInUserAgent);
}
public build(): IBrowserOsDetector {
@@ -28,22 +20,34 @@ export class DetectorBuilder {
throw new Error('Must include at least a part');
}
return {
detect: (userAgent) => {
if (!userAgent) {
throw new Error('User agent is null or undefined');
}
for (const exitingPart of this.existingPartsInUserAgent) {
if (!userAgent.includes(exitingPart)) {
return OperatingSystem.Unknown;
}
}
for (const notExistingPart of this.notExistingPartsInUserAgent) {
if (userAgent.includes(notExistingPart)) {
return OperatingSystem.Unknown;
}
}
return this.os;
},
detect: (agent) => this.detect(agent),
};
}
private detect(userAgent: string): OperatingSystem {
if (!userAgent) {
throw new Error('User agent is null or undefined');
}
if (this.existingPartsInUserAgent.some((part) => !userAgent.includes(part))) {
return OperatingSystem.Unknown;
}
if (this.notExistingPartsInUserAgent.some((part) => userAgent.includes(part))) {
return OperatingSystem.Unknown;
}
return this.os;
}
private add(part: string, array: string[]): DetectorBuilder {
if (!part) {
throw new Error('part is empty or undefined');
}
if (this.existingPartsInUserAgent.includes(part)) {
throw new Error(`part ${part} is already included as existing part`);
}
if (this.notExistingPartsInUserAgent.includes(part)) {
throw new Error(`part ${part} is already included as not existing part`);
}
array.push(part);
return this;
}
}

View File

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

View File

@@ -351,6 +351,26 @@ actions:
schtasks /change /TN "\Microsoft\Windows\Customer Experience Improvement Program\Consolidator" /ENABLE
schtasks /change /TN "\Microsoft\Windows\Customer Experience Improvement Program\KernelCeipTask" /ENABLE
schtasks /change /TN "\Microsoft\Windows\Customer Experience Improvement Program\UsbCeip" /ENABLE
-
name: Disable Webcam Telemetry (devicecensus.exe)
recommend: true
docs: https://www.ghacks.net/2019/09/23/what-is-devicecensus-exe-on-windows-10-and-why-does-it-need-internet-connectivity/
code: schtasks /change /TN "Microsoft\Windows\Device Information\Device" /DISABLE
revertCode: schtasks /change /TN "Microsoft\Windows\Device Information\Device" /ENABLE
-
name: Disable Application Experience (Compatibility Telemetry)
recommend: true
code: |-
schtasks /change /TN "Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" /DISABLE
schtasks /change /TN "Microsoft\Windows\Application Experience\ProgramDataUpdater" /DISABLE
schtasks /change /TN "Microsoft\Windows\Application Experience\StartupAppTask" /DISABLE
schtasks /change /TN "Microsoft\Windows\Application Experience\AitAgent" /DISABLE
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\CompatTelRunner.exe" /v Debugger /t REG_SZ /d "%windir%\System32\taskkill.exe" /f
revertCode: |-
schtasks /change /TN "Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" /ENABLE
schtasks /change /TN "Microsoft\Windows\Application Experience\ProgramDataUpdater" /ENABLE
schtasks /change /TN "Microsoft\Windows\Application Experience\StartupAppTask" /ENABLE
schtasks /change /TN "Microsoft\Windows\Application Experience\AitAgent" /ENABLE
-
name: Disable telemetry in data collection policy
recommend: true
@@ -368,16 +388,33 @@ actions:
name: Disable error reporting
recommend: true
code: |-
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" /v "Disabled" /t REG_DWORD /d "1" /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" /v "Disabled" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting" /v "Disabled" /t "REG_DWORD" /d "1" /f
sc stop "WerSvc" & sc config "WerSvc" start=disabled
sc stop "wercplsupport" & sc config "wercplsupport" start=disabled
revertCode: |-
reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting" /v "Disabled" /f
reg delete "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting" /v "Disabled" /f
sc config "WerSvc" start=demand
sc config "wercplsupport" start=demand
-
name: Disable online device metadata collection
recommend: true
recommend: false
docs:
- https://www.stigviewer.com/stig/windows_server_2012_member_server/2014-01-07/finding/V-21964
- https://docs.microsoft.com/en-us/windows/client-management/mdm/policy-csp-deviceinstallation#deviceinstallation-preventdevicemetadatafromnetwork
code: |-
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Metadata" /v "PreventDeviceMetadataFromNetwork" /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" /v "PreventDeviceMetadataFromNetwork" /t REG_DWORD /d 1 /f
revertCode: |-
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Metadata" /v "PreventDeviceMetadataFromNetwork" /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" /v "PreventDeviceMetadataFromNetwork" /t REG_DWORD /d 0 /f
-
name: Disable cloud speech recognation
recommend: true
docs: https://www.tenforums.com/tutorials/101902-turn-off-online-speech-recognition-windows-10-a.html
code: reg add "HKCU\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy" /v "HasAccepted" /t "REG_DWORD" /d 0 /f
revertCode: reg add "HKCU\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy" /v "HasAccepted" /t "REG_DWORD" /d 1 /f
-
name: Disable active prompting (pings to MSFT NCSI server)
recommend: false
@@ -701,13 +738,6 @@ actions:
reg add "HKLM\SOFTWARE\Microsoft\PolicyManager\default\System\AllowExperimentation" /v "value" /t "REG_DWORD" /d 0 /f
reg add "HKLM\SOFTWARE\Microsoft\WindowsSelfHost\UI\Visibility" /v "HideInsiderPage" /t "REG_DWORD" /d "1" /f
sc stop "wisvc" & sc config "wisvc" start=disabled
-
name: Disable the Windows Connect Now wizard
recommend: false
docs:
- https://docs.microsoft.com/en-us/windows/win32/wcn/about-windows-connect-now
- https://www.windows-security.org/f637a705712eb59f8cd410673c96472e/prohibit-access-of-the-windows-connect-now-wizards
code: reg add "HKCU\Software\Policies\Microsoft\Windows\WCN\UI" /v "DisableWcnUi" /t REG_DWORD /d 1 /f
-
category: Disable cloud sync
children:
@@ -834,9 +864,10 @@ actions:
recommend: true
code: reg add "HKLM\SOFTWARE\Policies\Microsoft\MRT" /v "DontReportInfectionInformation" /t REG_DWORD /d 1 /f
-
name: Disable NetCore Cli telemetry
name: Disable NET Core CLI telemetry
recommend: true
code: setx DOTNET_CLI_TELEMETRY_OPTOUT 1
revertCode: setx DOTNET_CLI_TELEMETRY_OPTOUT 0
-
name: Disable NVIDIA telemetry
recommend: true
@@ -1151,6 +1182,26 @@ actions:
code: |-
dism /online /Disable-Feature /FeatureName:"MicrosoftWindowsPowerShellV2Root" /NoRestart
dism /online /Disable-Feature /FeatureName:"MicrosoftWindowsPowerShellV2" /NoRestart
-
name: Disable the Windows Connect Now wizard
recommend: true
docs:
- https://docs.microsoft.com/en-us/windows/win32/wcn/about-windows-connect-now
- https://www.stigviewer.com/stig/windows_server_20122012_r2_domain_controller/2019-01-16/finding/V-15698
code: |-
reg add "HKLM\Software\Policies\Microsoft\Windows\WCN\UI" /v "DisableWcnUi" /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableFlashConfigRegistrar" /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableInBand802DOT11Registrar" /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableUPnPRegistrar" /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableWPDRegistrar" /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "EnableRegistrars" /t REG_DWORD /d 0 /f
revertCode: |-
reg add "HKLM\Software\Policies\Microsoft\Windows\WCN\UI" /v "DisableWcnUi" /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableFlashConfigRegistrar" /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableInBand802DOT11Registrar" /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableUPnPRegistrar" /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "DisableWPDRegistrar" /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WCN\Registrars" /v "EnableRegistrars" /t REG_DWORD /d 1 /f
-
category: Privacy over security
children:
@@ -1249,11 +1300,13 @@ actions:
-
name: Disable Sync Provider Notifications
recommend: false
code: REG ADD "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ShowSyncProviderNotifications" /d 0 /t REG_DWORD /f
code: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ShowSyncProviderNotifications" /d 0 /t REG_DWORD /f
revertCode: reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "ShowSyncProviderNotifications" /d 1 /t REG_DWORD /f
-
name: Turn hibernate off to disable sleep for quick start
recommend: false
code: powercfg -h off
revertCode: powercfg -h on
docs: http://www.windows10windows7.com/w10/win10zs/100102504.html
-
category: Hide from This PC and Browse in dialog boxes
@@ -1355,14 +1408,17 @@ actions:
name: Xbox Live Auth Manager
recommend: true
code: sc stop "XblAuthManager" & sc config "XblAuthManager" start=disabled
revetCode: sc config "XblAuthManager" start=demand
-
name: Xbox Live Game Save
recommend: true
code: sc stop "XblGameSave" & sc config "XblGameSave" start=disabled
revertCode: sc config "XblGameSave" start=demand
-
name: Xbox Live Networking Service
recommend: true
code: sc stop "XboxNetApiSvc" & sc config "XboxNetApiSvc" start=disabled
revetCode: sc config "XboxNetApiSvc" start=demand
-
name: Windows Biometric Service
recommend: true
@@ -1781,15 +1837,17 @@ actions:
-
name: Remove OneDrive
code: |-
taskkill /F /IM OneDrive.exe
taskkill /f /im OneDrive.exe
%SystemRoot%\System32\OneDriveSetup.exe /uninstall
%SystemRoot%\SysWOW64\OneDriveSetup.exe /uninstall
rd "%UserProfile%\OneDrive" /Q /S
rd "%LocalAppData%\Microsoft\OneDrive" /Q /S
rd "%ProgramData%\Microsoft OneDrive" /Q /S
rd "C:\OneDriveTemp" /Q /S
rd "%UserProfile%\OneDrive" /q /s
rd "%LocalAppData%\Microsoft\OneDrive" /q /s
rd "%ProgramData%\Microsoft OneDrive" /q /s
rd "C:\OneDriveTemp" /q /s
del "%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk" /s /f /q
reg delete "HKEY_CLASSES_ROOT\CLSID{018D5C66-4533-4307-9B53-224DE2ED1FE6}" /f
reg delete "HKEY_CLASSES_ROOT\Wow6432Node\CLSID{018D5C66-4533-4307-9B53-224DE2ED1FE6}" /f
reg add "HKEY_CLASSES_ROOT\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" /v System.IsPinnedToNameSpaceTree /d "0" /t REG_DWORD /f
-
category: Disable built-in Windows features
children:

View File

@@ -1,6 +1,6 @@
declare module 'js-yaml-loader!*' {
export type CategoryOrScript = YamlCategory | YamlScript;
type DocumentationUrls = ReadonlyArray<string> | string;
export type DocumentationUrls = ReadonlyArray<string> | string;
export interface YamlDocumentable {
docs?: DocumentationUrls;

View File

@@ -18,15 +18,7 @@ export class Application implements IApplication {
if (!repositoryUrl) { throw Error('Application has no repository url'); }
if (!version) { throw Error('Version cannot be empty'); }
this.flattened = flatten(actions);
if (this.flattened.allCategories.length === 0) {
throw new Error('Application must consist of at least one category');
}
if (this.flattened.allScripts.length === 0) {
throw new Error('Application must consist of at least one script');
}
if (this.flattened.allScripts.filter((script) => script.isRecommended).length === 0) {
throw new Error('Application must consist of at least one recommended script');
}
ensureValid(this.flattened);
ensureNoDuplicates(this.flattened.allCategories);
ensureNoDuplicates(this.flattened.allScripts);
}
@@ -75,30 +67,50 @@ interface IFlattenedApplication {
allScripts: IScript[];
}
function flattenRecursive(
function ensureValid(application: IFlattenedApplication) {
if (!application.allCategories || application.allCategories.length === 0) {
throw new Error('Application must consist of at least one category');
}
if (!application.allScripts || application.allScripts.length === 0) {
throw new Error('Application must consist of at least one script');
}
if (application.allScripts.filter((script) => script.isRecommended).length === 0) {
throw new Error('Application must consist of at least one recommended script');
}
}
function flattenCategories(
categories: ReadonlyArray<ICategory>,
flattened: IFlattenedApplication) {
flattened: IFlattenedApplication): IFlattenedApplication {
if (!categories || categories.length === 0) {
return flattened;
}
for (const category of categories) {
flattened.allCategories.push(category);
if (category.scripts) {
for (const script of category.scripts) {
flattened.allScripts.push(script);
}
}
if (category.subCategories && category.subCategories.length > 0) {
flattenRecursive(
category.subCategories as ReadonlyArray<ICategory>,
flattened);
}
flattened = flattenScripts(category.scripts, flattened);
flattened = flattenCategories(category.subCategories, flattened);
}
return flattened;
}
function flattenScripts(
scripts: ReadonlyArray<IScript>,
flattened: IFlattenedApplication): IFlattenedApplication {
if (!scripts) {
return flattened;
}
for (const script of scripts) {
flattened.allScripts.push(script);
}
return flattened;
}
function flatten(
categories: ReadonlyArray<ICategory>): IFlattenedApplication {
const flattened: IFlattenedApplication = {
let flattened: IFlattenedApplication = {
allCategories: new Array<ICategory>(),
allScripts: new Array<IScript>(),
};
flattenRecursive(categories, flattened);
flattened = flattenCategories(categories, flattened);
return flattened;
}

View File

@@ -4,7 +4,7 @@ import { faGithub } from '@fortawesome/free-brands-svg-icons';
/** BRAND ICONS (PREFIX: fab) */
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
/** REGULAR ICONS (PREFIX: far) */
import { faFolderOpen, faFolder, faComment, faSmile } from '@fortawesome/free-regular-svg-icons';
import { faFolderOpen, faFolder, faSmile } from '@fortawesome/free-regular-svg-icons';
/** SOLID ICONS (PREFIX: fas (default)) */
import { faTimes, faFileDownload, faCopy, faSearch, faInfoCircle, faUserSecret, faDesktop, faTag, faGlobe } from '@fortawesome/free-solid-svg-icons';

View File

@@ -30,19 +30,32 @@ export function getCategoryNodeId(category: ICategory): string {
function parseCategoryRecursively(
parentCategory: ICategory): INode[] {
if (!parentCategory) { throw new Error('parentCategory is undefined'); }
const nodes = new Array<INode>();
if (parentCategory.subCategories && parentCategory.subCategories.length > 0) {
for (const subCategory of parentCategory.subCategories) {
const subCategoryNodes = parseCategoryRecursively(subCategory);
nodes.push(convertCategoryToNode(subCategory, subCategoryNodes));
}
if (!parentCategory) {
throw new Error('parentCategory is undefined');
}
if (parentCategory.scripts && parentCategory.scripts.length > 0) {
for (const script of parentCategory.scripts) {
nodes.push(convertScriptToNode(script));
}
let nodes = new Array<INode>();
nodes = addCategories(parentCategory.subCategories, nodes);
nodes = addScripts(parentCategory.scripts, nodes);
return nodes;
}
function addScripts(scripts: ReadonlyArray<IScript>, nodes: INode[]): INode[] {
if (!scripts || scripts.length === 0) {
return nodes;
}
for (const script of scripts) {
nodes.push(convertScriptToNode(script));
}
return nodes;
}
function addCategories(categories: ReadonlyArray<ICategory>, nodes: INode[]): INode[] {
if (!categories || categories.length === 0) {
return nodes;
}
for (const category of categories) {
const subCategoryNodes = parseCategoryRecursively(category);
nodes.push(convertCategoryToNode(category, subCategoryNodes));
}
return nodes;
}

View File

@@ -9,8 +9,7 @@ export function convertExistingToNode(liquorTreeNode: ILiquorTreeExistingNode):
id: liquorTreeNode.id,
text: liquorTreeNode.data.text,
// selected: liquorTreeNode.states && liquorTreeNode.states.checked,
children: (!liquorTreeNode.children || liquorTreeNode.children.length === 0)
? [] : liquorTreeNode.children.map((childNode) => convertExistingToNode(childNode)),
children: convertChildren(liquorTreeNode.children, convertExistingToNode),
documentationUrls: liquorTreeNode.data.documentationUrls,
isReversible : liquorTreeNode.data.isReversible,
};
@@ -24,11 +23,19 @@ export function toNewLiquorTreeNode(node: INode): ILiquorTreeNewNode {
state: {
checked: false,
},
children: (!node.children || node.children.length === 0) ? [] :
node.children.map((childNode) => toNewLiquorTreeNode(childNode)),
children: convertChildren(node.children, toNewLiquorTreeNode),
data: {
documentationUrls: node.documentationUrls,
isReversible: node.isReversible,
},
};
}
function convertChildren<TOldNode, TNewNode>(
oldChildren: readonly TOldNode[],
callback: (value: TOldNode) => TNewNode): TNewNode[] {
if (!oldChildren || oldChildren.length === 0) {
return [];
}
return oldChildren.map((childNode) => callback(childNode));
}

View File

@@ -65,9 +65,9 @@ function getOperatingSystemName(os: OperatingSystem): string {
function getFileName(os: OperatingSystem, version: string): string {
switch (os) {
case OperatingSystem.Linux:
return `privacy.sexy-${version}.dmg`;
return `privacy.sexy-${version}.AppImage`;
case OperatingSystem.macOS:
return `privacy.sexy-${version}-mac.zip`;
return `privacy.sexy-${version}.dmg`;
case OperatingSystem.Windows:
return `privacy.sexy-Setup-${version}.exe`;
default:

View File

@@ -6,7 +6,7 @@
</div>
<div v-if="isDesktop" class="line">
<div class="line__emoji">🚫🌐</div>
<div>Everything is offline, except single request GitHub toto check for updates on application start.</div>
<div>Everything is offline, except single request GitHub to check for updates on application start.</div>
</div>
<div class="line">
<div class="line__emoji">🚫👀</div>