Compare commits
6 Commits
f4e09ca886
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 848e33d198 | |||
| 3e60f48c5e | |||
| 45fd4bd407 | |||
| e091ec75f7 | |||
| b13a1e7a31 | |||
| db5a997e50 |
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "oki-preview",
|
||||
"runtimeExecutable": "pnpm",
|
||||
"runtimeArgs": ["--dir", "frontend", "preview", "--port", "4173"],
|
||||
"port": 4173
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
.astro
|
||||
.git
|
||||
playwright-report
|
||||
test-results
|
||||
index.html
|
||||
images
|
||||
@@ -0,0 +1,51 @@
|
||||
name: "Nouvo zouti — Proposer un outil"
|
||||
description: "Pwopozé on zouti lib pou lis-la / Proposer un outil libre pour l'annuaire"
|
||||
title: "[zouti] "
|
||||
labels:
|
||||
- "nouvo-zouti"
|
||||
body:
|
||||
- type: input
|
||||
id: nom
|
||||
attributes:
|
||||
label: "Non a zouti-la / Nom de l'outil"
|
||||
placeholder: "ex. Signal"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: url
|
||||
attributes:
|
||||
label: "Sit ofisyèl / Site officiel"
|
||||
placeholder: "https://…"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: licence
|
||||
attributes:
|
||||
label: "Licence (identifiant SPDX si tu le connais)"
|
||||
placeholder: "ex. AGPL-3.0"
|
||||
- type: dropdown
|
||||
id: difficulte
|
||||
attributes:
|
||||
label: "Difikilté / Difficulté d'installation"
|
||||
options:
|
||||
- "🟢 Débitan / Débutant"
|
||||
- "🟡 Entèmédia / Intermédiaire"
|
||||
- "🔴 Avansé / Avancé"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: pourquoi
|
||||
attributes:
|
||||
label: "Poukisa i konté ? / Pourquoi il compte ?"
|
||||
description: "En quoi cet outil sert la souveraineté numérique ? Qui devrait s'en servir ?"
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: verifs
|
||||
attributes:
|
||||
label: "Vérifications"
|
||||
options:
|
||||
- label: "L'outil est libre / open-source (code source publié)"
|
||||
required: true
|
||||
- label: "J'ai vérifié qu'il n'est pas déjà dans l'annuaire"
|
||||
required: true
|
||||
@@ -1,48 +0,0 @@
|
||||
# CI: lint → typecheck → unit tests → build → e2e (incl. axe + zero-request).
|
||||
# Actions are SHA-pinned; no ${{ github.event.* }} is ever interpolated into
|
||||
# run: blocks (script-injection hygiene). Fork PRs run with a read-only token.
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, rebuild/astro]
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
- run: pnpm lint
|
||||
- run: pnpm format
|
||||
- run: pnpm check
|
||||
- run: pnpm build
|
||||
# tests run after build: the domain-allowlist suite audits dist/
|
||||
- run: pnpm test
|
||||
|
||||
- name: Install Playwright chromium
|
||||
run: pnpm exec playwright install --with-deps chromium
|
||||
|
||||
- run: pnpm test:e2e
|
||||
|
||||
- name: Upload Playwright report on failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 7
|
||||
@@ -1,38 +0,0 @@
|
||||
# Weekly link-rot watch: every cited source URL is checked over HTTP.
|
||||
# Surveillance archives decay — this applies the lesson to ourselves.
|
||||
# On failure it opens a triage issue (runner-provided vars only — nothing
|
||||
# attacker-controlled is interpolated).
|
||||
name: link-rot
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 6 * * 1' # Mondays 06:00 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Check cited sources
|
||||
run: node scripts/check-links.mjs
|
||||
|
||||
- name: Open triage issue on failure
|
||||
if: failure()
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh issue create \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--title "link-rot: cited sources failing ($(date -u +%F))" \
|
||||
--body "The weekly link check failed. See the run: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
|
||||
+7
-4
@@ -1,7 +1,10 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.astro/
|
||||
playwright-report/
|
||||
test-results/
|
||||
*.local
|
||||
.DS_Store
|
||||
|
||||
# SvelteKit (frontend/)
|
||||
frontend/.svelte-kit/
|
||||
frontend/build/
|
||||
|
||||
# Brief de mission (document de travail local)
|
||||
testoki_exit_chat_control.md
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
dist/
|
||||
.astro/
|
||||
node_modules/
|
||||
pnpm-lock.yaml
|
||||
index.html
|
||||
src/icons.generated.ts
|
||||
src/styles/brands.generated.css
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-astro"],
|
||||
"overrides": [{ "files": "*.astro", "options": { "parser": "astro" } }]
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
# ADR-001 — Backend : SvelteKit natif (fichiers plats), pas de Strapi
|
||||
|
||||
**Statut** : accepté · **Date** : 2026-07-10 · **Décideur** : migration OKI d'exitchatcontrol.org
|
||||
**Doctrine de référence** : `ui-ux-souveraine-oki.md` (citée « doctrine §x.y » ci-dessous)
|
||||
|
||||
## Contexte
|
||||
|
||||
exitchatcontrol.org est un annuaire de ~55 outils libres répartis en 23 sections
|
||||
thématiques, actuellement généré statiquement par Astro à partir de fichiers
|
||||
versionnés (`src/data/*.json`, `src/content/sections/*/*.mdx`). Le déploiement
|
||||
cible est un conteneur nginx auto-hébergé (YunoHost/Docker), sans backend.
|
||||
|
||||
Deux options étaient sur la table (mission §2.1) :
|
||||
|
||||
- **Option A** : Strapi v5 headless, base relationnelle, admin web, API, i18n plugin.
|
||||
- **Option B** : SvelteKit full-stack, contenu en fichiers Markdown/JSON versionnés,
|
||||
parsés au build, site prérendu.
|
||||
|
||||
## Décision
|
||||
|
||||
**Option B — SvelteKit 2 + Svelte 5, contenu en fichiers plats prérendus.**
|
||||
|
||||
## Justification par la règle de décision
|
||||
|
||||
La règle imposée : minimiser la charge cognitive **extrinsèque** (doctrine §1.2,
|
||||
Sweller) pour l'utilisateur final ET l'administrateur, dans le budget performance
|
||||
(doctrine §4.4).
|
||||
|
||||
1. **Les données sont déjà statiques et versionnées.** 55 outils, mises à jour
|
||||
par pull request espacées de plusieurs jours/semaines (historique git). Le seuil
|
||||
« le volume de données justifie une base relationnelle » posé comme condition
|
||||
de l'option A n'est pas atteint — 55 fiches tiennent dans un dossier de
|
||||
fichiers Markdown lisibles à l'œil nu.
|
||||
2. **Charge d'administration.** Strapi = un service Node persistant + une base +
|
||||
des migrations de schéma + des mises à jour de sécurité + des sauvegardes.
|
||||
Pour l'admin OKI, c'est de la charge extrinsèque pure : la tâche réelle
|
||||
(« corriger une fiche ») devient « se connecter à un admin, naviguer un CMS,
|
||||
publier, invalider un cache ». En fichiers plats : éditer un fichier, commit.
|
||||
Le git devient l'historique éditorial, la revue par PR devient la modération.
|
||||
3. **Budget performance (doctrine §4.4).** Site 100 % prérendu : premier rendu
|
||||
= HTML servi par nginx, zéro requête API, JS initial minimal (hydratation
|
||||
sélective). Strapi n'aiderait pas mais ajouterait un point de latence et de
|
||||
panne si l'on cédait à la tentation du rendu à la demande.
|
||||
4. **Souveraineté et surface d'attaque.** Un site statique n'a pas de CVE de CMS,
|
||||
pas de compte admin à voler, pas de base à exfiltrer. C'est la posture
|
||||
cohérente avec le sujet même du site (OPSEC, résistance à la censure) :
|
||||
le site doit être **mirrorable** (un tarball du build suffit), ce qu'un
|
||||
Strapi rend impossible.
|
||||
5. **Loi de Tesler (doctrine §1.3)** : la complexité éditoriale n'est pas
|
||||
supprimée, elle est déplacée vers le format de fichier. On l'absorbe par un
|
||||
frontmatter strict + validation au build (le build échoue si une fiche est
|
||||
invalide — équivalent des types du CMS, sans le CMS).
|
||||
|
||||
### Ce qui ferait rebasculer vers Strapi (critères de réversibilité)
|
||||
|
||||
- Une équipe éditoriale non-technique de plusieurs personnes publiant chaque semaine ;
|
||||
- Des soumissions communautaires en volume nécessitant un workflow draft/publish ;
|
||||
- Plus de ~500 fiches ou des relations réellement complexes.
|
||||
|
||||
Dans ce cas, le modèle de données de la mission §3 s'applique tel quel ; le
|
||||
frontend SvelteKit resterait inchangé (il consommerait l'API au build).
|
||||
Étape intermédiaire possible sans backend : Decap CMS (git-based) sur le dossier
|
||||
`content/` — écarté pour l'instant, « préférer la solution la plus simple ».
|
||||
|
||||
## Décisions techniques associées
|
||||
|
||||
- **adapter-static + prerender total** : parité avec le déploiement nginx actuel
|
||||
(Dockerfile conservé dans l'esprit). Un lien fonctionne sans JS (doctrine §4.4).
|
||||
- **Markdown + frontmatter maison** : parseur frontmatter minimal (~40 lignes,
|
||||
zéro dépendance) + `marked` (MIT) pour le corps, exécuté **au build uniquement**
|
||||
— rien de tout cela n'est expédié au client.
|
||||
- **i18n maison typé** (pattern repris du projet source) plutôt que
|
||||
Paraglide/inlang : ~40 lignes, dictionnaires JSON `fr`/`gcf` vérifiés par le
|
||||
compilateur TypeScript (une clé manquante = erreur de build). Paraglide reste
|
||||
la piste si le nombre de locales croît.
|
||||
- **Langues** : `fr` (défaut) + `gcf` (créole guadeloupéen, code ISO 639-3
|
||||
enregistré BCP 47 valide). Micro-textes créoles d'abord (doctrine §4.2 :
|
||||
impact affectif disproportionné pour un coût faible) ; traduction intégrale
|
||||
des fiches = chantier éditorial séparé (voir `docs/CONTENT_GUIDE.md`).
|
||||
- **CSS natif en `@layer`** : `reset → tokens → base → layouts → components →
|
||||
utilities` (doctrine §5.2), tokens `oklch()`, container queries, `clamp()`.
|
||||
Pas de Tailwind (doctrine §5.2 option 4 : écarté en connaissance de cause).
|
||||
- **Licence du code** : MIT, comme le projet source (continuité).
|
||||
+26
-22
@@ -1,40 +1,44 @@
|
||||
# Contributing to Exit Chat Control
|
||||
# Contribuer à Lagé Chat Control
|
||||
|
||||
Contributions are welcome — this guide exists because people share what works. But this is a **trust-first** project: readers follow our recommendations to protect themselves from surveillance. That trust is the product, so the rules below are strict and non-negotiable. Every submission is reviewed personally by the maintainer.
|
||||
Les contributions sont bienvenues — ce guide existe parce que les gens partagent ce qui marche. Mais c'est un projet où **la confiance prime** : les lecteurs et lectrices suivent nos recommandations pour se protéger de la surveillance. Cette confiance est le produit, donc les règles ci-dessous sont strictes et non négociables. Chaque soumission est relue personnellement.
|
||||
|
||||
## Adding a tool or resource
|
||||
Pour les gestes simples (proposer un outil, corriger une fiche), la page [/contribuer](frontend/src/routes/contribuer/+page.svelte) du site et le [guide de contenu](docs/CONTENT_GUIDE.md) suffisent. Ce document couvre la politique éditoriale et les changements plus larges.
|
||||
|
||||
A tool must meet all three of the original rules:
|
||||
## Ajouter un outil
|
||||
|
||||
1. **Traction** — an established, actively maintained project with a real user base. Not an obscure or abandoned tool, and not your three-month-old project.
|
||||
2. **Open source** — a public repository with an OSI-approved license.
|
||||
3. **Privacy-respecting** — no trackers, no data monetization, honest documentation.
|
||||
Un outil doit remplir les trois règles :
|
||||
|
||||
## Disclosure of affiliation (mandatory)
|
||||
1. **Traction** — un projet établi, activement maintenu, avec un vrai usage. Pas un outil obscur ou abandonné, pas ton projet vieux de trois mois.
|
||||
2. **Open source** — un dépôt public sous licence OSI reconnue.
|
||||
3. **Respectueux de la vie privée** — pas de traqueur, pas de monétisation des données, documentation honnête.
|
||||
|
||||
If you are the author, maintainer, employee, investor, or otherwise affiliated with a tool, service, or website you propose to add or link, **you must say so in the PR description**. Undisclosed self-promotion — however good the surrounding work — gets the PR closed and the account reported for inauthentic activity. This has happened before; it will happen again.
|
||||
## Déclaration d'affiliation (obligatoire)
|
||||
|
||||
## Link policy (enforced by CI)
|
||||
Si tu es autrice, mainteneur, salarié·e, investisseur ou autrement affilié·e à un outil que tu proposes, **dis-le dans la description de la demande**. Une auto-promotion non déclarée — même si le reste du travail est bon — entraîne la fermeture de la demande.
|
||||
|
||||
- Every external link is rendered through the `Ext` component, which enforces `rel="noopener noreferrer"`. No per-link `rel` exceptions, for anyone, ever.
|
||||
- Every external domain must be listed in `src/data/domains-allowlist.json`. The test suite fails if the built site links to a domain that isn't allowlisted — adding a domain is therefore always an explicit, reviewable diff.
|
||||
- Editorial placements ("featured", "guide's pick", ranking changes) are the maintainer's decision only. PRs that visually elevate one tool above others will be asked to remove that change.
|
||||
## Politique des liens
|
||||
|
||||
## Content and facts
|
||||
- Chaque outil référencé doit avoir une licence SPDX identifiable (voir [`content/outils/`](content/outils/)).
|
||||
- Les mises en avant éditoriales (`is_featured`, ordre des catégories) restent une décision de maintenance — une demande qui met en avant un outil au détriment des autres sera priée de revenir en arrière.
|
||||
|
||||
- Every dated claim (timeline, observatory) needs a source URL, primary wherever possible (legislation, court rulings, institutional press releases — not blog posts).
|
||||
- Translations: UI strings live in `src/i18n/<lang>.json`; long-form content in `src/content/sections/<lang>/`; dataset prose in `src/i18n/content/<lang>/`. Adding a language = adding those files plus one line in `src/i18n/locales.ts`. Parity is tested.
|
||||
## Contenu et faits
|
||||
|
||||
## Large changes
|
||||
- Chaque affirmation datée a besoin d'une source, primaire si possible (texte de loi, décision de justice, communiqué institutionnel — pas un article de blog).
|
||||
- Traductions : les micro-textes d'interface vivent dans `frontend/src/lib/i18n/<locale>.json` (clé manquante = erreur de build) ; le contenu des fiches dans `content/outils/` (FR) et `content/outils/gcf/` (jumelles créoles, voir [CONTENT_GUIDE.md](docs/CONTENT_GUIDE.md)).
|
||||
|
||||
Open an issue **before** writing a large PR (redesigns, stack changes, new sections). Unsolicited full rebuilds are closed by default — not because the work is bad, but because review cost and trust cost scale with diff size.
|
||||
## Changements de grande ampleur
|
||||
|
||||
## Development
|
||||
Ouvre une discussion **avant** d'écrire une grosse demande (refontes, changement de stack, nouvelles sections). Les reconstructions complètes non sollicitées sont fermées par défaut — pas parce que le travail est mauvais, mais parce que le coût de relecture et de confiance croît avec la taille du diff.
|
||||
|
||||
## Développement
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
pnpm install
|
||||
pnpm dev # dev server
|
||||
pnpm lint && pnpm check && pnpm build && pnpm test # what CI runs (tests audit dist/)
|
||||
pnpm dev # serveur de développement
|
||||
pnpm check # types + accessibilité (svelte-check)
|
||||
pnpm build # build statique complet
|
||||
pnpm audit:a11y # audit axe-core sur le build servi en local
|
||||
```
|
||||
|
||||
The site must remain: static, readable with JavaScript disabled, free of any request to a third-party domain, and printable. Tests enforce all four.
|
||||
Le site doit rester : statique, lisible sans JavaScript pour tout le contenu et les formulaires de base, sans requête vers un domaine tiers. Voir [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) pour la mise en production.
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# ── build: Astro static site + offline artifact + CSP hashes ──────────────
|
||||
FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 AS build
|
||||
WORKDIR /app
|
||||
RUN corepack enable
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
|
||||
pnpm install --frozen-lockfile
|
||||
COPY . .
|
||||
ENV ASTRO_TELEMETRY_DISABLED=1
|
||||
RUN pnpm build \
|
||||
&& find dist -type f \( -name '*.html' -o -name '*.css' -o -name '*.js' \
|
||||
-o -name '*.svg' -o -name '*.xml' -o -name '*.txt' -o -name '*.webmanifest' \) \
|
||||
-exec gzip -9k {} \;
|
||||
|
||||
# ── serve: nginx, ~10MB, security headers, precompressed assets ───────────
|
||||
FROM nginx:1.29-alpine@sha256:5616878291a2eed594aee8db4dade5878cf7edcb475e59193904b198d9b830de
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY docker/security-headers.conf /etc/nginx/snippets/security-headers.conf
|
||||
# csp.conf is generated by scripts/gen-csp.mjs during `pnpm build`
|
||||
COPY --from=build /app/docker/csp.conf /etc/nginx/snippets/csp.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
@@ -1,44 +1,59 @@
|
||||
# Exit Chat Control
|
||||
# Lagé Chat Control
|
||||
|
||||
A free, multilingual field guide to escape **Chat Control** and take back control of your digital privacy: encrypted messaging, email, VPN, DNS, 2FA, Linux, GrapheneOS, self-hosting, and more. Every tool is presented with **what it does**, **who it's for**, and **how to install it**.
|
||||
Un guide de terrain, libre et bilingue (français / kréyòl), pour échapper à **Chat Control** et reprendre le contrôle de sa vie privée numérique : messagerie chiffrée, e-mail, VPN, DNS, 2FA, Linux, GrapheneOS, auto-hébergement, et plus. Chaque outil est présenté avec **à quoi il sert**, **pour qui** et **comment l'installer**.
|
||||
|
||||
🔗 **Live site: https://exitchatcontrol.org**
|
||||
Projet OKI (Organisation Ka Internationale) — voir [`ADR.md`](ADR.md) pour la décision d'architecture et [`docs/`](docs/) pour la doctrine UI/UX, le design system et le guide de contenu.
|
||||
|
||||
## What is this?
|
||||
## En bref
|
||||
|
||||
In July 2026, the European Parliament let the "Chat Control" machinery advance — the amended text now sits with the Council, and the permanent version (CSAR, "Chat Control 2.0") is still being negotiated. This project is a practical, no-nonsense answer: a guide referencing privacy-respecting tools anyone can use to opt out of mass surveillance, from the everyday citizen to the whistleblower.
|
||||
|
||||
Its promises, all enforced by tests:
|
||||
|
||||
- **Static and self-contained** — no tracker, no cookie, not a single request to a third-party domain.
|
||||
- **Readable with JavaScript disabled** (Tor Browser "safest" mode included) — scripts only power the theme, filters, checklist and quiz.
|
||||
- **Multilingual by design** — every language is a real prerendered route with correct `hreflang`; adding one means adding translation files, not touching code.
|
||||
- **Educational quiz** — `/quiz` scores your censorship resistance on a 0–100 scale and points you at concrete fixes in the guide. Server-rendered questions and scoring key (readable with JS off); the score itself is computed locally in the browser, nothing sent or stored.
|
||||
- **Printable and mirrorable** — a single-file offline version ships with every build.
|
||||
- **Statique et auto-suffisant** — pas de traqueur, pas de cookie, aucune requête vers un domaine tiers, aucun CDN (polices et assets auto-hébergés).
|
||||
- **Lisible sans JavaScript** — le contenu et les formulaires de base fonctionnent nus ; le script n'enrichit que le quiz, la recherche instantanée et les filtres.
|
||||
- **Bilingue FR / kréyòl** — les micro-textes d'interface sont typés (une clé manquante = erreur de build) ; le contenu des fiches suit le même principe avec repli explicite quand une traduction manque.
|
||||
- **Quiz éducatif** — `/quiz` évalue ta résistance à la censure sur 100 points et pointe vers des pistes concrètes dans l'annuaire. Calcul entièrement local, rien n'est envoyé ni enregistré.
|
||||
- **PWA hors-ligne** — les fiches déjà consultées restent lisibles sans connexion.
|
||||
|
||||
## Stack
|
||||
|
||||
[Astro](https://astro.build) (static output, built-in i18n routing) · Tailwind CSS v4 (design tokens, `light-dark()` theming) · TypeScript strict · Vitest (content integrity, i18n parity, domain allowlist) · Playwright + axe (no-JS readability, zero-third-party-request guarantee, WCAG AA) · Docker (multi-stage build → nginx). Package manager: pnpm.
|
||||
**Svelte 5 + SvelteKit 2**, site 100 % prérendu (`adapter-static`) · **CSS natif** (`@layer`, `oklch()`, container queries, `clamp()` — pas de Tailwind) · contenu en fichiers Markdown/JSON versionnés dans [`content/`](content/), aucun CMS ni base de données. Gestionnaire de paquets : pnpm.
|
||||
|
||||
### Lancer en local
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
pnpm install
|
||||
pnpm dev # develop on http://localhost:4321
|
||||
pnpm build # static site + offline artifact in dist/
|
||||
docker compose -f docker-compose.dev.yml up preview # prod-like: nginx + security headers on :8080
|
||||
pnpm dev # http://localhost:5173
|
||||
```
|
||||
|
||||
Production deploys `docker-compose.yml` (single nginx service behind the platform's reverse proxy — Coolify, etc.), or point any static host at `pnpm build` → `dist/`.
|
||||
```sh
|
||||
pnpm build # site statique dans frontend/build/
|
||||
pnpm preview # sert ce build localement
|
||||
```
|
||||
|
||||
## Contributing
|
||||
### Déployer sur un VPS
|
||||
|
||||
Contributions are very welcome — a tool to add, a translation, a correction. **Read [`CONTRIBUTING.md`](./CONTRIBUTING.md) first**: it contains three simple rules for tools (traction, open source, privacy-respecting), a mandatory affiliation-disclosure policy, and a CI-enforced external-link policy. Large changes start with an issue, not a PR.
|
||||
Le build est un dossier de fichiers statiques — n'importe quel serveur web
|
||||
convient. Voir **[`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md)** pour la marche
|
||||
à suivre complète (Caddy avec TLS automatique, nginx, YunoHost, Docker) et
|
||||
la checklist de vérification post-déploiement.
|
||||
|
||||
Not comfortable with code? Open an issue with the app's name, its link, and why it qualifies, and it will be added for you.
|
||||
## Contribuer
|
||||
|
||||
## License
|
||||
Les contributions sont bienvenues — un outil à ajouter, une traduction, une
|
||||
correction. La page **[/contribuer](frontend/src/routes/contribuer/+page.svelte)**
|
||||
du site couvre les trois voies (proposer un outil, corriger une fiche,
|
||||
traduire) ; **[`CONTRIBUTING.md`](CONTRIBUTING.md)** détaille la politique
|
||||
éditoriale (traction, open source, respect de la vie privée, déclaration
|
||||
d'affiliation obligatoire) et **[`docs/CONTENT_GUIDE.md`](docs/CONTENT_GUIDE.md)**
|
||||
le format des fiches et le ton.
|
||||
|
||||
See [`LICENSE`](./LICENSE).
|
||||
Pas à l'aise avec le code ? Ouvre une demande sur
|
||||
[la forge](https://labola.o-k-i.net/cyber-mawonaj/lage-chat-control) avec le
|
||||
nom de l'outil, son lien, et pourquoi il a sa place.
|
||||
|
||||
## Licence
|
||||
|
||||
Voir [`LICENSE`](LICENSE) (MIT).
|
||||
|
||||
---
|
||||
|
||||
_Privacy is a right, not a confession. To encrypt is to vote. To self-host is to disobey. To reclaim your tools is to become ungovernable._
|
||||
_La vie privée est un droit, pas un aveu. Chiffrer, c'est voter. S'auto-héberger, c'est désobéir. Reprendre ses outils, c'est devenir ingouvernable._
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config'
|
||||
import mdx from '@astrojs/mdx'
|
||||
import sitemap from '@astrojs/sitemap'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
import { defaultLocale, locales } from './src/i18n/locales'
|
||||
|
||||
// Static multilingual guide. `/` is English (canonical); every other
|
||||
// locale in src/i18n/config.ts gets a full prerendered translation at
|
||||
// /<lang>/ — no dual-language DOM, no runtime language CSS toggling.
|
||||
// The whole site must stay readable with JS off.
|
||||
export default defineConfig({
|
||||
site: 'https://exitchatcontrol.org',
|
||||
output: 'static',
|
||||
trailingSlash: 'ignore',
|
||||
build: {
|
||||
// keep every stylesheet external so the CSP can stay `style-src 'self'`
|
||||
// (inline <style> would need per-build hashes)
|
||||
inlineStylesheets: 'never',
|
||||
},
|
||||
i18n: {
|
||||
defaultLocale,
|
||||
locales: [...locales],
|
||||
routing: {
|
||||
prefixDefaultLocale: false,
|
||||
},
|
||||
},
|
||||
integrations: [
|
||||
mdx(),
|
||||
sitemap({
|
||||
i18n: {
|
||||
defaultLocale,
|
||||
locales: Object.fromEntries(locales.map((l) => [l, l])),
|
||||
},
|
||||
}),
|
||||
],
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,92 @@
|
||||
[
|
||||
{
|
||||
"slug": "messagerie",
|
||||
"title": "Messagerie chiffrée",
|
||||
"order": 3,
|
||||
"part": 1
|
||||
},
|
||||
{
|
||||
"slug": "email",
|
||||
"title": "E-mail chiffré & PGP",
|
||||
"order": 4,
|
||||
"part": 2
|
||||
},
|
||||
{
|
||||
"slug": "navigateur",
|
||||
"title": "Navigateur & recherche",
|
||||
"order": 5,
|
||||
"part": 3
|
||||
},
|
||||
{
|
||||
"slug": "dns",
|
||||
"title": "DNS chiffré & Cloudflare",
|
||||
"order": 6,
|
||||
"part": 3
|
||||
},
|
||||
{
|
||||
"slug": "vpn",
|
||||
"title": "VPN : la vérité",
|
||||
"order": 7,
|
||||
"part": 4
|
||||
},
|
||||
{
|
||||
"slug": "stockage",
|
||||
"title": "Stockage chiffré",
|
||||
"order": 10,
|
||||
"part": 6
|
||||
},
|
||||
{
|
||||
"slug": "motsdepasse",
|
||||
"title": "Gestionnaire de mots de passe",
|
||||
"order": 11,
|
||||
"part": 7
|
||||
},
|
||||
{
|
||||
"slug": "deuxfa",
|
||||
"title": "Double authentification & clés matérielles",
|
||||
"order": 12,
|
||||
"part": 7
|
||||
},
|
||||
{
|
||||
"slug": "social",
|
||||
"title": "Réseaux sociaux décentralisés",
|
||||
"order": 13,
|
||||
"part": 8
|
||||
},
|
||||
{
|
||||
"slug": "argent",
|
||||
"title": "Souveraineté financière",
|
||||
"order": 14,
|
||||
"part": 9
|
||||
},
|
||||
{
|
||||
"slug": "ia",
|
||||
"title": "L'IA conversationnelle",
|
||||
"order": 15,
|
||||
"part": 9
|
||||
},
|
||||
{
|
||||
"slug": "boiteaoutils",
|
||||
"title": "La boîte à outils du quotidien",
|
||||
"order": 16,
|
||||
"part": 9
|
||||
},
|
||||
{
|
||||
"slug": "selfhost",
|
||||
"title": "Auto-hébergement",
|
||||
"order": 17,
|
||||
"part": 10
|
||||
},
|
||||
{
|
||||
"slug": "tor",
|
||||
"title": "Tor",
|
||||
"order": 18,
|
||||
"part": 11
|
||||
},
|
||||
{
|
||||
"slug": "os",
|
||||
"title": "Systèmes d'exploitation libres",
|
||||
"order": 19,
|
||||
"part": 12
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: "Aegis · Ente Auth"
|
||||
slug: "aegis"
|
||||
category: "deuxfa"
|
||||
difficulty: "beginner"
|
||||
license: "GPL-3.0"
|
||||
url: "https://getaegis.app"
|
||||
color: "#2c5c9c"
|
||||
monogram: "Ae"
|
||||
iconSlug: "aegisauthenticator"
|
||||
tags: ["Codes TOTP","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des applications qui génèrent les codes à six chiffres qui changent toutes les 30 secondes, en
|
||||
remplacement de Google Authenticator.
|
||||
|
||||
## why
|
||||
|
||||
<b>Aegis</b> (Android) garde vos codes dans un coffre chiffré local, sans cloud.{' '}
|
||||
<b>Ente Auth</b> ajoute une synchronisation chiffrée de bout en bout entre appareils, et a été
|
||||
audité. Bien plus sûrs que le SMS, et gratuits.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde : c'est le niveau de 2FA à adopter par défaut, avant les clés matérielles.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installez Aegis (F-Droid) ou Ente Auth (toutes plateformes).</li>
|
||||
<li>
|
||||
Sur chaque compte, activez la 2FA « application d'authentification » et scannez le QR code
|
||||
affiché.
|
||||
</li>
|
||||
<li>
|
||||
Notez les <b>codes de secours</b> sur papier et faites une sauvegarde chiffrée de votre
|
||||
coffre.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: "SimpleLogin · addy.io"
|
||||
slug: "alias"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "beginner"
|
||||
url: "https://simplelogin.io"
|
||||
color: "#c0392b"
|
||||
monogram: "@"
|
||||
iconSlug: "simplelogin"
|
||||
tags: ["Alias e-mail","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des alias e-mail jetables : une adresse unique par site, qui redirige vers votre vraie boîte
|
||||
sans jamais la révéler.
|
||||
|
||||
## why
|
||||
|
||||
Vous ne donnez plus votre vraie adresse partout. Si un site est piraté ou vous spamme, vous
|
||||
coupez l'alias correspondant, et vous savez immédiatement qui a fait fuiter vos données.{' '}
|
||||
<b>SimpleLogin</b> est intégré à Proton ; <b>addy.io</b> propose des alias illimités dès l'offre
|
||||
gratuite.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde, et particulièrement les comptes pseudonymes qui veulent cloisonner leurs
|
||||
inscriptions.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Créez un compte, installez l'extension de navigateur.</li>
|
||||
<li>À chaque inscription, générez un nouvel alias au lieu de saisir votre vraie adresse.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: "Sauvegardes chiffrées"
|
||||
slug: "backups"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "intermediate"
|
||||
url: "https://cryptomator.org"
|
||||
color: "#5a6570"
|
||||
monogram: "Bk"
|
||||
iconSlug: "cryptomator"
|
||||
tags: ["Cryptomator · restic","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
De quoi sauvegarder votre téléphone et votre ordinateur en chiffrant les données <b>avant</b>{' '}
|
||||
qu'elles ne partent dans un cloud.
|
||||
|
||||
## why
|
||||
|
||||
Les sauvegardes iCloud/Google sont souvent accessibles au fournisseur, donc à la justice.{' '}
|
||||
<b>Cryptomator</b> chiffre vos fichiers avant de les envoyer sur n'importe quel cloud ;{' '}
|
||||
<b>restic</b> fait des sauvegardes chiffrées automatiques ; <b>Proton Drive</b> est chiffré de
|
||||
bout en bout. Sur iPhone, activez la « Protection avancée des données » pour chiffrer vos
|
||||
sauvegardes iCloud.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde devrait chiffrer ses sauvegardes. Règle d'or : deux copies chiffrées, sur deux
|
||||
supports, en deux lieux.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
iPhone : Réglages > votre nom > iCloud > Protection avancée des données : activez-la.
|
||||
</li>
|
||||
<li>
|
||||
PC : installez Cryptomator, créez un coffre, placez-y vos fichiers avant de synchroniser vers
|
||||
le cloud.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: "Bitchat"
|
||||
slug: "bitchat"
|
||||
category: "messagerie"
|
||||
difficulty: "advanced"
|
||||
url: "https://bitchat.free"
|
||||
color: "#e8871e"
|
||||
monogram: "bit"
|
||||
tags: ["Mesh Bluetooth","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
La messagerie mesh de Jack Dorsey : les téléphones proches se relaient les messages de proche en
|
||||
proche, sans internet ni serveur ni compte.
|
||||
|
||||
## why
|
||||
|
||||
Chiffrement de bout en bout (AES-256-GCM) et un « mode panique » qui efface tout en trois
|
||||
tapotements sur le logo.
|
||||
|
||||
## who
|
||||
|
||||
Manifestations et blackout, en complément de Briar. À utiliser avec prudence.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installez depuis l'App Store (iOS) ou l'APK/GitHub (Android).</li>
|
||||
<li>Ouvrez l'application et choisissez un pseudo. Aucun compte à créer.</li>
|
||||
<li>Les appareils proches se découvrent automatiquement en Bluetooth.</li>
|
||||
<li>En cas de danger, triple-tapez le logo pour tout effacer (mode panique).</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: "Bitcoin (auto-conservation)"
|
||||
slug: "bitcoin"
|
||||
category: "argent"
|
||||
difficulty: "intermediate"
|
||||
url: "https://bitcoin.org"
|
||||
color: "#f7931a"
|
||||
monogram: "₿"
|
||||
iconSlug: "bitcoin"
|
||||
tags: ["Résistant à la censure"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une monnaie numérique que vous détenez vous-même, sans passer par une banque.
|
||||
|
||||
## why
|
||||
|
||||
En <b>auto-conservation</b> (vos clés dans un portefeuille que vous seul contrôlez), personne ne
|
||||
peut geler ni bloquer vos fonds. Sa confidentialité n'est pas parfaite (le registre est public),
|
||||
mais il échappe à la censure bancaire, utile le jour où un paiement est refusé.
|
||||
|
||||
## who
|
||||
|
||||
Se prémunir contre le gel de compte ou la dé-bancarisation, et payer anonymement un service
|
||||
comme un VPN.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Procurez-vous des bitcoins (plateforme d'échange, ou entre particuliers).</li>
|
||||
<li>
|
||||
Transférez-les aussitôt vers un portefeuille que <b>vous</b> contrôlez : un portefeuille
|
||||
matériel (Trezor, ColdCard) ou une application libre. Ne les laissez pas sur la plateforme.
|
||||
</li>
|
||||
<li>Sauvegardez votre phrase de récupération sur papier, jamais en photo ni en ligne.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: "Bitwarden"
|
||||
slug: "bitwarden"
|
||||
category: "motsdepasse"
|
||||
difficulty: "beginner"
|
||||
license: "GPL-3.0"
|
||||
url: "https://bitwarden.com"
|
||||
color: "#175ddc"
|
||||
monogram: "Bw"
|
||||
iconSlug: "bitwarden"
|
||||
tags: ["Le meilleur pour débuter","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un coffre-fort à mots de passe qui les mémorise, les génère et les remplit pour toi, sur tous tes appareils.
|
||||
|
||||
## why
|
||||
|
||||
Gratuit, audité, multiplateforme, chiffré de bout en bout. Tu n'as plus qu'un seul mot de passe fort à retenir — et le jour où tu veux ne dépendre de personne, il est <b>auto-hébergeable</b> (via Vaultwarden).
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde. C'est la fondation de toute ta sécurité : un mot de passe unique et fort par service, sans effort de mémoire.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Crée un compte sur bitwarden.com et choisis un mot de passe maître <b>long</b> — une phrase entière. Ne l'oublie jamais : il n'est pas récupérable, et c'est voulu.</li>
|
||||
<li>Installe l'extension de navigateur et l'application mobile.</li>
|
||||
<li>Au fil de tes connexions, laisse Bitwarden enregistrer puis remplacer tes vieux mots de passe par des mots de passe générés.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: "Brave"
|
||||
slug: "brave"
|
||||
category: "navigateur"
|
||||
difficulty: "beginner"
|
||||
license: "MPL-2.0"
|
||||
url: "https://brave.com"
|
||||
color: "#fb542b"
|
||||
monogram: "Bv"
|
||||
iconSlug: "brave"
|
||||
tags: ["Bloque tout par défaut","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un navigateur basé sur Chromium qui bloque publicités et traqueurs par défaut — avec en prime une fenêtre privée connectée à Tor.
|
||||
|
||||
## why
|
||||
|
||||
C'est le changement le plus indolore quand tu viens de Chrome : même ergonomie, sans le pistage. Il bloque les pubs YouTube nativement, propose une visio chiffrée (Brave Talk, basé sur Jitsi) et un accès Tor en un clic — pratique pour récupérer un site bloqué.
|
||||
|
||||
## who
|
||||
|
||||
Celles et ceux qui veulent quitter Chrome sans rien réapprendre. (Les fonctions crypto et pubs récompensées ? Ignore-les, elles se désactivent.)
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installe Brave depuis <b>brave.com</b>.</li>
|
||||
<li>Règle les « Boucliers » (Shields) sur « agressif », et désactive Brave Rewards si tu ne veux pas de pubs.</li>
|
||||
<li>Pour Tor : menu > « Nouvelle fenêtre privée avec Tor », puis attends « Tor connecté ».</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: "Briar"
|
||||
slug: "briar"
|
||||
category: "messagerie"
|
||||
difficulty: "advanced"
|
||||
license: "GPL-3.0"
|
||||
url: "https://briarproject.org"
|
||||
color: "#c1272d"
|
||||
monogram: "Br"
|
||||
tags: ["Hors-ligne / P2P","Android · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une messagerie pair-à-pair qui fonctionne <b>sans internet</b> : par Bluetooth, Wi-Fi Direct ou
|
||||
Tor.
|
||||
|
||||
## why
|
||||
|
||||
Aucun serveur, donc rien à couper ni à saisir. Résiste aux coupures d'internet et à la censure
|
||||
réseau.
|
||||
|
||||
## who
|
||||
|
||||
Manifestations, catastrophes, zones isolées, blackout. Android uniquement, et les deux personnes
|
||||
doivent avoir l'application.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez depuis <b>briarproject.org</b> ou F-Droid (pas d'iOS).
|
||||
</li>
|
||||
<li>
|
||||
Créez un compte <b>local</b> (pseudo + mot de passe), stocké seulement sur le téléphone.
|
||||
</li>
|
||||
<li>Ajoutez un contact proche en scannant son QR code, ou à distance via un lien.</li>
|
||||
<li>
|
||||
Quand le réseau est coupé, activez le Bluetooth : les messages passent d'appareil à appareil.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: "Duck.ai · Lumo (Proton)"
|
||||
slug: "cloudai"
|
||||
category: "ia"
|
||||
difficulty: "beginner"
|
||||
url: "https://duck.ai"
|
||||
color: "#de5833"
|
||||
monogram: "☁"
|
||||
iconSlug: "duckduckgo"
|
||||
tags: ["Cloud orienté vie privée"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des accès à l'IA dans le cloud, mais conçus pour la vie privée, quand une IA locale n'est pas
|
||||
possible.
|
||||
|
||||
## why
|
||||
|
||||
<b>Duck.ai</b> (DuckDuckGo) donne un accès anonymisé à plusieurs modèles. <b>Lumo</b> (Proton)
|
||||
chiffre les échanges et ne s'en sert pas pour entraîner. Bien mieux que ChatGPT grand public,
|
||||
mais cela reste un serveur distant.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent la commodité du cloud sans nourrir les géants. Gardez-y les sujets non
|
||||
sensibles.
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: "Cloudflare 1.1.1.1 (à nuancer)"
|
||||
slug: "cloudflare"
|
||||
category: "dns"
|
||||
difficulty: "beginner"
|
||||
url: "https://one.one.one.one"
|
||||
color: "#f38020"
|
||||
monogram: "CF"
|
||||
iconSlug: "cloudflare"
|
||||
tags: ["Rapide mais centralisé","🇺🇸"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Le DNS chiffré 1.1.1.1 et l'application WARP de Cloudflare : rapides, gratuits, et un vrai
|
||||
progrès face au résolveur de votre FAI.
|
||||
|
||||
## why
|
||||
|
||||
C'est utile, avec un engagement de non-journalisation audité. Mais soyez lucide : Cloudflare se
|
||||
trouve déjà devant une immense partie du web (comme intermédiaire technique, il peut voir le
|
||||
trafic en clair vers ces sites). Y router aussi votre DNS revient à{' '}
|
||||
<b>concentrer encore plus de vos traces</b> chez une seule entreprise américaine soumise au
|
||||
droit américain.
|
||||
|
||||
## who
|
||||
|
||||
Bon pour un usage courant et le blocage des maliciels (1.1.1.1 for Families). À éviter ou à
|
||||
diversifier pour un usage sensible : préférez alors Quad9 ou Mullvad DNS.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "Cryptomator"
|
||||
slug: "cryptomator"
|
||||
category: "stockage"
|
||||
difficulty: "intermediate"
|
||||
license: "GPL-3.0"
|
||||
url: "https://cryptomator.org"
|
||||
color: "#26a69a"
|
||||
monogram: "Cy"
|
||||
iconSlug: "cryptomator"
|
||||
tags: ["Chiffre avant l'envoi","🇩🇪 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un coffre qui chiffre vos fichiers <b>avant</b> de les envoyer sur n'importe quel cloud, même
|
||||
Google Drive ou Dropbox.
|
||||
|
||||
## why
|
||||
|
||||
L'astuce parfaite si vous devez garder un cloud existant : vous conservez le service pratique,
|
||||
mais le fournisseur ne voit plus que du charabia chiffré. Vous gardez seul la clé.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui ne peuvent pas quitter un cloud grand public tout de suite, mais veulent protéger leurs
|
||||
fichiers dès maintenant.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installez Cryptomator (PC et mobile) depuis cryptomator.org.</li>
|
||||
<li>
|
||||
Créez un « coffre » dans le dossier synchronisé de votre cloud, choisissez un mot de passe
|
||||
fort.
|
||||
</li>
|
||||
<li>
|
||||
Placez vos fichiers dans le coffre : ils sont chiffrés puis synchronisés automatiquement.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "Effacer ses données (RGPD)"
|
||||
slug: "databrokers"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "intermediate"
|
||||
url: "https://www.cnil.fr"
|
||||
color: "#b8860b"
|
||||
monogram: "RG"
|
||||
tags: ["Courtiers en données"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Faire retirer vos informations personnelles des « courtiers en données » qui les collectent et
|
||||
les revendent.
|
||||
|
||||
## why
|
||||
|
||||
En Europe, le RGPD (article 17) vous donne un <b>droit à l'effacement</b> : vous pouvez exiger,
|
||||
gratuitement, qu'une entreprise supprime vos données, en principe sous un mois. Des services
|
||||
comme <b>Incogni</b> automatisent ces demandes en masse, moyennant paiement.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent réduire leur exposition. Attention : les données réapparaissent avec le temps,
|
||||
et cela ne touche ni les registres publics ni les réseaux sociaux. Le faire soi-même est gratuit
|
||||
mais fastidieux.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Pour une demande manuelle : écrivez au courtier en invoquant l'article 17 du RGPD et demandez
|
||||
la suppression.
|
||||
</li>
|
||||
<li>
|
||||
Pour automatiser : souscrivez à un service de retrait et laissez-le envoyer les demandes en
|
||||
votre nom.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "Matrix / Element"
|
||||
slug: "element"
|
||||
category: "social"
|
||||
difficulty: "intermediate"
|
||||
url: "https://element.io"
|
||||
color: "#0dbd8b"
|
||||
monogram: "El"
|
||||
iconSlug: "element"
|
||||
tags: ["Remplace Discord / Slack","🌍 · fédéré · E2EE"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une messagerie de communautés, dans l'esprit de Discord ou Slack, mais fédérée et chiffrable de
|
||||
bout en bout. Element est l'application, Matrix le réseau.
|
||||
|
||||
## why
|
||||
|
||||
Vous pouvez héberger votre propre serveur (Synapse) et contrôler vos données. Parfait pour un
|
||||
collectif, une rédaction, une association qui veut son espace indépendant.
|
||||
|
||||
## who
|
||||
|
||||
Communautés et groupes. Voir la nuance sur les métadonnées ci-dessous.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez Element (element.io) et créez un compte sur un serveur public, ou sur le vôtre
|
||||
(section 10).
|
||||
</li>
|
||||
<li>
|
||||
Rejoignez ou créez des salons, et activez le chiffrement de bout en bout pour les
|
||||
conversations privées.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "Pixelfed · PeerTube · Lemmy"
|
||||
slug: "fediverse"
|
||||
category: "social"
|
||||
difficulty: "intermediate"
|
||||
url: "https://pixelfed.org"
|
||||
color: "#ea580c"
|
||||
monogram: "Pi"
|
||||
iconSlug: "pixelfed"
|
||||
tags: ["Insta · YouTube · Reddit","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Les cousins fédérés d'Instagram (Pixelfed), de YouTube (PeerTube) et de Reddit (Lemmy).
|
||||
|
||||
## why
|
||||
|
||||
Même logique que Mastodon : pas de propriétaire unique, pas d'algorithme publicitaire, pas de
|
||||
traçage. Vous publiez photos, vidéos ou discussions sans nourrir une machine à profiler.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent quitter Instagram, YouTube ou Reddit sans renoncer au format.
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: "Firefox (durci)"
|
||||
slug: "firefox"
|
||||
category: "navigateur"
|
||||
difficulty: "beginner"
|
||||
license: "MPL-2.0"
|
||||
url: "https://www.mozilla.org/firefox"
|
||||
color: "#e66000"
|
||||
monogram: "Fx"
|
||||
iconSlug: "firefoxbrowser"
|
||||
tags: ["Remplace Chrome","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Le navigateur libre de référence pour un usage quotidien respectueux de la vie privée.
|
||||
|
||||
## why
|
||||
|
||||
Contrairement à Chrome (un mouchard publicitaire de Google), Firefox est développé par une
|
||||
fondation et n'a pas d'intérêt à vous profiler. Avec quelques réglages (le guide{' '}
|
||||
<em>arkenfox</em>) et l'extension uBlock Origin, il devient très solide.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde, comme navigateur principal au quotidien.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez Firefox depuis <b>mozilla.org/firefox</b>.
|
||||
</li>
|
||||
<li>
|
||||
Ajoutez l'extension <b>uBlock Origin</b> (blocage des pubs et traqueurs).
|
||||
</li>
|
||||
<li>
|
||||
Dans les réglages de vie privée, choisissez « Stricte », désactivez la télémétrie, et videz
|
||||
les cookies à la fermeture. Pour aller plus loin, appliquez le guide arkenfox.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "Bitwarden"
|
||||
slug: "bitwarden"
|
||||
lang: "gcf"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
On kòf a modpas ki ka sonjé-yo, jénéré-yo é ranpli-yo pou vou, asi tout apawèy a-w.
|
||||
|
||||
## why
|
||||
|
||||
Gratis, odité, miltiplatfòwm, chifré bout-an-bout. Ou ni yenki on sèl modpas fò pou sonjé — é jou ou vlé pa dépann di pèsonn, ou pé <b>oto-ébèjé'y</b> (èvè Vaultwarden).
|
||||
|
||||
## who
|
||||
|
||||
Tout moun. Sé fondasyon a tout sékirité a-w : on modpas inik é fò pou chak sèwvis, san fòsé mémwa a-w.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Kréyé on kont asi bitwarden.com é chwazi on modpas mèt <b>long</b> — on fraz antyé. Pa janmé oublié'y : i pa rékipérab, é sé fè èsprè.</li>
|
||||
<li>Enstalé èkstansyon navigatè-la é aplikasyon mobil-la.</li>
|
||||
<li>O fi a konèksyon a-w, kité Bitwarden anrèjistré é apré ranplasé vyé modpas a-w pa modpas jénéré.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "Brave"
|
||||
slug: "brave"
|
||||
lang: "gcf"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
On navigatè basé asi Chromium ki ka bloké piblisité é trakè pa défo — èvè an plis on fenèt privé konèkté asi Tor.
|
||||
|
||||
## why
|
||||
|
||||
Sé chanjman pi dous-la lè ou ka sòti an Chrome : menm èwgonomi, san pistaj-la. I ka bloké pib YouTube dirèk, i ka pwopozé on vizyo chifré (Brave Talk, basé asi Jitsi) é on aksè Tor an on klik — pratik pou ratrapé on sit bloké.
|
||||
|
||||
## who
|
||||
|
||||
Moun ki vlé kité Chrome san riaprann ayen. (Fonksyon crypto é pib rékonpansé ? Inyoré-yo, yo ka tenn.)
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Enstalé Brave dépi <b>brave.com</b>.</li>
|
||||
<li>Réglé « Bouklyé »-la (Shields) asi « agrésif », é tenn Brave Rewards si ou pa vlé pib.</li>
|
||||
<li>Pou Tor : mèni > « Nouvo fenèt privé èvè Tor », apré atann « Tor konèkté ».</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: "Proton Mail"
|
||||
slug: "protonmail"
|
||||
lang: "gcf"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
On bwèt imèl chifré ki ka ranplasé Gmail oben Outlook — é kont pivo a tout ékosistèm Proton-la.
|
||||
|
||||
## why
|
||||
|
||||
Basé an Swis, andéwò a jiridiksyon « Five Eyes »-la. Konpatib OpenPGP : chifraj-la otomatik ant kont Proton é lòt sèwvis PGP. Kouryé a-w, sé korèspondans a-w — pa on matyè prèmyé pou piblisité.
|
||||
|
||||
## who
|
||||
|
||||
Tout moun. Sé pi bon pòt pou sòti an Google : louvè kont-la, rès a suit-la (ajanda, drive, VPN) ka suiv tousèl.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Kréyé on kont asi <b>proton.me</b> (òf gratis-la ka sifi pou koumansé).</li>
|
||||
<li>Rapatriyé vyé mésaj é kontak a-w èvè <b>Easy Switch</b> (entégré).</li>
|
||||
<li>Mèt on rédirèksyon dépi Gmail é prévien kontak a-w di nouvo adrès a-w.</li>
|
||||
<li>Enstalé aplikasyon mobil-la, limé <b>doub otantifikasyon-la</b> — é Proton Bridge si ou ka rété asi Thunderbird.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: "Quad9"
|
||||
slug: "quad9"
|
||||
lang: "gcf"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
On rézolvè DNS chifré, swis é san bi likratif, ki ka bloké an plis domèn malfézan yo ja konnèt.
|
||||
|
||||
## why
|
||||
|
||||
Founisè aksè a-w ka vwè chak sit ou ka vizité gras a DNS-la. Quad9 ka chifré dimann-lasa yo, i pa ka gadé adrès IP a-w, é i ka pwotéjé-w kont lamèkantri an menm tan. On réglaj « fè'y é oublié'y ».
|
||||
|
||||
## who
|
||||
|
||||
Tout moun — sitou si ou vlé on vré gany san enstalé ayen anplis.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Asi Android : Réglaj > Rézo > <b>DNS privé</b> > matjé <b>dns.quad9.net</b>.</li>
|
||||
<li>Asi iPhone/Mac : enstalé profil DoH-la dépi quad9.net. Asi PC : konfiguré DNS-over-HTTPS an navigatè-la oben an sistèm-la.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: "Signal"
|
||||
slug: "signal"
|
||||
lang: "gcf"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
On mésajri chifré pou tèks, apèl, vizyo é group a-w. Sé ranplasan dirèk a WhatsApp — menm senplisité, san Meta dèyè.
|
||||
|
||||
## why
|
||||
|
||||
Chifraj bout-an-bout pa défo, san bi likratif, protokòl odité ki ka sèwvi référans toupatou. Prèské pon métadoné pa ka rété, é ékip-la ja di : yo ké kité Léwòp olyé yo enstalé on skannaj. Chak moun ou ka fè pasé, sé on konvèsasyon anplis ki ka sòti an survéyans-la.
|
||||
|
||||
## who
|
||||
|
||||
Tout moun, jòdi-la menm. Sé prèmyé jès-la, é pi itil-la : koumansé èvè group a fanmi a-w. Yenki on kontrent : on niméwo téléfòn — ou pé séré'y dèyè on non itilizatè.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Enstalé dépi <b>signal.org</b> (App Store, Google Play, oben APK dirèk asi Android).</li>
|
||||
<li>Konfirmé niméwo a-w pa SMS, apré chwazi on kòd PIN.</li>
|
||||
<li>Réglaj > Konfidansyalité : kréyé on <b>non itilizatè</b> pou séré niméwo a-w, é limé <b>vèwou enskripsyon-la</b>.</li>
|
||||
<li>Envité moun a-w — group fanmi-la avan. Asi òwdinatè, lyanné aplikasyon biwo-la èvè téléfòn a-w.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: "uBlock Origin"
|
||||
slug: "ublock"
|
||||
lang: "gcf"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Èkstansyon-la ki ka bloké piblisité, trakè é èskrip èspyon. Jès pi rantab a tout gid-lasa : dis ségonn, éfè imedya.
|
||||
|
||||
## why
|
||||
|
||||
Piblisité an liny sé prensipal chimen a survéyans é profilaj. Bloké'y, sé koupé pi gwo moso a pistaj-la — é an menm balan paj a-w ka chajé pi vit é fòfé data a-w ka respiré.
|
||||
|
||||
## who
|
||||
|
||||
Tout moun, asi Firefox kon asi navigatè Chromium. Si ou ka fè yenki on sèl jès jòdi-la, fè ta-lasa.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Louvè magazen èkstansyon a navigatè a-w é chèché « uBlock Origin » (orijinal-la, pa Raymond Hill).</li>
|
||||
<li>Enstalé'y. I ka travay lamenm, san pon réglaj.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
name: "GrapheneOS"
|
||||
slug: "grapheneos"
|
||||
category: "os"
|
||||
difficulty: "advanced"
|
||||
license: "MIT"
|
||||
url: "https://grapheneos.org"
|
||||
color: "#1f8a70"
|
||||
monogram: "Gr"
|
||||
iconSlug: "grapheneos"
|
||||
tags: ["Mobile dégooglisé","Android · Pixel · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un Android entièrement dégooglisé, installé sur un téléphone Pixel : la souveraineté sur mobile.
|
||||
|
||||
## why
|
||||
|
||||
C'est la défense structurelle par excellence contre un OS ou un magasin d'applications qui
|
||||
voudrait vous scanner. Services Google en bac à sable optionnel,{' '}
|
||||
<b>permissions réseau par application</b>, profils cloisonnés, redémarrage automatique qui purge
|
||||
les clés de la mémoire, code PIN de contrainte qui efface le téléphone. Réputé pour sa sécurité
|
||||
au point d'être utilisé par des cibles de logiciels espions.
|
||||
|
||||
## who
|
||||
|
||||
Profils exposés, mais aussi tout citoyen prêt à acheter un Pixel pour reprendre le contrôle de
|
||||
son téléphone.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Procurez-vous un téléphone <b>Google Pixel</b> compatible (c'est le seul matériel supporté,
|
||||
pour des raisons de sécurité).
|
||||
</li>
|
||||
<li>
|
||||
Sur un ordinateur, allez sur <b>grapheneos.org/install</b> et suivez l'installeur web
|
||||
(quelques clics, aucun terminal requis).
|
||||
</li>
|
||||
<li>
|
||||
Pour vos applications, installez le magasin libre F-Droid ; ajoutez Google Play en bac à sable
|
||||
seulement si nécessaire.
|
||||
</li>
|
||||
<li>
|
||||
Réglez un long mot de passe (pas un code à 4 chiffres) et découvrez le mode « Lockdown ».
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: "IVPN"
|
||||
slug: "ivpn"
|
||||
category: "vpn"
|
||||
difficulty: "intermediate"
|
||||
url: "https://www.ivpn.net"
|
||||
color: "#3b5bdb"
|
||||
monogram: "iv"
|
||||
tags: ["Sans e-mail · no-log","🇬🇮 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un petit fournisseur de VPN particulièrement rigoureux et transparent, sur le même modèle que
|
||||
Mullvad.
|
||||
|
||||
## why
|
||||
|
||||
Politique no-log auditée, pas d'e-mail obligatoire, paiement en crypto ou en espèces. Il propose
|
||||
même des options anti-traçage (blocage des trackers au niveau réseau) et une inscription sans
|
||||
aucun identifiant.
|
||||
|
||||
## who
|
||||
|
||||
Une alternative solide à Mullvad, pour les profils pseudonymes et à haut risque qui veulent
|
||||
diversifier.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Sur <b>ivpn.net</b>, générez un compte (un identifiant est créé pour vous, sans e-mail).
|
||||
</li>
|
||||
<li>Payez en cryptomonnaie ou en espèces, comme pour Mullvad.</li>
|
||||
<li>
|
||||
Installez l'application, connectez-vous hors UE, activez le kill switch et le protocole
|
||||
WireGuard.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: "KeePassXC"
|
||||
slug: "keepassxc"
|
||||
category: "motsdepasse"
|
||||
difficulty: "advanced"
|
||||
license: "GPL-2.0/3.0"
|
||||
url: "https://keepassxc.org"
|
||||
color: "#2c6b9e"
|
||||
monogram: "Kp"
|
||||
iconSlug: "keepassxc"
|
||||
tags: ["100% local","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un coffre-fort <b>local</b> : un fichier chiffré que vous seul détenez, sans aucun cloud ni
|
||||
compte.
|
||||
|
||||
## why
|
||||
|
||||
Rien ne quitte votre appareil, sauf si vous décidez de synchroniser le fichier vous-même (par
|
||||
exemple via Cryptomator). C'est le choix des puristes qui ne veulent aucun intermédiaire.
|
||||
|
||||
## who
|
||||
|
||||
Les profils avancés qui veulent le contrôle total et zéro dépendance en ligne.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez KeePassXC (PC) et une application compatible sur mobile (KeePassDX sur Android,
|
||||
Strongbox sur iOS).
|
||||
</li>
|
||||
<li>Créez un fichier de base de données protégé par un mot de passe maître.</li>
|
||||
<li>Pour l'avoir sur tous vos appareils, synchronisez ce fichier via un cloud chiffré.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: "Linux (sur ordinateur)"
|
||||
slug: "linux"
|
||||
category: "os"
|
||||
difficulty: "intermediate"
|
||||
url: "https://distrochooser.de/fr"
|
||||
color: "#2b2b2b"
|
||||
monogram: "🐧"
|
||||
iconSlug: "linux"
|
||||
tags: ["Remplace Windows / macOS","🌍 · libre & gratuit"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un système d'exploitation libre et gratuit pour votre ordinateur, en remplacement de Windows ou
|
||||
de macOS. Il en existe de nombreuses variantes, appelées « distributions ».
|
||||
|
||||
## why
|
||||
|
||||
C'est le point aveugle de beaucoup de gens : ils chiffrent leurs messages mais gardent un
|
||||
Windows qui transmet en continu de la télémétrie à Microsoft (et dont la fonction « Recall » a
|
||||
voulu photographier l'écran en permanence), ou un macOS qui signale les applications que vous
|
||||
lancez. Linux, lui, ne vous espionne pas, il est gratuit, il ressuscite les vieux ordinateurs et
|
||||
il vous rend enfin maître de votre machine. C'est plus facile que sa réputation : les
|
||||
distributions modernes ressemblent à Windows ou macOS.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde peut franchir le pas. Pour débuter, <b>Linux Mint</b> (le plus proche de Windows)
|
||||
ou <b>Fedora</b> ; <b>Debian</b> pour la stabilité. Pas besoin de tout casser : on peut d'abord
|
||||
tester, puis installer à côté de son système actuel.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Pas sûr de la distribution ? Répondez au questionnaire <b>distrochooser.de/fr</b>, qui vous
|
||||
oriente selon vos besoins.
|
||||
</li>
|
||||
<li>
|
||||
Testez-la <b>sans rien installer</b> directement dans votre navigateur sur{' '}
|
||||
<b>distrosea.com</b>.
|
||||
</li>
|
||||
<li>
|
||||
Une fois convaincu, téléchargez l'image de la distribution et créez une clé USB de démarrage
|
||||
(avec Ventoy ou Balena Etcher).
|
||||
</li>
|
||||
<li>
|
||||
Démarrez sur la clé pour essayer le système « en live », puis lancez l'installation. Activez
|
||||
le chiffrement du disque proposé.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: "Ollama · LM Studio · Jan · GPT4All"
|
||||
slug: "localai"
|
||||
category: "ia"
|
||||
difficulty: "intermediate"
|
||||
url: "https://lmstudio.ai"
|
||||
color: "#111111"
|
||||
monogram: "Ai"
|
||||
iconSlug: "ollama"
|
||||
tags: ["Remplace ChatGPT","🌍 · 100% local"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des logiciels pour faire tourner un modèle d'intelligence artificielle directement sur votre
|
||||
ordinateur.
|
||||
|
||||
## why
|
||||
|
||||
Vos questions ne quittent jamais l'appareil : aucun serveur, aucun compte, aucune télémétrie, et
|
||||
ça marche hors ligne. La qualité dépend de votre matériel, mais rien ne fuit. <b>Ollama</b> et{' '}
|
||||
<b>LM Studio</b> sont les plus simples ; <b>Jan</b> et <b>GPT4All</b> visent la vie privée
|
||||
maximale.
|
||||
|
||||
## who
|
||||
|
||||
Tous ceux qui utilisent l'IA pour des sujets un tant soit peu personnels et ne veulent pas les
|
||||
confier à un serveur américain.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Pour débuter en douceur, installez <b>LM Studio</b> ou <b>Jan</b> (interface graphique, comme
|
||||
une application classique).
|
||||
</li>
|
||||
<li>
|
||||
Téléchargez un modèle proposé dans l'application (par exemple Llama ou Mistral), adapté à la
|
||||
puissance de votre machine.
|
||||
</li>
|
||||
<li>
|
||||
Discutez : tout se passe en local. Ollama est la version en ligne de commande pour les plus
|
||||
techniques.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: "mailbox.org · Posteo"
|
||||
slug: "mailbox"
|
||||
category: "email"
|
||||
difficulty: "beginner"
|
||||
url: "https://mailbox.org"
|
||||
color: "#2470d4"
|
||||
monogram: "mx"
|
||||
tags: ["Mail classique éthique","🇩🇪 · UE · PGP"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Deux fournisseurs de mail européens, éthiques et peu coûteux, avec support PGP côté serveur.
|
||||
|
||||
## why
|
||||
|
||||
Respectueux de la vie privée et de l'écologie, sur des standards ouverts (IMAP, PGP). Ils
|
||||
fonctionnent avec n'importe quel logiciel de messagerie.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent un mail « classique » (relevé dans Thunderbird) mais éthique, plutôt qu'une
|
||||
messagerie chiffrée fermée.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Créez un compte (payant, de l'ordre de 1 à 3 € par mois).</li>
|
||||
<li>Activez le chiffrement PGP côté serveur (fonction « Guard » chez mailbox.org).</li>
|
||||
<li>Configurez le compte dans Thunderbird ou l'application mobile de votre choix.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: "Organic Maps · OsmAnd"
|
||||
slug: "maps"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "beginner"
|
||||
url: "https://organicmaps.app"
|
||||
color: "#0a7d33"
|
||||
monogram: "Om"
|
||||
iconSlug: "openstreetmap"
|
||||
tags: ["Remplace Google Maps","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des applications de cartes et de navigation, fondées sur OpenStreetMap, qui fonctionnent hors
|
||||
ligne.
|
||||
|
||||
## why
|
||||
|
||||
Google Maps enregistre chacun de vos trajets et bâtit un historique de lieux d'une précision
|
||||
redoutable. <b>Organic Maps</b> ne trace rien et n'affiche aucune publicité ; <b>OsmAnd</b> vise
|
||||
les utilisateurs avancés (randonnée, courbes de niveau, navigation détaillée).
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde. Le trafic en temps réel et les transports sont moins complets que chez Google,
|
||||
mais la navigation quotidienne est excellente.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installez depuis F-Droid, l'App Store ou Google Play.</li>
|
||||
<li>
|
||||
Téléchargez à l'avance les cartes des régions qui vous intéressent pour l'usage hors ligne.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "Mastodon"
|
||||
slug: "mastodon"
|
||||
category: "social"
|
||||
difficulty: "beginner"
|
||||
license: "AGPL-3.0"
|
||||
url: "https://joinmastodon.org"
|
||||
color: "#6364ff"
|
||||
monogram: "Ma"
|
||||
iconSlug: "mastodon"
|
||||
tags: ["Remplace X / Twitter","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
L'alternative à X/Twitter : un réseau social fait de milliers de serveurs indépendants qui
|
||||
communiquent entre eux (le « fédiverse »).
|
||||
|
||||
## why
|
||||
|
||||
Pas de patron unique, pas d'algorithme qui décide à votre place, pas de bannissement arbitraire
|
||||
par une seule entreprise. Le fil est chronologique, sans publicité ni manipulation.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde. Idéal pour les comptes d'information qui veulent une présence qu'aucune
|
||||
entreprise ne peut couper.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Sur joinmastodon.org, choisissez un serveur (ou « instance ») qui vous correspond, puis créez
|
||||
un compte.
|
||||
</li>
|
||||
<li>
|
||||
Installez une application (l'officielle, ou Ivory, Tusky…) et suivez des comptes : vous voyez
|
||||
tout le fédiverse, quel que soit leur serveur.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "Molly"
|
||||
slug: "molly"
|
||||
category: "messagerie"
|
||||
difficulty: "advanced"
|
||||
license: "GPL-3.0"
|
||||
url: "https://molly.im"
|
||||
color: "#6d4bb3"
|
||||
monogram: "M"
|
||||
tags: ["Signal durci","Android · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une version durcie de Signal pour Android, compatible avec le même réseau.
|
||||
|
||||
## why
|
||||
|
||||
Base de données chiffrée au repos, verrouillage automatique, et une variante « FOSS »
|
||||
entièrement sans services Google.
|
||||
|
||||
## who
|
||||
|
||||
Utilisateurs avancés, notamment sur GrapheneOS, avec un modèle de menace élevé. Android
|
||||
uniquement.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Ajoutez le dépôt Molly dans F-Droid, ou récupérez l'APK sur <b>molly.im</b>.
|
||||
</li>
|
||||
<li>
|
||||
Choisissez <b>Molly-FOSS</b> si vous voulez zéro dépendance Google.
|
||||
</li>
|
||||
<li>Enregistrez-vous avec votre numéro (même réseau que Signal).</li>
|
||||
<li>Définissez un mot de passe de base de données et le verrouillage automatique.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "Monero (XMR)"
|
||||
slug: "monero"
|
||||
category: "argent"
|
||||
difficulty: "advanced"
|
||||
license: "BSD-3-Clause"
|
||||
url: "https://www.getmonero.org"
|
||||
color: "#ff6600"
|
||||
monogram: "ɱ"
|
||||
iconSlug: "monero"
|
||||
tags: ["Confidentiel par défaut"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
La cryptomonnaie de la vie privée : montants, expéditeur et destinataire sont masqués par
|
||||
défaut.
|
||||
|
||||
## why
|
||||
|
||||
C'est l'exact opposé de Bitcoin sur ce point : les transactions sont confidentielles par
|
||||
conception. C'est le meilleur moyen de payer un service sans laisser de trace reliable à vous.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent le maximum de confidentialité financière. Note : Monero est déjà retiré de
|
||||
plusieurs plateformes en Europe, il faut souvent passer par un échange décentralisé.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installez un portefeuille (l'officiel sur getmonero.org, ou Cake Wallet sur mobile).</li>
|
||||
<li>
|
||||
Obtenez des XMR via un service d'échange décentralisé (par exemple un « swap » depuis une
|
||||
autre crypto).
|
||||
</li>
|
||||
<li>Sauvegardez votre phrase de récupération sur papier.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
name: "Mullvad VPN"
|
||||
slug: "mullvad"
|
||||
category: "vpn"
|
||||
difficulty: "beginner"
|
||||
url: "https://mullvad.net"
|
||||
color: "#2b4b8f"
|
||||
monogram: "Mv"
|
||||
iconSlug: "mullvad"
|
||||
tags: ["Sans compte · cash/Monero","🇸🇪 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un VPN qui masque votre adresse IP et chiffre votre trafic jusqu'à ses serveurs, sans jamais
|
||||
vous demander la moindre information personnelle.
|
||||
|
||||
## why
|
||||
|
||||
C'est l'étalon-or de la vie privée. Pas d'e-mail, pas de nom : à l'inscription, on vous attribue
|
||||
un simple numéro de compte. Politique « no-log » auditée, prix unique et honnête (5 € par mois,
|
||||
sans palier ni fausse promesse), et paiement possible en espèces ou en Monero. C'est précisément
|
||||
ce qui compte le jour où un État tente de couper l'accès aux VPN : un compte impossible à relier
|
||||
à votre identité, et un paiement que les banques ne peuvent pas bloquer.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde, du citoyen qui veut contourner une vérification d'identité au profil à haut
|
||||
risque. C'est le VPN à recommander en priorité.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Allez sur <b>mullvad.net</b>. Si le site est bloqué dans votre pays, ouvrez-le via le
|
||||
navigateur Tor ou son adresse <b>.onion</b>. Cliquez sur « Générer un numéro de compte » :
|
||||
aucun e-mail ni nom n'est demandé. Notez ce numéro dans votre gestionnaire de mots de passe et
|
||||
ne le partagez jamais, c'est votre unique clé d'accès.
|
||||
</li>
|
||||
<li>
|
||||
Choisissez la durée et le mode de paiement. Le prix est fixe. Trois voies : carte bancaire (le
|
||||
plus simple si elle n'est pas bloquée), espèces envoyées par courrier, ou cryptomonnaie.
|
||||
</li>
|
||||
<li>
|
||||
<b>Paiement anonyme en crypto :</b> cliquez sur « Créer une adresse de paiement à usage unique
|
||||
». Mullvad affiche une adresse (Bitcoin ou Monero) et un montant exact. Envoyez ce montant
|
||||
depuis votre portefeuille. Pour l'anonymat maximal, préférez <b>Monero</b> (confidentiel par
|
||||
défaut) ; Bitcoin est plus simple mais traçable. Voir la section 09 pour acheter de la crypto.
|
||||
Comptez environ 30 minutes de confirmation.
|
||||
</li>
|
||||
<li>
|
||||
Téléchargez l'application sur <b>mullvad.net/download</b> (via Tor si le site est filtré) et
|
||||
installez-la. Sur mobile, passez par l'App Store, Google Play, ou l'APK officiel si
|
||||
l'application a été retirée de votre magasin.
|
||||
</li>
|
||||
<li>
|
||||
Lancez l'application, entrez votre numéro de compte, puis connectez-vous à un serveur situé{' '}
|
||||
<b>hors de votre pays</b>, idéalement hors Union européenne (Suisse, États-Unis…). Activez le
|
||||
« kill switch » (qui coupe Internet si le VPN tombe) et le DNS de Mullvad.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "Mullvad Browser"
|
||||
slug: "mullvadbrowser"
|
||||
category: "navigateur"
|
||||
difficulty: "intermediate"
|
||||
url: "https://mullvad.net/browser"
|
||||
color: "#2b4b8f"
|
||||
monogram: "Mb"
|
||||
iconSlug: "mullvad"
|
||||
tags: ["Anti-empreinte","🇸🇪 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Le navigateur du Tor Browser, mais sans le réseau Tor : à utiliser avec votre VPN pour un
|
||||
ordinateur difficile à pister.
|
||||
|
||||
## why
|
||||
|
||||
Développé avec le Tor Project, il est conçu pour que tous ses utilisateurs présentent la{' '}
|
||||
<b>même empreinte numérique</b>. Résultat : au lieu d'être unique et donc traçable, vous vous
|
||||
fondez dans la masse. C'est le meilleur choix de vie privée sur ordinateur.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent aller au-delà du simple blocage de pub, notamment les comptes pseudonymes et
|
||||
les profils exposés.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Téléchargez-le sur <b>mullvad.net/browser</b> (Windows, macOS, Linux).
|
||||
</li>
|
||||
<li>
|
||||
Utilisez-le tel quel, sans le personnaliser : chaque extension ou réglage ajouté vous rend à
|
||||
nouveau identifiable.
|
||||
</li>
|
||||
<li>Associez-le à votre VPN pour masquer aussi votre adresse IP.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: "Mullvad DNS · NextDNS"
|
||||
slug: "mullvaddns"
|
||||
category: "dns"
|
||||
difficulty: "intermediate"
|
||||
url: "https://mullvad.net/help/dns-over-https-and-dns-over-tls"
|
||||
color: "#2b4b8f"
|
||||
monogram: "DNS"
|
||||
iconSlug: "mullvad"
|
||||
tags: ["Filtrage réseau"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Deux résolveurs chiffrés qui bloquent en plus pubs et traqueurs pour tout l'appareil.
|
||||
|
||||
## why
|
||||
|
||||
<b>Mullvad DNS</b> (Suède, no-log) est gratuit et propose des listes de blocage. <b>NextDNS</b>{' '}
|
||||
est très personnalisable, avec un tableau de bord et des profils par appareil, mais il est basé
|
||||
aux États-Unis et journalise par défaut (à désactiver dans les réglages).
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent un blocage des pubs à l'échelle du système, sans installer d'application par
|
||||
navigateur.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Mullvad DNS : utilisez l'adresse indiquée sur mullvad.net/help/dns comme DNS privé (même
|
||||
méthode que Quad9).
|
||||
</li>
|
||||
<li>
|
||||
NextDNS : créez un profil sur nextdns.io, <b>désactivez la journalisation</b>, puis appliquez
|
||||
la configuration à vos appareils.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "Nextcloud"
|
||||
slug: "nc-storage"
|
||||
category: "stockage"
|
||||
difficulty: "advanced"
|
||||
url: "https://nextcloud.com"
|
||||
color: "#0082c9"
|
||||
monogram: "Nc"
|
||||
iconSlug: "nextcloud"
|
||||
tags: ["Votre propre cloud","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Votre propre nuage (fichiers, agenda, contacts, notes) hébergé sur votre serveur.
|
||||
|
||||
## why
|
||||
|
||||
Le degré ultime de contrôle : vos données ne quittent jamais votre matériel. Détaillé dans la
|
||||
section 10 (Auto-hébergement).
|
||||
|
||||
## who
|
||||
|
||||
Les auto-hébergeurs. Voir la fiche complète en section 10.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: "Nextcloud"
|
||||
slug: "nextcloud"
|
||||
category: "selfhost"
|
||||
difficulty: "advanced"
|
||||
license: "AGPL-3.0"
|
||||
url: "https://nextcloud.com"
|
||||
color: "#0082c9"
|
||||
monogram: "Nc"
|
||||
iconSlug: "nextcloud"
|
||||
tags: ["Remplace toute la suite Google","🇩🇪 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Votre propre nuage : fichiers, agenda, contacts, photos, notes et documents collaboratifs, sur
|
||||
votre serveur.
|
||||
|
||||
## why
|
||||
|
||||
C'est le remplacement complet de Google Drive, Agenda et Contacts, mais chez vous. Vous décidez
|
||||
de la juridiction et personne d'autre n'a la main sur vos fichiers. À savoir : c'est la
|
||||
confidentialité « votre serveur », pas un chiffrement de bout en bout par défaut ; vous devez le
|
||||
maintenir à jour.
|
||||
|
||||
## who
|
||||
|
||||
Les auto-hébergeurs. Le plus simple est de l'installer via YunoHost ou Umbrel.
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "Nostr"
|
||||
slug: "nostr"
|
||||
category: "social"
|
||||
difficulty: "intermediate"
|
||||
url: "https://nostr.com"
|
||||
color: "#8e30eb"
|
||||
monogram: "No"
|
||||
tags: ["Incensurable","🌍 · protocole ouvert"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Pas une application mais un protocole : un réseau social où votre identité est une simple paire
|
||||
de clés, comme pour Bitcoin.
|
||||
|
||||
## why
|
||||
|
||||
Zéro e-mail, zéro mot de passe, aucun compte qu'on puisse supprimer. Vos messages voyagent sur
|
||||
des relais décentralisés et vous possédez vraiment votre audience : personne ne peut vous bannir
|
||||
durablement. Vous pouvez même recevoir des pourboires en Bitcoin (les « zaps ») et changer
|
||||
d'application quand vous voulez sans perdre vos abonnés.
|
||||
|
||||
## who
|
||||
|
||||
Comptes d'information et créateurs qui craignent la censure de plateforme et veulent une
|
||||
présence vraiment à eux.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installez un client : Damus (iPhone), Amethyst ou Primal (Android), ou une version web.</li>
|
||||
<li>
|
||||
L'application génère votre paire de clés. <b>Sauvegardez votre clé privée (nsec)</b> comme une
|
||||
phrase de récupération Bitcoin : sur papier, jamais partagée.
|
||||
</li>
|
||||
<li>Créez votre profil, suivez des gens, activez les zaps pour recevoir des sats.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: "Standard Notes · Joplin · CryptPad"
|
||||
slug: "notes"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "beginner"
|
||||
url: "https://standardnotes.com"
|
||||
color: "#2e7d6b"
|
||||
monogram: "No"
|
||||
tags: ["Remplace Docs / Notion","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des notes et documents chiffrés de bout en bout, pour remplacer Google Docs, Notion ou Evernote.
|
||||
|
||||
## why
|
||||
|
||||
<b>Standard Notes</b> (par Proton) chiffre vos notes par défaut. <b>Joplin</b> gère des carnets
|
||||
en Markdown avec chiffrement optionnel et la synchronisation de votre choix. <b>CryptPad</b>{' '}
|
||||
(français) offre l'équivalent de Google Docs en temps réel, entièrement chiffré.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde pour les notes ; CryptPad pour la collaboration à plusieurs.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Standard Notes / Joplin : créez un compte, installez l'application, et activez le chiffrement
|
||||
(par défaut sur Standard Notes, à activer dans Joplin).
|
||||
</li>
|
||||
<li>
|
||||
CryptPad : utilisez cryptpad.fr ou une autre instance, aucun compte requis pour commencer.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "Ente · Immich"
|
||||
slug: "photos"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "intermediate"
|
||||
url: "https://ente.io"
|
||||
color: "#7b3fbf"
|
||||
monogram: "Ph"
|
||||
iconSlug: "immich"
|
||||
tags: ["Remplace Google Photos","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Deux façons de garder vos photos sans les confier à Google ou Apple.
|
||||
|
||||
## why
|
||||
|
||||
<b>Ente</b> est un service géré, chiffré de bout en bout, avec reconnaissance et recherche
|
||||
faites sur l'appareil : simple et sûr. <b>Immich</b> est un clone de Google Photos que vous{' '}
|
||||
<b>hébergez vous-même</b> (recherche par visages et objets incluse), à réserver à ceux qui
|
||||
savent gérer un serveur.
|
||||
|
||||
## who
|
||||
|
||||
Ente pour tous ; Immich pour les auto-hébergeurs. Attention : Immich n'est pas chiffré de bout
|
||||
en bout, sa sécurité dépend de votre serveur.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Ente : installez l'application, créez un compte, activez la sauvegarde automatique de votre
|
||||
pellicule.
|
||||
</li>
|
||||
<li>
|
||||
Immich : déployez-le sur votre serveur (voir section 10) via Docker, puis connectez
|
||||
l'application mobile.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "Pi-hole · AdGuard Home"
|
||||
slug: "pihole"
|
||||
category: "dns"
|
||||
difficulty: "advanced"
|
||||
url: "https://pi-hole.net"
|
||||
color: "#96060c"
|
||||
monogram: "π"
|
||||
iconSlug: "pihole"
|
||||
tags: ["Blocage tout le réseau","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un bloqueur de publicités et de traqueurs qui protège <b>tout votre réseau à la fois</b>,
|
||||
installé sur un petit ordinateur comme un Raspberry Pi.
|
||||
|
||||
## why
|
||||
|
||||
Là où uBlock Origin protège un navigateur, Pi-hole filtre <b>chaque appareil</b> de la maison, y
|
||||
compris ceux où l'on ne peut pas installer d'extension : téléphones, téléviseurs connectés,
|
||||
objets connectés. Les pubs et traqueurs sont bloqués au niveau du DNS, avant même de se charger.{' '}
|
||||
<b>AdGuard Home</b> est une alternative à l'interface plus moderne.
|
||||
|
||||
## who
|
||||
|
||||
Les foyers qui veulent nettoyer tous leurs appareils d'un coup, et qui ont (ou veulent) un
|
||||
Raspberry Pi ou un petit serveur.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Sur un Raspberry Pi (ou un conteneur), lancez l'installeur officiel de Pi-hole.</li>
|
||||
<li>
|
||||
Dans les réglages de votre box/routeur, indiquez l'adresse du Pi-hole comme serveur DNS.
|
||||
</li>
|
||||
<li>Désormais, tous les appareils connectés à votre réseau sont filtrés automatiquement.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: "PocketPal AI"
|
||||
slug: "pocketpal"
|
||||
category: "ia"
|
||||
difficulty: "intermediate"
|
||||
license: "MIT"
|
||||
url: "https://pocketpal.dev"
|
||||
color: "#6b4eff"
|
||||
monogram: "Pp"
|
||||
tags: ["Remplace ChatGPT sur mobile","📱 · 100% local"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une application pour faire tourner des modèles d'IA directement sur votre téléphone, entièrement
|
||||
hors ligne.
|
||||
|
||||
## why
|
||||
|
||||
Vos requêtes ne quittent jamais le téléphone : aucun compte, aucun cloud, aucune télémétrie, et
|
||||
ça marche en mode avion. Open source (MIT), l'appli télécharge des modèles <b>GGUF</b> (Gemma,
|
||||
Qwen, Phi, Llama) depuis Hugging Face et les exécute sur le CPU, le GPU ou le NPU de l'appareil.
|
||||
Le pendant mobile d'Ollama et LM Studio.
|
||||
|
||||
## who
|
||||
|
||||
Tous ceux qui dégainent ChatGPT sur leur téléphone pour des questions personnelles et ne veulent
|
||||
pas les confier à un serveur américain.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez <b>PocketPal</b> depuis l'App Store ou Google Play (ou compilez les sources).
|
||||
</li>
|
||||
<li>
|
||||
Ouvrez <b>Models</b>, choisissez un modèle adapté à votre téléphone et téléchargez-le.
|
||||
</li>
|
||||
<li>Chargez-le et discutez : tout tourne hors ligne, sur l'appareil.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: "Proton Drive"
|
||||
slug: "protondrive"
|
||||
category: "stockage"
|
||||
difficulty: "beginner"
|
||||
url: "https://proton.me/drive"
|
||||
color: "#6d4aff"
|
||||
monogram: "Pd"
|
||||
iconSlug: "protondrive"
|
||||
tags: ["Remplace Google Drive / iCloud","🇨🇭 · E2EE"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un cloud chiffré de bout en bout pour vos fichiers et vos photos, intégré à Proton.
|
||||
|
||||
## why
|
||||
|
||||
Contrairement à Google Drive ou iCloud, Proton ne peut pas lire vos fichiers : ils sont chiffrés
|
||||
avant de quitter votre appareil. Juridiction suisse, même compte que Proton Mail.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde, comme remplacement direct et simple du cloud de Google ou d'Apple.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Activez Proton Drive dans votre compte Proton et installez l'application.</li>
|
||||
<li>Activez la sauvegarde automatique de vos photos, puis désactivez celle de Google/Apple.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: "Proton Mail"
|
||||
slug: "protonmail"
|
||||
category: "email"
|
||||
difficulty: "beginner"
|
||||
url: "https://proton.me/mail"
|
||||
color: "#6d4aff"
|
||||
monogram: "Pm"
|
||||
iconSlug: "protonmail"
|
||||
tags: ["Remplace Gmail","🇨🇭 · open-source · OpenPGP"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une boîte mail chiffrée qui remplace Gmail ou Outlook — et le compte pivot de tout l'écosystème Proton.
|
||||
|
||||
## why
|
||||
|
||||
Basée en Suisse, hors juridiction des « Five Eyes ». Compatible OpenPGP : le chiffrement est automatique entre comptes Proton et vers les autres services PGP. Ton courrier, c'est ta correspondance — pas une matière première publicitaire.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde. C'est la meilleure porte de sortie de Google : ouvre le compte, le reste de la suite (agenda, drive, VPN) suit tout seul.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Crée un compte sur <b>proton.me</b> (l'offre gratuite suffit largement pour commencer).</li>
|
||||
<li>Rapatrie tes anciens messages et contacts avec <b>Easy Switch</b> (intégré).</li>
|
||||
<li>Mets une redirection depuis Gmail et préviens tes contacts de ta nouvelle adresse.</li>
|
||||
<li>Installe l'application mobile, active la <b>double authentification</b> — et Proton Bridge si tu tiens à Thunderbird.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "Proton Pass"
|
||||
slug: "protonpass"
|
||||
category: "motsdepasse"
|
||||
difficulty: "beginner"
|
||||
url: "https://proton.me/pass"
|
||||
color: "#6d4aff"
|
||||
monogram: "Pp"
|
||||
tags: ["Avec alias e-mail","🇨🇭 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Le gestionnaire de mots de passe de l'écosystème Proton, avec des alias e-mail jetables
|
||||
intégrés.
|
||||
|
||||
## why
|
||||
|
||||
Idéal si vous êtes déjà chez Proton : un seul compte pour le mail, le cloud et les mots de
|
||||
passe. Ses alias e-mail vous évitent de donner votre vraie adresse partout.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent tout regrouper chez Proton.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: "Proton VPN"
|
||||
slug: "protonvpn"
|
||||
category: "vpn"
|
||||
difficulty: "beginner"
|
||||
url: "https://protonvpn.com"
|
||||
color: "#6d4aff"
|
||||
monogram: "Pv"
|
||||
iconSlug: "protonvpn"
|
||||
tags: ["Offre gratuite honnête","🇨🇭 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Le VPN de l'écosystème Proton, avec une véritable offre gratuite (rare et honnête).
|
||||
|
||||
## why
|
||||
|
||||
Basé en Suisse, audité, open-source. Son offre gratuite est sans publicité, sans revente de
|
||||
données et sans limite de volume (le nombre de pays est simplement réduit). C'est la porte
|
||||
d'entrée idéale pour un débutant, surtout si vous utilisez déjà Proton Mail.
|
||||
|
||||
## who
|
||||
|
||||
Débutants, et toute personne déjà dans l'écosystème Proton qui veut un seul compte pour tout.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Rendez-vous sur <b>protonvpn.com</b> et connectez-vous avec votre compte Proton (ou créez-en
|
||||
un).
|
||||
</li>
|
||||
<li>Installez l'application (Windows, macOS, Linux, Android, iOS).</li>
|
||||
<li>
|
||||
Utilisez « Quick Connect » ou choisissez un pays, puis activez le kill switch et NetShield
|
||||
(blocage des pubs et traqueurs).
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: "Quad9"
|
||||
slug: "quad9"
|
||||
category: "dns"
|
||||
difficulty: "beginner"
|
||||
url: "https://quad9.net"
|
||||
color: "#1a5fb4"
|
||||
monogram: "9"
|
||||
iconSlug: "quad9"
|
||||
tags: ["Anti-maliciel","🇨🇭 à but non lucratif"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un résolveur DNS chiffré, suisse et à but non lucratif, qui bloque en plus les domaines malveillants connus.
|
||||
|
||||
## why
|
||||
|
||||
Ton fournisseur d'accès voit chaque site que tu visites via le DNS. Quad9 chiffre ces requêtes, ne conserve pas ton adresse IP, et te protège de l'hameçonnage au passage. Un réglage « fais-le et oublie-le ».
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde — surtout si tu veux un gain réel sans rien installer de nouveau.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Sur Android : Réglages > Réseau > <b>DNS privé</b> > saisis <b>dns.quad9.net</b>.</li>
|
||||
<li>Sur iPhone/Mac : installe le profil DoH depuis quad9.net. Sur PC : configure le DNS-over-HTTPS dans le navigateur ou le système.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: "Qubes OS · postmarketOS"
|
||||
slug: "qubes"
|
||||
category: "os"
|
||||
difficulty: "advanced"
|
||||
url: "https://www.qubes-os.org"
|
||||
color: "#3874d8"
|
||||
monogram: "Qb"
|
||||
iconSlug: "qubesos"
|
||||
tags: ["Cloisonnement","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Deux systèmes de niche : Qubes cloisonne votre PC en machines virtuelles étanches ; postmarketOS
|
||||
fait tourner du Linux sur d'anciens téléphones.
|
||||
|
||||
## why
|
||||
|
||||
Qubes isole chaque activité (travail, banque, navigation risquée) dans son propre compartiment :
|
||||
une compromission n'atteint pas le reste. postmarketOS prolonge la vie de téléphones abandonnés
|
||||
par leur constructeur.
|
||||
|
||||
## who
|
||||
|
||||
Utilisateurs experts avec un modèle de menace très élevé.
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "DuckDuckGo · Brave Search · SearXNG"
|
||||
slug: "search"
|
||||
category: "navigateur"
|
||||
difficulty: "beginner"
|
||||
url: "https://duckduckgo.com"
|
||||
color: "#de5833"
|
||||
monogram: "🔎"
|
||||
iconSlug: "duckduckgo"
|
||||
tags: ["Remplace Google Search"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des moteurs de recherche qui ne profilent pas chaque requête, contrairement à Google.
|
||||
|
||||
## why
|
||||
|
||||
DuckDuckGo et Brave Search ne conservent pas d'historique lié à votre identité. Startpage vous
|
||||
sert des résultats Google sans le pistage. SearXNG va plus loin : c'est un métamoteur{' '}
|
||||
<b>auto-hébergeable</b>, la souveraineté jusque dans la barre de recherche.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde. SearXNG vise ceux qui veulent héberger leur propre moteur.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Dans les réglages de votre navigateur, changez le moteur par défaut pour DuckDuckGo, Brave
|
||||
Search ou Startpage.
|
||||
</li>
|
||||
<li>
|
||||
Pour SearXNG : utilisez une instance publique (annuaire sur searx.space) ou hébergez la vôtre
|
||||
(voir section 10).
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: "Session"
|
||||
slug: "session"
|
||||
category: "messagerie"
|
||||
difficulty: "intermediate"
|
||||
license: "GPL-3.0"
|
||||
url: "https://getsession.org"
|
||||
color: "#178a5a"
|
||||
monogram: "Se"
|
||||
iconSlug: "session"
|
||||
tags: ["Sans numéro","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un chiffrement à la Signal, mais sans numéro de téléphone et avec un routage en oignon.
|
||||
|
||||
## why
|
||||
|
||||
Votre identité est un « Session ID » aléatoire. Le trafic passe par un réseau décentralisé
|
||||
(Lokinet) qui réduit fortement les métadonnées.
|
||||
|
||||
## who
|
||||
|
||||
Quand un numéro de téléphone est un risque. Écosystème plus petit, à réserver aux échanges qui
|
||||
comptent.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez depuis <b>getsession.org</b> (toutes plateformes).
|
||||
</li>
|
||||
<li>
|
||||
« Create account » génère votre Session ID et une <b>phrase de récupération</b>.
|
||||
</li>
|
||||
<li>Notez la phrase de récupération sur papier : c'est la seule clé de votre compte.</li>
|
||||
<li>Partagez votre Session ID (ou QR) à vos contacts.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: "Signal"
|
||||
slug: "signal"
|
||||
category: "messagerie"
|
||||
difficulty: "beginner"
|
||||
license: "AGPL-3.0"
|
||||
url: "https://signal.org"
|
||||
color: "#3a76f0"
|
||||
monogram: "S"
|
||||
iconSlug: "signal"
|
||||
tags: ["Remplace WhatsApp","🇺🇸 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une messagerie chiffrée pour tes textos, appels, visios et groupes. C'est le remplaçant direct de WhatsApp — aussi simple, sans Meta derrière.
|
||||
|
||||
## why
|
||||
|
||||
Chiffrement de bout en bout par défaut, à but non lucratif, protocole audité qui sert de référence mondiale. Presque aucune métadonnée gardée, et l'équipe a promis de quitter l'UE plutôt que d'installer un scan. Chaque proche que tu fais basculer, c'est une conversation de plus qui sort de la surveillance.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde, dès aujourd'hui. C'est le premier geste, et le plus utile : commence par ton groupe de famille. Seule contrainte : un numéro de téléphone — que tu peux cacher derrière un nom d'utilisateur.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Installe depuis <b>signal.org</b> (App Store, Google Play, ou l'APK direct sur Android).</li>
|
||||
<li>Confirme ton numéro par SMS, puis choisis un code PIN.</li>
|
||||
<li>Réglages > Confidentialité : crée un <b>nom d'utilisateur</b> pour cacher ton numéro, et active le <b>verrou d'inscription</b>.</li>
|
||||
<li>Invite tes proches — le groupe famille d'abord. Sur ordinateur, lie l'application de bureau à ton téléphone.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: "SimpleX Chat"
|
||||
slug: "simplex"
|
||||
category: "messagerie"
|
||||
difficulty: "intermediate"
|
||||
url: "https://simplex.chat"
|
||||
color: "#1e63d0"
|
||||
monogram: "SX"
|
||||
iconSlug: "simplex"
|
||||
tags: ["Sans identifiant","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une messagerie chiffrée sans aucun compte, sans numéro et sans identifiant. On se connecte en
|
||||
partageant un lien ou un QR code.
|
||||
|
||||
## why
|
||||
|
||||
Par conception, même les serveurs ignorent qui parle à qui. C'est aujourd'hui l'option la plus
|
||||
protectrice contre la corrélation des métadonnées.
|
||||
|
||||
## who
|
||||
|
||||
Comptes pseudonymes, contacts sensibles, haut risque. Un peu plus jeune que Signal, avec
|
||||
quelques aspérités.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez depuis <b>simplex.chat</b> (F-Droid, Google Play, App Store ou APK).
|
||||
</li>
|
||||
<li>
|
||||
Choisissez un nom d'affichage <b>local</b> (jamais votre vrai nom : il ne quitte pas votre
|
||||
appareil).
|
||||
</li>
|
||||
<li>
|
||||
Pour ajouter un contact, partagez un <b>lien d'invitation à usage unique</b> ou un QR code.
|
||||
</li>
|
||||
<li>Activez le verrou par code, et (avancé) configurez vos propres serveurs SMP.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: "Matrix Synapse"
|
||||
slug: "synapse"
|
||||
category: "selfhost"
|
||||
difficulty: "advanced"
|
||||
license: "AGPL-3.0"
|
||||
url: "https://element.io/server"
|
||||
color: "#0dbd8b"
|
||||
monogram: "Mx"
|
||||
iconSlug: "matrix"
|
||||
tags: ["Votre serveur de chat","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Votre propre serveur de messagerie Matrix, sur lequel tournent Element et les appels chiffrés.
|
||||
|
||||
## why
|
||||
|
||||
En hébergeant le serveur, vous contrôlez aussi les <b>métadonnées</b> (qui parle à qui, quand),
|
||||
le point faible de Matrix en fédération. C'est la messagerie communautaire dont vous êtes le
|
||||
seul maître.
|
||||
|
||||
## who
|
||||
|
||||
Communautés, collectifs, rédactions qui veulent leur espace fédéré indépendant.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: "Tails"
|
||||
slug: "tails"
|
||||
category: "os"
|
||||
difficulty: "advanced"
|
||||
license: "GPL-3.0"
|
||||
url: "https://tails.net"
|
||||
color: "#56347c"
|
||||
monogram: "Ta"
|
||||
iconSlug: "tails"
|
||||
tags: ["Clé USB amnésique","🌍 · tout via Tor"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un système qui démarre depuis une clé USB, fait passer tout le trafic par Tor et ne laisse{' '}
|
||||
<b>aucune trace</b> à l'extinction.
|
||||
|
||||
## why
|
||||
|
||||
À l'arrêt, tout est oublié : c'est « amnésique ». Idéal pour un travail sensible et ponctuel sur
|
||||
un ordinateur qui n'est pas le vôtre, sans rien y laisser.
|
||||
|
||||
## who
|
||||
|
||||
Lanceurs d'alerte, journalistes, sources. L'outil de référence pour les missions à haut risque.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Téléchargez Tails sur <b>tails.net</b> et suivez l'assistant pour créer la clé USB.
|
||||
</li>
|
||||
<li>Redémarrez l'ordinateur sur cette clé. Utilisez-le, puis éteignez : tout disparaît.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: "Tailscale · Headscale · WireGuard"
|
||||
slug: "tailscale"
|
||||
category: "vpn"
|
||||
difficulty: "advanced"
|
||||
license: "BSD-3-Clause"
|
||||
url: "https://tailscale.com"
|
||||
color: "#242424"
|
||||
monogram: "Ts"
|
||||
iconSlug: "tailscale"
|
||||
tags: ["Accès privé à son serveur","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un réseau privé chiffré qui relie vos appareils à votre serveur, sans jamais l'exposer sur
|
||||
l'Internet public.
|
||||
|
||||
## why
|
||||
|
||||
Au lieu d'ouvrir des ports (et de vous faire attaquer), <b>Tailscale</b> crée un tunnel
|
||||
WireGuard entre vos seuls appareils autorisés : votre serveur n'a aucune surface d'attaque
|
||||
publique. <b>Headscale</b> est la version que vous hébergez vous-même, pour ne dépendre d'aucun
|
||||
tiers. <b>WireGuard</b> seul offre le contrôle total, au prix d'une configuration manuelle.
|
||||
|
||||
## who
|
||||
|
||||
Tout auto-hébergeur. C'est la façon sûre d'atteindre son Nextcloud ou ses photos depuis
|
||||
l'extérieur.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Installez Tailscale sur votre serveur et sur votre téléphone/PC, connectez-les au même compte.
|
||||
</li>
|
||||
<li>
|
||||
Vos appareils se voient aussitôt sur un réseau privé ; accédez à votre serveur par son adresse
|
||||
Tailscale.
|
||||
</li>
|
||||
<li>Pour zéro dépendance, remplacez le serveur de coordination par Headscale, auto-hébergé.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: "Tor Browser"
|
||||
slug: "tor"
|
||||
category: "tor"
|
||||
difficulty: "advanced"
|
||||
license: "BSD-3-Clause"
|
||||
url: "https://www.torproject.org"
|
||||
color: "#7d4698"
|
||||
monogram: "Tor"
|
||||
iconSlug: "torbrowser"
|
||||
tags: ["Anonymat réseau","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un réseau qui sépare qui vous êtes de ce que vous faites en ligne, accessible via le Tor
|
||||
Browser.
|
||||
|
||||
## why
|
||||
|
||||
Votre trafic rebondit à travers plusieurs relais chiffrés dans le monde : aucun ne connaît à la
|
||||
fois votre identité et votre destination. C'est l'outil des journalistes et des sources, et le
|
||||
moyen d'atteindre un site bloqué (par exemple pour télécharger un VPN censuré).
|
||||
|
||||
## who
|
||||
|
||||
Profils à haut risque, et quiconque doit dissocier son activité de son adresse IP réelle. À
|
||||
utiliser ponctuellement, pas comme navigateur de tous les jours.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Téléchargez le Tor Browser sur <b>torproject.org</b> (Windows, macOS, Linux, Android).
|
||||
</li>
|
||||
<li>
|
||||
Lancez-le et cliquez « Se connecter ». Si Tor est bloqué dans votre pays, activez un « pont »
|
||||
(bridge).
|
||||
</li>
|
||||
<li>
|
||||
Naviguez sans maximiser la fenêtre, sans installer d'extension, et{' '}
|
||||
<b>sans vous connecter à vos vrais comptes</b>.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: "Tuta"
|
||||
slug: "tuta"
|
||||
category: "email"
|
||||
difficulty: "beginner"
|
||||
license: "GPL-3.0"
|
||||
url: "https://tuta.com"
|
||||
color: "#b01e2e"
|
||||
monogram: "Tu"
|
||||
iconSlug: "tuta"
|
||||
tags: ["Remplace Gmail","🇩🇪 · open-source · post-quantique"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une messagerie e-mail allemande, entièrement open-source et sans aucun service Google.
|
||||
|
||||
## why
|
||||
|
||||
Elle chiffre aussi <b>l'objet et une partie des métadonnées</b>, avec un chiffrement résistant à
|
||||
l'informatique quantique. Juridiction UE.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent le maximum de métadonnées chiffrées et du 100 % libre. Elle n'utilise pas PGP :
|
||||
pour écrire chiffré à l'extérieur, on protège le message par mot de passe.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Créez un compte sur <b>tuta.com</b> et installez l'application (disponible sur F-Droid).
|
||||
</li>
|
||||
<li>
|
||||
Pour écrire à un non-utilisateur de façon chiffrée : cliquez sur le cadenas et définissez un
|
||||
mot de passe, transmis à votre correspondant par un autre canal.
|
||||
</li>
|
||||
<li>Activez la double authentification.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: "uBlock Origin"
|
||||
slug: "ublock"
|
||||
category: "navigateur"
|
||||
difficulty: "beginner"
|
||||
url: "https://ublockorigin.com"
|
||||
color: "#7a0d0d"
|
||||
monogram: "uB"
|
||||
iconSlug: "ublockorigin"
|
||||
tags: ["Extension","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
L'extension qui bloque publicités, traqueurs et scripts espions. Le geste le plus rentable de tout ce guide : dix secondes, effet immédiat.
|
||||
|
||||
## why
|
||||
|
||||
La publicité en ligne est le principal vecteur de surveillance et de profilage. La bloquer, c'est couper l'essentiel du pistage — et au passage tes pages chargent plus vite et ton forfait data respire.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde, sur Firefox comme sur les navigateurs Chromium. Si tu ne fais qu'un seul geste aujourd'hui, fais celui-là.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Ouvre le magasin d'extensions de ton navigateur et cherche « uBlock Origin » (l'original, par Raymond Hill).</li>
|
||||
<li>Installe-le. Il travaille aussitôt, sans aucun réglage.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: "Jitsi Meet · Element Call"
|
||||
slug: "visio"
|
||||
category: "boiteaoutils"
|
||||
difficulty: "beginner"
|
||||
url: "https://jitsi.org"
|
||||
color: "#1d6fb8"
|
||||
monogram: "Vi"
|
||||
iconSlug: "jitsi"
|
||||
tags: ["Remplace Zoom / Meet","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des outils de visioconférence sans compte ni installation lourde, pour remplacer Zoom, Google
|
||||
Meet ou Teams.
|
||||
|
||||
## why
|
||||
|
||||
<b>Jitsi Meet</b> se lance dans le navigateur, sans compte, et peut être auto-hébergé (c'est
|
||||
aussi la base de Brave Talk). <b>Element Call</b> est chiffré de bout en bout et fédéré via
|
||||
Matrix. Pour un appel simple et totalement chiffré, les appels <b>Signal</b> font aussi le
|
||||
travail.
|
||||
|
||||
## who
|
||||
|
||||
Tout le monde. Sur un serveur Jitsi public, les appels à plusieurs sont chiffrés en transport ;
|
||||
le chiffrement de bout en bout est en option.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Jitsi : allez sur meet.jit.si, créez un nom de salon, partagez le lien. Rien à installer.
|
||||
</li>
|
||||
<li>Element Call : depuis l'application Element (Matrix), lancez un appel dans un salon.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: "Votre propre site web"
|
||||
slug: "website"
|
||||
category: "selfhost"
|
||||
difficulty: "intermediate"
|
||||
url: "https://astro.build"
|
||||
color: "#7a4ddb"
|
||||
monogram: "www"
|
||||
tags: ["Résister au bannissement"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Un site à vous, sur votre nom de domaine, où votre contenu ne dépend d'aucune plateforme.
|
||||
|
||||
## why
|
||||
|
||||
Le jour où un réseau supprime ou suspend votre compte, tout votre travail disparaît. Un site
|
||||
personnel est votre point d'ancrage : vos articles y restent, archivés et à jour, quoi qu'il
|
||||
arrive. C'est exactement ce que font les comptes d'information prudents. Un site statique
|
||||
(généré par Hugo, Astro ou Jekyll) suffit et se publie presque gratuitement ; pour un blog
|
||||
dynamique, un WordPress ou un Ghost auto-hébergé fait l'affaire.
|
||||
|
||||
## who
|
||||
|
||||
Comptes d'information, créateurs, militants, quiconque publie et craint la censure de
|
||||
plateforme.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Achetez un nom de domaine (idéalement chez un registraire respectueux de la vie privée).
|
||||
</li>
|
||||
<li>
|
||||
Choisissez un générateur de site statique (Astro, Hugo) et hébergez le résultat, ou installez
|
||||
WordPress/Ghost sur votre serveur.
|
||||
</li>
|
||||
<li>
|
||||
Renvoyez-y systématiquement depuis vos réseaux : votre audience vous retrouve même si un
|
||||
compte tombe.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: "YubiKey · Nitrokey"
|
||||
slug: "yubikey"
|
||||
category: "deuxfa"
|
||||
difficulty: "intermediate"
|
||||
url: "https://www.yubico.com"
|
||||
color: "#84bd00"
|
||||
monogram: "Yk"
|
||||
iconSlug: "yubico"
|
||||
tags: ["Clé matérielle FIDO2"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Une petite clé physique (format USB, souvent avec NFC) qui prouve votre identité d'un simple
|
||||
contact du doigt.
|
||||
|
||||
## why
|
||||
|
||||
C'est la 2FA la plus solide : elle résiste à l'hameçonnage, car la clé vérifie l'adresse réelle
|
||||
du site avant de répondre. <b>Nitrokey</b> est l'alternative à matériel et micrologiciel
|
||||
entièrement ouverts. Un faux site ne peut pas vous piéger.
|
||||
|
||||
## who
|
||||
|
||||
Ceux qui veulent le maximum de sécurité sur leurs comptes clés. Achetez-en <b>deux</b> (une
|
||||
principale, une de secours).
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>Procurez-vous deux clés sur yubico.com ou nitrokey.com.</li>
|
||||
<li>
|
||||
Dans les réglages de sécurité de chaque compte (e-mail, gestionnaire de mots de passe…),
|
||||
ajoutez une « clé de sécurité » ou « passkey ». Enregistrez vos deux clés.
|
||||
</li>
|
||||
<li>Gardez la clé de secours dans un lieu sûr, séparé.</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: "YunoHost · Umbrel · Start9"
|
||||
slug: "yunohost"
|
||||
category: "selfhost"
|
||||
difficulty: "advanced"
|
||||
license: "AGPL-3.0"
|
||||
url: "https://yunohost.org"
|
||||
color: "#e29100"
|
||||
monogram: "Yh"
|
||||
tags: ["Serveur clé en main","🌍 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
|
||||
Des systèmes qui transforment un vieux PC ou un Raspberry Pi en serveur personnel, avec un
|
||||
catalogue d'applications à installer en quelques clics.
|
||||
|
||||
## why
|
||||
|
||||
L'auto-hébergement fait peur, mais ces outils font le gros du travail. <b>YunoHost</b> gère même
|
||||
votre propre e-mail et une authentification unique. <b>Umbrel</b> offre un magasin de plus de
|
||||
300 applications, très prisé des amateurs de vie privée et de Bitcoin. <b>Start9</b> chiffre les
|
||||
sauvegardes et donne une adresse Tor à chaque service par défaut.
|
||||
|
||||
## who
|
||||
|
||||
Les profils avancés prêts à consacrer un après-midi à monter leur propre cloud. C'est la parade
|
||||
structurelle la plus radicale à Chat Control.
|
||||
|
||||
## install
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Récupérez un vieil ordinateur, un Raspberry Pi, ou louez un petit serveur (VPS) dans un pays
|
||||
protecteur.
|
||||
</li>
|
||||
<li>Installez YunoHost, Umbrel ou Start9 en suivant leur guide officiel.</li>
|
||||
<li>Depuis le catalogue, installez Nextcloud, un serveur Matrix, une galerie photo, etc.</li>
|
||||
<li>
|
||||
Accédez-y en privé avec Tailscale (section VPN) plutôt que d'exposer le serveur au public.
|
||||
</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"bands": [
|
||||
{
|
||||
"id": "exposed",
|
||||
"min": 0,
|
||||
"max": 24,
|
||||
"title": "Exposé",
|
||||
"summary": "Ta pile est encore très dépendante des grandes plateformes. Les premières étapes sont simples et à fort impact."
|
||||
},
|
||||
{
|
||||
"id": "awakening",
|
||||
"min": 25,
|
||||
"max": 49,
|
||||
"title": "Éveil",
|
||||
"summary": "Tu as commencé à diversifier tes outils. Quelques changements bien choisis feraient une vraie différence."
|
||||
},
|
||||
{
|
||||
"id": "resistant",
|
||||
"min": 50,
|
||||
"max": 74,
|
||||
"title": "Résistant",
|
||||
"summary": "Ta configuration est déjà sérieuse. Tu as une vraie base de résistance à la censure et à la surveillance."
|
||||
},
|
||||
{
|
||||
"id": "hardened",
|
||||
"min": 75,
|
||||
"max": 89,
|
||||
"title": "Durci",
|
||||
"summary": "Tu as une pile plus dure et un socle pseudonyme solide. L'objectif devient la discipline et la séparation des identités."
|
||||
},
|
||||
{
|
||||
"id": "sovereign",
|
||||
"min": 90,
|
||||
"max": 100,
|
||||
"title": "Souverain",
|
||||
"summary": "Ta posture est déjà très robuste. Tu es proche d'une forte souveraineté numérique, avec des choix techniques exigeants."
|
||||
}
|
||||
],
|
||||
"questions": [
|
||||
{
|
||||
"id": "messaging",
|
||||
"category": "messagerie",
|
||||
"label": "Messagerie",
|
||||
"prompt": "Comment échanges-tu le plus souvent avec tes proches ?",
|
||||
"rec": "Bascule tes conversations sensibles vers Signal, SimpleX ou Session.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "WhatsApp / Messenger / SMS", "hint": "Les métadonnées et les plateformes centralisées restent le point faible." },
|
||||
{ "points": 2, "label": "Telegram pour la plupart des conversations", "hint": "Mieux que les grands réseaux, mais la confidentialité reste limitée." },
|
||||
{ "points": 6, "label": "Signal ou Molly pour la plupart des échanges", "hint": "C'est déjà une bonne base pour la résistance à la censure." },
|
||||
{ "points": 10, "label": "SimpleX / Session / Matrix pour les usages sensibles", "hint": "Moins de dépendance au numéro de téléphone et à la plateforme." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "email",
|
||||
"category": "email",
|
||||
"label": "E-mail",
|
||||
"prompt": "Quel service utilises-tu le plus pour tes e-mails ?",
|
||||
"rec": "Utilise Proton Mail ou Tuta, et ajoute PGP pour les contacts qui comptent.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Gmail / Outlook / iCloud Mail", "hint": "Le stockage et l'accès au contenu restent très centralisés." },
|
||||
{ "points": 5, "label": "Proton Mail ou Tuta au quotidien", "hint": "Déjà une option plus sérieuse pour la confidentialité." },
|
||||
{ "points": 7, "label": "Proton / Tuta + PGP pour certains contacts", "hint": "Un bon niveau de résistance si tu es régulier·ère." },
|
||||
{ "points": 10, "label": "PGP / OpenPGP régulier et attention aux métadonnées", "hint": "Une posture beaucoup plus robuste." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "browser",
|
||||
"category": "navigateur",
|
||||
"label": "Navigateur & recherche",
|
||||
"prompt": "Quels navigateur et moteur de recherche utilises-tu le plus ?",
|
||||
"rec": "Quitte Chrome + Google pour un navigateur et un moteur respectueux de la vie privée.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Chrome + Google", "hint": "Confortable, mais fortement traçable." },
|
||||
{ "points": 5, "label": "Firefox ou Brave avec un moteur privé", "hint": "Un vrai pas en avant pour la vie privée." },
|
||||
{ "points": 7, "label": "Brave / Firefox + DuckDuckGo / Startpage / SearXNG", "hint": "C'est déjà une bonne base quotidienne." },
|
||||
{ "points": 10, "label": "Mullvad Browser / LibreWolf / Tor Browser selon le contexte", "hint": "Une posture plus sérieuse face à la surveillance." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dns",
|
||||
"category": "dns",
|
||||
"label": "DNS",
|
||||
"prompt": "Comment résous-tu les noms de domaine ?",
|
||||
"rec": "Passe à un DNS chiffré avec un résolveur minimaliste et respectueux.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Le DNS de ton FAI ou de ta box", "hint": "Le plus simple, mais souvent le moins privé." },
|
||||
{ "points": 4, "label": "Un DNS chiffré chez un fournisseur grand public", "hint": "Un bon premier pas." },
|
||||
{ "points": 7, "label": "Quad9 / Mullvad DNS / NextDNS", "hint": "Une vraie amélioration pour limiter la traçabilité." },
|
||||
{ "points": 10, "label": "DNS chiffré + stratégie anti-tracking assumée", "hint": "Une posture plus consciente et plus robuste." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "vpn",
|
||||
"category": "vpn",
|
||||
"label": "VPN",
|
||||
"prompt": "Quel type de VPN utilises-tu ?",
|
||||
"rec": "Choisis un VPN honnête sans journalisation : Mullvad, Proton VPN ou IVPN.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Pas de VPN", "hint": "Le cas le plus exposé pour la traçabilité réseau." },
|
||||
{ "points": 2, "label": "Un VPN gratuit ou douteux", "hint": "Parfois pire que rien si le fournisseur est opaque." },
|
||||
{ "points": 7, "label": "Un VPN honnête, no-log, avec une vraie politique", "hint": "Une vraie amélioration pour la confidentialité." },
|
||||
{ "points": 10, "label": "Mullvad / Proton VPN / IVPN au quotidien", "hint": "Une posture plus sérieuse et cohérente." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "passwords",
|
||||
"category": "motsdepasse",
|
||||
"label": "Mots de passe",
|
||||
"prompt": "Comment gères-tu tes mots de passe ?",
|
||||
"rec": "Adopte un gestionnaire de mots de passe avec des mots de passe uniques et longs.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Mots de passe réutilisés ou stockés dans le navigateur", "hint": "Risque élevé en cas de fuite ou de compromission." },
|
||||
{ "points": 5, "label": "Un gestionnaire de mots de passe basique", "hint": "Déjà un très bon pas en avant." },
|
||||
{ "points": 7, "label": "Bitwarden / KeePassXC / Proton Pass", "hint": "Une posture saine, simple à maintenir." },
|
||||
{ "points": 10, "label": "Gestionnaire + mots de passe uniques et longs", "hint": "Le niveau le plus solide pour limiter les dégâts." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "twofa",
|
||||
"category": "deuxfa",
|
||||
"label": "Double authentification",
|
||||
"prompt": "Quel niveau de double authentification utilises-tu ?",
|
||||
"rec": "Passe la 2FA sur une application, ou mieux, une clé matérielle.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Pas de 2FA", "hint": "Le plus faible niveau de protection des comptes." },
|
||||
{ "points": 2, "label": "SMS ou appel", "hint": "Mieux que rien, mais très fragile." },
|
||||
{ "points": 6, "label": "TOTP sur une application (Aegis / Ente Auth)", "hint": "Une bonne protection au quotidien." },
|
||||
{ "points": 10, "label": "Clé matérielle ou 2FA résistante au phishing", "hint": "Le meilleur niveau de résistance pratique." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "storage",
|
||||
"category": "stockage",
|
||||
"label": "Stockage",
|
||||
"prompt": "Où stockes-tu tes fichiers sensibles ?",
|
||||
"rec": "Déplace tes fichiers sensibles vers Proton Drive, Cryptomator ou un stockage local chiffré.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Google Drive / iCloud / OneDrive", "hint": "Très pratique, mais centralisé." },
|
||||
{ "points": 5, "label": "Proton Drive ou un stockage chiffré de base", "hint": "Une vraie amélioration." },
|
||||
{ "points": 7, "label": "Cryptomator ou un stockage local chiffré", "hint": "Une posture plus robuste." },
|
||||
{ "points": 10, "label": "Stockage local + auto-hébergement / chiffrement avancé", "hint": "Le niveau le plus sérieux pour la souveraineté." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "social",
|
||||
"category": "social",
|
||||
"label": "Réseaux sociaux",
|
||||
"prompt": "Où passes-tu l'essentiel de ta vie sociale en ligne ?",
|
||||
"rec": "Ancre ta présence sur des réseaux décentralisés et réduis la dépendance aux plateformes.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Meta / X / grands réseaux uniquement", "hint": "Le plus simple, mais le plus exposé aux pressions." },
|
||||
{ "points": 5, "label": "Mastodon / Matrix / Nostr de façon ponctuelle", "hint": "Une diversification utile." },
|
||||
{ "points": 7, "label": "Un mix de réseaux décentralisés et de contacts directs", "hint": "Une posture plus indépendante." },
|
||||
{ "points": 10, "label": "Réseaux alternatifs et faible dépendance aux plateformes", "hint": "C'est la vraie logique de résistance." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "os",
|
||||
"category": "os",
|
||||
"label": "Système d'exploitation",
|
||||
"prompt": "Quel système d'exploitation utilises-tu le plus ?",
|
||||
"rec": "Évolue vers GrapheneOS sur mobile et Linux sur l'ordinateur.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Android / iOS / Windows standard", "hint": "Très pratique, mais beaucoup moins respectueux de la vie privée." },
|
||||
{ "points": 5, "label": "Un Android plus privé / Linux / macOS", "hint": "Déjà un bon progrès." },
|
||||
{ "points": 8, "label": "GrapheneOS / Linux / BSD", "hint": "Une base plus sérieuse." },
|
||||
{ "points": 10, "label": "GrapheneOS + Linux + discipline d'installation", "hint": "Déjà une posture très forte." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "tor",
|
||||
"category": "tor",
|
||||
"label": "Tor & anonymat",
|
||||
"prompt": "Dans quelle mesure utilises-tu Tor / Tails / l'anonymat ?",
|
||||
"rec": "Prends l'habitude de Tor (et de Tails au besoin) pour tes tâches les plus sensibles.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Jamais ou presque jamais", "hint": "Très exposé si la menace devient sérieuse." },
|
||||
{ "points": 3, "label": "De temps en temps, sans discipline", "hint": "Un premier pas, mais encore fragile." },
|
||||
{ "points": 6, "label": "Tor pour certaines tâches sensibles", "hint": "Déjà plus sérieux." },
|
||||
{ "points": 10, "label": "Tor + Tails avec une discipline forte", "hint": "Le niveau le plus adapté à une menace élevée." }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "money",
|
||||
"category": "argent",
|
||||
"label": "Argent",
|
||||
"prompt": "Comment gères-tu ton argent numérique ?",
|
||||
"rec": "Ajoute des moyens de paiement plus privés et sépare tes identités quand c'est possible.",
|
||||
"options": [
|
||||
{ "points": 0, "label": "Cartes bancaires et comptes standards uniquement", "hint": "La traçabilité est forte." },
|
||||
{ "points": 4, "label": "Quelques outils de paiement plus privés", "hint": "Un premier effort de séparation." },
|
||||
{ "points": 6, "label": "Un mix de comptes privés et de crypto limitée", "hint": "Déjà plus réfléchi." },
|
||||
{ "points": 10, "label": "Pratiques de souveraineté financière plus fortes", "hint": "Une posture beaucoup plus sérieuse." }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
# Local development only — NOT what production deploys.
|
||||
# docker compose -f docker-compose.dev.yml up dev # HMR on :4321
|
||||
# docker compose -f docker-compose.dev.yml up preview # prod-like on :8080
|
||||
services:
|
||||
dev:
|
||||
image: node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2
|
||||
working_dir: /app
|
||||
command: sh -c "corepack enable && pnpm install --frozen-lockfile && pnpm dev --host"
|
||||
ports:
|
||||
- '4321:4321'
|
||||
volumes:
|
||||
- .:/app
|
||||
- node_modules:/app/node_modules
|
||||
environment:
|
||||
- ASTRO_TELEMETRY_DISABLED=1
|
||||
|
||||
preview:
|
||||
build: .
|
||||
ports:
|
||||
- '8080:80'
|
||||
|
||||
volumes:
|
||||
node_modules:
|
||||
@@ -1,10 +0,0 @@
|
||||
# Production compose (what Coolify deploys): one service, the static site
|
||||
# built by the multi-stage Dockerfile and served by hardened nginx on port
|
||||
# 80 (EXPOSEd by the Dockerfile). No ports/expose/networks here: the
|
||||
# platform's reverse proxy (Traefik) routes to the container from the
|
||||
# domain assigned in Coolify. For local development use
|
||||
# docker-compose.dev.yml instead.
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
restart: always
|
||||
@@ -1 +0,0 @@
|
||||
add_header Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-APKfv1xaOELs5yz+tPQqjel8CVdobT1z0n9rysaGXPk=' 'sha256-FaYmk1uHh+UNUdWrZIkUBDinPxk/ARkHrA23xUfa/Gk=' 'sha256-8UX5i4mkZDhNhuSxNOdkip2H+FxRXqR708bF3BQPnko=' 'sha256-KU52uW0NoYJbkMOy2EcHza0G3yVB1nScn+wH44Buzr4=' 'sha256-4h+PBVSAvnFY4ecAonGUp9Ne4aHhAuAU8je+PqVl6I4=' 'sha256-J7fub090nAsxTSG8BOZrqblL942lG2lnHuFfzZkky7o=' 'sha256-4hyaOQzqvLr9R6SuXkYh80AxSXJ0K9kC9zbii9v8DGY='; style-src 'self'; img-src 'self' data:; font-src 'self'; manifest-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'" always;
|
||||
@@ -1,27 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
charset utf-8;
|
||||
|
||||
gzip_static on;
|
||||
|
||||
error_page 404 /404.html;
|
||||
|
||||
# hashed build assets: cache forever
|
||||
location /_astro/ {
|
||||
include /etc/nginx/snippets/security-headers.conf;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable" always;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# everything else (HTML, sitemap, offline artifact): revalidate
|
||||
location / {
|
||||
include /etc/nginx/snippets/security-headers.conf;
|
||||
add_header Cache-Control "no-cache" always;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# Shared security headers. nginx's add_header does NOT inherit across
|
||||
# levels once a location adds its own header, so every location includes
|
||||
# this snippet explicitly.
|
||||
include /etc/nginx/snippets/csp.conf;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
||||
@@ -0,0 +1,66 @@
|
||||
# Piège Apache (o2switch) : « Index of /… » au lieu des pages
|
||||
|
||||
Symptôme : le site est déployé sur un hébergement mutualisé Apache (o2switch),
|
||||
la page d'accueil s'affiche, mais **cliquer sur un lien interne affiche
|
||||
« Index of /chatcontrol/quiz »** (un listing de dossier) au lieu de la page.
|
||||
|
||||
## Cause : conflit fichier / dossier
|
||||
|
||||
SvelteKit (adapter-static, `trailingSlash` par défaut = `'never'`) génère :
|
||||
|
||||
```
|
||||
build/
|
||||
├── quiz.html ← la page
|
||||
├── quiz/ ← dossier créé pour __data.json
|
||||
│ └── __data.json
|
||||
├── outils.html
|
||||
├── outils/
|
||||
│ └── …
|
||||
```
|
||||
|
||||
Quand le navigateur demande `/chatcontrol/quiz`, Apache voit qu'un **dossier**
|
||||
`quiz/` existe et redirige (301) vers `/chatcontrol/quiz/`. Comme ce dossier
|
||||
ne contient pas de `index.html`, Apache sert son **autoindex** (le listing).
|
||||
Le fichier `quiz.html`, lui, n'est jamais trouvé.
|
||||
|
||||
Apache donne toujours la priorité au dossier quand les deux existent —
|
||||
ce problème revient à chaque site statique posé sur du mutualisé Apache.
|
||||
|
||||
## Correctif (déjà appliqué dans ce dépôt)
|
||||
|
||||
`frontend/src/routes/+layout.ts` :
|
||||
|
||||
```ts
|
||||
export const trailingSlash = 'always'
|
||||
```
|
||||
|
||||
Chaque page est alors générée **dans** son dossier :
|
||||
|
||||
```
|
||||
build/
|
||||
├── quiz/
|
||||
│ ├── index.html ← la page, servie par Apache
|
||||
│ └── __data.json
|
||||
├── outils/
|
||||
│ ├── index.html
|
||||
│ └── aegis/
|
||||
│ └── index.html
|
||||
```
|
||||
|
||||
Plus de conflit possible : le dossier existe, il contient un `index.html`,
|
||||
Apache le sert.
|
||||
|
||||
## Checklist quand ça arrive
|
||||
|
||||
1. `export const trailingSlash = 'always'` dans le `+layout.ts` racine.
|
||||
2. `pnpm build` → vérifier que `build/quiz/index.html` existe
|
||||
(et non `build/quiz.html`).
|
||||
3. **Vider le dossier distant avant de re-uploader** : les anciens
|
||||
`quiz.html` / `outils.html` et les vieux assets `_app/immutable/` hashés
|
||||
doivent partir, sinon ils traînent indéfiniment.
|
||||
4. Tester `curl -s https://<site>/<page>/` → du HTML, pas « Index of ».
|
||||
|
||||
Note : les liens internes relatifs (`./outils`) provoquent une petite
|
||||
redirection 301 vers l'URL avec `/` final. Normal, invisible pour
|
||||
l'utilisateur. L'éviter exigerait `paths.relative: false`, au prix de la
|
||||
consultation locale des fichiers du build.
|
||||
@@ -0,0 +1,89 @@
|
||||
# Guide de rédaction — fiches d'outils FR/créole
|
||||
|
||||
## Format d'une fiche (`content/outils/<slug>.md`)
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: "Signal"
|
||||
slug: "signal"
|
||||
category: "messagerie" # slug d'une catégorie de content/categories.json
|
||||
difficulty: "beginner" # beginner | intermediate | advanced
|
||||
license: "AGPL-3.0" # identifiant SPDX exact (spdx.org/licenses)
|
||||
url: "https://signal.org"
|
||||
color: "#3a76f0" # couleur du monogramme (décorative)
|
||||
monogram: "S"
|
||||
tags: ["Remplace WhatsApp","🇺🇸 · open-source"]
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
## what
|
||||
À quoi sert l'outil, en deux phrases maximum.
|
||||
|
||||
## why
|
||||
Pourquoi il compte pour la souveraineté numérique.
|
||||
|
||||
## who
|
||||
Pour qui, et à quel moment du parcours.
|
||||
|
||||
## install
|
||||
<ol><li>Étapes concrètes, numérotées.</li></ol>
|
||||
```
|
||||
|
||||
Les valeurs du frontmatter sont encodées en JSON (guillemets doubles).
|
||||
Le corps accepte Markdown et HTML simple ; il est rendu au build, rien n'est
|
||||
interprété côté client. **Le build échoue si une fiche est invalide** — c'est
|
||||
le contrat de validation (ADR-001).
|
||||
|
||||
## Ton éditorial
|
||||
|
||||
- **Militant mais chaleureux, ancré Caraïbe.** Pas de langage corporate, pas
|
||||
de peur gratuite : on explique le geste, on donne le pouvoir d'agir.
|
||||
- Tutoiement. Phrases courtes. Le premier mot de chaque section porte le sens
|
||||
(motif en F, doctrine §1.1).
|
||||
- `what` dit le service rendu, `why` dit l'enjeu politique/technique, `who`
|
||||
donne la porte d'entrée (« commence ici si… »), `install` est actionnable
|
||||
sans autre lecture.
|
||||
- Exemples et localisation ancrés territoire — jamais de Lorem ipsum
|
||||
hexagonal (doctrine §4.2).
|
||||
|
||||
### Fiches de référence pour le ton
|
||||
|
||||
Six fiches sont réécrites au registre OKI et servent de modèle : `signal`,
|
||||
`protonmail`, `brave`, `bitwarden`, `ublock`, `quad9`. Avant d'écrire ou de
|
||||
réviser une fiche, relis-en deux. Ce qui change par rapport au ton d'origine :
|
||||
tutoiement systématique, le geste avant la technique (« dix secondes, effet
|
||||
immédiat »), l'enjeu politique dit sans détour (« ta correspondance — pas une
|
||||
matière première publicitaire »), et un ancrage collectif (« commence par ton
|
||||
groupe de famille »).
|
||||
|
||||
## Créole guadeloupéen (gcf)
|
||||
|
||||
- Les **micro-textes de l'interface** (boutons, filtres, états vides, marqueur
|
||||
de fin) vivent dans `frontend/src/lib/i18n/gcf.json`. C'est la couche à
|
||||
plus fort impact affectif pour le plus faible coût (doctrine §4.2) — elle
|
||||
est traduite en premier.
|
||||
- ⚠️ **Relecture par un locuteur natif requise** : les chaînes gcf actuelles
|
||||
sont un premier jet à valider avant mise en production. La graphie de
|
||||
référence à trancher (GEREC-F ou autre) doit être notée ici une fois choisie.
|
||||
- Chaque fiche peut avoir sa **jumelle créole** : `content/outils/gcf/<slug>.md`
|
||||
(frontmatter minimal : `name`, `slug`, `lang: "gcf"` ; mêmes sections
|
||||
`## what/why/who/install`). Elle s'affiche automatiquement quand la personne
|
||||
choisit Kréyòl, avec un bandeau « tradiksyon an chantyé » ; sans jumelle,
|
||||
la version française s'affiche avec un bandeau « póko tradui ». Six jumelles
|
||||
pilotes existent (mêmes slugs que les fiches de référence ci-dessus) —
|
||||
**premier jet non relu**, à valider avant d'en faire des modèles.
|
||||
- Termes fixés : « zouti » (outil), « Ou pa manké ayen » (fin de liste),
|
||||
« Chwazi zouti ou » (héros), niveaux « Débitan / Entèmédia / Avansé ».
|
||||
|
||||
## Ajouter une catégorie
|
||||
|
||||
Ajouter une entrée à `content/categories.json` (`slug`, `title`, `order`,
|
||||
`part`). La navigation n'affiche que 4 catégories avant la divulgation
|
||||
progressive (Hick-Hyman, doctrine §1.3) : l'ordre `order` décide lesquelles.
|
||||
|
||||
## Vérifications avant merge
|
||||
|
||||
- [ ] `license` est un identifiant SPDX valide
|
||||
- [ ] `difficulty` reflète l'expérience réelle d'installation (pas le prestige)
|
||||
- [ ] Chaque section respecte sa question (what/why/who/install)
|
||||
- [ ] `pnpm build` passe (validation du frontmatter incluse)
|
||||
@@ -0,0 +1,206 @@
|
||||
# Déployer lage-chat-control sur un VPS
|
||||
|
||||
Le site est **100 % statique** (ADR-001) : le déploiement consiste à poser le
|
||||
contenu du dossier `frontend/build/` derrière un serveur web. Pas de base de
|
||||
données, pas de service Node à maintenir, pas de tâche cron. Un miroir du site
|
||||
= une copie du dossier.
|
||||
|
||||
## 0. Prérequis
|
||||
|
||||
- Un VPS (1 vCPU / 512 Mo suffisent très largement) sous Debian/Ubuntu
|
||||
- Un nom de domaine pointant sur le VPS (enregistrement A/AAAA)
|
||||
- En local : Node ≥ 22.12 et pnpm (le build se fait **sur ta machine**,
|
||||
le VPS n'a besoin ni de Node ni de pnpm)
|
||||
|
||||
## 1. Construire le site
|
||||
|
||||
```sh
|
||||
git clone https://labola.o-k-i.net/cyber-mawonaj/lage-chat-control.git
|
||||
cd lage-chat-control/frontend
|
||||
pnpm install
|
||||
pnpm build # produit frontend/build/ (~60 pages statiques)
|
||||
```
|
||||
|
||||
> **Racine de domaine** : le site est servi à la racine de
|
||||
> `https://chatcontrol.o-k-i.net/` (YunoHost, voir §5) — aucun `paths.base`.
|
||||
> Pour un déploiement sous un sous-chemin, ajoute `paths: { base: '/prefixe' }`
|
||||
> dans `frontend/svelte.config.js` avant `pnpm build` et adapte les règles
|
||||
> `try_files` côté serveur (ex. nginx : `location /prefixe/ { … }`).
|
||||
|
||||
> **Mutualisé Apache (o2switch)** : si les liens internes affichent
|
||||
> « Index of /… » (listing de dossier) au lieu des pages, c'est le conflit
|
||||
> fichier/dossier classique — voir [APACHE_AUTOINDEX.md](./APACHE_AUTOINDEX.md).
|
||||
|
||||
> **CSP et hydratation (critique)** : SvelteKit démarre côté navigateur via
|
||||
> un script *inline* (qui embarque les données de la page). Un en-tête HTTP
|
||||
> `Content-Security-Policy` contenant `script-src 'self'` — comme celui posé
|
||||
> par le compte o2switch — **bloque ce script et tue toute l'interactivité**
|
||||
> (recherche, filtres, sélecteur de langue), sans message visible. Chaque page
|
||||
> prérendue porte donc sa propre `<meta>` CSP avec l'empreinte (`sha256-…`) de
|
||||
> son script inline (`csp.mode: 'hash'` dans `frontend/svelte.config.js`).
|
||||
> Règle côté serveur : **ne jamais fixer `script-src` dans l'en-tête HTTP** —
|
||||
> le retirer de la config cPanel/`.htaccess`/reverse proxy (le reste de la CSP
|
||||
> peut y rester). Si l'hébergeur impose un `script-src` en en-tête, le régler
|
||||
> sur `script-src 'self' 'unsafe-inline'` (plus faible, mais fonctionnel).
|
||||
|
||||
## 2. Option A — Caddy (recommandé : TLS automatique)
|
||||
|
||||
```sh
|
||||
# sur le VPS
|
||||
sudo apt install caddy
|
||||
sudo mkdir -p /srv/lage-chat-control
|
||||
```
|
||||
|
||||
`/etc/caddy/Caddyfile` :
|
||||
|
||||
```caddy
|
||||
chatcontrol.o-k-i.net {
|
||||
root * /srv/lage-chat-control
|
||||
file_server
|
||||
encode zstd gzip
|
||||
|
||||
# SvelteKit adapter-static : pages pré-générées + fallback
|
||||
try_files {path} {path}.html {path}/index.html /404.html
|
||||
|
||||
header {
|
||||
# le service worker doit pouvoir se mettre à jour
|
||||
Cache-Control "no-cache" /service-worker.js
|
||||
# assets immuables (noms hachés)
|
||||
Cache-Control "public, max-age=31536000, immutable" /_app/immutable/*
|
||||
# en-têtes de sécurité
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options "nosniff"
|
||||
Referrer-Policy "no-referrer"
|
||||
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
||||
# CSP stricte : le site n'a aucune dépendance externe.
|
||||
# NE PAS remettre script-src ici : il est porté par la <meta> CSP de
|
||||
# chaque page (empreinte du script inline de démarrage, différente
|
||||
# d'une page à l'autre — inexprimable dans un en-tête statique).
|
||||
Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Le TLS (Let's Encrypt) est automatique, rien d'autre à faire.
|
||||
|
||||
## 3. Option B — nginx
|
||||
|
||||
```sh
|
||||
sudo apt install nginx certbot python3-certbot-nginx
|
||||
```
|
||||
|
||||
`/etc/nginx/sites-available/lage-chat-control` :
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name chatcontrol.o-k-i.net;
|
||||
root /srv/lage-chat-control;
|
||||
index index.html;
|
||||
|
||||
# pages pré-générées : /outils/ → outils/index.html, fallback 404
|
||||
location / {
|
||||
try_files $uri $uri/ $uri.html $uri/index.html /404.html;
|
||||
}
|
||||
|
||||
location /_app/immutable/ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
}
|
||||
|
||||
location = /service-worker.js {
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'" always;
|
||||
# NB : pas de script-src ici — voir le commentaire CSP de l'option A.
|
||||
|
||||
gzip on;
|
||||
gzip_types text/html text/css application/javascript application/json image/svg+xml;
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
sudo ln -s /etc/nginx/sites-available/lage-chat-control /etc/nginx/sites-enabled/
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
sudo certbot --nginx -d chatcontrol.o-k-i.net # TLS
|
||||
```
|
||||
|
||||
## 4. Publier (et republier)
|
||||
|
||||
```sh
|
||||
# depuis ta machine, après chaque `pnpm build`
|
||||
rsync -avz --delete frontend/build/ vps:/srv/lage-chat-control/
|
||||
```
|
||||
|
||||
C'est l'intégralité du « pipeline de déploiement ». Pour automatiser :
|
||||
un runner Forgejo Actions sur labola peut exécuter build + rsync à chaque
|
||||
push sur `main` (à ajouter quand le besoin se présente, pas avant).
|
||||
|
||||
## 5. Option C — YunoHost (cible de production)
|
||||
|
||||
Le site tourne en production sur **`chatcontrol.o-k-i.net`** via l'app
|
||||
**`my_webapp`** (site statique) :
|
||||
|
||||
1. Installe `my_webapp` depuis le catalogue YunoHost avec le domaine
|
||||
`chatcontrol.o-k-i.net`, le chemin `/`, un accès **public** (visiteurs
|
||||
compris), sans PHP ni base de données.
|
||||
2. Copie le contenu de `frontend/build/` dans le `www/` de l'app, avec
|
||||
l'utilisateur SFTP dédié créé par l'app (son nom exact figure dans la
|
||||
page de l'app, section « Accès SFTP ») :
|
||||
```sh
|
||||
rsync -avz --delete frontend/build/ my_webapp@chatcontrol.o-k-i.net:www/
|
||||
```
|
||||
3. C'est tout : la conf nginx générée sert déjà `<route>/index.html` (avec
|
||||
redirection automatique vers le `/` final). YunoHost gère TLS, HSTS et
|
||||
le renouvellement des certificats.
|
||||
|
||||
Durcissements optionnels (panneau de config de l'app, ou
|
||||
`/etc/nginx/conf.d/chatcontrol.o-k-i.net.d/my_webapp.conf`) :
|
||||
|
||||
- `error_page 404 /404.html;` — notre page 404 plutôt que celle de nginx ;
|
||||
- cache long sur les assets immuables :
|
||||
`location /_app/immutable/ { add_header Cache-Control "public, max-age=31536000, immutable"; }`
|
||||
- revalidation du service worker :
|
||||
`location = /service-worker.js { add_header Cache-Control "no-cache"; }`
|
||||
|
||||
Ne pose **pas** d'en-tête CSP globale côté YunoHost : la `<meta>` CSP de
|
||||
chaque page suffit (voir l'encadré CSP en §1). À noter : l'overlay du portail
|
||||
YunoHost, injecté uniquement pour les visiteurs déjà connectés au SSO, est
|
||||
bloqué par cette CSP — cosmétique, sans effet pour les visiteurs anonymes.
|
||||
|
||||
## 6. Option D — Docker
|
||||
|
||||
Le dépôt n'embarque volontairement aucun `Dockerfile` (un site 100 % statique
|
||||
n'en a pas besoin — c'est un dossier de fichiers). Si le reste de l'infra OKI
|
||||
tourne déjà en conteneurs, ce `Dockerfile` minimal (nginx durci, sans build
|
||||
step) suffit :
|
||||
|
||||
```dockerfile
|
||||
FROM nginx:alpine
|
||||
COPY frontend/build/ /usr/share/nginx/html/
|
||||
COPY docs/nginx.conf.example /etc/nginx/conf.d/default.conf
|
||||
```
|
||||
|
||||
Reprends le bloc `server {}` de l'option B ci-dessus dans
|
||||
`docs/nginx.conf.example` (à créer), en retirant `server_name`/`certbot`
|
||||
(le TLS se termine en amont, sur un reverse proxy ou le load balancer).
|
||||
Sinon, les options A/B sont plus simples et suffisent dans l'immense
|
||||
majorité des cas.
|
||||
|
||||
## 7. Vérifier après mise en ligne
|
||||
|
||||
- [ ] `curl -s https://chatcontrol.o-k-i.net/outils/ | grep -o 'http-equiv="Content-Security-Policy"'`
|
||||
→ la `<meta>` CSP par page est présente (elle porte `script-src` + empreinte)
|
||||
- [ ] `curl -sI https://chatcontrol.o-k-i.net/outils/ | grep -i content-security`
|
||||
→ l'en-tête HTTP éventuelle ne contient **pas** de `script-src` bloquant
|
||||
- [ ] Ouvrir `/outils`, taper « signal » dans la recherche → la liste
|
||||
se filtre sans rechargement (preuve que l'hydratation fonctionne) ;
|
||||
cliquer une catégorie → l'URL gagne `?cat=…` et la liste se filtre
|
||||
- [ ] DevTools > Console : aucune erreur CSP (« violates the following Content
|
||||
Security Policy directive ») au chargement
|
||||
- [ ] DevTools > Application > Service worker : enregistré ; passer hors-ligne
|
||||
et recharger une fiche déjà visitée → elle s'affiche
|
||||
- [ ] observatory.mozilla.org : note A/A+ attendue avec les en-têtes ci-dessus
|
||||
- [ ] Aucune requête sortante vers un domaine tiers (onglet Réseau)
|
||||
@@ -0,0 +1,72 @@
|
||||
# Design system OKI — Lagé Chat Control
|
||||
|
||||
Toutes les valeurs visuelles vivent dans
|
||||
[`frontend/src/styles/tokens.css`](../frontend/src/styles/tokens.css).
|
||||
Les composants Svelte consomment les tokens ; **jamais de valeur brute**
|
||||
(couleur, taille) dans un composant (doctrine §5.2).
|
||||
|
||||
## Architecture CSS
|
||||
|
||||
Cascade explicite par `@layer` ([app.css](../frontend/src/app.css)) :
|
||||
|
||||
```
|
||||
reset → tokens → base → layouts → components → utilities
|
||||
```
|
||||
|
||||
- `reset.css` — reset moderne minimal (~40 lignes), inclut `prefers-reduced-motion`.
|
||||
- `tokens.css` — custom properties : couleurs `oklch()`, typo fluide `clamp()`, espacements, interaction.
|
||||
- `base.css` — HTML sémantique nu : typo, liens, focus visible, boutons.
|
||||
- `layouts.css` — primitives Every Layout : `.stack`, `.cluster`, `.center`, `.card-grid` (container queries, pas de media queries de largeur d'écran).
|
||||
- Le style propre à chaque composant vit dans son `<style>` Svelte (scopé à la compilation).
|
||||
|
||||
## Couleurs
|
||||
|
||||
En `oklch()` : la luminance perceptuelle rend les contrastes WCAG calculables
|
||||
(méthode modus-vivendi, doctrine §4.3). `light-dark()` + `color-scheme` gèrent
|
||||
le mode sombre sans duplication.
|
||||
|
||||
| Token | Rôle | Note contraste |
|
||||
|---|---|---|
|
||||
| `--oki-ink` / `--oki-surface` | texte / fond | ≥ 7:1 (AAA) dans les deux modes |
|
||||
| `--oki-ink-2` | texte secondaire | ≥ 4.5:1 (AA) |
|
||||
| `--oki-jaune` `--oki-vert` `--oki-rouge` `--oki-noir` | identité panafricaine | décoratif — jamais porteur d'information seul |
|
||||
| `--accent` / `--accent-ink` | accent actif / accent texte | `--accent-ink` ≥ 4.5:1 sur `--oki-surface` |
|
||||
| `--diff-*` / `--diff-*-ink` | difficulté (fond / texte) | les variantes `-ink` sont AA sur `--oki-surface` |
|
||||
|
||||
**Règle absolue** : la difficulté n'est jamais codée par la couleur seule —
|
||||
`DifficultyBadge` = forme (●/◆/▲) + texte + couleur (doctrine §1.1, ~8 % de
|
||||
déficience de vision des couleurs).
|
||||
|
||||
## Typographie
|
||||
|
||||
- Corps : **Atkinson Hyperlegible** 400 (SIL OFL, conçue pour la lisibilité).
|
||||
- Display (titres, marque) : **Fraunces** 700 (SIL OFL).
|
||||
- 2 fichiers WOFF2 auto-hébergés (`static/fonts/`), ~35 Ko au total,
|
||||
`font-display: swap` — jamais de Google Fonts (doctrine §5.3).
|
||||
- Échelle modulaire ratio 1.25, fluide par `clamp()` : `--text-0` … `--text-5`.
|
||||
- `--measure: 65ch` sur `p, li` et `.prose` (doctrine §2.2 : 45–75 caractères).
|
||||
- Tout en `rem` : la taille utilisateur est respectée.
|
||||
|
||||
## Interaction
|
||||
|
||||
- `--tap-target: 48px` : tout élément interactif (boutons, liens de nav,
|
||||
filtres, switcher) a une hauteur minimale de 48 px (Fitts, doctrine §1.3).
|
||||
- `:focus-visible` global : anneau 3 px `--accent`, offset 2 px.
|
||||
- Durées `--duration-1/2` + `--ease-out` ; annulées par `prefers-reduced-motion`.
|
||||
|
||||
## Composants
|
||||
|
||||
| Composant | Rôle | Principe doctrinal |
|
||||
|---|---|---|
|
||||
| `DifficultyBadge` | niveau (forme + texte + couleur) | §1.1 — jamais couleur seule |
|
||||
| `ToolCard` | fiche condensée, vrai `<a>` couvrant | §4.3 — pas de div cliquable |
|
||||
| `CategoryNav` | 4 catégories visibles + `<details>` | §1.3 Hick-Hyman, divulgation progressive, sans JS |
|
||||
| `SearchBar` | recherche instantanée, raccourci `/` | §2.2 — le clavier est roi |
|
||||
| `LanguageSwitcher` | FR / Kréyòl, persisté localStorage | §4.2 — bilinguisme |
|
||||
| `EndMarker` | « Ou pa manké ayen » en fin de liste | §1.5, §3 — point d'arrêt explicite |
|
||||
|
||||
## Test des 50 ms (doctrine §1.1)
|
||||
|
||||
L'identité OKI est reconnaissable avant toute lecture : bandes panafricaines
|
||||
vert/jaune/rouge dans la marque d'en-tête, soulignés et bordures jaune OKI,
|
||||
titres Fraunces, créole visible dès le héros (« Chwazi zouti ou »).
|
||||
@@ -1,24 +0,0 @@
|
||||
// @ts-check
|
||||
import js from '@eslint/js'
|
||||
import astro from 'eslint-plugin-astro'
|
||||
import globals from 'globals'
|
||||
import tseslint from 'typescript-eslint'
|
||||
|
||||
export default tseslint.config(
|
||||
{ ignores: ['dist/', '.astro/', 'node_modules/', 'playwright-report/', 'test-results/'] },
|
||||
js.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...astro.configs.recommended,
|
||||
{
|
||||
files: ['scripts/**/*.mjs', 'migration/**/*.mjs'],
|
||||
languageOptions: {
|
||||
globals: { ...globals.node },
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['src/**/*.{ts,astro}'],
|
||||
languageOptions: {
|
||||
globals: { ...globals.browser },
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,49 @@
|
||||
# Lagé Chat Control × OKI — frontend
|
||||
|
||||
Annuaire souverain d'outils libres. SvelteKit 2 + Svelte 5, site 100 %
|
||||
prérendu, zéro CDN tiers, zéro tracker. Voir [`ADR.md`](../ADR.md) pour la
|
||||
décision d'architecture et `../docs/` pour le design system et le guide
|
||||
de contenu.
|
||||
|
||||
## Prérequis
|
||||
|
||||
Node ≥ 22.12, pnpm.
|
||||
|
||||
## Commandes
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
pnpm dev # serveur de développement
|
||||
pnpm build # build statique dans build/ (prérend toutes les pages)
|
||||
pnpm preview # sert le build localement
|
||||
pnpm check # svelte-check (types + a11y)
|
||||
pnpm audit:a11y # audit axe-core sur le build servi en local
|
||||
```
|
||||
|
||||
## Déploiement
|
||||
|
||||
`build/` est un site statique : n'importe quel serveur de fichiers convient.
|
||||
Voir [`docs/DEPLOYMENT.md`](../docs/DEPLOYMENT.md) pour la mise en production
|
||||
sur un VPS (Caddy, nginx, YunoHost, Docker). Aucune dépendance cloud, aucun
|
||||
service à maintenir — un miroir = une copie du dossier.
|
||||
|
||||
## Arborescence
|
||||
|
||||
```
|
||||
src/styles/ tokens, reset, base, layouts (cascade @layer)
|
||||
src/lib/i18n/ fr.json + gcf.json typés, store de langue (runes)
|
||||
src/lib/components/ ToolCard, DifficultyBadge, CategoryNav, SearchBar,
|
||||
LanguageSwitcher, EndMarker, ShortcutsDialog,
|
||||
OfflineBadge, AdoptButton
|
||||
src/lib/content/ chargeurs build-time des fichiers ../content/
|
||||
(tools.server.ts, quiz.server.ts)
|
||||
src/routes/ / (landing), /outils (annuaire filtrable),
|
||||
/outils/[slug], /quiz, /contribuer
|
||||
src/service-worker.js précache + offline-first
|
||||
static/fonts/ 2 WOFF2 auto-hébergés (Atkinson Hyperlegible, Fraunces)
|
||||
scripts/audit-a11y.mjs audit axe-core (pnpm audit:a11y)
|
||||
```
|
||||
|
||||
Le contenu éditorial (fiches d'outils, quiz, catégories) vit dans
|
||||
[`../content/`](../content/) à la racine du dépôt, pas dans `frontend/` —
|
||||
voir [`docs/CONTENT_GUIDE.md`](../docs/CONTENT_GUIDE.md) pour l'éditer.
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "lage-chat-control",
|
||||
"private": true,
|
||||
"version": "4.0.0-alpha.1",
|
||||
"type": "module",
|
||||
"description": "Lagé Chat Control × OKI — annuaire souverain d'outils libres. SvelteKit statique, zéro tracker, zéro CDN.",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"prebuild": "node scripts/gen-sitemap.mjs",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"audit:a11y": "node scripts/audit-a11y.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.12.1",
|
||||
"@fontsource/atkinson-hyperlegible": "^5.2.8",
|
||||
"@fontsource/fraunces": "^5.2.9",
|
||||
"@playwright/test": "1.61.1",
|
||||
"@sveltejs/adapter-static": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||
"@types/node": "^26.1.1",
|
||||
"marked": "^16.0.0",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"typescript": "^5.6.0",
|
||||
"vite": "^7.0.0"
|
||||
}
|
||||
}
|
||||
Generated
+1133
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
onlyBuiltDependencies:
|
||||
- esbuild
|
||||
allowBuilds:
|
||||
esbuild: true
|
||||
@@ -0,0 +1,24 @@
|
||||
// Audit axe-core des pages clés servies sur localhost:4173
|
||||
import { chromium } from '@playwright/test'
|
||||
import { AxeBuilder } from '@axe-core/playwright'
|
||||
|
||||
const PAGES = ['/', '/outils', '/outils/signal', '/outils/tor', '/contribuer', '/quiz']
|
||||
const browser = await chromium.launch()
|
||||
const context = await browser.newContext()
|
||||
const page = await context.newPage()
|
||||
let total = 0
|
||||
|
||||
for (const path of PAGES) {
|
||||
await page.goto(`http://localhost:4173${path}`, { waitUntil: 'networkidle' })
|
||||
const results = await new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa', 'wcag22aa']).analyze()
|
||||
total += results.violations.length
|
||||
console.log(`\n═══ ${path} — ${results.violations.length} violation(s)`)
|
||||
for (const v of results.violations) {
|
||||
console.log(` [${v.impact}] ${v.id}: ${v.help}`)
|
||||
for (const n of v.nodes.slice(0, 3)) console.log(` → ${n.target.join(' ')}`)
|
||||
}
|
||||
}
|
||||
|
||||
await browser.close()
|
||||
console.log(`\nTOTAL: ${total} violation(s)`)
|
||||
process.exit(total > 0 ? 1 : 0)
|
||||
@@ -0,0 +1,47 @@
|
||||
// Génère static/sitemap.xml au build (script `prebuild`) — remplace le
|
||||
// sitemap qu'apportait @astrojs/sitemap à l'ère Astro. Zéro dépendance :
|
||||
// les slugs sont relus depuis les frontmatters de content/outils/.
|
||||
import { readdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const SITE_URL = 'https://chatcontrol.o-k-i.net'
|
||||
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const OUTILS = path.resolve(ROOT, '..', 'content', 'outils')
|
||||
|
||||
// les valeurs du frontmatter sont encodées en JSON (cf. tools.server.ts)
|
||||
function slugOf(file) {
|
||||
const raw = readFileSync(path.join(OUTILS, file), 'utf8')
|
||||
const m = raw.match(/^slug:\s*("(?:[^"\\]|\\.)*")/m)
|
||||
return m ? JSON.parse(m[1]) : file.replace(/\.md$/, '')
|
||||
}
|
||||
|
||||
const slugs = readdirSync(OUTILS)
|
||||
.filter((f) => f.endsWith('.md'))
|
||||
.map(slugOf)
|
||||
.sort((a, b) => a.localeCompare(b, 'fr'))
|
||||
|
||||
const lastmod = new Date().toISOString().slice(0, 10)
|
||||
|
||||
const entry = (loc, priority) => ` <url>
|
||||
<loc>${SITE_URL}${loc}</loc>
|
||||
<lastmod>${lastmod}</lastmod>
|
||||
<priority>${priority}</priority>
|
||||
</url>`
|
||||
|
||||
const urls = [
|
||||
entry('/', '1.0'),
|
||||
entry('/outils/', '0.8'),
|
||||
...slugs.map((slug) => entry(`/outils/${slug}/`, '0.6')),
|
||||
entry('/quiz/', '0.5'),
|
||||
entry('/contribuer/', '0.5')
|
||||
]
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
${urls.join('\n')}
|
||||
</urlset>
|
||||
`
|
||||
|
||||
writeFileSync(path.join(ROOT, 'static', 'sitemap.xml'), xml)
|
||||
console.log(`sitemap.xml : ${urls.length} URLs (lastmod ${lastmod})`)
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* app.css — ordre de cascade explicite et auditable (doctrine §5.2).
|
||||
* Chaque couche est déclarée AVANT tout import : la position dans la
|
||||
* cascade est ici, pas dans l'ordre des fichiers.
|
||||
*/
|
||||
@layer reset, tokens, base, layouts, components, utilities;
|
||||
|
||||
/* @font-face n'est pas concerné par les couches */
|
||||
@import './styles/fonts.css';
|
||||
|
||||
@import './styles/reset.css' layer(reset);
|
||||
@import './styles/tokens.css' layer(tokens);
|
||||
@import './styles/base.css' layer(base);
|
||||
@import './styles/layouts.css' layer(layouts);
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="theme-color" content="#17181f" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<link rel="manifest" href="%sveltekit.assets%/site.webmanifest" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,39 @@
|
||||
import { browser } from '$app/environment'
|
||||
|
||||
/**
|
||||
* « Jès fèt » — les outils que la personne a adoptés.
|
||||
* Effet Zeigarnik utilisé positivement (doctrine §1.2) : une progression
|
||||
* choisie, pas un streak. Stocké uniquement sur l'appareil, jamais envoyé
|
||||
* nulle part (pas de compte, pas de télémétrie — doctrine §3.3 : aucune
|
||||
* métrique anxiogène ; le compteur n'apparaît qu'après le premier geste).
|
||||
*/
|
||||
const STORAGE_KEY = 'oki-jes'
|
||||
|
||||
function initial(): string[] {
|
||||
if (!browser) return []
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY)
|
||||
return raw ? (JSON.parse(raw) as string[]) : []
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const state = $state({ slugs: initial() })
|
||||
|
||||
function persist() {
|
||||
if (browser) localStorage.setItem(STORAGE_KEY, JSON.stringify(state.slugs))
|
||||
}
|
||||
|
||||
export function isAdopted(slug: string): boolean {
|
||||
return state.slugs.includes(slug)
|
||||
}
|
||||
|
||||
export function adoptedCount(): number {
|
||||
return state.slugs.length
|
||||
}
|
||||
|
||||
export function toggleAdopted(slug: string) {
|
||||
state.slugs = isAdopted(slug) ? state.slugs.filter((s) => s !== slug) : [...state.slugs, slug]
|
||||
persist()
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { isAdopted, toggleAdopted } from '$lib/adopted.svelte'
|
||||
import { t } from '$lib/i18n/index.svelte'
|
||||
|
||||
let { slug }: { slug: string } = $props()
|
||||
let adopted = $derived(isAdopted(slug))
|
||||
</script>
|
||||
|
||||
<!-- Amélioration progressive : sans JS le bouton n'apparaît pas du tout
|
||||
(rendu identique, aucune fonction cassée). -->
|
||||
<button type="button" class:adopted aria-pressed={adopted} onclick={() => toggleAdopted(slug)}>
|
||||
{adopted ? t('adopted.marked') : t('adopted.mark')}
|
||||
<span class="visually-hidden">{t('adopted.srHint')}</span>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
button {
|
||||
border: 2px solid var(--oki-vert);
|
||||
background: transparent;
|
||||
color: var(--oki-ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
button.adopted {
|
||||
background: var(--oki-vert);
|
||||
color: oklch(98% 0 0);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,102 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment'
|
||||
import { base } from '$app/paths'
|
||||
import { page } from '$app/state'
|
||||
import { t } from '$lib/i18n/index.svelte'
|
||||
|
||||
interface NavCategory {
|
||||
slug: string
|
||||
title: string
|
||||
}
|
||||
|
||||
let { categories }: { categories: NavCategory[] } = $props()
|
||||
|
||||
// Hick-Hyman (doctrine §1.3) : ≤ 5 entrées visibles, le reste en
|
||||
// divulgation progressive (<details>, fonctionne sans JS).
|
||||
const VISIBLE = 4
|
||||
let visible = $derived(categories.slice(0, VISIBLE))
|
||||
let rest = $derived(categories.slice(VISIBLE))
|
||||
// searchParams non lisibles au prerender : garde `browser`
|
||||
let current = $derived(browser ? page.url.searchParams.get('cat') : null)
|
||||
|
||||
function href(slug: string | null): string {
|
||||
return slug ? `${base}/outils?cat=${slug}` : `${base}/outils`
|
||||
}
|
||||
</script>
|
||||
|
||||
<nav aria-label={t('directory.filterCategory')} class="catnav">
|
||||
<ul class="cluster">
|
||||
<li><a href={href(null)} aria-current={current === null ? 'page' : undefined}>{t('directory.allCategories')}</a></li>
|
||||
{#each visible as cat (cat.slug)}
|
||||
<li>
|
||||
<a href={href(cat.slug)} aria-current={current === cat.slug ? 'page' : undefined}>{cat.title}</a>
|
||||
</li>
|
||||
{/each}
|
||||
{#if rest.length > 0}
|
||||
<li>
|
||||
<details>
|
||||
<summary>+ {rest.length}</summary>
|
||||
<ul class="stack">
|
||||
{#each rest as cat (cat.slug)}
|
||||
<li>
|
||||
<a href={href(cat.slug)} aria-current={current === cat.slug ? 'page' : undefined}>{cat.title}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: var(--tap-target);
|
||||
padding-inline: var(--space-3);
|
||||
border: 1px solid var(--oki-line);
|
||||
border-radius: var(--radius-2);
|
||||
text-decoration: none;
|
||||
color: var(--oki-ink);
|
||||
}
|
||||
|
||||
a[aria-current='page'] {
|
||||
background: var(--oki-jaune);
|
||||
border-color: var(--oki-jaune);
|
||||
color: var(--oki-noir);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
details {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: var(--tap-target);
|
||||
padding-inline: var(--space-3);
|
||||
border: 1px dashed var(--oki-line);
|
||||
border-radius: var(--radius-2);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
details ul {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
inset-inline-start: 0;
|
||||
margin-block-start: var(--space-1);
|
||||
padding: var(--space-2);
|
||||
background: var(--oki-surface);
|
||||
border: 1px solid var(--oki-line);
|
||||
border-radius: var(--radius-2);
|
||||
min-inline-size: 16rem;
|
||||
box-shadow: 0 4px 16px oklch(0% 0 0 / 0.15);
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user