Improve user role management with enhanced restrictions and messaging

Implement role update restrictions to prevent demoting self/last admin and add error messages.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 91318273-c764-4fd4-be04-bdc12c38af32
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/9d9e1107-c416-4124-a939-a91c612c56a1.jpg
This commit is contained in:
michaelschal committed 2025-07-09 23:14:51 +00:00
1 parent 207b51c162
commit f1b0cb07b7
2 files changed
+66 -20

No files matched your search

+44 -20
View File
@@ -55,6 +55,15 @@ export default function Administration() {
const [editingUser, setEditingUser] = useState<User | null>(null); const [editingUser, setEditingUser] = useState<User | null>(null);
const [editingStore, setEditingStore] = useState<Store | null>(null); const [editingStore, setEditingStore] = useState<Store | null>(null);
// Get current user info to prevent self-role modification
const { data: currentUser } = useQuery<User>({
queryKey: ['/api/auth/me'],
queryFn: async () => {
const response = await apiRequest('/api/auth/me');
return response.json();
},
});
// Queries // Queries
const { data: users = [], isLoading: usersLoading } = useQuery<User[]>({ const { data: users = [], isLoading: usersLoading } = useQuery<User[]>({
queryKey: ['/api/admin/users'], queryKey: ['/api/admin/users'],
@@ -126,8 +135,11 @@ export default function Administration() {
editUserForm.reset(); editUserForm.reset();
toast({ title: "Utilisateur modifié avec succès" }); toast({ title: "Utilisateur modifié avec succès" });
}, },
onError: () => { onError: (error) => {
toast({ title: "Erreur", description: "Impossible de modifier l'utilisateur", variant: "destructive" }); const errorMessage = error.message.includes("Vous ne pouvez pas changer votre propre rôle")
? "Vous ne pouvez pas changer votre propre rôle d'administrateur"
: "Impossible de modifier l'utilisateur";
toast({ title: "Erreur", description: errorMessage, variant: "destructive" });
}, },
}); });
@@ -813,24 +825,36 @@ export default function Administration() {
<FormField <FormField
control={editUserForm.control} control={editUserForm.control}
name="role" name="role"
render={({ field }) => ( render={({ field }) => {
<FormItem> const isEditingSelf = editingUser?.id === currentUser?.id;
<FormLabel>Rôle</FormLabel> return (
<Select value={field.value} onValueChange={field.onChange}> <FormItem>
<FormControl> <FormLabel>Rôle</FormLabel>
<SelectTrigger> <Select
<SelectValue /> value={field.value}
</SelectTrigger> onValueChange={field.onChange}
</FormControl> disabled={isEditingSelf}
<SelectContent> >
<SelectItem value="employee">Employé</SelectItem> <FormControl>
<SelectItem value="manager">Manager</SelectItem> <SelectTrigger>
<SelectItem value="administrator">Administrateur</SelectItem> <SelectValue />
</SelectContent> </SelectTrigger>
</Select> </FormControl>
<FormMessage /> <SelectContent>
</FormItem> <SelectItem value="employee">Employé</SelectItem>
)} <SelectItem value="manager">Manager</SelectItem>
<SelectItem value="administrator">Administrateur</SelectItem>
</SelectContent>
</Select>
{isEditingSelf && (
<p className="text-sm text-muted-foreground">
Vous ne pouvez pas modifier votre propre rôle
</p>
)}
<FormMessage />
</FormItem>
);
}}
/> />
<FormField <FormField
control={editUserForm.control} control={editUserForm.control}
+22
View File
@@ -291,7 +291,29 @@ export async function registerRoutes(app: Express): Promise<Server> {
app.put('/api/admin/users/:id', requireRole(['admin']), async (req, res) => { app.put('/api/admin/users/:id', requireRole(['admin']), async (req, res) => {
try { try {
const userId = parseInt(req.params.id); const userId = parseInt(req.params.id);
const currentUser = await storage.getUser(req.session.userId!);
const userData = insertUserSchema.partial().parse(req.body); const userData = insertUserSchema.partial().parse(req.body);
// Protection : empêcher un admin de changer son propre rôle par accident
if (userId === currentUser?.id && userData.role && userData.role !== 'administrator') {
return res.status(400).json({
error: "Vous ne pouvez pas changer votre propre rôle d'administrateur"
});
}
// Protection : ne pas permettre de changer le rôle du dernier administrateur
if (userData.role && userData.role !== 'administrator') {
const users = await storage.getAllUsers();
const adminUsers = users.filter(u => u.role === 'administrator');
const userToUpdate = users.find(u => u.id === userId);
if (userToUpdate?.role === 'administrator' && adminUsers.length <= 1) {
return res.status(400).json({
error: "Impossible de modifier le rôle du dernier administrateur"
});
}
}
const user = await storage.updateUser(userId, userData); const user = await storage.updateUser(userId, userData);
if (!user) { if (!user) {
return res.status(404).json({ error: "User not found" }); return res.status(404).json({ error: "User not found" });