# TRAIL DPS Workspace 1.1.1-lot3 - Correctif mot de passe, roles et QPM

Date de reference : 4 aout 2026

## Perimetre

Ce correctif ajoute la reinitialisation de mot de passe par courriel, impose un role metier unique, expose le catalogue des droits et corrige la boucle SQL d'idempotence susceptible de saturer la base `synoluisharing`.

## Reinitialisation de mot de passe

### Parcours public

- Nouvelle route publique `POST /api/v1/auth/password-reset/request`.
- Reponse volontairement identique, que l'adresse existe ou non.
- Seuls les comptes actifs possedant au moins une adhesion active peuvent recevoir un lien.
- Jeton aleatoire, stockage SHA-256, usage unique, expiration 30 minutes.
- Les anciens jetons non utilises du compte sont revoques avant emission du nouveau.
- Le jeton est place dans le fragment URL `#token=` afin de ne pas etre transmis dans la requete HTTP initiale.
- Nouvelle page publique `public/password-reset.php` avec CSP stricte, `no-referrer`, `no-store` et effacement immediat du fragment dans l'historique du navigateur.
- Apres confirmation, les sessions refresh existantes sont revoquees.

### Parcours ADMIN_ORGA

- La route membre envoie maintenant le courriel au lieu de retourner un jeton a copier.
- Un membre revoque recoit l'erreur `MEMBER_REACTIVATION_REQUIRED` et doit etre reactive avant l'envoi.
- L'envoi est audite sans enregistrer le jeton.

### Limitation des demandes

La migration 006 cree `password_reset_requests` pour appliquer :

- au moins 10 minutes entre deux demandes pour une meme adresse ;
- maximum 5 demandes sur 24 heures par adresse ;
- maximum 20 demandes par heure et par adresse IP ;
- aucun renseignement public sur l'existence du compte.

## Configuration SMTP

Le fichier `config/mail.local.example.php` est fourni sans secret. En production :

1. copier cet exemple vers `config/mail.local.php` ;
2. renseigner le mot de passe de la boite `dpstrail-noreply@synoluvia.fr` uniquement dans ce fichier local ;
3. verifier `app.base_url = https://traildpsworkspace-staging.synoluvia.fr` dans la configuration active ;
4. ne jamais integrer `config/mail.local.php` dans un ZIP, un depot ou un journal.

Le modele utilise le SMTP MX Plan sur `ssl0.ovh.net`, port 465, SSL/TLS et authentification par l'adresse e-mail complete.

Sur RESTORE, ne pas creer `config/mail.local.php` : l'envoi reste desactive. Pour une recette exceptionnelle, utiliser uniquement `recipient_override` vers une adresse controlee.

## Roles

- Un seul role metier est accepte par utilisateur lors de la modification et de la reactivation.
- `ADMIN_POSTE` demeure un role local PLACE et n'est jamais affectable dans le Workspace.
- La liste des membres retourne `role_catalog` et `single_role_required=true` sans appel API supplementaire.

## Correctif QPM / base synoluisharing

### Idempotence

L'ancien traitement pouvait rappeler recursivement `begin()` lorsqu'une cle expiree restait presente sur la cle primaire. Le nouveau traitement :

- recherche la ligne meme expiree sous transaction et `FOR UPDATE` ;
- rejoue une reponse active ou signale un conflit de corps ;
- recycle atomiquement une ligne expiree ;
- borne a deux passages la seule course insertion/lecture concurrente ;
- ne traite comme doublon que SQLSTATE `23000` avec code MySQL `1062` ;
- supprime toute recursion.

### HMAC et reprise client

- Un doublon de nonce reste un rejeu HMAC.
- Toute autre erreur PDO devient `DATABASE_UNAVAILABLE` avec HTTP 503 et `Retry-After`.
- Les reponses API peuvent maintenant transmettre `Retry-After` a PLACE.

## Migration

Migration a appliquer : `006_password_reset_mail_and_rate_limit.sql`.

Depuis PowerShell, apres depot des fichiers, utiliser le script fourni :

```powershell
.\scripts\Invoke-WorkspaceMigration.ps1 `
  -SshTarget "UTILISATEUR@HOTE_SSH" `
  -RemotePath "/home/synolui/programme/traildpsworkspace-staging"
```

Pour RESTORE, remplacer le chemin par :

```text
/home/synolui/programme/traildpsworkspace-restore
```

Le script execute uniquement :

1. `php scripts/migrate.php` ;
2. `php scripts/verify_installation.php` ;
3. `php scripts/lot3_readiness.php`.

## Controles apres migration

- `migration_006_applied` doit etre `true`.
- `password_reset_rate_limit` doit etre `true`.
- La version doit etre `1.1.1-lot3`.
- Le contrat PLACE recommande doit etre `4.2.7-lot3.1.0`.
- Tester une demande publique avec une adresse active, puis une demande administrateur.
- Verifier qu'un membre `REVOKED` ne peut recevoir aucun lien avant reactivation.
- Surveiller les statistiques SQL OVH pendant 48 a 72 heures avant toute decision de migration vers Web Cloud Databases.

## Validation

- Lint PHP de tous les fichiers livres par le correctif : OK. Le fichier actif `config/config.php`, propre a chaque serveur et exclu du ZIP incrementiel, doit etre conserve et valide sur le serveur.
- Suite contractuelle Workspace : 41 tests sur 41 reussis sur STAGING.
