summaryrefslogtreecommitdiff
path: root/react/08-auth-with-context/src/contexts
diff options
context:
space:
mode:
Diffstat (limited to 'react/08-auth-with-context/src/contexts')
-rw-r--r--react/08-auth-with-context/src/contexts/AuthContext.jsx83
1 files changed, 83 insertions, 0 deletions
diff --git a/react/08-auth-with-context/src/contexts/AuthContext.jsx b/react/08-auth-with-context/src/contexts/AuthContext.jsx
new file mode 100644
index 0000000..9ac16b1
--- /dev/null
+++ b/react/08-auth-with-context/src/contexts/AuthContext.jsx
@@ -0,0 +1,83 @@
+import { createContext, useState, useEffect, use } from 'react';
+
+// 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 () => {
+ const response = await fetch('/bff/api/security/user');
+ const data = await response.json();
+ setUser(data); // Data format: { username: "john", name: "John", roles: ["ADMIN", "MANAGER"] }
+ };
+ fetchUser();
+ }, []);
+
+ const login = () => {
+ // TODO: Start single sign-on process (say using OAuth2, OpenID)
+
+ // For testing
+ setUser({ username: "john", name: "John", roles: ["ADMIN", "MANAGER"] })
+ }
+
+ const logout = async () => {
+ const logoutUser = async () => {
+ const response = await fetch('/bff/logout');
+ const data = await response.json();
+ setUser(null);
+ // TODO: Send user to somewhere
+ };
+ logoutUser();
+
+ // For testing
+ setUser(null);
+ };
+
+ 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;
+}