import { createContext, useState, useEffect, use } from 'react'; import axios from 'axios'; // 1. Initialize Context const AuthContext = createContext(null); // 2. Create a Custom Provider Component export function AuthProvider({ children }) { const [user, setUser] = useState(null); useEffect(() => { // Fetch user data from your backend API const fetchUser = async () => { // axios is directly used from Axios library to avoid interceptor // added in services/api.js try { const response = await axios.get("/bff/api/security/me", { timeout: 30000, // 30 seconds headers: { 'Content-Type': 'application/json' }, withCredentials: true }); if (response.data && 'username' in response.data) { setUser(response.data); } } catch (error) { console.log(error); } }; fetchUser(); }, []); const login = () => { // Start single sign-on process (Using OAuth2, OpenID) // Access /ui of API gateway. // API gateway will redirect user to authorization server if the user is not logged in // If logged in, API gateway will redirect browser to React app itself reloading the app. window.location.href = "/bff/ui"; } const logout = async () => { // Logout from API gateway try { const response = await axios.post('/bff/logout', { timeout: 30000, // 30 seconds headers: { 'Content-Type': 'application/json' }, withCredentials: true }); // Redirect browser to logout from authorization server. window.location.href = response.headers.location; // setUser(null) is not needed since browser is redirected. } catch (error) { console.log(error); } }; const isLoggedIn = () => { if (user) { return true; } return false; }; const isAdmin = () => { return isInRole("ADMIN"); } const isInRole = (role) => { if (user && role && user.roles) { return user.roles.includes(role); } return false; }; const isInRoles = (roles) => { if (user && roles && user.roles) { return roles.some(value => user.roles.includes(value)); } return false; } // Provide the state and the modifier function as a value object return ( {children} ); } // 3. Create a clean Custom Hook to consume this specific context export function useAuth() { const context = use(AuthContext); if (!context) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }