veza/docs/REMEDIATION_PROGRESS.md
senke b103a09a25 chore: consolidate CI, E2E, backend and frontend updates
- CI: workflows updates (cd, ci), remove playwright.yml
- E2E: global-setup, auth/playlists/profile specs
- Remove playwright-report and test-results artifacts from tracking
- Backend: auth, handlers, services, workers, migrations
- Frontend: components, features, vite config
- Add e2e-results.json to gitignore
- Docs: REMEDIATION_PROGRESS, audit archive
- Rust: chat-server, stream-server updates
2026-02-17 16:43:21 +01:00

169 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Progression de la remédiation — Stabilisation frontend
**Référence** : [Plan de remédiation](.cursor/plans/frontend_stabilization_remediation_b9e1b51d.plan.md)
**Dernière mise à jour** : 16 février 2026 (Phase 2 audit complétée, E2E auth corrigés)
### Phase 2 — Stabilisation (Audit technique) ✅
- **P2.1 OAuth** : Vérifié — `GetUserByOAuthID` et `getOrCreateUser` en place.
- **P2.2 Education** : Vérifié — aucune route education dans `internal/`.
- **P2.3 npm** : Vérifié — `npm audit --audit-level=critical` = 0 vulnérabilités.
- **P2.4 Bypass flags** : Vérifié — `validateNoBypassFlagsInProduction` rejette en prod.
- **P2.5 E2E auth** : Corrigé — `VITE_API_URL=/api/v1` en CI, health check global-setup pour URLs relatives, timeouts et sélecteurs auth renforcés (commit 85267d2b).
---
## Audit sécurité (AUDIT_TECHNIQUE_INTEGRAL_2026_02_16)
Référence : [archive/AUDIT_TECHNIQUE_INTEGRAL_2026_02_16.md](archive/AUDIT_TECHNIQUE_INTEGRAL_2026_02_16.md).
**Référence** : [Plan de remédiation sécurité](.cursor/plans/remédiation_sécurité_audit_veza_0de3fd35.plan.md)
### Lot 2 — Routes Education fantômes (A01) ✅
- **Constat** : Les packages `internal/api/education/` et `internal/core/education/` étaient des répertoires vides (aucun fichier Go, aucune route enregistrée).
- **Action** : Suppression des répertoires vides. Aucune route Education n'était exposée ; le risque identifié dans l'audit ne s'appliquait pas au code actuel.
### Lot 6 — Bypass flags (A05) ✅
- **Constat** : `BYPASS_CONTENT_CREATOR_ROLE` et `CSRF_DISABLED` sont déjà rejetés en production via `validateNoBypassFlagsInProduction()`.
- **Vérification** : `NewConfig()` appelle `ValidateForEnvironment()` qui invoque `validateNoBypassFlagsInProduction(c.Env)` au démarrage. Aucun changement nécessaire.
### Lot 8 — Vulnérabilités npm (A06) ✅
- **Action** : Suppression de `@lhci/cli`, `newman`, `pa11y-ci` (devDependencies avec vulnérabilités, utilisées uniquement par Makefile.old obsolète).
- **Scripts** : `qa:postman`, `qa:lh`, `qa:a11y` redirigés vers message explicatif.
- **Résultat** : 25 vulnérabilités → 0 (npm audit fix pour lodash).
### Lot 9 — 2FA login flow (A07) ✅
- **Vérification** : Flow correct — Login → requires_2fa → TwoFactorVerify → onSuccess(code) → complete2FALogin → POST /auth/login/2fa.
- **Tests** : E2E existant dans `auth.spec.ts` (« should complete login with 2FA code ») avec E2E_2FA_CODE. Aucune correction nécessaire.
### Lot 10 — OAuth user lookup (A07) ✅
- **Vérification** : `GetUserByOAuthID(oauthID, provider)` déjà implémenté dans `database.go` (lignes 557-576). Utilise `federated_identities` avec `provider` et `provider_id`. `OAuthService.getOrCreateUser` appelle ce lookup en priorité (ligne 403). Aucune correction nécessaire.
### Lot 11 — Download tracks public (A04) ✅
- **Action** : Vérification des droits avant téléchargement pour les tracks payants. Nouveau service `TrackDownloadLicenseChecker` (`internal/services/track_download_license.go`) qui vérifie si le track est vendu comme produit et si l'utilisateur a une licence valide. Injection dans `TrackHandler.DownloadTrack` — si track vendu et utilisateur non propriétaire, 403 sans licence.
### Lot 12 — Alignement Go version (CI) ✅
- **Action** : `go-version` dans `.github/workflows/ci.yml` aligné sur `1.24` pour correspondre à `go.mod`.
### Lot 13 — .unwrap() / .expect() critiques en Rust (Stabilité) ✅
- **Action** : Remplacement des unwrap critiques dans `veza-stream-server/src/utils/mod.rs``validate_signature` et `generate_signature`. `duration_since(UNIX_EPOCH)` gère maintenant l'erreur (retourne false). `generate_signature` retourne `Option<String>` au lieu de paniquer sur HMAC invalide. ~80+ unwraps restants (tests, regex statiques) — risque accepté pour l'instant.
---
## Vulnérabilités npm (A06 — Phase 1) ✅
Référence : [archive/AUDIT_TECHNIQUE_INTEGRAL_2026_02_16.md](archive/AUDIT_TECHNIQUE_INTEGRAL_2026_02_16.md) section A06.
### Correctifs appliqués
- **npm audit fix** : brace-expansion, diff, undici corrigés automatiquement.
- **React Router XSS (GHSA-2w69-qvjg-hvjx)** : `react-router-dom` mis à jour vers ^6.30.3 (@remix-run/router 1.23.2).
- **Axios DoS (GHSA-43fc-jf86-j433)** : override `axios >= 1.13.5` dans `package.json` racine.
- **class-variance-authority** : réintégré (dépendance manquante pour button/card).
- **CI** : `npm audit --audit-level=high` exécuté depuis la racine du monorepo.
### Vulnérabilités restantes (devDependencies uniquement)
25 vulnérabilités dans @lhci/cli, newman, pa11y-ci (cookie, jose, lodash, node-forge, qs, semver, tar-fs, tmp, ws). **Risque accepté** : ces packages ne sont pas inclus dans le build de production. Correction via `npm audit fix --force` entraînerait des breaking changes (downgrade @lhci/cli, newman, pa11y-ci).
---
## Rate limiting (A04) ✅
Référence : [archive/AUDIT_TECHNIQUE_INTEGRAL_2026_02_16.md](archive/AUDIT_TECHNIQUE_INTEGRAL_2026_02_16.md) — Points de rupture (ligne 170), A04 (ligne 232).
### Correctifs appliqués
- **Rate limiting toujours actif** : suppression de la condition `Env != EnvDevelopment` pour le rate limit global et register.
- **Limites assouplies en dev** : `getDefaultRateLimitLimit(env)` — 1000 req/min en dev/test, 200 en staging/prod.
- **Register assoupli en dev** : `getDefaultRegisterAttempts(env)` — 20 inscriptions/heure en dev/test, 3 en staging/prod.
- **Documentation** : README mis à jour avec tableau des limites par environnement.
---
## Phase 1 — Backend solide ✅
### 1.1 Sécurité backend ✅
- **.gitignore** : Renforcement des patterns pour `.env`, `.env.*`, `**/.env`, `**/.env.local`, `veza-*/.env`, `apps/web/.env.local` (ne jamais committer de secrets).
- **Chat server** : Dans `veza-chat-server/src/jwt_manager.rs`, `validate_access_token` vérifie désormais en base que lutilisateur existe (si `db_pool` disponible) ; pas de fallback « user » si absent en DB — connexion refusée.
- **Backend Go** : Le handler de refresh token vérifie déjà lexistence de lutilisateur en DB (voir `internal/core/auth/service.go` RefreshToken).
- **Pagination** : Contrôle strict `page >= 1` et `1 <= limit <= 100` avec retour **400** et message clair dans :
- `internal/handlers/playlist_handler.go` (GetPlaylists),
- `internal/handlers/profile_handler.go` (ListUsers),
- `internal/core/track/handler.go` (ListTracks).
### 1.2 API et contrats ✅
- **Healthcheck** : Les Dockerfiles (Dockerfile, Dockerfile.production) utilisent déjà `http://localhost:8080/api/v1/health`.
- **go-clamd** : Documenté dans `veza-backend-api/docs/CLAMAV_SETUP.md` (limitation : lib abandonnée ; désactivation via `ENABLE_CLAMAV=false` = pas de scan).
- **Search** : Contrat documenté dans `veza-backend-api/docs/API_DOCUMENTATION.md` — recherche par ressource (`/api/v1/tracks/search`, `/api/v1/playlists/search`, `/api/v1/users/search`) ; pas dendpoint unifié `GET /api/v1/search`.
- **Endpoints marketplace / social** : Routes existantes (wishlist, panier, groups) ; pas de 501 ajouté.
### 1.3 Services Rust ✅
- **Redis** : Versions alignées (redis 0.32) dans `veza-chat-server` et `veza-stream-server` (Cargo.toml).
### 1.4 Infra et CD ✅
- **Docker-compose** : Mots de passe en dur remplacés par variables denvironnement (`POSTGRES_PASSWORD`, `RABBITMQ_DEFAULT_PASS`, etc.) avec valeurs par défaut pour le dev dans `docker-compose.yml`.
- **CD** : Commentaire ajouté dans `.github/workflows/cd.yml` : pour pousser vers un registry, configurer les secrets `DOCKER_REGISTRY`, `DOCKER_REGISTRY_USERNAME`, `DOCKER_REGISTRY_PASSWORD`.
---
## Phase 2 — Frontend : bugs et comportements critiques
### 2.1 Auth et 2FA ✅
- **2FA login** : Implémenté. Backend : `POST /api/v1/auth/login/2fa` (body : `email`, `password`, `code`, `remember_me`) ; frontend : `completeLogin2FA()` dans `apps/web/src/services/api/auth.ts`, action `complete2FALogin` dans le store, flux dans LoginPage (affichage TwoFactorVerify quand `requires_2fa`, puis appel API et redirection).
- **Typage auth** : Traité dans `apps/web/src/services/api/auth.ts` (réponse typée `LoginResponse`/`RegisterResponse`, options logout typées, `isAxiosError` pour les erreurs).
- **Redirect si déjà authentifié** : LoginPage / RegisterPage utilisent `authStore` / `useUser` ; à vérifier en conditions réelles (pas de boucle login → redirect).
### 2.2 Memory leaks et logs ✅
- **setTimeout** : ChatInput, SocialViewFeedItem, PostCard ont déjà un cleanup (clearTimeout dans le return du `useEffect`).
- **console.log** : GlobalSearchBar utilise `logger.debug` ; pas de suppression massive demandée pour linstant.
### 2.3 Accessibilité ✅
- **ChatInput** : Le champ principal a déjà `aria-label="Type a message"`.
- **Sidebar (layout)** : `components/layout/Sidebar.tsx` utilise déjà `FocusTrap` quand la sidebar est ouverte en mobile (`sidebarOpen && isMobile`).
---
## Phase 3 — Tests (en cours)
- **Vitest** : Suite complète **0 échec** (265 fichiers passés, 4 skippés ; 3230 tests passés, 87 skippés). Corrections appliquées :
- **SettingsPage.test.tsx** : Load error → assertion sur `getByRole('alert')` + contenu flexible ; save error → reset de `settingsSchema.safeParse` dans `beforeEach` (évite que le test « validation errors » laisse `safeParse` en échec pour le test suivant) ; userEvent pour le clic Save.
- **RegisterPage.test.tsx** : Terms → assertion sur « handleRegister non appelé » + optionnel message terms ; username « déjà pris » → `getAllByText` (plusieurs nœuds affichent le message) ; vérification notice → `findByText` + `act` autour du mock + rerender ; email dans la notice → texte partiel + `test@example.com` (texte split dans le DOM).
- **ForgotPasswordForm.test.tsx** : « should disable form while loading » → attente après `waitFor` pour que la promesse mock se résolve avant teardown (évite « state update after unmount »).
- **usePlaybackRealtime.test.ts** : 8 tests réactivés dans un second `describe` avec vrais timers (WebSocket lifecycle) ; plus de skip.
- **Tests par groupes (machines limitées)** : Vitest configuré pour limiter RAM/CPU (`pool: 'threads'`, `maxThreads: 2`, `fileParallelism: false`). Scripts npm ajoutés pour exécuter les tests par groupe : `test:auth`, `test:tracks`, `test:playlists`, `test:player`, `test:streaming`, `test:settings-profile-chat`, `test:components-ui`, `test:components-other`, `test:services`, `test:hooks`, `test:misc`. Commande `test:groups` lance tous les groupes séquentiellement. Ordre recommandé pour le diagnostic : petits groupes d'abord (settings-profile-chat, streaming, hooks, misc) puis les plus gros.
- **Providers / mocks** : Wrappers dans `src/test/` ; MSW dans `src/mocks/`. À aligner sur les contrats API si besoin.
- **Storybook** : `npm run test:storybook` (script `scripts/audit-storybook.js`) nécessite Storybook servi sur **port 6007** ; lancer `npm run build-storybook` puis servir le dossier `storybook-static` sur 6007, puis `npm run test:storybook`.
- **E2E** : Playwright (`npm run test:e2e`). Parcours critiques et fichiers listés dans `apps/web/e2e/README.md` (auth, smoke, playlists, search, profile, upload). Test search : `e2e/tests/search.spec.ts` (navigation `/search`, saisie requête, résultats ou état vide). Test 2FA : dans `auth.spec.ts` (skippé sauf si `E2E_2FA_CODE` et compte 2FA configurés).
## Phase 4 — Dette structurante ✅
- **Loading** : Composants centralisés en place — `LoadingState`, `LoadingSpinner`, `Skeleton`, `ButtonLoading` ; guide `apps/web/src/docs/LOADING_STATES_PATTERN.md` mis à jour avec section **LoadingState** et recommandation (full-page/block → LoadingState, list/card → Skeleton).
- **Modal → Dialog** : `Modal` déprécié (S1.4) ; `Dialog` sappuie dessus. Feature modals récents utilisent déjà `Dialog`. Préférer `Dialog` pour tout nouveau code.
- **Track type** : Commentaire ajouté dans `apps/web/src/features/tracks/types.ts` — source of truth pour Track = `features/player/types` ; champs upload/backend = `features/tracks/types/track.ts`.
- **Interceptors** : Documenté en en-tête dans `interceptors.ts` ; pas de découpage supplémentaire pour linstant.
## Phase 5 — Features fantômes et cohérence ✅
- **Coming Soon** : Routes documentées dans `apps/web/docs/FEATURE_STATUS.md``/gear`, `/live`, `/education`, `/queue`, `/developer` (placeholder `ComingSoon` dans `routeConfig.tsx`).
- **Feature flags** : Référence dans `FEATURE_STATUS.md` vers `src/config/features.ts` et `VITE_FEATURE_*` ; liste des flags (TWO_FACTOR_AUTH, PLAYLIST_*, HLS_STREAMING, ROLE_MANAGEMENT, NOTIFICATIONS).
- **Marketplace / groups / search** : Mention dans `FEATURE_STATUS.md` (routes marketplace, search par ressource, groups dans Social).
- **Typo** : `useLibraryManager.ts` — message « coming soon available » corrigé en « coming soon — available in the next release ».
## Phase 6 — Maturité ✅
- **TypeScript** : `npx tsc --noEmit` exécuté — 0 erreur.
- **Docs** : `FEATURE_STATUS.md` créé (Coming Soon + feature flags + marketplace/search) ; `LOADING_STATES_PATTERN.md` enrichi ; `REMEDIATION_PROGRESS.md` à jour.
- **UX** : Checklist finale rappelée ci-dessous (skip link, aria-label, focus trap, pas de console.log en prod).
---
## Checklist de validation finale (rappel)
- **Validation légère (machine limitée)** : `./scripts/validate-light.sh` — évite `go test ./...` et Playwright qui peuvent saturer la RAM. Lance : go build, tsc, npm build, tests auth/hooks/services/misc, cargo build.
- `npx vitest run` : 0 échec (ou < 5 % skippés avec ticket). Sur machine limitée en RAM/CPU : utiliser `npm run test:groups` ou les scripts par groupe (`test:auth`, `test:tracks`, etc.) pour éviter la saturation des ressources.
- `npm run build` : succès sans warning bloquant.
- `npx tsc --noEmit` : 0 erreur.
- `npm run test:storybook` : 0 erreur. **Procédure de validation Storybook sur 6007** :
1. `cd apps/web && npm run build-storybook`
2. Démarrer le serveur sur le port **6007** : `node scripts/serve-storybook-static.cjs` (ou `npx serve storybook-static -l 6007`) et le laisser tourner
3. Dans un autre terminal : `npm run test:storybook` (le script [scripts/audit-storybook.js](apps/web/scripts/audit-storybook.js) cible `http://localhost:6007` et ne démarre pas le serveur). Option : `npm run test:storybook:playwright` démarre automatiquement le serveur via [playwright.config.storybook.ts](apps/web/playwright.config.storybook.ts).
- Aucun `console.log` / debug en prod.
- Skip link + aria-label ChatInput + focus trap Sidebar en place.
- 2FA login : backend à compléter puis frontend à brancher.