[pop-out][Bookmark] | [Editer][Source][.ext][Pretty] | [Copier] | [Partager]
- TOC ancre uniquement au markdown (plus de bouton TOC sur .sh/.py/...)
- PDF/Export deja ancres au markdown: groupe export = [Copier] seul sur texte
- tests toolbar-order mis a jour (conditions is_markdown sur nav/export)
ObsiGate — Historique des fonctionnalités complétées (v1.0.0 → v2.2)
Rôle : archive détaillée des fonctionnalités livrées. Le suivi des versions est la
responsabilité de CHANGELOG.md ; la Roadmap ne contient
plus que le travail à venir et un index compact vers ce fichier.
Fixtures : vault de test (utilise les vaults Docker existants)
Test : dashboard → stats, tabs, Quick Help, sidebar
Test : recherche full-text → résultats, snippets, tri pertinence/date
Test : ouverture fichier → viewer Markdown, métadonnées
Test : éditeur → Forge, basic modal, Ctrl+S
Test : rendu Mermaid dans le viewer + preview Forge
Test : export PDF → bouton présent
Test : mode sombre → toggle, persistence localStorage
Test : responsive mobile → layout, recherche, barre flottante
Test : barre flottante résultats → compteur, nav, toggles Aa/wd
Test : sauvegardes → filtres Tous/Recherches/Répertoires
Test : raccourcis clavier → Ctrl+K, /, Escape
Test : menu contextuel répertoire
Intégration CI : job e2e dans .gitea/workflows/ci.yml
#59 — Mode hors-ligne PWA complet ✅ TERMINÉ
Effort : 3-4 jours | Impact :🟡
Description : Service worker avancé avec IndexedDB pour permettre la navigation et la recherche en mode hors-ligne, avec file de synchronisation au retour réseau.
Implémentation :offline-db.js (377 lignes) + offline.js (209 lignes). IndexedDB 3 stores (files, content, pending). Badge hors-ligne dans le header. Modale résolution de conflits.
Sous-tâches :
IndexedDB : stockage local de l'index des fichiers (paths, titles, tags)
Moteur de recherche offline via IndexedDB (cursor + filtre)
Cache des fichiers markdown récemment ouverts (derniers 50, prune)
Stratégie de cache : Network First avec fallback IndexedDB
File de synchronisation : modifications offline → appliquées au retour réseau
UI indicateur : badge « Hors-ligne » + compteur de modifications en attente
Gestion des conflits : détection et résolution manuelle (choix version locale vs serveur)
Description : Système de plugins permettant aux utilisateurs d'étendre ObsiGate avec des renderers personnalisés, des opérateurs de recherche, et des hooks d'UI. Inspiré du modèle de plugins Obsidian.
Sous-tâches :
Spécification du format de plugin : plugin.json (name, version, hooks, permissions)
API de hooks : onFileRender, onSearchFilter, onEditorAction, onSidebarItem, onFileCreate, onFileDelete, onVaultMount
Sandbox d'exécution : Web Worker isolé pour le code plugin (blob URL, postMessage structuré, CSP sans importScripts)
UI : page « Plugins » dans les paramètres (installer, activer/désactiver, désinstaller, template, viewer)
Distribution : dépôt de plugins communautaire (fichier JSON index) — ⚪ NON RETENU (backlog)
Hot-reload : activation/désactivation sans rechargement de page (marker .disabled)
Sécurité : manifest de permissions, validation path-traversal, CSP restrictif
Description : Ajout d'un second facteur d'authentification obligatoire pour les comptes administrateur. Deux méthodes sont proposées :
TOTP (Time-based One-Time Password) : l'utilisateur scanne un QR code avec son app d'authentification (Google Authenticator, Authy, Bitwarden) qui génère un code à 6 chiffres renouvelé toutes les 30 secondes. Au login, après avoir saisi son mot de passe, l'utilisateur doit entrer le code affiché sur son téléphone. Même si le mot de passe est volé, le compte reste protégé car l'attaquant n'a pas le téléphone.
WebAuthn (clés de sécurité physiques) : l'utilisateur enregistre une clé USB (YubiKey, SoloKey) ou utilise la biométrie de son appareil (empreinte digitale, Face ID, Windows Hello). Au login, le navigateur demande de toucher la clé physique ou de scanner le doigt. C'est le niveau de sécurité le plus élevé — résistant au phishing car la clé vérifie le domaine du site avant de répondre.
Codes de secours : 8 codes à usage unique imprimables, à conserver en lieu sûr, qui permettent de se connecter même si on perd son téléphone ou sa clé. Chaque code ne fonctionne qu'une seule fois.
Pourquoi c'est important : Le vol de mot de passe est la cause #1 de brèches de sécurité. Avec un vault Obsidian contenant des notes personnelles, projets sensibles, secrets et tokens API, l'authentification par simple mot de passe n'est plus suffisante. Le MFA empêche 99.9% des attaques de prise de compte automatisées (source : Microsoft Security).
Sous-tâches :
TOTP : génération de secret, QR code, vérification code 6 chiffres
WebAuthn : enregistrement de clé, assertion, attestation (backend/auth/webauthn_mfa.py, lib webauthn==2.6.0, challenges in-memory TTL 180s à usage unique) — FAIT en 2026-09 (commit ab795ec)
UI : page « Sécurité du compte » avec activation/désactivation MFA + gestion des clés WebAuthn (liste, ajout, retrait)
Flow login : mot de passe → challenge TOTP OU WebAuthn selon mfa_method retourné par /login
Recovery codes : 8 codes de backup à usage unique (générés à l'activation, hachés SHA-256)
Stockage : mfa_secret + webauthn_credentials[] dans users.json
Description : Exposition de variables CSS pour permettre aux utilisateurs de créer des thèmes personnalisés. Presets inclus : light, dark, high-contrast, sepia.
Sous-tâches :
Audit des variables CSS existantes → 40+ variables
Endpoints : GET /api/export/html, GET /api/export/md-bundle, GET /api/export/epub
#67 — Notifications web — Push API ✅ TERMINÉ
Effort : 2 jours | Impact :🟢
Description : Recevoir des notifications sur le bureau ou le téléphone quand un fichier est modifié, ajouté ou supprimé dans un de vos vaults, même si ObsiGate n'est pas ouvert dans le navigateur.
Fonctionnement : Le navigateur s'abonne auprès du serveur via la Push API (standard W3C). Le serveur stocke l'abonnement (endpoint + clés de chiffrement). Quand un fichier change (détecté par le watcher existant), le serveur envoie une notification chiffrée au push service du navigateur (Firebase pour Chrome, APNs pour Safari, etc.), qui la relaye au navigateur même s'il est fermé. Le service worker ObsiGate affiche alors la notification système.
Contenu : titre du fichier modifié, nom du vault, type d'action (créé/modifié/supprimé). Un clic sur la notification ouvre directement le fichier dans ObsiGate.
Configuration : activation/désactivation par vault. L'utilisateur choisit pour quels vaults il reçoit des notifications.
VAPID : protocole d'authentification volontaire qui permet au serveur de s'identifier auprès du push service sans avoir à s'enregistrer comme application. Une paire de clés publique/privée est générée — la clé publique est partagée avec le navigateur, la clé privée reste sur le serveur.
Pourquoi c'est important : Collaborer sans avoir à constamment rafraîchir l'interface pour voir si quelqu'un a modifié quelque chose. Particulièrement utile en équipe ou pour les vaults partagés via Syncthing — on sait immédiatement quand une note est mise à jour.
Implémentation :backend/push.py, endpoints POST /api/push/subscribe, config VAPID dans config.json, UI toggle par vault. Livré avec #77 (commit ac16fc1).
Sous-tâches :
Souscription Push : endpoint POST /api/push/subscribe (stockage subscription + vault)
Envoi : webhook interne on_file_change → dispatch notification via Web Push
Configuration VAPID : clés publique/privée dans config.json
UI : permission navigateur + toggle activer/désactiver par vault
Payload : titre du fichier, vault, action (created/modified/deleted)
Clic sur notification → ouvre le fichier dans ObsiGate
#68 — Health check enrichi ✅ TERMINÉ
Effort : 1 jour | Impact :🟢
Description : Un endpoint /api/health qui ne se contente pas de dire « je suis vivant », mais donne un diagnostic complet de l'état du serveur. Essentiel pour le monitoring et le debugging.
Métriques exposées :
Index : nombre de fichiers indexés, nombre de tokens, date de la dernière indexation complète. Permet de détecter si l'indexeur est bloqué ou ne tourne plus.
Mémoire : consommation RAM du processus (RSS), heap Python utilisé. Permet de détecter les fuites mémoire avant qu'elles ne crashent le serveur.
Uptime : depuis quand le serveur tourne. Simple, mais indispensable pour corréler un problème avec un redémarrage.
Connexions : nombre de connexions SSE actives (recherche en cours, streaming AI, etc.). Permet de savoir combien d'utilisateurs sont connectés.
Backups : nombre total, âge du backup le plus ancien, espace disque consommé. Permet de détecter si les backups s'accumulent anormalement.
Disque : espace libre sur la partition /data. Évite le crash silencieux quand le disque est plein.
Format : JSON structuré, facile à intégrer dans des outils de monitoring (Prometheus, Grafana, Uptime Kuma, Healthchecks.io).
Sécurité : l'endpoint public /api/health retourne ok ou degraded, l'endpoint détaillé est protégé par authentification admin.
Implémentation :GET /api/health/detailed (admin-gated) dans backend/main.py:1176. Livré avec #77 (commit ac16fc1).
Sous-tâches :
Métriques index : nombre de fichiers, nombre de tokens, génération courante
Métriques mémoire : RSS, heap used (via psutil ou /proc/self/status)
Description : Une page web dédiée accessible uniquement aux administrateurs qui centralise tout le monitoring et la gestion du serveur ObsiGate en un seul endroit. Un cockpit de pilotage pour le sysadmin.
Description : Une page de documentation interactive et auto-générée de toutes les API REST d'ObsiGate, accessible via un bouton dans l'interface. L'équivalent d'un manuel technique mais qui se teste en direct.
OpenAPI 3.1 : c'est le format standard mondial pour décrire une API REST. Un seul fichier JSON/YAML contient la description de tous les endpoints, leurs paramètres, les formats de réponse, les codes d'erreur, et les modèles de données. Ce standard est supporté par des centaines d'outils.
Swagger UI : une interface web qui lit le fichier OpenAPI et génère automatiquement une documentation interactive. L'utilisateur voit chaque endpoint, peut remplir les paramètres dans un formulaire, cliquer « Execute » et voir la réponse réelle de l'API en direct. Parfait pour les développeurs qui veulent intégrer ObsiGate à leurs scripts ou comprendre comment fonctionne l'API.
Redoc : une alternative à Swagger UI, plus propre et orientée lecture, idéale pour la documentation publique.
Contenu documenté :
Les 40+ endpoints existants, regroupés par catégorie (Fichiers, Vaults, Recherche, Auth, AI, Backups).
Chaque endpoint avec description, paramètres obligatoires/optionnels, exemples de requête et réponse.
Les modèles de données Pydantic exposés comme schémas JSON (ex: structure d'un FileInfo, d'un SearchResult).
Les codes d'erreur possibles avec leur signification.
Auto-génération : FastAPI génère déjà partiellement le schéma OpenAPI. Le travail consiste à compléter les docstrings manquantes, ajouter response_model sur les endpoints qui n'en ont pas, et enrichir avec des exemples.
Pourquoi c'est important : Une API sans documentation est comme un logiciel sans interface — techniquement fonctionnel mais inutilisable. Avec une doc OpenAPI, ObsiGate devient intégrable dans n'importe quel écosystème. Un développeur peut en 5 minutes comprendre comment uploader un fichier, chercher dans un vault, ou récupérer le contenu d'une note — et écrire un script qui automatise ses workflows.
Sous-tâches :
Audit des endpoints existants → compléter les docstrings manquants
Ajout de response_model sur tous les endpoints (40+ actuellement, ~15 sans modèle)
Exemples dans les schémas : examples=[...] pour les endpoints clés
Tagging des endpoints par catégorie (Files, Vaults, Search, Auth, AI, Backups)
Serveur mock : prism ou openapi-generator pour tests sans backend — ⚪ NON RETENU (le schéma 3.1 est validé par tests/test_openapi.py)
Page de documentation intégrée : lien dans le menu header (« API »)
Traitement des vulnérabilités de la revue statique du 2026-09-13 (BUG-021 → BUG-034).
Sanitizer XSS serveur (backend/services/sanitizer.py, stdlib, liste blanche
de balises/attributs/schémas) appliqué au rendu markdown et à la page publique
/s/{token} (titre, frontmatter et JSON échappés, </script> neutralisé).
Auth durcie : rate-limit IP + compte et verrouillage sur les endpoints MFA ;
rotation du refresh token et révocation de l'access token au logout ; politique de
mot de passe centralisée (8–128) ; password_changed_at invalide les jetons
antérieurs ; verrou RLock sur users.json.
Isolation & réseau : resolve_safe_path compare par segments (vault ≠
vault-evil) ; webhooks protégés contre le SSRF (HTTPS, IP privées bloquées,
résolution vérifiée, redirections interdites, secret externalisé) ; IP client
réelle dans les audits.
Robustesse : validation des regex (ReDoS), symlinks hors vault ignorés à
l'indexation, recherche simple et search_fulltext branchés sur l'inverted index.
Frontend : token d'accès en mémoire + cookie HttpOnly (plus de
sessionStorage), CSP durcie (object-src, base-uri, form-action,
frame-ancestors).
Viewer principal (frontend/js/viewer.js, renderFile) : construction par
groupes navBtns / editBtns / exportBtns / shareBtns ; TOC ancré au
markdown seul (.sh/.py/etc. sans TOC) ; « Pretty » (fichiers texte) ancré
au groupe édition après le bouton d'extension ; les spacers d'un groupe vide
(ex. fichier image ou binaire) ne sont pas rendus.
Pop-out (frontend/popout.html) : même assemblage groupé, ordre aligné.