From 9a0959e1cbe35042ca243f56b5b91c24eeb2cc68 Mon Sep 17 00:00:00 2001 From: Giovanni-Josserand Date: Wed, 14 Jan 2026 22:44:07 +0100 Subject: [PATCH] permissions review --- src/components/Footer/Footer.jsx | 1 - src/components/Header/Header.jsx | 10 ++---- .../PendingMembers/PendingMembers.jsx | 4 +-- src/components/SearchBar/SearchBar.jsx | 2 +- .../SettingsModal/SettingsModal.jsx | 16 +++++++++ .../SettingsModal/SettingsModal.module.css | 5 +++ src/components/ToolBar/ToolBar.jsx | 7 ++-- src/components/manageMember/ManageMember.jsx | 23 ++++++++----- .../deactivateMemberBtn.jsx} | 14 ++++---- .../VolunteerProfile/VolunteerProfilePage.jsx | 2 +- .../ValidationErrorPage.jsx | 8 +++-- .../echo/listeners/userCreatedListener.js | 2 +- .../listeners/userNotificationsListener.js | 1 - src/utils/users/deactivateUser.js | 34 +++++++++++++++++++ src/utils/users/deleteOtherUser.js | 34 +++++++++++++++++++ src/utils/users/deleteUser.js | 9 ++--- 16 files changed, 131 insertions(+), 41 deletions(-) rename src/components/manageMember/{deleteMember/deleteMemberBtn.jsx => deactivateMember/deactivateMemberBtn.jsx} (63%) create mode 100644 src/utils/users/deactivateUser.js create mode 100644 src/utils/users/deleteOtherUser.js diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx index 4906ceb..b88fb34 100644 --- a/src/components/Footer/Footer.jsx +++ b/src/components/Footer/Footer.jsx @@ -45,7 +45,6 @@ export default function Footer(){ - {/* TODO : mettre nos noms dans un fichier de configuration */} setIsCopyrightModal(false)}>
diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index cbb531e..706775e 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -9,7 +9,6 @@ import getUserNotifications from "../../utils/notifications/getUserNotifications import deleteNotificationUser from "../../utils/notifications/deleteNotificationUser.js"; import initEcho from "../../utils/echo/initEcho.js" import readNotifications from "../../utils/notifications/readNotifications.js"; -import getUser from "../../utils/getUser.js"; import { userCreatedListener } from "../../utils/echo/listeners/userCreatedListener"; import { userNotificationsListener } from "../../utils/echo/listeners/userNotificationsListener.js"; import NotificationCard from "../NotificationCard/NotificationCard.jsx"; @@ -28,10 +27,7 @@ function Header() { async function initializeHeader() { try { - const [userData, notifData] = await Promise.all([ - getUser(), - getUserNotifications() - ]); + const notifData = await getUserNotifications(); const data = notifData || []; setNotifications(data); @@ -42,8 +38,8 @@ function Header() { echoInstance = echo; const activeChannels = [ - userCreatedListener(echo, userData, setNotifications, setunreadNotification), - userNotificationsListener(echo, userData, setNotifications, setunreadNotification), + userCreatedListener(echo, user, setNotifications, setunreadNotification), + userNotificationsListener(echo, user, setNotifications, setunreadNotification), ]; channelsToLeave = activeChannels.filter(name => name !== null); diff --git a/src/components/PendingMembers/PendingMembers.jsx b/src/components/PendingMembers/PendingMembers.jsx index 77fabf7..80dbd31 100644 --- a/src/components/PendingMembers/PendingMembers.jsx +++ b/src/components/PendingMembers/PendingMembers.jsx @@ -5,7 +5,7 @@ import styles from "./PendingMembers.module.css"; import getUserToValidate from "../../utils/users/getUserToValidate"; import getUserById from "../../utils/users/getUserById"; import validateUser from "../../utils/users/validateUser"; -import deleteUser from "../../utils/users/deleteUser"; +import deleteOtherUser from "../../utils/users/deleteOtherUser.js"; function PendingMembers() { const [pendingMembers, setPendingMembers] = useState([]); @@ -55,7 +55,7 @@ function PendingMembers() { setActionLoading(id); setError(null); try { - const result = await deleteUser(id); + const result = await deleteOtherUser(id); if (result.success) { removeMember(id); } else { diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx index 6635d98..a1dded2 100644 --- a/src/components/SearchBar/SearchBar.jsx +++ b/src/components/SearchBar/SearchBar.jsx @@ -65,7 +65,7 @@ function SearchBar() {
{searchResults.map((result, i) => ( (location.pathname.includes("events")) ? ( - +
{result.image == null ? ( diff --git a/src/components/SettingsModal/SettingsModal.jsx b/src/components/SettingsModal/SettingsModal.jsx index dee82e7..739da76 100644 --- a/src/components/SettingsModal/SettingsModal.jsx +++ b/src/components/SettingsModal/SettingsModal.jsx @@ -6,6 +6,7 @@ import ThemeSwitcher from "../ui/themeSwitcher/ThemeSwitcher.jsx"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; import TextInput from "../ui/input/input.jsx"; import updateUser from "../../utils/users/updateUser.js"; +import deleteUser from "../../utils/users/deleteUser.js"; export default function SettingsModal() { @@ -13,6 +14,7 @@ export default function SettingsModal() { const { user, logout, update } = useContext(AuthContext); const [open, setOpen] = useState(false); + const [isDelete, setIsDelete] = useState(false); const [name, setName] = useState(user?.name); const [lastname, setLastName] = useState(user?.lastname); @@ -27,6 +29,11 @@ export default function SettingsModal() { update(); } + const handleDelete = async () => { + await deleteUser(); + update(); + } + return ( <> +

Changer de Prénom

@@ -65,6 +73,14 @@ export default function SettingsModal() {
+ + + setIsDelete(false)}> +
+

Êtes vous vraiment sûr de vouloir supprimer votre compte ?

+ +
+
) } \ No newline at end of file diff --git a/src/components/SettingsModal/SettingsModal.module.css b/src/components/SettingsModal/SettingsModal.module.css index 80b9d81..320b760 100644 --- a/src/components/SettingsModal/SettingsModal.module.css +++ b/src/components/SettingsModal/SettingsModal.module.css @@ -20,4 +20,9 @@ .submitBtn { align-self: center; +} + + +.alignText{ + text-align: center; } \ No newline at end of file diff --git a/src/components/ToolBar/ToolBar.jsx b/src/components/ToolBar/ToolBar.jsx index 3c4c298..2b90746 100644 --- a/src/components/ToolBar/ToolBar.jsx +++ b/src/components/ToolBar/ToolBar.jsx @@ -1,12 +1,13 @@ import styles from "./ToolBar.module.css" import Filter from "../Filter/Filter.jsx"; -import {useEffect, useState} from "react"; +import {useContext, useEffect, useState} from "react"; import SearchBar from "../SearchBar/SearchBar.jsx"; import CreateEventBtn from "../createEventBtn/CreateEventBtn.jsx"; import Button from "../ui/button/button.jsx"; - +import {AuthContext} from "../../contexts/auth/AuthContext.js"; function ToolBar({setFilters, filters, showCreate = true}) { + const { user } = useContext(AuthContext); const [isFilterVisible, setIsFilterVisible] = useState(false); const [isSearchVisible, setIsSearchVisible] = useState(false); const toggleFilters = () => { @@ -37,7 +38,7 @@ function ToolBar({setFilters, filters, showCreate = true}) {
) : null}
- {showCreate ? ( + {showCreate && user.isAdmin ? ( ) : null} diff --git a/src/components/manageMember/ManageMember.jsx b/src/components/manageMember/ManageMember.jsx index 04bef13..cc695fb 100644 --- a/src/components/manageMember/ManageMember.jsx +++ b/src/components/manageMember/ManageMember.jsx @@ -1,12 +1,15 @@ import Button from "../ui/button/button.jsx"; import Modal from "../ui/modal/modal.jsx"; -import { useState } from "react"; +import {useContext, useState} from "react"; import styles from "./manageMember.module.css" -import DeleteMemberBtn from "./deleteMember/deleteMemberBtn.jsx"; +import DeactivateMemberBtn from "./deactivateMember/deactivateMemberBtn.jsx"; import ModifyRole from "./modifyrole/ModifyRole.jsx"; +import {AuthContext} from "../../contexts/auth/AuthContext.js"; -export default function ManageMember({ user }) { +export default function ManageMember({ userToManage }) { + + const { user } = useContext(AuthContext); const [open, setOpen] = useState(false); @@ -16,16 +19,18 @@ export default function ManageMember({ user }) {

Gérer

- setOpen(false)} title={`Gestion de l'utilisateur ${user.name}`}> + setOpen(false)} title={`Gestion de l'utilisateur ${userToManage.name}`}> -
-

Supprimer le compte

- -
+ {(user.id != userToManage.id) ? ( +
+

Désactiver le compte

+ +
+ ) : null}

Modifier le rôle

- +
diff --git a/src/components/manageMember/deleteMember/deleteMemberBtn.jsx b/src/components/manageMember/deactivateMember/deactivateMemberBtn.jsx similarity index 63% rename from src/components/manageMember/deleteMember/deleteMemberBtn.jsx rename to src/components/manageMember/deactivateMember/deactivateMemberBtn.jsx index aa686aa..1368668 100644 --- a/src/components/manageMember/deleteMember/deleteMemberBtn.jsx +++ b/src/components/manageMember/deactivateMember/deactivateMemberBtn.jsx @@ -1,16 +1,16 @@ import Button from "../../ui/button/button.jsx"; import Modal from "../../ui/modal/modal.jsx"; import { useState } from "react"; -import deleteUser from "../../../utils/users/deleteUser.js" +import deactivateUser from "../../../utils/users/deactivateUser.js" import { useNavigate } from "react-router"; -export default function DeleteMemberBtn({ name, id, ...props }) { +export default function DeactivateMemberBtn({ name, id, ...props }) { const [open, setOpen] = useState(false); const navigate = useNavigate(); - const delMember = async () => { - const result = await deleteUser(id); + const deactivateMember = async () => { + const result = await deactivateUser(id); if (result.status === 200 || result.status === 204) { setOpen(false); @@ -19,12 +19,12 @@ export default function DeleteMemberBtn({ name, id, ...props }) { } return
- + setOpen(false)} title={"Supprimer"}>
-

Etes-vous sur de vouloir supprimer le compte {name} ?

- +

Etes-vous sur de vouloir désactiver le compte {name} ?

+
diff --git a/src/pages/VolunteerProfile/VolunteerProfilePage.jsx b/src/pages/VolunteerProfile/VolunteerProfilePage.jsx index 4c24a51..f44d566 100644 --- a/src/pages/VolunteerProfile/VolunteerProfilePage.jsx +++ b/src/pages/VolunteerProfile/VolunteerProfilePage.jsx @@ -45,7 +45,7 @@ export default function VolunteerProfilePage() {

{user.name} {user.lastname}

- {currentUser?.isAdmin && } + {currentUser?.isAdmin && }
diff --git a/src/pages/waitValidationPage/ValidationErrorPage.jsx b/src/pages/waitValidationPage/ValidationErrorPage.jsx index 15995e9..7ca38f9 100644 --- a/src/pages/waitValidationPage/ValidationErrorPage.jsx +++ b/src/pages/waitValidationPage/ValidationErrorPage.jsx @@ -3,7 +3,7 @@ import Background from "../../components/background/background.jsx"; import Button from "../../components/ui/button/button.jsx"; import { useContext } from "react"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; -import { Navigate, useNavigate } from "react-router"; +import { Navigate, useNavigate, Link } from "react-router"; export default function ValidationErrorPage() { @@ -22,7 +22,11 @@ export default function ValidationErrorPage() {

Votre compte n'a pas été validé

Votre compte n'a pas encore été validé, veuillez attendre la vérification de votre compte par un membre autorisé.

-

Contact : contact@example.com

+

Contact : + + https://comite.beaupont.fr/contactez-nous + +

diff --git a/src/utils/echo/listeners/userCreatedListener.js b/src/utils/echo/listeners/userCreatedListener.js index dddab10..e2bb017 100644 --- a/src/utils/echo/listeners/userCreatedListener.js +++ b/src/utils/echo/listeners/userCreatedListener.js @@ -1,5 +1,5 @@ export const userCreatedListener = (echo, userData, setNotifications, setunreadNotification) => { - if (userData.isAdmin || userData.role === "Gérant") { + if (userData.isAdmin) { const channelName = "users.registration"; echo.private(channelName) .listen(".users.registration", (event) => { diff --git a/src/utils/echo/listeners/userNotificationsListener.js b/src/utils/echo/listeners/userNotificationsListener.js index 6b07beb..7d94483 100644 --- a/src/utils/echo/listeners/userNotificationsListener.js +++ b/src/utils/echo/listeners/userNotificationsListener.js @@ -1,5 +1,4 @@ export const userNotificationsListener = (echo, userData, setNotifications, setunreadNotification) => { - if (!userData?.id) return null; const channelName = `user.${userData.id}`; diff --git a/src/utils/users/deactivateUser.js b/src/utils/users/deactivateUser.js new file mode 100644 index 0000000..61ac0c7 --- /dev/null +++ b/src/utils/users/deactivateUser.js @@ -0,0 +1,34 @@ +import getXSRFToken from "../getXSRF.js"; + +export default async function deactivateUser(userId) { + const csrfToken = await getXSRFToken(); + + try { + const response = await fetch(`${import.meta.env.VITE_API_URL}/api/users/${userId}/deactivate`, { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'X-XSRF-TOKEN': csrfToken, + 'Accept': 'application/json' + }, + body: JSON.stringify({ + id: userId + }) + }); + + const data = await response.json(); + + if (!response.ok) { + return { + status: response.status, + errors: data.errors || data.message + }; + } + + return { status: response.status, data }; + + } catch (error) { + return { status: 500, error }; + } +} diff --git a/src/utils/users/deleteOtherUser.js b/src/utils/users/deleteOtherUser.js new file mode 100644 index 0000000..101cf94 --- /dev/null +++ b/src/utils/users/deleteOtherUser.js @@ -0,0 +1,34 @@ +import getXSRFToken from "../getXSRF.js"; + +export default async function deleteOtherUser(userId) { + const csrfToken = await getXSRFToken(); + + try { + const response = await fetch(`${import.meta.env.VITE_API_URL}/api/users/${userId}`, { + method: 'DELETE', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'X-XSRF-TOKEN': csrfToken, + 'Accept': 'application/json' + }, + body: JSON.stringify({ + id: userId + }) + }); + + const data = await response.json(); + + if (!response.ok) { + return { + status: response.status, + errors: data.errors || data.message + }; + } + + return { status: response.status, data }; + + } catch (error) { + return { status: 500, error }; + } +} diff --git a/src/utils/users/deleteUser.js b/src/utils/users/deleteUser.js index 4e3f24d..932167d 100644 --- a/src/utils/users/deleteUser.js +++ b/src/utils/users/deleteUser.js @@ -1,20 +1,17 @@ import getXSRFToken from "../getXSRF.js"; -export default async function deleteUser(userId) { +export default async function deleteUser() { const csrfToken = await getXSRFToken(); try { - const response = await fetch(`${import.meta.env.VITE_API_URL}/api/users/${userId}`, { + const response = await fetch(`${import.meta.env.VITE_API_URL}/api/users`, { method: 'DELETE', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-XSRF-TOKEN': csrfToken, 'Accept': 'application/json' - }, - body: JSON.stringify({ - id: userId - }) + } }); const data = await response.json();