Checkpoint: Ajout de l'identifiant de connexion et modification du mot de passe dans la gestion des utilisateurs
Modifications apportées : - Ajout du champ username (identifiant de connexion) dans le schéma de la base de données avec contrainte UNIQUE - Mise à jour des procédures tRPC create et update pour gérer username et password - Implémentation du hashage du mot de passe avec bcryptjs dans createUser et updateUser - Ajout de la colonne "Identifiant" dans le tableau de la page de gestion des utilisateurs - Ajout des champs "Identifiant de connexion" et "Mot de passe" dans le formulaire de création - Ajout des champs "Identifiant de connexion" et "Nouveau mot de passe" dans le formulaire d'édition avec notes explicatives - Les mots de passe sont hashés avant d'être stockés en base de données pour la sécurité - Dans le formulaire d'édition, les champs username et password sont optionnels (laissez vide pour ne pas modifier)
This commit is contained in:
@@ -44,11 +44,15 @@ export default function AdminUsers() {
|
||||
openId: "",
|
||||
name: "",
|
||||
email: "",
|
||||
username: "",
|
||||
password: "",
|
||||
role: "user" as "user" | "admin",
|
||||
});
|
||||
const [editForm, setEditForm] = useState({
|
||||
name: "",
|
||||
email: "",
|
||||
username: "",
|
||||
password: "",
|
||||
role: "user" as "user" | "admin",
|
||||
});
|
||||
|
||||
@@ -63,6 +67,8 @@ export default function AdminUsers() {
|
||||
openId: "",
|
||||
name: "",
|
||||
email: "",
|
||||
username: "",
|
||||
password: "",
|
||||
role: "user",
|
||||
});
|
||||
},
|
||||
@@ -127,6 +133,8 @@ export default function AdminUsers() {
|
||||
openId: createForm.openId,
|
||||
name: createForm.name || undefined,
|
||||
email: createForm.email || undefined,
|
||||
username: createForm.username || undefined,
|
||||
password: createForm.password || undefined,
|
||||
role: createForm.role,
|
||||
isActive: true,
|
||||
});
|
||||
@@ -137,6 +145,8 @@ export default function AdminUsers() {
|
||||
setEditForm({
|
||||
name: user.name || "",
|
||||
email: user.email || "",
|
||||
username: user.username || "",
|
||||
password: "", // Toujours vide pour la sécurité
|
||||
role: user.role,
|
||||
});
|
||||
setEditDialogOpen(true);
|
||||
@@ -145,12 +155,23 @@ export default function AdminUsers() {
|
||||
const handleSaveEdit = () => {
|
||||
if (!selectedUser) return;
|
||||
|
||||
updateMutation.mutate({
|
||||
// Ne pas envoyer username et password s'ils sont vides
|
||||
const updateData: any = {
|
||||
id: selectedUser.id,
|
||||
name: editForm.name || undefined,
|
||||
email: editForm.email || undefined,
|
||||
role: editForm.role,
|
||||
});
|
||||
};
|
||||
|
||||
if (editForm.username) {
|
||||
updateData.username = editForm.username;
|
||||
}
|
||||
|
||||
if (editForm.password) {
|
||||
updateData.password = editForm.password;
|
||||
}
|
||||
|
||||
updateMutation.mutate(updateData);
|
||||
};
|
||||
|
||||
const handleToggleStatus = (user: any) => {
|
||||
@@ -281,6 +302,7 @@ export default function AdminUsers() {
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead>Nom</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Identifiant</TableHead>
|
||||
<TableHead>Rôle</TableHead>
|
||||
<TableHead>Statut</TableHead>
|
||||
<TableHead>Dernière connexion</TableHead>
|
||||
@@ -291,7 +313,7 @@ export default function AdminUsers() {
|
||||
<TableBody>
|
||||
{filteredUsers.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} className="text-center py-8 text-muted-foreground">
|
||||
<TableCell colSpan={9} className="text-center py-8 text-muted-foreground">
|
||||
Aucun utilisateur trouvé
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -301,6 +323,7 @@ export default function AdminUsers() {
|
||||
<TableCell className="font-medium">{user.id}</TableCell>
|
||||
<TableCell>{user.name || "N/A"}</TableCell>
|
||||
<TableCell>{user.email || "N/A"}</TableCell>
|
||||
<TableCell>{user.username || "N/A"}</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant={user.role === "admin" ? "default" : "secondary"}>
|
||||
{user.role === "admin" ? "Administrateur" : "Utilisateur"}
|
||||
@@ -403,6 +426,27 @@ export default function AdminUsers() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="createUsername">Identifiant de connexion</Label>
|
||||
<Input
|
||||
id="createUsername"
|
||||
value={createForm.username}
|
||||
onChange={(e) => setCreateForm({ ...createForm, username: e.target.value })}
|
||||
placeholder="Identifiant unique pour la connexion"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="createPassword">Mot de passe</Label>
|
||||
<Input
|
||||
id="createPassword"
|
||||
type="password"
|
||||
value={createForm.password}
|
||||
onChange={(e) => setCreateForm({ ...createForm, password: e.target.value })}
|
||||
placeholder="Minimum 6 caractères"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="createRole">Rôle</Label>
|
||||
<Select
|
||||
@@ -465,6 +509,29 @@ export default function AdminUsers() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="editUsername">Identifiant de connexion</Label>
|
||||
<Input
|
||||
id="editUsername"
|
||||
value={editForm.username}
|
||||
onChange={(e) => setEditForm({ ...editForm, username: e.target.value })}
|
||||
placeholder="Identifiant unique pour la connexion"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground mt-1">Laissez vide pour ne pas modifier</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="editPassword">Nouveau mot de passe</Label>
|
||||
<Input
|
||||
id="editPassword"
|
||||
type="password"
|
||||
value={editForm.password}
|
||||
onChange={(e) => setEditForm({ ...editForm, password: e.target.value })}
|
||||
placeholder="Laissez vide pour ne pas modifier"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground mt-1">Minimum 6 caractères si modifié</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="editRole">Rôle</Label>
|
||||
<Select
|
||||
|
||||
Reference in New Issue
Block a user