Files
SchotzIAD/frontend/src/app/shared/components/password-input/password-input.component.html
T
MadJax ee47d04b90 Navigation utilisateur : avatar, paramétrage, maintenance, mot de passe
Réorganisation complète de la navigation suite au retour d'usage, plus
changement de mot de passe et affichage/masquage des mots de passe saisis.

Backend :
- Nouvel endpoint POST /api/auth/change-password (ChangePasswordDto,
  MotDePasseActuelInvalideException, validateur, AuthService.ChangePasswordAsync).
  Exige l'ancien mot de passe, distinct de la réinitialisation par e-mail.
- Endpoint placé dans SessionController (protégé par l'autorisation globale) et
  NON dans AuthController : AuthController porte [AllowAnonymous] au niveau
  classe, ce qui rend inopérant un [Authorize] posé sur une seule action (bug de
  sécurité détecté par test manuel — l'endpoint était accessible sans jeton —
  puis corrigé par ce déplacement).

Frontend :
- Page « Compte utilisateur » (ProfilComponent renommé) : section Maintenance
  extraite vers MaintenanceComponent (route /maintenance) ; nouvelle section de
  changement de mot de passe (ancien + nouveau + confirmation).
- ParametrageComponent (route /parametrage) : menu latéral Compte / Véhicules /
  Barème + contenu en routes enfants, réutilisant les composants existants.
  Compte et Véhicules en authGuard seul ; Barème garde profilConfigureGuard.
- Barre de navigation : Véhicules et Barème retirés (rejoignent Paramétrage) ;
  logo passé en format horizontal (icône + texte).
- Avatar utilisateur (initiales) à droite de la barre : sous-menu au survol
  (identité, Paramétrage, Maintenance, Se déconnecter). Menu « Specs » converti
  en dropdown survolable (Exigences / Conception / Tâches).
- Dropdowns : panneau collé au bouton (plus d'espace mort) pour que le survol
  reste continu jusqu'au panneau — un espace créait une fermeture prématurée.
- Barre masquée sur les pages publiques (login/register/forgot/reset-password)
  même avec un jeton résiduel expiré/invalide (détection via Router events, pas
  seulement la présence du jeton).
- PasswordInputComponent (shared) : bouton œil afficher/masquer, ControlValueAccessor,
  style aligné sur les champs texte classiques. Appliqué aux 8 champs mot de
  passe de l'application (login, register, reset-password, compte utilisateur).

Specs : requirements.md (exigences 20, 21 + glossaire) et design.md (endpoints,
DTO, composants) mis à jour. 54 tests backend au vert.
2026-09-22 09:54:25 +02:00

37 lines
1.6 KiB
HTML

<div class="password-input">
<input
[id]="id"
[type]="visible() ? 'text' : 'password'"
[autocomplete]="autocomplete"
[attr.aria-describedby]="ariaDescribedby"
[attr.aria-invalid]="ariaInvalid"
[disabled]="disabled()"
[value]="value"
(input)="onInput($any($event.target).value)"
(blur)="onBlur()"
/>
<button
type="button"
class="password-input__bouton-oeil"
[attr.aria-label]="visible() ? 'Masquer le mot de passe' : 'Afficher le mot de passe'"
[attr.aria-pressed]="visible()"
[title]="visible() ? 'Masquer le mot de passe' : 'Afficher le mot de passe'"
(click)="basculerVisibilite()"
>
@if (visible()) {
<!-- Icône « œil barré » (mot de passe visible : cliquer pour masquer). -->
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 3l18 18" stroke-linecap="round" />
<path d="M10.58 10.58a2 2 0 0 0 2.83 2.83" stroke-linecap="round" />
<path d="M9.88 4.24A9.94 9.94 0 0 1 12 4c5 0 9 4 10 8-.31 1.14-.85 2.28-1.57 3.32M6.11 6.1C4.24 7.44 2.77 9.5 2 12c1 4 5 8 10 8 1.06 0 2.07-.18 3-.5" stroke-linecap="round" />
</svg>
} @else {
<!-- Icône « œil ouvert » (mot de passe masqué : cliquer pour afficher). -->
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M2 12s4-8 10-8 10 8 10 8-4 8-10 8-10-8-10-8Z" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="12" cy="12" r="3" />
</svg>
}
</button>
</div>