Skip to content

feat(web): wiki public /wiki lisible sans connexion - #301

Merged
bobdivx merged 1 commit into
mainfrom
feat/public-wiki
Nov 2, 2026
Merged

bobdivx merged 1 commit into
mainfrom
feat/public-wiki

Conversation

@bobdivx

@bobdivx bobdivx commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Wiki public intégré à l'app

/wiki/ est lisible sans connexion. Les pages wiki/*.md du dépôt sont figées dans le build du front, donc dans l'image. Il n'y a aucune dépendance au GitHub Wiki (désactivé).

Contenu

  • /wiki/ : l'accueil (Home.md) suivi de tuiles par section, d'après _Sidebar.md.
  • /wiki/<Page>/ : une page par fichier. Fil d'Ariane, sommaire latéral sur bureau et tiroir sur mobile.
  • Recherche simple : index statique /wiki/search-index.json, chargé à la première frappe et insensible aux accents.
  • Mobile : sommaire en tiroir, tableaux qui défilent horizontalement, cibles tactiles de 44 px. Aucun débordement de page n'a été mesuré à 390 px.
  • Liens « Wiki » dans l'en-tête et le pied de page de la vitrine.

Créer si absent

  • Si le dossier wiki/ est absent au build, le site affiche un accueil minimal avec un bandeau « contenu minimal ». Le build n'échoue pas.
  • Pour une page inconnue (/wiki/Foo/), le serveur renvoie l'accueil du wiki, qui annonce « La page « Foo » n'existe pas (encore) ». Le visiteur ne retombe pas sur la vitrine.

Sécurité

  • Lecture seule et 100 % statique : aucune route API, aucun accès disque piloté par l'URL. Les slugs viennent d'une liste blanche fixée au build (^[A-Za-z0-9][A-Za-z0-9-]*$). _Sidebar, _Footer et README ne sont pas publiés.
  • ServeDir : des tests vérifient que .., %2e%2e et ..%2f ne sortent jamais de web/.
  • Rendu Markdown sans innerHTML : le HTML brut reste du texte. Seuls les liens vers les pages connues, les ancres et http(s)/mailto sont acceptés. javascript:, data:, //… et les chemins hors dépôt sont rendus en texte. Les liens externes portent noopener noreferrer.
  • Le contenu exposé est celui du dossier wiki/, déjà public dans le dépôt. Les API restent protégées (/api/v1/projects → 401 sans cookie).

Fichiers

  • apps/web/src/lib/wiki.ts (règles pures) et wiki-source.ts (lecture fs au build uniquement).
  • components/wiki/WikiApp.tsx et WikiMarkdown.tsx.
  • pages/wiki/index.astro, [slug].astro et search-index.json.ts.
  • apps/server/src/static_web.rs : service statique partagé par le leader et le worker, avec repli wiki. Tests inclus.
  • Dockerfile : COPY wiki/ /wiki/ + DEVFORGE_WIKI_DIR. La CI web monte wiki/ en lecture seule.
  • Docker reste le backend par défaut. Rien ne change côté runtime.

Tests

  • cargo test -p devforge-server static_web : 5 tests, dont l'anti-traversée et le repli.
  • Vitest : 200/200, dont 13 nouveaux (XSS, liens dangereux, tableaux [[a|b]], listes imbriquées, recherche, secours).
  • check-jsx-imports et check-forbidden-names OK. astro build génère 29 pages wiki.
  • Serveur local avec le dist construit, sans cookie : /wiki/ 200, /wiki/Kubernetes/ 200, /wiki/Inexistante/ → accueil wiki, traversées → accueil wiki sans fuite, /api/v1/health 200.

- Pages wiki/*.md figées au build du front (Dockerfile : COPY wiki/), aucune
  dépendance au GitHub Wiki ; dossier absent → accueil minimal.
- /wiki/ (accueil + tuiles), /wiki/<Page>/, sommaire _Sidebar, recherche
  simple (index statique), mobile (tiroir, tableaux défilants).
- Rendu Markdown sans innerHTML : HTML brut affiché en texte, liens limités
  aux pages connues, ancres et http(s)/mailto ; [[Page]] / [[Libellé|Page]].
- Serveur : page de wiki inconnue → accueil du wiki (annonce « page absente ») ;
  ServeDir partagé leader/worker, tests anti-traversée.
- Liens Wiki dans l'en-tête et le pied de la vitrine.
@bobdivx
bobdivx merged commit 0ca1010 into main Nov 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant