update api users and groups and users 12
This commit is contained in:
parent
159ad9cbdf
commit
4a9bfebecf
@ -1,76 +0,0 @@
|
|||||||
import { getServerSession } from "next-auth";
|
|
||||||
import { authOptions } from "../../auth/[...nextauth]/route";
|
|
||||||
import { NextResponse } from "next/server";
|
|
||||||
|
|
||||||
//TODO: Ajouter la suppression automatique du compte Nextcloud
|
|
||||||
export async function DELETE(
|
|
||||||
req: Request,
|
|
||||||
{ params }: { params: { userId: string } }
|
|
||||||
) {
|
|
||||||
const session = await getServerSession(authOptions);
|
|
||||||
|
|
||||||
if (!session) {
|
|
||||||
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// First get an admin token using client credentials
|
|
||||||
const tokenResponse = await fetch(
|
|
||||||
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
|
|
||||||
{
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
body: new URLSearchParams({
|
|
||||||
grant_type: 'client_credentials',
|
|
||||||
client_id: process.env.KEYCLOAK_CLIENT_ID!,
|
|
||||||
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const tokenData = await tokenResponse.json();
|
|
||||||
|
|
||||||
if (!tokenResponse.ok) {
|
|
||||||
console.error("Failed to get admin token:", tokenData);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Erreur d'authentification" },
|
|
||||||
{ status: 401 }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete user using admin token
|
|
||||||
const response = await fetch(
|
|
||||||
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${params.userId}`,
|
|
||||||
{
|
|
||||||
method: "DELETE",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${tokenData.access_token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Delete response:", {
|
|
||||||
status: response.status,
|
|
||||||
ok: response.ok
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
const errorText = await response.text();
|
|
||||||
console.error("Delete error:", errorText);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Erreur lors de la suppression", details: errorText },
|
|
||||||
{ status: response.status }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NextResponse.json({ success: true });
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error deleting user:", error);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Erreur serveur", details: error },
|
|
||||||
{ status: 500 }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -62,9 +62,9 @@ export async function PUT(
|
|||||||
|
|
||||||
// Find roles to add and remove
|
// Find roles to add and remove
|
||||||
const rolesToAdd = roles.filter(
|
const rolesToAdd = roles.filter(
|
||||||
(role: string) => !currentRoles.clientMappings?.some((r: RoleRepresentation) => r.name === role)
|
(role: string) => !currentRoles.realmMappings?.some((r: RoleRepresentation) => r.name === role)
|
||||||
);
|
);
|
||||||
const rolesToRemove = currentRoles.clientMappings?.filter(
|
const rolesToRemove = currentRoles.realmMappings?.filter(
|
||||||
(role: RoleRepresentation) => !roles.includes(role.name)
|
(role: RoleRepresentation) => !roles.includes(role.name)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { getServerSession } from "next-auth";
|
import { getServerSession } from "next-auth";
|
||||||
import { authOptions } from "../../auth/[...nextauth]/route";
|
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
//TODO: Ajouter la suppression automatique du compte Nextcloud
|
//TODO: Ajouter la suppression automatique du compte Nextcloud
|
||||||
|
|||||||
@ -432,64 +432,61 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<Dialog open={manageMembersDialog} onOpenChange={(open) => {
|
<Dialog open={manageMembersDialog} onOpenChange={setManageMembersDialog}>
|
||||||
if (!open) {
|
<DialogContent className="max-h-[80vh] overflow-y-auto">
|
||||||
setSelectedGroup(null);
|
|
||||||
setGroupMembers([]);
|
|
||||||
setAvailableUsers([]);
|
|
||||||
}
|
|
||||||
setManageMembersDialog(open);
|
|
||||||
}}>
|
|
||||||
<DialogContent className="max-w-2xl">
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Gérer les membres du groupe {selectedGroup?.name}</DialogTitle>
|
<DialogTitle>Gérer les membres du groupe {selectedGroup?.name}</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Membres actuels</Label>
|
<Label>Membres actuels</Label>
|
||||||
<div className="border rounded-md p-4 space-y-2">
|
<div className="max-h-[200px] overflow-y-auto border rounded-md p-2">
|
||||||
{groupMembers.length === 0 ? (
|
{groupMembers.length === 0 ? (
|
||||||
<p className="text-sm text-gray-500">Aucun membre</p>
|
<p className="text-sm text-muted-foreground">Aucun membre</p>
|
||||||
) : (
|
) : (
|
||||||
groupMembers.map(member => (
|
<div className="space-y-2">
|
||||||
<div key={member.id} className="flex items-center justify-between p-2 hover:bg-gray-50 rounded-md">
|
{groupMembers.map((member) => (
|
||||||
<div>
|
<div key={member.id} className="flex items-center justify-between p-2 hover:bg-muted rounded-md">
|
||||||
<p className="font-medium">{member.username}</p>
|
<div>
|
||||||
<p className="text-sm text-gray-500">{member.email}</p>
|
<p className="font-medium">{member.username}</p>
|
||||||
|
<p className="text-sm text-muted-foreground">{member.email}</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => handleRemoveMember(member.id)}
|
||||||
|
>
|
||||||
|
<Trash className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
))}
|
||||||
variant="ghost"
|
</div>
|
||||||
size="sm"
|
|
||||||
onClick={() => handleRemoveMember(member.id)}
|
|
||||||
>
|
|
||||||
Retirer
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Ajouter des membres</Label>
|
<Label>Ajouter un membre</Label>
|
||||||
<div className="border rounded-md p-4 space-y-2">
|
<div className="max-h-[200px] overflow-y-auto border rounded-md p-2">
|
||||||
{availableUsers.length === 0 ? (
|
{availableUsers.length === 0 ? (
|
||||||
<p className="text-sm text-gray-500">Aucun utilisateur disponible</p>
|
<p className="text-sm text-muted-foreground">Aucun utilisateur disponible</p>
|
||||||
) : (
|
) : (
|
||||||
availableUsers.map(user => (
|
<div className="space-y-2">
|
||||||
<div key={user.id} className="flex items-center justify-between p-2 hover:bg-gray-50 rounded-md">
|
{availableUsers.map((user) => (
|
||||||
<div>
|
<div key={user.id} className="flex items-center justify-between p-2 hover:bg-muted rounded-md">
|
||||||
<p className="font-medium">{user.username}</p>
|
<div>
|
||||||
<p className="text-sm text-gray-500">{user.email}</p>
|
<p className="font-medium">{user.username}</p>
|
||||||
|
<p className="text-sm text-muted-foreground">{user.email}</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => handleAddMember(user.id)}
|
||||||
|
>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
))}
|
||||||
variant="ghost"
|
</div>
|
||||||
size="sm"
|
|
||||||
onClick={() => handleAddMember(user.id)}
|
|
||||||
>
|
|
||||||
Ajouter
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -223,11 +223,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
throw new Error("Erreur lors de la mise à jour des rôles");
|
throw new Error("Erreur lors de la mise à jour des rôles");
|
||||||
}
|
}
|
||||||
|
|
||||||
setUsers(prevUsers => prevUsers.map(user =>
|
await fetchUsers();
|
||||||
user.id === selectedUser.id
|
|
||||||
? { ...user, roles: formData.roles }
|
|
||||||
: user
|
|
||||||
));
|
|
||||||
|
|
||||||
setManageRolesDialog(false);
|
setManageRolesDialog(false);
|
||||||
setSelectedUser(null);
|
setSelectedUser(null);
|
||||||
@ -650,14 +646,6 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
<DialogTitle>Modifier l'utilisateur</DialogTitle>
|
<DialogTitle>Modifier l'utilisateur</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<form onSubmit={handleUpdateUser} className="space-y-4">
|
<form onSubmit={handleUpdateUser} className="space-y-4">
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="edit-lastName">Nom</Label>
|
|
||||||
<Input
|
|
||||||
id="edit-lastName"
|
|
||||||
value={formData.lastName}
|
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-firstName">Prénom</Label>
|
<Label htmlFor="edit-firstName">Prénom</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -666,6 +654,14 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="edit-lastName">Nom</Label>
|
||||||
|
<Input
|
||||||
|
id="edit-lastName"
|
||||||
|
value={formData.lastName}
|
||||||
|
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-email">Email</Label>
|
<Label htmlFor="edit-email">Email</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user