feat: intégration TikTak #197-200 + scoped tokens, webhooks filtrés, listes mtime/size ; fix e2e-server BUG-112
This commit is contained in:
+58
-10
@@ -100,13 +100,37 @@ Gestion :
|
||||
|
||||
| Endpoint | Rôle |
|
||||
|---|---|
|
||||
| `GET /api/auth/tokens` | Lister vos clés (`last_used_at`, statut) |
|
||||
| `POST /api/auth/tokens` | Créer (`{name, expiry}`) |
|
||||
| `GET /api/auth/tokens` | Lister vos clés (`last_used_at`, statut, **portée**) |
|
||||
| `POST /api/auth/tokens` | Créer (`{name, expiry, vaults?, scope?}`) |
|
||||
| `DELETE /api/auth/tokens/{jti}` | Révoquer immédiatement (API **et** MCP) |
|
||||
|
||||
> Le JWT brut n'est **jamais persisté** : copiez-le à la création. Plafond :
|
||||
> 50 clés actives par utilisateur.
|
||||
|
||||
### 2.3 Clés à portée limitée (synchronisation externe, ex. TikTak)
|
||||
|
||||
Une clé peut être confinée **à un ou plusieurs vaults** et **aux fichiers seuls** —
|
||||
si elle fuit, le reste reste hors de portée :
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://localhost:2020/api/auth/tokens \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"TikTak sync","expiry":"never","vaults":["TikTak"],"scope":"files"}'
|
||||
```
|
||||
|
||||
- `vaults` : sous-ensemble de vos vaults (`400` si inconnu, `403` si hors de vos
|
||||
accès ; omis = tous vos vaults, comme avant).
|
||||
- `scope: "files"` : surface fichiers uniquement (CRUD, listes, recherche,
|
||||
backups lecture/restauration, `GET /api/vaults`, `/mcp`). Tout le reste —
|
||||
admin, config, IA, webhooks, partages, **gestion des clés elle-même** — répond
|
||||
**403**. Les outils MCP hors fichiers sont refusés (`token_scope_denied`) et
|
||||
masqués du `list_tools`.
|
||||
- La portée est affichée dans l'interface (Configurations → **🔑 Clés API & MCP**)
|
||||
et renvoyée par `GET /api/auth/tokens` (`scope`, `vaults`).
|
||||
- Les clés créées avant cette fonction n'ont aucune portée = accès complet,
|
||||
comportement inchangé (non-régression testée).
|
||||
|
||||
---
|
||||
|
||||
## 3. Référence des endpoints
|
||||
@@ -166,7 +190,7 @@ Gestion :
|
||||
| `/api/suggest?q=` | Autocomplétion de titres | GET | Oui |
|
||||
| `/api/tags/suggest?q=` | Autocomplétion de tags | GET | Oui |
|
||||
| `/api/tree-search` | Recherche de fichiers/dossiers | GET | Oui |
|
||||
| `/api/vault/{vault}/paths` | Liste de chemins | GET | Oui |
|
||||
| `/api/vault/{vault}/paths` | Liste de chemins **avec `size`/`mtime`/`mtime_iso`** (réconciliation externe en un appel) | GET | Oui |
|
||||
| `/api/graph/{vault}` | Graphe de liens | GET | Oui |
|
||||
|
||||
### 3.5 Sauvegardes
|
||||
@@ -231,7 +255,7 @@ Gestion :
|
||||
|---|---|---|
|
||||
| `/api/share/{vault}` | Créer un lien de partage public | POST |
|
||||
| `/api/shares` | Lister / supprimer les partages | GET/DELETE |
|
||||
| `/api/webhooks` | CRUD webhooks (HMAC-SHA256) | GET/POST/PATCH/DELETE |
|
||||
| `/api/webhooks` | CRUD webhooks (HMAC-SHA256, **filtres `vault` / `path_prefix`**) | GET/POST/PATCH/DELETE |
|
||||
| `/api/conflicts` · `/api/conflicts/resolve` | Conflits Syncthing | GET/POST |
|
||||
| `/api/plugins` | Installer / activer / désactiver | GET/POST/DELETE |
|
||||
| `/api/push/*` | Abonnement Web Push (VAPID) | GET/POST/DELETE |
|
||||
@@ -285,9 +309,33 @@ curl -s $BASE/api/index/reload -H "Authorization: Bearer $TOKEN"
|
||||
|
||||
---
|
||||
|
||||
## 5. Temps réel
|
||||
## 5. Synchronisation externe (TikTak)
|
||||
|
||||
### 5.1 SSE — `/api/events`
|
||||
Recette complète côté ObsiGate : fiche
|
||||
[`../features/tiktak-integration-197-200.md`](../features/tiktak-integration-197-200.md)
|
||||
(#200 : provisionnement du vault « TikTak », #199 : clé limitée, #198 : webhook
|
||||
filtré). Boucle de réconciliation type avec **un seul appel de liste** :
|
||||
|
||||
```bash
|
||||
KEY=<clé scope=files, vaults=[TikTak]>
|
||||
# 1. Inventaire : chemin + mtime + taille, sans lire les contenus
|
||||
curl -s "$BASE/api/vault/TikTak/paths?limit=20000" -H "Authorization: Bearer $KEY" \
|
||||
| jq -r '.results[] | select(.type=="file") | "\(.mtime) \(.size) \(.path)"' > avant.txt
|
||||
# 2. … modifications …
|
||||
# 3. Détecter les changés par comparaison avec l'inventaire précédent
|
||||
curl -s "$BASE/api/vault/TikTak/paths?limit=20000" -H "Authorization: Bearer $KEY" \
|
||||
| jq -r '.results[] | select(.type=="file") | "\(.mtime) \(.size) \(.path)"' > apres.txt
|
||||
```
|
||||
|
||||
> `PUT /api/file/{vault}/save` rafraîchit l'index de façon synchrone : la re-liste
|
||||
> qui suit voit le nouveau `mtime`/`size` sans attendre le watcher. Les sauvegardes
|
||||
> texte émettent `file_modified` (webhook) pour tirer les retours.
|
||||
|
||||
---
|
||||
|
||||
## 6. Temps réel
|
||||
|
||||
### 6.1 SSE — `/api/events`
|
||||
|
||||
Flux d'événements de changement d'index (fichiers créés/supprimés/modifiés), avec
|
||||
reconnexion automatique côté client.
|
||||
@@ -296,7 +344,7 @@ reconnexion automatique côté client.
|
||||
curl -N "$BASE/api/events"
|
||||
```
|
||||
|
||||
### 5.2 WebSocket — collaboration
|
||||
### 6.2 WebSocket — collaboration
|
||||
|
||||
`ws(s)://<hôte>/ws/collab/{vault}/{path}` transporte les mises à jour
|
||||
Yjs/CRDT et la présence (curseurs distants). Authentification par cookie
|
||||
@@ -305,7 +353,7 @@ Voir [Édition & collaboration](./COLLABORATION.md).
|
||||
|
||||
---
|
||||
|
||||
## 6. Limites et bonnes pratiques
|
||||
## 7. Limites et bonnes pratiques
|
||||
|
||||
- **Rate limiting** : les endpoints de login et les outils IA sont limités ;
|
||||
respectez `retry_after` en cas de `429`.
|
||||
@@ -320,12 +368,12 @@ Voir [Édition & collaboration](./COLLABORATION.md).
|
||||
|
||||
---
|
||||
|
||||
## 7. Dépannage
|
||||
## 8. Dépannage
|
||||
|
||||
| Code | Cause probable |
|
||||
|---|---|
|
||||
| `401` | Jeton absent, expiré ou révoqué |
|
||||
| `403` | Compte sans accès à cette vault / réservé admin |
|
||||
| `403` | Compte sans accès à cette vault / réservé admin / clé à portée limitée hors périmètre |
|
||||
| `404` | Vault, fichier ou chemin inexistant |
|
||||
| `409` | Conflit (fichier déjà existant, etc.) |
|
||||
| `422` | Corps de requête invalide (schéma Pydantic) |
|
||||
|
||||
@@ -19,6 +19,10 @@ Cline, tout client compatible MCP) via un serveur **Streamable HTTP** monté sur
|
||||
(`Authorization: Bearer <token>`). Une seule clé fonctionne pour l'API REST
|
||||
**et** le MCP. Créez-la depuis l'interface (Configurations → 🔑 Clés API & MCP)
|
||||
ou via `POST /api/auth/tokens` — voir [API REST §2.2](./API_REST.md#22-clés-api-longue-durée-recommandé-pour-scripts--mcp).
|
||||
Pour une intégration limitée aux fichiers (ex. TikTak), créez une clé
|
||||
`{"vaults":["TikTak"],"scope":"files"}` ([API REST §2.3](./API_REST.md#23-clés-à-portée-limitée-synchronisation-externe-ex-tiktak)) :
|
||||
les outils hors fichiers sont refusés (`token_scope_denied`) et masqués du
|
||||
`list_tools`, et les autres vaults répondent en erreur d'accès.
|
||||
3. Si l'authentification est désactivée (`OBSIGATE_AUTH_ENABLED=false`), le
|
||||
serveur MCP accepte un utilisateur anonyme disposant de tous les vaults.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user