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.
63 lines
3.1 KiB
C#
63 lines
3.1 KiB
C#
using SchotzIadKmTracker.Api.Models.DTOs;
|
|
|
|
namespace SchotzIadKmTracker.Api.Services;
|
|
|
|
/// <summary>
|
|
/// Logique métier d'authentification de l'application mono-utilisateur :
|
|
/// existence du compte, inscription, connexion, demande et application de la
|
|
/// réinitialisation du mot de passe.
|
|
/// </summary>
|
|
public interface IAuthService
|
|
{
|
|
/// <summary>
|
|
/// Indique si un compte existe déjà, afin d'orienter le frontend (inscription vs connexion).
|
|
/// </summary>
|
|
/// <param name="ct">Jeton d'annulation de l'opération.</param>
|
|
/// <returns><c>true</c> s'il existe au moins un compte, <c>false</c> sinon (Exigences 1.2, 9.1).</returns>
|
|
Task<bool> CompteExisteAsync(CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// Inscrit le compte unique. Lève <see cref="Exceptions.CompteDejaExistantException"/>
|
|
/// si un compte existe déjà (Exigence 1).
|
|
/// </summary>
|
|
/// <param name="dto">Email et mot de passe fournis à l'inscription.</param>
|
|
/// <param name="ct">Jeton d'annulation de l'opération.</param>
|
|
Task RegisterAsync(RegisterDto dto, CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// Authentifie le compte et émet un jeton JWT. Lève
|
|
/// <see cref="Exceptions.IdentifiantsInvalidesException"/> si les identifiants sont invalides (Exigence 2).
|
|
/// </summary>
|
|
/// <param name="dto">Identifiants de connexion (email et mot de passe).</param>
|
|
/// <param name="ct">Jeton d'annulation de l'opération.</param>
|
|
/// <returns>Le jeton JWT émis et sa date d'expiration.</returns>
|
|
Task<LoginResultDto> LoginAsync(LoginDto dto, CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// Traite une demande de réinitialisation de mot de passe. Par principe de non-divulgation,
|
|
/// se termine toujours sans exception, que l'email corresponde ou non à un compte (Exigence 6.6).
|
|
/// </summary>
|
|
/// <param name="dto">Email pour lequel demander la réinitialisation.</param>
|
|
/// <param name="ct">Jeton d'annulation de l'opération.</param>
|
|
Task ForgotPasswordAsync(ForgotPasswordDto dto, CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// Réinitialise le mot de passe à partir d'un jeton de réinitialisation. Lève
|
|
/// <see cref="Exceptions.LienResetInvalideException"/> si le jeton est inconnu ou déjà utilisé,
|
|
/// <see cref="Exceptions.LienResetExpireException"/> s'il a expiré (Exigence 7).
|
|
/// </summary>
|
|
/// <param name="dto">Jeton de réinitialisation et nouveau mot de passe.</param>
|
|
/// <param name="ct">Jeton d'annulation de l'opération.</param>
|
|
Task ResetPasswordAsync(ResetPasswordDto dto, CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// Change le mot de passe d'un utilisateur déjà authentifié (page Compte utilisateur).
|
|
/// Contrairement à <see cref="ResetPasswordAsync"/> (jeton reçu par email), exige la
|
|
/// saisie de l'ancien mot de passe. Lève
|
|
/// <see cref="Exceptions.MotDePasseActuelInvalideException"/> si celui-ci est incorrect.
|
|
/// </summary>
|
|
/// <param name="dto">Mot de passe actuel et nouveau mot de passe.</param>
|
|
/// <param name="ct">Jeton d'annulation de l'opération.</param>
|
|
Task ChangePasswordAsync(ChangePasswordDto dto, CancellationToken ct);
|
|
}
|