From 01066e282bc1772b64fdcb5ac660b041a0718f3b Mon Sep 17 00:00:00 2001 From: Warix <39554785+warix8@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:29:53 +0200 Subject: [PATCH 1/5] Auth module --- front/package-lock.json | 32 ++++++++++++++++++++++++++++++++ front/package.json | 1 + front/src/App.jsx | 3 +++ 3 files changed, 36 insertions(+) diff --git a/front/package-lock.json b/front/package-lock.json index 037325e..fa29451 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@headlessui/react": "^2.2.0", + "@tasoskakour/react-use-oauth2": "^2.0.2", "framer-motion": "^12.4.3", "lucide-react": "^0.475.0", "react": "^19.0.0", @@ -1483,6 +1484,21 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@tasoskakour/react-use-oauth2": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@tasoskakour/react-use-oauth2/-/react-use-oauth2-2.0.2.tgz", + "integrity": "sha512-rPWXCUwSsF+/7LMFTMB39K1lWknk0OSqBGLRN3Wgl9CUcj07aAeplSH+1ot5DMbzM6PJSM/VsWlo0ltAAg2RFQ==", + "license": "MIT", + "dependencies": { + "use-local-storage-state": "^18.3.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -4744,6 +4760,22 @@ "punycode": "^2.1.0" } }, + "node_modules/use-local-storage-state": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/use-local-storage-state/-/use-local-storage-state-18.3.3.tgz", + "integrity": "sha512-SwwW6LPbxf3q5XimJyYE2jBefpvEJTjAgBO47wCs0+ZkL/Hx8heF/0wtBJ7Df0SiSwyfNDIPHo+8Z3q569jlow==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/astoilkov" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/vite": { "version": "6.2.5", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", diff --git a/front/package.json b/front/package.json index 3d64489..f218037 100644 --- a/front/package.json +++ b/front/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@headlessui/react": "^2.2.0", + "@tasoskakour/react-use-oauth2": "^2.0.2", "framer-motion": "^12.4.3", "lucide-react": "^0.475.0", "react": "^19.0.0", diff --git a/front/src/App.jsx b/front/src/App.jsx index 60f86e2..edef928 100644 --- a/front/src/App.jsx +++ b/front/src/App.jsx @@ -1,9 +1,11 @@ +/* eslint-disable react/jsx-no-comment-textnodes */ import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Header from "./components/Header"; import Footer from "./components/Footer"; import { ThemeProvider, useTheme } from "./ThemeProvider"; import ScrollToTopButton from "./components/ScrollTop"; import ScrollToTop from './components/ScrollTopImmediate'; +import { OAuthPopup } from "@tasoskakour/react-use-oauth2"; import Exemple from "./pages/Exemple-page"; @@ -86,6 +88,7 @@ function App() {
} /> + } path="/callback" /> } /> //Vie courante From 68fc07a8d6c3c5cebc435dd7dd78a022586dce39 Mon Sep 17 00:00:00 2001 From: Warix <39554785+warix8@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:49:46 +0200 Subject: [PATCH 2/5] Infirmerie contact with myECL auth integration --- front/src/auth.jsx | 41 ++++++++++++++ front/src/pages/Contact/Infirmerie.jsx | 74 +++++++++++++++++++++----- 2 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 front/src/auth.jsx diff --git a/front/src/auth.jsx b/front/src/auth.jsx new file mode 100644 index 0000000..9d5a3b1 --- /dev/null +++ b/front/src/auth.jsx @@ -0,0 +1,41 @@ +import { useOAuth2 } from "@tasoskakour/react-use-oauth2"; + +export const useAuth = () => { + + const { data, loading, error, getAuth, logout } = useOAuth2({ + authorizeUrl: "http://localhost:8000/auth/authorize", + clientId: "SafetyCards", + clientSecret: "SafetyCards", + redirectUri: `${document.location.origin}/callback`, + scope: "API", + responseType: "code", + // Suppression de exchangeCodeForTokenQuery + exchangeCodeForTokenQueryFn: async (callbackParameters) => { + const params = new URLSearchParams(callbackParameters); + params.append("grant_type", "authorization_code"); + params.append("client_id", "SafetyCards"); + params.append("client_secret", "SafetyCards"); + const response = await fetch("http://localhost:8000/auth/token", { + method: "POST", + body: params.toString(), + headers: { + "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" + } + }); + if (!response.ok) { + throw new Error("Token exchange failed: " + response.statusText); + } + return response.json(); + }, + onSuccess: (payload) => console.log("Success", payload), + onError: (error_) => console.log("Error", error_) + }); + + return { + data, + loading, + error, + getAuth, + logout + }; +} \ No newline at end of file diff --git a/front/src/pages/Contact/Infirmerie.jsx b/front/src/pages/Contact/Infirmerie.jsx index f086fb1..b1b76c3 100644 --- a/front/src/pages/Contact/Infirmerie.jsx +++ b/front/src/pages/Contact/Infirmerie.jsx @@ -1,27 +1,73 @@ -import Quote from "../../components/Citation"; -import ImageTextPopup from "../../components/Cartes"; -import ListeNumerotee from "../../components/Listes"; -import ExternalLinkBlock from "../../components/Liens-ext"; -import Components from "../../components/Common"; -import ContactCard from "../../components/Contact"; -import React from "react"; -import { Chiffre, ChiffresGroup } from "../../components/Chiffres"; -import Separateur from "../../components/Separateur"; +import { useEffect, useState } from "react"; import "../../App.css"; +import { useAuth } from "../../auth"; -const { BulletList, NumberedList, TextImageRight, ImageCenter, Navbar, YouTubeVideo} = Components; - - const Infirmerie = () => { + + const { data, loading, error, getAuth, logout } = useAuth(); // Assurez-vous que le hook useAuth est correctement importé + + const isLoggedIn = Boolean(data?.access_token); // or whatever... + + const [contacts, setContacts] = useState([]); + + useEffect(() => { + async function fetchContacts() { + if (!data?.access_token) return; // ne fetch pas si l'utilisateur n'est pas authentifié + try { + const response = await fetch("http://localhost:8000/advert/adverts", { + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer " + data?.access_token, + }, + }); + if (!response.ok) { + data.access_token = null; // Réinitialiser le token si la requête échoue + logout(); // Déconnexion de l'utilisateur + throw new Error("Failed to fetch users"); + } + const contactsData = await response.json(); + setContacts(contactsData); + } catch (err) { + console.error("Error fetching contacts:", err); + } + } + fetchContacts(); + }, [data, data?.access_token, logout]); + + if (error) { + return
Erreur lors de la connexion à MyECL.
; + } + + if (loading) { + return
Loading...
; + } + + if (isLoggedIn) { return (

Infirmerie

Contact

+

Mail : {contacts.mail}

+

Téléphone : {contacts.phone}

+

Adresse : {contacts.adresse}

+

Horaires : {contacts.horaire}

+ + +
+ ) + } + + return ( +
+

Connexion

+ +

Vous devez vous connecter pour accéder à ses informations :

-

Mail :

-

Téléphone :

+
); From 3fbb186652b8744553dee445bf5a9d8537e7fd23 Mon Sep 17 00:00:00 2001 From: Warix <39554785+warix8@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:29:53 +0200 Subject: [PATCH 3/5] Auth module --- front/package-lock.json | 32 ++++++++++++++++++++++++++++++++ front/package.json | 1 + front/src/App.jsx | 3 +++ 3 files changed, 36 insertions(+) diff --git a/front/package-lock.json b/front/package-lock.json index 037325e..fa29451 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@headlessui/react": "^2.2.0", + "@tasoskakour/react-use-oauth2": "^2.0.2", "framer-motion": "^12.4.3", "lucide-react": "^0.475.0", "react": "^19.0.0", @@ -1483,6 +1484,21 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@tasoskakour/react-use-oauth2": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@tasoskakour/react-use-oauth2/-/react-use-oauth2-2.0.2.tgz", + "integrity": "sha512-rPWXCUwSsF+/7LMFTMB39K1lWknk0OSqBGLRN3Wgl9CUcj07aAeplSH+1ot5DMbzM6PJSM/VsWlo0ltAAg2RFQ==", + "license": "MIT", + "dependencies": { + "use-local-storage-state": "^18.3.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -4744,6 +4760,22 @@ "punycode": "^2.1.0" } }, + "node_modules/use-local-storage-state": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/use-local-storage-state/-/use-local-storage-state-18.3.3.tgz", + "integrity": "sha512-SwwW6LPbxf3q5XimJyYE2jBefpvEJTjAgBO47wCs0+ZkL/Hx8heF/0wtBJ7Df0SiSwyfNDIPHo+8Z3q569jlow==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/astoilkov" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/vite": { "version": "6.2.5", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", diff --git a/front/package.json b/front/package.json index 3d64489..f218037 100644 --- a/front/package.json +++ b/front/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@headlessui/react": "^2.2.0", + "@tasoskakour/react-use-oauth2": "^2.0.2", "framer-motion": "^12.4.3", "lucide-react": "^0.475.0", "react": "^19.0.0", diff --git a/front/src/App.jsx b/front/src/App.jsx index c6b554d..26052e1 100644 --- a/front/src/App.jsx +++ b/front/src/App.jsx @@ -1,9 +1,11 @@ +/* eslint-disable react/jsx-no-comment-textnodes */ import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Header from "./components/Header"; import Footer from "./components/Footer"; import { ThemeProvider, useTheme } from "./ThemeProvider"; import ScrollToTopButton from "./components/ScrollTop"; import ScrollToTop from './components/ScrollTopImmediate'; +import { OAuthPopup } from "@tasoskakour/react-use-oauth2"; import Exemple from "./pages/Exemple-page"; @@ -89,6 +91,7 @@ function App() {
} /> + } path="/callback" /> } /> //Vie courante From d64ff3a7fac18e3195a97e80058011abdd49bbca Mon Sep 17 00:00:00 2001 From: Warix <39554785+warix8@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:49:46 +0200 Subject: [PATCH 4/5] Infirmerie contact with myECL auth integration --- front/src/auth.jsx | 41 ++++++++++++++ front/src/pages/Contact/Infirmerie.jsx | 74 +++++++++++++++++++++----- 2 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 front/src/auth.jsx diff --git a/front/src/auth.jsx b/front/src/auth.jsx new file mode 100644 index 0000000..9d5a3b1 --- /dev/null +++ b/front/src/auth.jsx @@ -0,0 +1,41 @@ +import { useOAuth2 } from "@tasoskakour/react-use-oauth2"; + +export const useAuth = () => { + + const { data, loading, error, getAuth, logout } = useOAuth2({ + authorizeUrl: "http://localhost:8000/auth/authorize", + clientId: "SafetyCards", + clientSecret: "SafetyCards", + redirectUri: `${document.location.origin}/callback`, + scope: "API", + responseType: "code", + // Suppression de exchangeCodeForTokenQuery + exchangeCodeForTokenQueryFn: async (callbackParameters) => { + const params = new URLSearchParams(callbackParameters); + params.append("grant_type", "authorization_code"); + params.append("client_id", "SafetyCards"); + params.append("client_secret", "SafetyCards"); + const response = await fetch("http://localhost:8000/auth/token", { + method: "POST", + body: params.toString(), + headers: { + "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" + } + }); + if (!response.ok) { + throw new Error("Token exchange failed: " + response.statusText); + } + return response.json(); + }, + onSuccess: (payload) => console.log("Success", payload), + onError: (error_) => console.log("Error", error_) + }); + + return { + data, + loading, + error, + getAuth, + logout + }; +} \ No newline at end of file diff --git a/front/src/pages/Contact/Infirmerie.jsx b/front/src/pages/Contact/Infirmerie.jsx index f086fb1..b1b76c3 100644 --- a/front/src/pages/Contact/Infirmerie.jsx +++ b/front/src/pages/Contact/Infirmerie.jsx @@ -1,27 +1,73 @@ -import Quote from "../../components/Citation"; -import ImageTextPopup from "../../components/Cartes"; -import ListeNumerotee from "../../components/Listes"; -import ExternalLinkBlock from "../../components/Liens-ext"; -import Components from "../../components/Common"; -import ContactCard from "../../components/Contact"; -import React from "react"; -import { Chiffre, ChiffresGroup } from "../../components/Chiffres"; -import Separateur from "../../components/Separateur"; +import { useEffect, useState } from "react"; import "../../App.css"; +import { useAuth } from "../../auth"; -const { BulletList, NumberedList, TextImageRight, ImageCenter, Navbar, YouTubeVideo} = Components; - - const Infirmerie = () => { + + const { data, loading, error, getAuth, logout } = useAuth(); // Assurez-vous que le hook useAuth est correctement importé + + const isLoggedIn = Boolean(data?.access_token); // or whatever... + + const [contacts, setContacts] = useState([]); + + useEffect(() => { + async function fetchContacts() { + if (!data?.access_token) return; // ne fetch pas si l'utilisateur n'est pas authentifié + try { + const response = await fetch("http://localhost:8000/advert/adverts", { + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer " + data?.access_token, + }, + }); + if (!response.ok) { + data.access_token = null; // Réinitialiser le token si la requête échoue + logout(); // Déconnexion de l'utilisateur + throw new Error("Failed to fetch users"); + } + const contactsData = await response.json(); + setContacts(contactsData); + } catch (err) { + console.error("Error fetching contacts:", err); + } + } + fetchContacts(); + }, [data, data?.access_token, logout]); + + if (error) { + return
Erreur lors de la connexion à MyECL.
; + } + + if (loading) { + return
Loading...
; + } + + if (isLoggedIn) { return (

Infirmerie

Contact

+

Mail : {contacts.mail}

+

Téléphone : {contacts.phone}

+

Adresse : {contacts.adresse}

+

Horaires : {contacts.horaire}

+ + +
+ ) + } + + return ( +
+

Connexion

+ +

Vous devez vous connecter pour accéder à ses informations :

-

Mail :

-

Téléphone :

+
); From f26d468b3b22eb72860b44fd187d7899fc093179 Mon Sep 17 00:00:00 2001 From: Warix <39554785+warix8@users.noreply.github.com> Date: Fri, 16 May 2025 17:36:26 +0200 Subject: [PATCH 5/5] Temp data fetch --- front/src/App.jsx | 2 +- front/src/pages/Contact/Infirmerie.jsx | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/front/src/App.jsx b/front/src/App.jsx index 26052e1..bca03ca 100644 --- a/front/src/App.jsx +++ b/front/src/App.jsx @@ -2,7 +2,7 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Header from "./components/Header"; import Footer from "./components/Footer"; -import { ThemeProvider, useTheme } from "./ThemeProvider"; +import { ThemeProvider } from "./ThemeProvider"; import ScrollToTopButton from "./components/ScrollTop"; import ScrollToTop from './components/ScrollTopImmediate'; import { OAuthPopup } from "@tasoskakour/react-use-oauth2"; diff --git a/front/src/pages/Contact/Infirmerie.jsx b/front/src/pages/Contact/Infirmerie.jsx index b1b76c3..144543b 100644 --- a/front/src/pages/Contact/Infirmerie.jsx +++ b/front/src/pages/Contact/Infirmerie.jsx @@ -14,7 +14,16 @@ const Infirmerie = () => { useEffect(() => { async function fetchContacts() { if (!data?.access_token) return; // ne fetch pas si l'utilisateur n'est pas authentifié - try { + + await new Promise((resolve) => setTimeout(resolve, 1000)); // Simule un délai de 1 seconde + setContacts({ + mail: "test.exemple@ex.com", + phone: "01 02 03 04 05", + adresse: "1 rue de la sécurité, 75000 Paris", + horaire: "Lundi au Vendredi, 9h-17h", + }); + + /*try { const response = await fetch("http://localhost:8000/advert/adverts", { headers: { "Content-Type": "application/json", @@ -30,7 +39,7 @@ const Infirmerie = () => { setContacts(contactsData); } catch (err) { console.error("Error fetching contacts:", err); - } + }*/ } fetchContacts(); }, [data, data?.access_token, logout]);