Files
ObsiGate/docs/features/settings-order-avatar-113.md
bruno 33fe1a3439
CI / lint (push) Successful in 1m59s
CI / security (push) Successful in 1m28s
CI / test (push) Successful in 4m14s
CI / build (push) Successful in 1m20s
CI / e2e (push) Successful in 13m43s
feat: ordre naturel des sections Configurations et avatar utilisateur #113
2026-09-23 22:18:29 -04:00

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é).