From aa122113ade36f02dc8fdbebdf1232b5c4b8742c Mon Sep 17 00:00:00 2001
From: Kamal Wickramanayake <kamal@inbox.lk>
Date: Fri, 3 Jul 2026 19:02:36 +0530
Subject: Microservice sample projects

---
 .../04-react-app/src/contexts/AuthContext.jsx      | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 microservices/04-react-app/src/contexts/AuthContext.jsx

(limited to 'microservices/04-react-app/src/contexts/AuthContext.jsx')

diff --git a/microservices/04-react-app/src/contexts/AuthContext.jsx b/microservices/04-react-app/src/contexts/AuthContext.jsx
new file mode 100644
index 0000000..9bb5937
--- /dev/null
+++ b/microservices/04-react-app/src/contexts/AuthContext.jsx
@@ -0,0 +1,99 @@
+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 (
+        <AuthContext value={{ user, login, logout, isLoggedIn, isAdmin, isInRole, isInRoles }}>
+            {children}
+        </AuthContext>
+    );
+}
+
+// 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;
+}
-- 
cgit v1.2.3

