95 lines
4.7 KiB
Markdown
95 lines
4.7 KiB
Markdown
# #113 — Ordre naturel des sections Configurations & avatar utilisateur
|
|
|
|
> **Version livrée :** 2.22.0 · **Statut :** 🟢 · **Impact :** 🟡
|
|
> **Zone :** frontend (`index.html`, `frontend/js/config.js`, `frontend/js/auth.js`,
|
|
> `frontend/style.css`, i18n FR/EN) + backend (`backend/auth/router.py`,
|
|
> `backend/auth/user_store.py`) + CI (`.gitea/workflows/ci.yml`).
|
|
|
|
## Contexte
|
|
|
|
Deux irritants sur la page **Configurations** :
|
|
|
|
- l'ordre des sections était historique et peu naturel (Recherche en tête, Profil
|
|
noyé en position 11, À propos au milieu) ;
|
|
- la section **Profil** ne permettait pas de personnaliser l'image affichée dans le
|
|
cercle du compte en bas de la sidebar (initiales uniquement).
|
|
|
|
## Ce qui a été livré
|
|
|
|
### A. Ordre naturel des sections (TOC = page)
|
|
|
|
Nouvel ordre, appliqué **à la liste `<ul class="help-nav-list">` (TOC) et aux
|
|
`<section>` de la page**, dans le même ordre :
|
|
|
|
1. **Profil** (`#cfg-profile`) — en premier
|
|
2. Sécurité du compte (`#cfg-security`)
|
|
3. Thèmes (`#cfg-themes`)
|
|
4. Paramètres de recherche (`#cfg-search`)
|
|
5. Historique récent (`#cfg-recent`)
|
|
6. Filtrage de tags (`#cfg-tags`)
|
|
7. Fichiers cachés (`#cfg-hidden-files`)
|
|
8. Synchronisation (`#cfg-sync`)
|
|
9. Paramètres backend (`#cfg-backend-settings`)
|
|
10. Diagnostics (`#cfg-diags`)
|
|
11. Clés API IA (`#cfg-ai`)
|
|
12. Sources connectées (`#cfg-sources`)
|
|
13. Clés API & MCP (`#cfg-tokens`)
|
|
14. Notifications push (`#cfg-push`)
|
|
15. Webhooks (`#cfg-webhooks`)
|
|
16. Partages publics (`#cfg-partages-publics`)
|
|
17. Plugins (`#cfg-plugins`)
|
|
18. **À propos** (`#cfg-about`) — en dernier
|
|
|
|
Regroupement retenu : **Compte & apparence → Navigation & contenu → Système →
|
|
Intégrations & notifications → À propos**.
|
|
|
|
Les ancres `cfg-tags` et `cfg-partages-publics` étaient posées sur un `<h2>` à
|
|
l'intérieur d'une `<section>` sans id : elles sont désormais portées par la
|
|
`<section>` elle-même, pour que le scroll vise le haut de la section (comme toutes
|
|
les autres).
|
|
|
|
### B. Avatar utilisateur ( Profil )
|
|
|
|
- **Import d'image** : bouton « Choisir une image » + overlay caméra au survol de
|
|
l'aperçu circulaire (88 px) → `<input type="file" accept="image/png,image/jpeg,image/webp">`.
|
|
- **Traitement client** (`config.js`) : garde type (PNG/JPEG/WEBP) et taille brute
|
|
(8 Mo), **recadrage carré central** et redimensionnement à **256 px** via canvas,
|
|
export JPEG qualitée 0,85 (fond blanc pour les PNG transparents).
|
|
- **Persistance serveur** : `PATCH /api/auth/me` avec `{"avatar": "<data-url>"}` ;
|
|
`""` supprime. Validation stricte dans `backend/auth/router.py`
|
|
(`_validate_avatar`) : data-URL PNG/JPEG/WebP uniquement (**SVG refusé** — surface
|
|
XSS), plafond 400 000 caractères, base64 valide et **octets magiques** contrôlés.
|
|
Champ `avatar` ajouté à `data/users.json` (`create_user`), renvoyé par
|
|
`GET/PATCH /api/auth/me` et par le payload `user` de login.
|
|
- **Affichage sidebar** (`auth.js`) : `renderUserSection()` insère un
|
|
`<img class="sidebar-user-avatar-img">` dans `#sidebar-user-avatar` quand
|
|
`user.avatar` est défini, sinon les initiales (repli inchangé). Helpers
|
|
`AuthManager.updateCachedUser()` et `AuthManager.isAuthEnabled()`.
|
|
- **Suppression** : bouton « Supprimer la photo » (stylisté danger), revenu aux
|
|
initiales.
|
|
- **Auth désactivée** : le bloc avatar est masqué (pas de compte, sidebar masquée).
|
|
- Feedback : toasts `config.avatar_updated` / `config.avatar_removed`, erreurs en
|
|
ligne (`config.avatar_invalid_type`, `config.avatar_too_large`,
|
|
`config.avatar_upload_failed`).
|
|
|
|
## Tests
|
|
|
|
- `tests/test_auth_api.py` — classe `TestAvatar` (+8) : GET/PATCH exposent
|
|
l'avatar, data-URL PNG acceptée, `""` efface, SVG refusé, payload non-image refusé,
|
|
trop grand refusé, base64 invalide refusé, avatar présent dans le payload de login.
|
|
- `tests/frontend/settings-order-avatar.test.mjs` (nouveau, ajouté au job `lint`) —
|
|
9 tests : ordre TOC (Profil 1er, À propos dernier), ordre de page strictement
|
|
identique à la TOC, aucune ancre morte / section orpheline, présence de l'UI avatar
|
|
dans `#cfg-profile`, flux `config.js` (types, taille, resize, PATCH, rafraîchissement
|
|
sidebar), rendu `auth.js`, règles CSS, clés i18n FR/EN, validation backend.
|
|
- Vérifications locales : pytest 1302 passed, ruff/mypy 0 erreur, tests frontend
|
|
statiques + JSDOM verts.
|
|
|
|
## Limitations connues
|
|
|
|
- L'avatar est stocké en data-URL dans `data/users.json` (adéquat pour un usage
|
|
personnel ; un stockage fichier dédié restera possible si les comptes se multiplient).
|
|
- La conversion GIF/animé n'est pas prise en charge (types PNG/JPEG/WEBP uniquement).
|
|
- Le nom d'affichage du profil reste local (`localStorage`) et n'est pas poussé au
|
|
serveur (comportement antérieur conservé).
|