feat: Gestion des utilisateurs (invitation, blocage, déblocage)
Permet aux administrateurs d'un établissement de gérer le cycle de vie des comptes utilisateurs : inviter de nouveaux membres, bloquer/débloquer des comptes actifs, et renvoyer des invitations en attente. Chaque mutation vérifie l'appartenance au tenant courant pour empêcher les accès cross-tenant. Le blocage est restreint aux comptes actifs uniquement et un administrateur ne peut pas bloquer son propre compte. Les comptes suspendus reçoivent une erreur 403 spécifique au login (sans déclencher l'escalade du rate limiting) et les tentatives sont tracées dans les métriques Prometheus.
This commit is contained in:
98
backend/templates/emails/invitation.html.twig
Normal file
98
backend/templates/emails/invitation.html.twig
Normal file
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Invitation - Classeo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
border-bottom: 2px solid #4f46e5;
|
||||
}
|
||||
.header h1 {
|
||||
color: #4f46e5;
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
}
|
||||
.content {
|
||||
padding: 30px 0;
|
||||
}
|
||||
.info-box {
|
||||
background-color: #f3f4f6;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.info-box p {
|
||||
margin: 5px 0;
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
background-color: #4f46e5;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 12px 24px;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.button:hover {
|
||||
background-color: #4338ca;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
color: #6b7280;
|
||||
font-size: 14px;
|
||||
}
|
||||
.warning {
|
||||
background-color: #fef3c7;
|
||||
border-left: 4px solid #f59e0b;
|
||||
padding: 12px 16px;
|
||||
margin: 20px 0;
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>Classeo</h1>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h2>Bienvenue sur Classeo !</h2>
|
||||
|
||||
<p>Bonjour {{ firstName }},</p>
|
||||
|
||||
<p>Vous avez été invité(e) à rejoindre Classeo en tant que <strong>{{ role }}</strong>.</p>
|
||||
|
||||
<div class="info-box">
|
||||
<p>Cliquez sur le bouton ci-dessous pour activer votre compte et définir votre mot de passe.</p>
|
||||
</div>
|
||||
|
||||
<p style="text-align: center; margin: 30px 0;">
|
||||
<a href="{{ activationUrl }}" class="button">Activer mon compte</a>
|
||||
</p>
|
||||
|
||||
<div class="warning">
|
||||
<p><strong>Ce lien expire dans 7 jours.</strong></p>
|
||||
<p>Si vous ne pouvez pas cliquer sur le bouton, copiez ce lien dans votre navigateur :</p>
|
||||
<p style="word-break: break-all; font-size: 12px;">{{ activationUrl }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Cet email a été envoyé automatiquement par Classeo.</p>
|
||||
<p>Si vous n'attendiez pas cette invitation, vous pouvez ignorer cet email.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user