mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-23 15:18:17 +02:00
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:
1 parent
207b51c162
commit
f1b0cb07b7
2 files changed
+66
-20
No files matched your search
@@ -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}
|
||||||
|
|||||||
@@ -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" });
|
||||||
|
|||||||
Reference in new issue
Block a user