1
0
mirror of https://github.com/privacyguides/privacyguides.org.git synced 2025-09-12 13:08:47 +00:00

Compare commits

..

3 Commits

Author SHA1 Message Date
rollsicecream
47f4ca1979 update!: Add KeePassium (#3048)
Signed-off-by: redoomed1 <redoomed1@privacyguides.org>
Signed-off-by: Daniel Gray <dngray@privacyguides.org>
2025-09-12 18:10:02 +09:30
fria
dc6f326f96 update: Add download links for uBO Lite on Safari and Edge (#3087)
Signed-off-by: redoomed1 <redoomed1@privacyguides.org>
Signed-off-by: Daniel Gray <dngray@privacyguides.org>
2025-09-12 16:41:16 +09:30
b55f1cdb44 feat!: Include ZIM files in releases (#3102) 2025-09-12 01:03:53 -05:00
27 changed files with 803 additions and 141 deletions

View File

@@ -80,7 +80,7 @@ jobs:
needs: [submodule, metadata]
strategy:
matrix:
lang: [es, fr, he, it, nl, ru, zh-Hant, zh-TW]
lang: [es, fr, he, it, nl, ru, zh-Hant]
fail-fast: false
uses: ./.github/workflows/build.yml
with:
@@ -101,6 +101,16 @@ jobs:
continue-on-error: true
privileged: ${{ fromJSON(needs.metadata.outputs.privileged) }}
build_zimfile:
if: ${{ contains(github.event.pull_request.labels.*.name, 'ci:build zimfile') }}
needs: [submodule, metadata]
uses: ./.github/workflows/build-zimfile.yml
with:
ref: ${{github.event.pull_request.head.ref}}
repo: ${{github.event.pull_request.head.repo.full_name}}
secrets:
RO_DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
combine_build:
needs: [build_english, build_i18n, build_blog]
if: |
@@ -129,5 +139,5 @@ jobs:
cleanup:
if: ${{ always() }}
needs: [build_english, build_i18n, build_blog]
needs: [build_english, build_i18n, build_blog, build_zimfile]
uses: privacyguides/.github/.github/workflows/cleanup.yml@main

603
.github/workflows/build-zimfile.yml vendored Normal file
View File

@@ -0,0 +1,603 @@
name: 🥝 Build Zimfile
on:
workflow_call:
inputs:
ref:
required: true
type: string
repo:
required: true
type: string
secrets:
RO_DISCOURSE_API_KEY:
required: false
permissions:
contents: read
env:
VIDEOS_SITE_BASE_URL: https://www.privacyguides.org/videos/
HOMEPAGE_CTA_ABOUT_LINK: about.html
HOMEPAGE_CTA_DONATE_LINK: about/donate.html
BUILD_OFFLINE: true
PRODUCTION: true
CARDS: false
GITREVISIONDATE: false
GITAUTHORS: false
jobs:
package_eng:
runs-on: ubuntu-latest
permissions:
contents: read
env:
LANGUAGE_SWITCHER: false
MAIN_SITE_BASE_URL: /en/index.html
MAIN_SITE_ABOUT_URL: /en/about.html
MAIN_SITE_RECOMMENDATIONS_URL: /en/tools.html
MAIN_SITE_KNOWLEDGE_BASE_URL: /en/basics/why-privacy-matters.html
ARTICLES_SITE_BASE_URL: /articles/index.html
steps:
- name: Add GitHub Token to Environment
run: |
echo "GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> "$GITHUB_ENV"
- name: Download Repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.ref }}
persist-credentials: "false"
fetch-depth: 0
- name: Download Submodules
uses: actions/download-artifact@v4
with:
pattern: repo-*
path: modules
- name: Move mkdocs-material-insiders to mkdocs-material
run: |
rmdir modules/mkdocs-material
mv modules/repo-mkdocs-material-insiders modules/mkdocs-material
- name: Move brand submodule to theme/assets/brand
run: |
rmdir theme/assets/brand
mv modules/repo-brand theme/assets/brand
- name: Install Python (pipenv)
uses: actions/setup-python@v5
with:
cache: "pipenv"
- name: Install Python Dependencies
run: |
pip install pipenv
pipenv install
sudo apt install pngquant
- name: Generate Donating Members List
continue-on-error: true
env:
DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
run: |
pip install requests
python tools/generate-members.py > includes/members.md
- name: Build English
run: |
./run.sh --build --production --insiders --offline --lang=en
- name: Delete Unreferenced Assets
run: |
bash tools/delete-unreferenced.sh
env:
ASSETS_DIR: site/en/assets
SEARCH_DIR: site/en
- name: Run generate-topics.sh for top posts
run: |
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/top.json?period=weekly' \
--tag="top posts" \
--destination="./site/en/index.html" \
--count=3
- name: Run generate-topics.sh for latest posts
run: |
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/latest.json' \
--tag="latest posts" \
--destination="./site/en/index.html" \
--count=12
- name: Build Articles
run: |
pipenv run mkdocs build --config-file mkdocs.blog.yml
- name: Delete Unreferenced Assets
run: |
bash tools/delete-unreferenced.sh
env:
ASSETS_DIR: site/articles/assets
SEARCH_DIR: site/articles
- name: Remove Duplicate Files
run: |
cd site && bash ../tools/symlink-duplicates.sh
ln -s en/index.html index.html
ln -s en/about/notices.html license
cd ..
- name: Set zimfile name
run: |
echo "ZIMFILE_NAME=privacyguides.org_en_all_$(date +%Y)-$(date +%m).zim" >> "$GITHUB_ENV"
- name: Create ZIM File
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimwriterfs \
-w index.html \
-I en/assets/brand/logos/png/square/pg-yellow.png \
-l eng \
-t "Privacy Guides" \
-d "Your central privacy and security resource to protect yourself online." \
-c "Privacy Guides" \
-p "Privacy Guides" \
-e "https://www.privacyguides.org" \
-n "privacyguides.org_en_all" \
/data/site/ /data/${{ env.ZIMFILE_NAME }}
- name: Upload ZIM File
uses: actions/upload-artifact@v4
with:
path: ${{ env.ZIMFILE_NAME }}
name: ${{ env.ZIMFILE_NAME }}
compression-level: 0
- name: Run zimcheck
uses: addnab/docker-run-action@v3
continue-on-error: true
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimcheck /data/${{ env.ZIMFILE_NAME }}
package_eng_kb:
runs-on: ubuntu-latest
permissions:
contents: read
env:
LANGUAGE_SWITCHER: false
ARTICLES_SITE_BASE_URL: https://www.privacyguides.org/articles/
steps:
- name: Add GitHub Token to Environment
run: |
echo "GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> "$GITHUB_ENV"
- name: Download Repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.ref }}
persist-credentials: "false"
fetch-depth: 0
- name: Download Submodules
uses: actions/download-artifact@v4
with:
pattern: repo-*
path: modules
- name: Move mkdocs-material-insiders to mkdocs-material
run: |
rmdir modules/mkdocs-material
mv modules/repo-mkdocs-material-insiders modules/mkdocs-material
- name: Move brand submodule to theme/assets/brand
run: |
rmdir theme/assets/brand
mv modules/repo-brand theme/assets/brand
- name: Install Python (pipenv)
uses: actions/setup-python@v5
with:
cache: "pipenv"
- name: Install Python Dependencies
run: |
pip install pipenv
pipenv install
sudo apt install pngquant
- name: Generate Donating Members List
continue-on-error: true
env:
DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
run: |
pip install requests
python tools/generate-members.py > includes/members.md
- name: Build English
run: |
./run.sh --build --production --insiders --offline --lang=en
- name: Run generate-topics.sh for top posts
run: |
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/top.json?period=weekly' \
--tag="top posts" \
--destination="./site/en/index.html" \
--count=3
- name: Run generate-topics.sh for latest posts
run: |
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/latest.json' \
--tag="latest posts" \
--destination="./site/en/index.html" \
--count=12
- name: Delete Unreferenced Assets
run: |
bash tools/delete-unreferenced.sh
env:
ASSETS_DIR: site/en/assets
SEARCH_DIR: site/en
- name: Remove Duplicate Files
run: |
cd site && bash ../tools/symlink-duplicates.sh
ln -s en/index.html index.html
ln -s en/about/notices.html license
cd ..
- name: Set zimfile name
run: |
echo "ZIMFILE_NAME=privacyguides.org_en_kb_$(date +%Y)-$(date +%m).zim" >> "$GITHUB_ENV"
- name: Create ZIM File
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimwriterfs \
-w index.html \
-I en/assets/brand/logos/png/square/pg-yellow.png \
-l eng \
-t "Privacy Guides" \
-d "Knowledge base articles and recommendations from Privacy Guides." \
-c "Privacy Guides" \
-p "Privacy Guides" \
-e "https://www.privacyguides.org" \
-n "privacyguides.org_en_kb" \
/data/site/ /data/${{ env.ZIMFILE_NAME }}
- name: Upload ZIM File
uses: actions/upload-artifact@v4
with:
path: ${{ env.ZIMFILE_NAME }}
name: ${{ env.ZIMFILE_NAME }}
compression-level: 0
- name: Run zimcheck
uses: addnab/docker-run-action@v3
continue-on-error: true
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimcheck /data/${{ env.ZIMFILE_NAME }}
package_eng_articles:
runs-on: ubuntu-latest
permissions:
contents: read
env:
MAIN_SITE_BASE_URL: https://www.privacyguides.org/en/
MAIN_SITE_ABOUT_URL: https://www.privacyguides.org/en/about/
MAIN_SITE_RECOMMENDATIONS_URL: https://www.privacyguides.org/en/tools/
MAIN_SITE_KNOWLEDGE_BASE_URL: https://www.privacyguides.org/en/basics/
steps:
- name: Add GitHub Token to Environment
run: |
echo "GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> "$GITHUB_ENV"
- name: Download Repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.ref }}
persist-credentials: "false"
fetch-depth: 0
- name: Download Submodules
uses: actions/download-artifact@v4
with:
pattern: repo-*
path: modules
- name: Move mkdocs-material-insiders to mkdocs-material
run: |
rmdir modules/mkdocs-material
mv modules/repo-mkdocs-material-insiders modules/mkdocs-material
- name: Move brand submodule to theme/assets/brand
run: |
rmdir theme/assets/brand
mv modules/repo-brand theme/assets/brand
- name: Install Python (pipenv)
uses: actions/setup-python@v5
with:
cache: "pipenv"
- name: Install Python Dependencies
run: |
pip install pipenv
pipenv install
sudo apt install pngquant
- name: Build Articles
run: |
pipenv run mkdocs build --config-file mkdocs.blog.yml
- name: Delete Unreferenced Assets
run: |
bash tools/delete-unreferenced.sh
env:
ASSETS_DIR: site/articles/assets
SEARCH_DIR: site/articles
- name: Remove Duplicate Files
run: |
cd site && bash ../tools/symlink-duplicates.sh
ln -s articles/index.html index.html
cd ..
- name: Set zimfile name
run: |
echo "ZIMFILE_NAME=privacyguides.org_en_articles_$(date +%Y)-$(date +%m).zim" >> "$GITHUB_ENV"
- name: Create ZIM File
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimwriterfs \
-w index.html \
-I articles/assets/brand/logos/png/square/pg-yellow.png \
-l eng \
-t "Privacy Guides" \
-d "Long-form articles from the Privacy Guides team and other contributors." \
-c "Privacy Guides" \
-p "Privacy Guides" \
-e "https://www.privacyguides.org" \
-n "privacyguides.org_en_articles" \
/data/site/ /data/${{ env.ZIMFILE_NAME }}
- name: Upload ZIM File
uses: actions/upload-artifact@v4
with:
path: ${{ env.ZIMFILE_NAME }}
name: ${{ env.ZIMFILE_NAME }}
compression-level: 0
- name: Run zimcheck
uses: addnab/docker-run-action@v3
continue-on-error: true
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimcheck /data/${{ env.ZIMFILE_NAME }}
build_mul:
runs-on: ubuntu-latest
continue-on-error: true
permissions:
contents: read
env:
MAIN_SITE_BASE_URL: /en/index.html
MAIN_SITE_ABOUT_URL: /en/about.html
MAIN_SITE_RECOMMENDATIONS_URL: /en/tools.html
MAIN_SITE_KNOWLEDGE_BASE_URL: /en/basics/why-privacy-matters.html
ARTICLES_SITE_BASE_URL: /articles/index.html
strategy:
matrix:
lang: [en, es, fr, he, it, nl, ru, zh-Hant]
steps:
- name: Add GitHub Token to Environment
run: |
echo "GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> "$GITHUB_ENV"
- name: Download Repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.ref }}
persist-credentials: "false"
fetch-depth: 0
- name: Download Submodules
uses: actions/download-artifact@v4
with:
pattern: repo-*
path: modules
- name: Move mkdocs-material-insiders to mkdocs-material
run: |
rmdir modules/mkdocs-material
mv modules/repo-mkdocs-material-insiders modules/mkdocs-material
- name: Move brand submodule to theme/assets/brand
run: |
rmdir theme/assets/brand
mv modules/repo-brand theme/assets/brand
- name: Copy Translation Files
if: matrix.lang != 'en'
run: |
cp -rl modules/repo-i18n/i18n .
cp -rl modules/repo-i18n/includes .
- name: Install Python (pipenv)
uses: actions/setup-python@v5
with:
cache: "pipenv"
- name: Install Python Dependencies
run: |
pip install pipenv
pipenv install
sudo apt install pngquant
- name: Generate Donating Members List
continue-on-error: true
env:
DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
run: |
pip install requests
python tools/generate-members.py > includes/members.md
- name: Build Website
run: |
./run.sh --build --production --insiders --offline --lang=${{ matrix.lang }}
- name: Run generate-topics.sh for top posts
if: matrix.lang == 'en'
run: |
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/top.json?period=weekly' \
--tag="top posts" \
--destination="./site/en/index.html" \
--count=3
- name: Run generate-topics.sh for latest posts
if: matrix.lang == 'en'
run: |
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/latest.json' \
--tag="latest posts" \
--destination="./site/en/index.html" \
--count=12
- name: Delete Unreferenced Assets
run: |
bash tools/delete-unreferenced.sh
env:
ASSETS_DIR: site/${{ matrix.lang }}/assets
SEARCH_DIR: site/${{ matrix.lang }}
- name: Build Articles
if: matrix.lang == 'en'
run: |
pipenv run mkdocs build --config-file mkdocs.blog.yml
- name: Delete Unreferenced Assets
if: matrix.lang == 'en'
run: |
bash tools/delete-unreferenced.sh
env:
ASSETS_DIR: site/articles/assets
SEARCH_DIR: site/articles
- name: Package Website
run: |
tar -czf site-zimready-${{ matrix.lang }}.tar.gz site
- name: Upload Site
uses: actions/upload-artifact@v4
with:
name: site-zimready-${{ matrix.lang }}.tar.gz
path: site-zimready-${{ matrix.lang }}.tar.gz
retention-days: 1
compression-level: 0
package_mul:
runs-on: ubuntu-latest
needs: [build_mul]
permissions:
contents: read
steps:
- name: Download Repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.repo }}
ref: ${{ inputs.ref }}
persist-credentials: "false"
fetch-depth: 0
- name: Download All Sites
uses: actions/download-artifact@v4
with:
pattern: site-zimready-*
merge-multiple: true
- name: List Files (for debugging)
run: |
for file in *.tar.gz; do tar -zxf "$file"; done
ls -la site/
- name: Remove Duplicate Files
run: |
cd site && bash ../tools/symlink-duplicates.sh
ln -s en/index.html index.html
ln -s en/about/notices.html license
cd ..
- name: Set zimfile name
run: |
echo "ZIMFILE_NAME=privacyguides.org_mul_all_$(date +%Y)-$(date +%m).zim" >> "$GITHUB_ENV"
- name: Create ZIM File
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimwriterfs \
-w index.html \
-I en/assets/brand/logos/png/square/pg-yellow.png \
-l mul \
-t "Privacy Guides" \
-d "Your central privacy and security resource to protect yourself online." \
-c "Privacy Guides" \
-p "Privacy Guides" \
-e "https://www.privacyguides.org" \
-n "privacyguides.org_mul_all" \
/data/site/ /data/${{ env.ZIMFILE_NAME }}
- name: Upload ZIM File
uses: actions/upload-artifact@v4
with:
path: ${{ env.ZIMFILE_NAME }}
name: ${{ env.ZIMFILE_NAME }}
compression-level: 0
- name: Run zimcheck
uses: addnab/docker-run-action@v3
continue-on-error: true
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimcheck /data/${{ env.ZIMFILE_NAME }}

View File

@@ -180,7 +180,7 @@ jobs:
DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
run: |
pip install requests
python generate-members.py > includes/members.md
python tools/generate-members.py > includes/members.md
- name: Build Website
run: |
@@ -189,7 +189,7 @@ jobs:
- name: Run generate-topics.sh for top posts
if: inputs.lang == 'en'
run: |
bash generate-topics.sh \
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/top.json?period=weekly' \
--tag="top posts" \
--destination="./site/en/index.html" \
@@ -198,7 +198,7 @@ jobs:
- name: Run generate-topics.sh for latest posts
if: inputs.lang == 'en'
run: |
bash generate-topics.sh \
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/latest.json' \
--tag="latest posts" \
--destination="./site/en/index.html" \
@@ -259,47 +259,3 @@ jobs:
name: members.md
path: includes/members.md
retention-days: 1
offline_package:
if: inputs.config == 'offline' && inputs.lang == 'en'
needs: build
runs-on: ubuntu-latest
continue-on-error: ${{ inputs.continue-on-error }}
permissions:
contents: read
steps:
- uses: actions/download-artifact@v4
with:
name: site-offline-en.tar.gz
- run: |
tar -xzf site-offline-en.tar.gz
tar -czf offline.tar.gz site/en
zip -r -q offline.zip site/en
- name: Upload tar.gz file
uses: actions/upload-artifact@v4
with:
name: offline.tar.gz
path: offline.tar.gz
- name: Upload zip file
uses: actions/upload-artifact@v4
with:
name: offline.zip
path: offline.zip
- name: Create ZIM File
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/openzim/zim-tools:3.1.3
options: -v ${{ github.workspace }}:/data
run: |
zimwriterfs -w index.html -I assets/brand/logos/png/square/pg-yellow.png -l eng -t "Privacy Guides" -d "Your central privacy and security resource to protect yourself online." -c "Privacy Guides" -p "Jonah Aragon" -n "Privacy Guides" -e "https://github.com/privacyguides/privacyguides.org" /data/site/en /data/offline-privacy_guides.zim
- name: Upload ZIM file
uses: actions/upload-artifact@v4
with:
name: offline-privacy_guides.zim
path: offline-privacy_guides.zim

View File

@@ -50,8 +50,8 @@ jobs:
needs: submodule
strategy:
matrix:
lang: [en, es, fr, he, it, nl, ru, zh-Hant, zh-TW]
build: [build, offline]
lang: [en, es, fr, he, it, nl, ru, zh-Hant]
build: [build]
permissions:
contents: read
uses: ./.github/workflows/build.yml
@@ -77,9 +77,20 @@ jobs:
continue-on-error: false
context: production
build_zimfile:
needs: submodule
permissions:
contents: read
uses: ./.github/workflows/build-zimfile.yml
with:
repo: ${{ github.repository }}
ref: ${{ github.ref }}
secrets:
RO_DISCOURSE_API_KEY: ${{ secrets.RO_DISCOURSE_API_KEY }}
release:
name: Create release notes
needs: build
needs: [build, build_zimfile]
runs-on: ubuntu-latest
permissions:
contents: write
@@ -87,14 +98,14 @@ jobs:
steps:
- uses: actions/download-artifact@v4
with:
pattern: offline*
pattern: "*.zim"
merge-multiple: true
- name: Create release notes
uses: ncipollo/release-action@v1
with:
generateReleaseNotes: true
artifacts: "offline.zip,offline.tar.gz,offline-privacy_guides.zim"
artifacts: "*.zim"
makeLatest: true
deploy:
@@ -115,5 +126,5 @@ jobs:
cleanup:
if: ${{ always() }}
needs: [build, build_blog]
needs: [build, build_blog, build_zimfile]
uses: privacyguides/.github/.github/workflows/cleanup.yml@main

View File

@@ -57,7 +57,7 @@ jobs:
- name: Run generate-topics.sh for top posts
run: |
bash generate-topics.sh \
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/top.json?period=weekly' \
--tag="top posts" \
--destination="./site/en/index.html" \
@@ -65,7 +65,7 @@ jobs:
- name: Run generate-topics.sh for latest posts
run: |
bash generate-topics.sh \
bash tools/generate-topics.sh \
--source='https://discuss.privacyguides.net/latest.json' \
--tag="latest posts" \
--destination="./site/en/index.html" \

View File

@@ -14,7 +14,6 @@ preview:
# The Power of Digital Provenance in the Age of AI
![Article cover showing a painterly background with cool colors and the Content Credentials logo](../assets/images/digital-provenance/cover.jpg)
<small aria-hidden="true">Photo: Kseniya Lapteva / Pexels | Logo: Content Credentials</small>
With the popularity of generative AI, it's becoming more and more difficult to [distinguish](https://uwaterloo.ca/news/media/can-you-tell-ai-generated-people-real-ones) reality from fiction. Can this problem be solved using cryptography? What are the privacy implications of the currently proposed systems?<!-- more -->

View File

@@ -19,7 +19,6 @@ schema_type: NewsArticle
# Welcome to Privacy Guides
![Privacy Guides cover image](../assets/brand/images/png/cover.png)
<small aria-hidden="true">Illustration: Jonah Aragon / Privacy Guides</small>
We are excited to announce the launch of [Privacy Guides](https://www.privacyguides.org/) and [r/PrivacyGuides](https://www.reddit.com/r/PrivacyGuides/), and welcome the privacy community to participate in our crowdsourced software recommendations and share tips and tricks for keeping your data safe online. Our goal is to be a central resource for privacy and security-related tips that are usable by anybody, and to carry on the trusted legacy of PrivacyTools.<!-- more -->

View File

@@ -37,7 +37,7 @@ The best way to get individual help is from our community on Discourse. If you n
![Signal contact QR code](assets/img/layout/signal-contact-qr.png){ align=right }
Have a tip for us, or need to share some sensitive information? The best way to get in touch with us securely is via `@privacyguides.01` on Signal. This group account is monitored by [Jonah](https://discuss.privacyguides.net/u/jonah), [Niek](https://discuss.privacyguides.net/u/niek-de-wilde), [Em](https://discuss.privacyguides.net/u/ematprivacyguides), and [Jordan](https://discuss.privacyguides.net/u/jordan).
Have a tip for us, or need to share some sensitive information? The best way to get in touch with us securely is via `@privacyguides.01` on Signal. This group account is monitored by [Jonah](https://discuss.privacyguides.net/u/jonah), [Niek](https://discuss.privacyguides.net/u/niek-de-wilde), [Em](https://discuss.privacyguides.net/u/em), and [Jordan](https://discuss.privacyguides.net/u/jordan).
[:simple-signal: Chat on Signal](https://signal.me/#eu/zg9xcrIv5w-EtXt2FmTJgfWv01LmyTed8rpr7RDv35Mizq8ISZ9NJLmYtzsxI0Z4){ .md-button }
@@ -130,7 +130,7 @@ Our staff are paid to contribute to supplemental content at Privacy Guides, like
:material-text-account: Journalist
[:material-account: Profile](https://discuss.privacyguides.net/u/ematprivacyguides)
[:material-account: Profile](https://discuss.privacyguides.net/u/em)
[:material-github:](https://github.com/EmAtPrivacyGuides "GitHub")
[:material-mastodon:](https://infosec.exchange/@Em0nM4stodon "@Em0nM4stodon@infosec.exchange"){rel=me}

View File

@@ -70,6 +70,8 @@ uBlock Origin also has a "Lite" version of their extension, which offers a very
<summary>Downloads</summary>
- [:simple-googlechrome: Chrome](https://chrome.google.com/webstore/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh)
- [:fontawesome-brands-edge: Edge](https://microsoftedge.microsoft.com/addons/detail/cimighlppcgcoapaliogpjjdehbnofhn)
- [:simple-safari: Safari](https://apps.apple.com/app/id6745342698)
</details>

View File

@@ -285,8 +285,6 @@ On iOS, any app that can browse the web is [restricted](https://developer.apple.
### Recommended Safari Configuration
We would suggest installing [AdGuard](browser-extensions.md#adguard) if you want a content blocker in Safari.
The following privacy/security-related options can be found in :gear: **Settings****Apps****Safari**.
#### Allow Safari to Access

View File

@@ -360,6 +360,35 @@ KeePassXC stores its export data as [CSV](https://en.wikipedia.org/wiki/Comma-se
The [pro version](https://play.google.com/store/apps/details?id=com.kunzisoft.keepass.pro) of the app allows you to unlock cosmetic content and non-standard protocol features, but more importantly, it helps and encourages development.
### KeePassium (iOS & macOS)
<div class="admonition recommendation" markdown>
![KeePassium logo](assets/img/password-management/keepassium.svg){ align=right }
KeePassium is a commercial, open-source password manager made by KeePassium Labs that's compatible with other KeePass applications. It provides autofill support, passkey management, automatic two-way synchronization through [most cloud storage providers](https://support.keepassium.com/kb/sync), and more.
[:material-star-box: Read our latest KeePassium review.](https://www.privacyguides.org/articles/2025/05/13/keepassium-review)
[:octicons-home-16: Homepage](https://keepassium.com){ .md-button .md-button--primary }
[:octicons-eye-16:](https://keepassium.com/privacy/app){ .card-link title="Privacy Policy" }
[:octicons-info-16:](https://support.keepassium.com){ .card-link title="Documentation" }
[:octicons-code-16:](https://github.com/keepassium/KeePassium){ .card-link title="Source Code" }
[:octicons-heart-16:](https://keepassium.com/donate){ .card-link title="Contribute" }
<details class="downloads" markdown>
<summary>Downloads</summary>
- [:simple-appstore: App Store](https://apps.apple.com/us/app/id1435127111)
</details>
</div>
KeePassium offers a [Premium version](https://keepassium.com/pricing) with additional features such as support for multiple databases, YubiKey support, and a password audit tool.
KeePassium's iOS app has been [audited](https://cure53.de/pentest-report_keepassium.pdf) by Cure53 in October 2024, and all [issues](https://keepassium.com/blog/2024/11/independent-security-audit-complete) found in the audit were subsequently fixed.
### Gopass (CLI)
<div class="admonition recommendation" markdown>

View File

@@ -572,6 +572,7 @@ For encrypting your OS drive, we typically recommend using the encryption tool y
- ![Psono logo](assets/img/password-management/psono.svg){ .twemoji loading=lazy } [Psono](passwords.md#psono)
- ![KeePassXC logo](assets/img/password-management/keepassxc.svg){ .twemoji loading=lazy } [KeePassXC](passwords.md#keepassxc)
- ![KeePassDX logo](assets/img/password-management/keepassdx.svg){ .twemoji loading=lazy } [KeePassDX (Android)](passwords.md#keepassdx-android)
- ![KeePassium logo](assets/img/password-management/keepassium.svg){ .twemoji loading=lazy } [KeePassium (iOS & macOS)](passwords.md#keepassium-ios-macos)
- ![Gopass logo](assets/img/password-management/gopass.svg){ .twemoji loading=lazy } [Gopass (CLI)](passwords.md#gopass-cli)
</div>

View File

@@ -123,10 +123,10 @@ extra:
link: https://matrix.to/#/#privacyguides:matrix.org
- icon: material/information-outline
name: !ENV [HOMEPAGE_CTA_ABOUT_NAME, "Learn more about us"]
link: about/
link: !ENV [HOMEPAGE_CTA_ABOUT_LINK, "about/"]
- icon: material/hand-coin
name: !ENV [HOMEPAGE_CTA_DONATE_NAME, "Donate to Privacy Guides"]
link: about/donate/
link: !ENV [HOMEPAGE_CTA_DONATE_LINK, "about/donate/"]
description:
!ENV [
HOMEPAGE_CTA_DESCRIPTION,
@@ -183,6 +183,7 @@ extra:
- icon: simple/torbrowser
link: http://www.xoe4vn5uwdztif6goazfbmogh6wh5jc4up35bqdflu6bkdc5cas5vjqd.onion/
name: !ENV [SOCIAL_TOR_SITE, "Hidden service"]
language_switcher: !ENV [LANGUAGE_SWITCHER, true]
alternate:
- name: English
link: /en/
@@ -208,14 +209,10 @@ extra:
link: /nl/
lang: nl
icon: https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/1f1f3-1f1f1.svg
- name: 中文 (繁體)
- name: 正體中文
link: /zh-hant/
lang: zh-Hant
icon: https://raw.githubusercontent.com/jdecked/twemoji/master/assets/svg/1f1ed-1f1f0.svg
- name: 中文 (繁體,台灣)
link: /zh-TW/
lang: zh-TW
icon: https://raw.githubusercontent.com/jdecked/twemoji/master/assets/svg/1f1f9-1f1fc.svg
icon: https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/1f1ed-1f1f0.svg
- name: Русский
link: /ru/
lang: ru

6
run.sh
View File

@@ -100,14 +100,14 @@ if [ "$language" == "he" ]; then
export BUILD_THEME_FONT_TEXT="Open Sans"
fi
# Set font if russian or chinese
if [[ "ru zh-Hant zh-TW" =~ $language ]]; then
# Set font if chinese
if [ "$language" == "zh-Hant" ]; then
export BUILD_THEME_FONT_CODE="Noto Sans TC"
export BUILD_THEME_FONT_TEXT="Noto Sans TC"
fi
# Set stylesheet if hebrew or russian or chinese
if [[ "he ru zh-Hant zh-TW" =~ $language ]]; then
if [[ "he ru zh-Hant" =~ $language ]]; then
export TRANSLATION_STYLESHEET="assets/stylesheets/lang-$language.css?v=20240410"
fi

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,58 +0,0 @@
/*
/// Copyright (c) 2023 Jonah Aragon <jonah@triplebit.net>
///
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS
*/
/* chinese-traditional */
@font-face {
font-family: 'Noto Serif TC';
font-style: normal;
font-weight: 400;
src: url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-chinese-traditional-400-normal.woff2) format('woff2'), url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-chinese-traditional-400-normal.woff) format('woff');
}
/* latin */
@font-face {
font-family: 'Noto Serif TC';
font-style: normal;
font-weight: 400;
src: url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-latin-400-normal.woff2) format('woff2'), url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-latin-400-normal.woff) format('woff');
}
/* chinese-traditional */
@font-face {
font-family: 'Noto Serif TC';
font-style: normal;
font-weight: 700;
src: url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-chinese-traditional-700-normal.woff2) format('woff2'), url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-chinese-traditional-700-normal.woff) format('woff');
}
/* latin */
@font-face {
font-family: 'Noto Serif TC';
font-style: normal;
font-weight: 700;
src: url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-latin-700-normal.woff2) format('woff2'), url(https://fonts.bunny.net/noto-serif-tc/files/noto-serif-tc-latin-700-normal.woff) format('woff');
}
h1, h2, h3, .md-header__topic {
font-family: "Bagnard", "Noto Serif TC", serif;
font-weight: 700!important;
}

View File

@@ -11,7 +11,7 @@ definitions:
- &font_family >-
{%- if config.theme.language == "he" -%}
Suez One
{%- elif config.theme.language == ("ru" or "zh-Hant" or "zh-TW") -%}
{%- elif config.theme.language == ("zh-Hant" or "ru") -%}
Noto Sans TC
{%- else -%}
Public Sans

View File

@@ -19,7 +19,7 @@ definitions:
- &title_font_family >-
{%- if config.theme.language == "he" -%}
Suez One
{%- elif config.theme.language == ("ru" or "zh-Hant" or "zh-TW") -%}
{%- elif config.theme.language == ("zh-Hant" or "ru") -%}
Noto Serif TC
{%- else -%}
Bagnard
@@ -35,7 +35,7 @@ definitions:
- &font_family >-
{%- if config.theme.language == "he" -%}
Suez One
{%- elif config.theme.language == ("ru" or "zh-Hant" or "zh-TW") -%}
{%- elif config.theme.language == ("zh-Hant" or "ru") -%}
Noto Sans TC
{%- else -%}
Public Sans

View File

@@ -15,7 +15,7 @@ definitions:
- &title_font_family >-
{%- if config.theme.language == "he" -%}
Suez One
{%- elif config.theme.language == ("ru" or "zh-Hant" or "zh-TW") -%}
{%- elif config.theme.language == ("zh-Hant" or "ru") -%}
Noto Serif TC
{%- else -%}
Bagnard
@@ -24,7 +24,7 @@ definitions:
- &font_family >-
{%- if config.theme.language == "he" -%}
Suez One
{%- elif config.theme.language == ("ru" or "zh-Hant" or "zh-TW") -%}
{%- elif config.theme.language == ("zh-Hant" or "ru") -%}
Noto Sans TC
{%- else -%}
Public Sans

View File

@@ -29,7 +29,7 @@
<br />
{{ copyright.note }}
<br />
<a href='/license' aria-label="More information about our website license.">
<a href='https://www.privacyguides.org/license' aria-label="More information about our website license.">
{% for icon in copyright.license %}
<span class="twemoji">{% include ".icons/" ~ icon ~ ".svg" %}</span>
{% endfor %}

View File

@@ -1,7 +1,7 @@
<div class="md-header__option">
<div class="">
{% set icon = "material/heart" %}
<a href="/en/about/donate/" class="md-header__button md-icon pg-red" title="Donate">
<a href="https://www.privacyguides.org/{{ config.theme.language }}/about/donate/" class="md-header__button md-icon pg-red" title="Donate">
{% include ".icons/" ~ icon ~ ".svg" %}
</a>
</div>

View File

@@ -121,7 +121,7 @@
{% endif %}
<!-- Site language selector -->
{% if config.extra.alternate %}
{% if config.extra.alternate and config.extra.language_switcher %}
{% include "partials/alternate.html" %}
{% endif %}

19
tools/archive-releases.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail
REPO="privacyguides/privacyguides.org"
BASE_DIR="releases"
mkdir -p "$BASE_DIR"
# Get all release tags using gh CLI
release_tags=$(gh release list -R "$REPO" --limit 1000 | awk '{print $1}')
for tag in $release_tags; do
target_dir="$BASE_DIR/$tag"
mkdir -p "$target_dir"
echo "Downloading assets for release: $tag"
gh release download "$tag" -R "$REPO" --dir "$target_dir"
done
echo "All releases downloaded."

View File

@@ -0,0 +1,64 @@
#!/bin/bash
# Script to find and delete unreferenced asset files
# This script searches through all HTML, CSS, and JavaScript files to see if asset files are referenced
set -e # Exit on any error
echo -e "Starting unreferenced asset cleanup..."
echo "Assets directory: $ASSETS_DIR"
echo "Search directory: $SEARCH_DIR"
echo ""
# Check if assets directory exists
if [ ! -d "$ASSETS_DIR" ]; then
echo -e "Error: Assets directory '$ASSETS_DIR' not found!"
exit 1
fi
# Find all asset files recursively
echo "Finding all asset files..."
ASSET_FILES=$(find "$ASSETS_DIR" -type f)
ASSET_COUNT=$(echo "$ASSET_FILES" | wc -l)
echo "Found $ASSET_COUNT asset files"
echo ""
# Find all HTML, CSS, and JavaScript files
echo "Finding all HTML, CSS, and JavaScript files..."
SEARCH_FILES=$(find "$SEARCH_DIR" \( -name "*.html" -o -name "*.css" -o -name "*.js" \) -type f)
SEARCH_COUNT=$(echo "$SEARCH_FILES" | wc -l)
echo "Found $SEARCH_COUNT HTML, CSS, and JavaScript files"
echo ""
# Process each asset file
echo "Checking each asset file for references..."
echo ""
while IFS= read -r asset_file; do
if [ -z "$asset_file" ]; then
continue
fi
# Get just the filename (without path)
asset_filename=$(basename "$asset_file")
# Search for this filename in all HTML, CSS, and JavaScript files
found_reference=false
while IFS= read -r search_file; do
if [ -z "$search_file" ]; then
continue
fi
# Simple string search for the filename in the file
if grep -q "$asset_filename" "$search_file" 2>/dev/null; then
found_reference=true
break
fi
done <<< "$SEARCH_FILES"
if [ "$found_reference" = false ]; then
echo -e "Unreferenced: $asset_file"
rm "$asset_file"
fi
done <<< "$ASSET_FILES"

View File

@@ -67,7 +67,9 @@ for row in $(echo "${topics}" | jq -r '.[] | @base64'); do
html_output+="<hr>"
html_output+="<p class='discourse-author'>"
html_output+="<span class='discourse-author'>"
html_output+="<img src='https://forum-cdn.privacyguides.net/user_avatar/discuss.privacyguides.net/${author_username}/48/1.png' loading='lazy' aria-hidden='true' alt='${author_username}' width='20' height='20' class='middle'>"
if [[ -z "$BUILD_OFFLINE" ]]; then
html_output+="<img src='https://forum-cdn.privacyguides.net/user_avatar/discuss.privacyguides.net/${author_username}/48/1.png' loading='lazy' aria-hidden='true' alt='${author_username}' width='20' height='20' class='middle'>"
fi
html_output+="<span> Posted by <em>$author_username</em></span>"
html_output+="</span>"
html_output+="</p>"

View File

@@ -0,0 +1,20 @@
#!/bin/bash
set -euo pipefail
declare -A file_hashes
find . -type f | while read -r file; do
hash=$(sha256sum "$file" | awk '{print $1}')
if [[ -n "${file_hashes[$hash]+_}" ]]; then
# Duplicate found, replace with symlink to first copy
first="${file_hashes[$hash]}"
# Remove the duplicate file
rm "$file"
# Create symlink (relative path)
ln -s "$(realpath --relative-to="$(dirname "$file")" "$first")" "$file"
echo "Replaced duplicate: $file -> $first"
else
# First time seeing this hash
file_hashes[$hash]="$file"
fi
done