exguard-client 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -815,20 +815,22 @@ function ExGuardRealtimeProvider({ children }) {
815
815
  await triggerRbacRefresh();
816
816
  };
817
817
  React.useEffect(() => {
818
- const accessToken = localStorage.getItem("access_token");
819
- if (!accessToken) {
820
- console.warn("[ExGuardRealtimeProvider] \u26A0\uFE0F No access token found in localStorage");
821
- return;
822
- }
823
- if (connectionAttempted.current) {
824
- return;
825
- }
826
- connectionAttempted.current = true;
827
818
  const initializeConnection = async () => {
819
+ const accessToken = localStorage.getItem("access_token");
820
+ if (!accessToken) {
821
+ console.warn("[ExGuardRealtimeProvider] \u26A0\uFE0F No access token found in localStorage");
822
+ return;
823
+ }
824
+ if (connectionAttempted.current) {
825
+ console.log("[ExGuardRealtimeProvider] \u2139\uFE0F Connection already attempted, skipping");
826
+ return;
827
+ }
828
+ connectionAttempted.current = true;
828
829
  try {
829
830
  const userId = await getCurrentUserId();
830
831
  if (!userId) {
831
832
  console.error("[ExGuardRealtimeProvider] \u274C Failed to get userId from backend");
833
+ connectionAttempted.current = false;
832
834
  return;
833
835
  }
834
836
  currentUserRef.current = { token: accessToken, userId };
@@ -847,9 +849,22 @@ function ExGuardRealtimeProvider({ children }) {
847
849
  token: tokenStr
848
850
  });
849
851
  setIsConnected(false);
852
+ connectionAttempted.current = false;
850
853
  }
851
854
  };
855
+ const handleStorageChange = (e) => {
856
+ if (e.key === "access_token" && e.newValue && !connectionAttempted.current) {
857
+ console.log("[ExGuardRealtimeProvider] \u{1F511} Access token detected, initializing connection");
858
+ void initializeConnection();
859
+ }
860
+ };
861
+ const handleTokenUpdate = () => {
862
+ console.log("[ExGuardRealtimeProvider] \u{1F511} Token update event received, initializing connection");
863
+ void initializeConnection();
864
+ };
852
865
  void initializeConnection();
866
+ window.addEventListener("storage", handleStorageChange);
867
+ window.addEventListener("exguard:token-updated", handleTokenUpdate);
853
868
  let lastConnectedState = realtimeClient.getIsConnected();
854
869
  const interval = setInterval(() => {
855
870
  const currentConnectedState = realtimeClient.getIsConnected();
@@ -860,6 +875,8 @@ function ExGuardRealtimeProvider({ children }) {
860
875
  }, 1e3);
861
876
  return () => {
862
877
  clearInterval(interval);
878
+ window.removeEventListener("storage", handleStorageChange);
879
+ window.removeEventListener("exguard:token-updated", handleTokenUpdate);
863
880
  };
864
881
  }, []);
865
882
  const handleConnect = async (token, userId) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/exguard-config.ts","../src/config/realtime-rbac-config.ts","../src/api/exguard-api.ts","../src/providers/exguard-realtime-context.ts","../src/hooks/use-user-access.ts","../src/components/ui/spinner.tsx","../src/components/ui/button.tsx","../src/components/ui/card.tsx","../src/components/permission-guard.tsx","../src/lib/realtime-client.ts","../src/hooks/use-realtime.ts","../src/providers/use-exguard-realtime.ts","../src/hooks/use-exguard-rbac.ts","../src/utils/exguard-realtime-utils.ts","../src/providers/exguard-realtime-provider.tsx","../src/providers/use-exguard-realtime-subscription.ts"],"names":["axios","createContext","useState","use","useCallback","useEffect","jsx","Navigate","jsxs","Lock","ShieldAlert","ArrowLeft","Outlet","io","useRef","React","unsubscribers"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * ExGuard API Configuration\r\n * Configuration for ExGuard backend API\r\n */\r\n\r\nexport interface ExGuardConfig {\r\n apiUrl: string;\r\n withCredentials?: boolean;\r\n getAuthToken?: () => string | null;\r\n}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Auto-detects API URL based on environment\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Configuration state\r\n */\r\nlet configuredApiUrl: string = '';\r\nlet customGetAuthToken: (() => string | null) | undefined;\r\n\r\n/**\r\n * Auto-detect API URL based on current environment\r\n */\r\nconst autoDetectApiUrl = (): string => {\r\n if (typeof window !== 'undefined') {\r\n const hostname = window.location.hostname;\r\n const protocol = window.location.protocol;\r\n \r\n // Local development\r\n if (hostname === 'localhost' || hostname === '127.0.0.1') {\r\n return 'http://localhost:3000';\r\n }\r\n \r\n // Production/Staging - use same domain with /api path\r\n return `${protocol}//${hostname}/api`;\r\n }\r\n \r\n // SSR fallback\r\n return process.env.EXGUARD_API_URL || 'http://localhost:3000';\r\n};\r\n\r\n/**\r\n * Set ExGuard configuration\r\n * @param config - Partial configuration to override defaults\r\n */\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n if (config.getAuthToken) {\r\n customGetAuthToken = config.getAuthToken;\r\n }\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL\r\n * Priority: 1) Manual config, 2) Environment var, 3) Auto-detect\r\n */\r\nexport const getExGuardApiUrl = (): string => {\r\n // 1. User-configured URL\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // 2. Check environment variables (Vite/Next.js)\r\n if (typeof window !== 'undefined') {\r\n // Vite apps\r\n if ((import.meta as any).env?.VITE_GUARD_APP_URL) {\r\n return (import.meta as any).env.VITE_GUARD_APP_URL;\r\n }\r\n \r\n // Next.js or injected env\r\n if ((window as any).__EXGUARD_API_URL__) {\r\n return (window as any).__EXGUARD_API_URL__;\r\n }\r\n }\r\n \r\n // 3. Auto-detect based on hostname\r\n return autoDetectApiUrl();\r\n};\r\n\r\n/**\r\n * Get authentication token\r\n * Uses custom getter if provided, otherwise defaults to localStorage\r\n */\r\nexport const getAuthToken = (): string | null => {\r\n if (customGetAuthToken) {\r\n return customGetAuthToken();\r\n }\r\n \r\n if (typeof window !== 'undefined') {\r\n return (\r\n localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n sessionStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n null\r\n );\r\n }\r\n \r\n return null;\r\n};\r\n\r\n/**\r\n * Storage keys for ExGuard\r\n */\r\nexport const EXGUARD_STORAGE_KEYS = {\r\n ACCESS_TOKEN: 'access_token',\r\n ID_TOKEN: 'id_token',\r\n REFRESH_TOKEN: 'refresh_token',\r\n} as const;\r\n","/**\n * ExGuard Realtime RBAC Configuration\n *\n * This file contains all configuration for realtime RBAC events\n * specific to ExGuard module (users, roles, permissions management)\n */\n\n/**\n * Channels to subscribe to for ExGuard RBAC\n */\nexport const EXGUARD_RBAC_CHANNELS = {\n ROLES: 'roles',\n PERMISSIONS: 'permissions',\n RBAC: 'rbac',\n} as const;\n\n/**\n * Event types for ExGuard RBAC realtime updates\n */\nexport const EXGUARD_RBAC_EVENTS = {\n // Role events\n ROLE_CREATED: 'role:created',\n ROLE_UPDATED: 'role:updated',\n ROLE_DELETED: 'role:deleted',\n\n // Permission events\n PERMISSION_CREATED: 'permission:created',\n PERMISSION_UPDATED: 'permission:updated',\n PERMISSION_DELETED: 'permission:deleted',\n\n // Role-Permission events\n ROLE_PERMISSION_ASSIGNED: 'role-permission:assigned',\n ROLE_PERMISSION_REMOVED: 'role-permission:removed',\n\n // User RBAC events\n USER_ROLES_UPDATED: 'user:roles-updated',\n USER_PERMISSIONS_CHANGED: 'user:permissions-changed',\n USER_ACCESS_CHANGED: 'user:access-changed',\n RBAC_USER_ASSIGNED_TO_GROUP: 'rbac:user-assigned-to-group',\n RBAC_USER_REMOVED_FROM_GROUP: 'rbac:user-removed-from-group',\n RBAC_PERMISSIONS_UPDATED: 'rbac:permissions-updated',\n\n // User status events\n USER_ONLINE: 'user:online',\n USER_OFFLINE: 'user:offline',\n\n // Group events\n GROUP_UPDATED: 'group:updated',\n} as const;\n\n/**\n * Reconnection delay after RBAC updates (in milliseconds)\n * This ensures backend has fully processed the update before refetching data\n */\nexport const RBAC_RECONNECT_DELAY = 300;\n\n/**\n * Configuration for automatic reconnection after specific events\n */\nexport const RBAC_AUTO_RECONNECT_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n] as const;\n\n/**\n * Events that should trigger user data refresh\n */\nexport const USER_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_PERMISSIONS_CHANGED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n EXGUARD_RBAC_EVENTS.RBAC_USER_ASSIGNED_TO_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_USER_REMOVED_FROM_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED,\n] as const;\n\n/**\n * Events that should trigger role data refresh\n */\nexport const ROLE_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n] as const;\n\n/**\n * Events that should trigger permission data refresh\n */\nexport const PERMISSION_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n] as const;\n","import axios, { type AxiosError } from 'axios';\nimport type { VerifyTokenResponse, UserAccessData, AuthApiResponse } from '../types/exguard-types';\nimport { getExGuardApiUrl, getAuthToken, EXGUARD_STORAGE_KEYS } from '../config/exguard-config';\n\n// Create a separate axios instance for Guard API endpoints\n// Note: baseURL is set dynamically in the interceptor to support runtime configuration\nconst guardApiClient = axios.create({\n withCredentials: true,\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n\n// Add interceptor to dynamically set baseURL and include access token\nguardApiClient.interceptors.request.use(\n (config) => {\n // Set baseURL dynamically from config (supports runtime configuration)\n config.baseURL = getExGuardApiUrl();\n \n const token = getAuthToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error: unknown) => Promise.reject(error instanceof Error ? error : new Error(String(error))),\n);\n\n/**\n * Verify ID token with ExGuard backend\n */\nexport async function verifyToken(): Promise<VerifyTokenResponse> {\n try {\n const idToken = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ID_TOKEN);\n const response = await guardApiClient.post<\n AuthApiResponse<{\n user?: {\n id: string;\n username: string;\n email: string;\n givenName: string;\n familyName: string;\n };\n }>\n >('/guard/verify-token', {\n id_token: idToken,\n });\n\n if (response.data.success && response.data.data) {\n // Map backend response to frontend format\n const backendData = response.data.data;\n const mappedResponse: VerifyTokenResponse = {\n valid: true,\n user: backendData.user\n ? {\n userId: backendData.user.id,\n username: backendData.user.username,\n email: backendData.user.email,\n givenName: backendData.user.givenName,\n familyName: backendData.user.familyName,\n }\n : undefined,\n };\n return mappedResponse;\n }\n\n throw new Error(response.data.message ?? 'Token verification failed');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Token verification failed';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n\n/**\n * Flag to ensure User Access Data is logged only once\n */\nlet hasLoggedUserAccess = false;\n\n/**\n * Get user access data including roles, permissions, modules, and field offices\n */\nexport async function getUserAccess(): Promise<UserAccessData> {\n try {\n const response = await guardApiClient.get<AuthApiResponse<UserAccessData>>('/guard/me');\n\n if (response.data.success && response.data.data) {\n if (!hasLoggedUserAccess) {\n console.log('User Access Data:', response.data.data);\n hasLoggedUserAccess = true;\n }\n\n return response.data.data;\n }\n\n throw new Error(response.data.message ?? 'Failed to get user access data');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Failed to get user access data';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n","/**\n * ExGuard Realtime Context\n *\n * Context for managing realtime RBAC connections and state\n */\n\nimport { createContext } from 'react';\n\nexport interface ExGuardRealtimeContextType {\n isConnected: boolean;\n connect: (token: string, userId: string) => Promise<void>;\n disconnect: () => void;\n reconnect: () => Promise<void>;\n refreshRbac: () => Promise<void>;\n registerRbacRefreshCallback: (callback: () => Promise<void>) => () => void;\n}\n\nexport const ExGuardRealtimeContext = createContext<ExGuardRealtimeContextType | undefined>(undefined);\n","import { useEffect, useState, useCallback, use } from 'react';\r\nimport { getUserAccess } from '../api/exguard-api';\r\nimport type { UserAccessData, ModulePermissions } from '../types/exguard-types';\r\nimport { ExGuardRealtimeContext } from '../providers/exguard-realtime-context';\r\n\r\ninterface UseUserAccessOptions {\r\n enabled?: boolean;\r\n refetchInterval?: number;\r\n}\r\n\r\n/**\r\n * Custom hook to fetch and manage user access data with RBAC\r\n * Includes caching and periodic refetching for real-time RBAC\r\n */\r\nexport const useUserAccess = (options: UseUserAccessOptions = {}) => {\r\n const { enabled = true, refetchInterval = 0 } = options;\r\n const [userAccess, setUserAccess] = useState<UserAccessData | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n const realtimeContext = use(ExGuardRealtimeContext);\r\n\r\n const fetchUserAccess = useCallback(async (silent = false): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n // Only set loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(true);\r\n }\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error('Failed to fetch user access');\r\n setError(errorObj);\r\n } finally {\r\n // Only clear loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(false);\r\n }\r\n }\r\n }, [enabled]);\r\n\r\n // Register for real-time RBAC updates from the realtime provider\r\n useEffect(() => {\r\n if (!realtimeContext) {\r\n return;\r\n }\r\n\r\n // Use silent refresh for realtime updates to prevent UI disruption\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(() => fetchUserAccess(true));\r\n\r\n return () => {\r\n unsubscribe();\r\n };\r\n }, [realtimeContext, fetchUserAccess]);\r\n\r\n useEffect(() => {\r\n void fetchUserAccess();\r\n\r\n if (refetchInterval > 0) {\r\n const interval = setInterval(() => {\r\n void fetchUserAccess();\r\n }, refetchInterval);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }\r\n }, [fetchUserAccess, refetchInterval]);\r\n\r\n const hasModuleAccess = useCallback(\r\n (moduleKey: string): boolean => {\r\n if (!userAccess) return false;\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return !!module && module.permissions.length > 0;\r\n },\r\n [userAccess],\r\n );\r\n\r\n const getModulePermissions = useCallback(\r\n (moduleKey: string): string[] => {\r\n if (!userAccess) return [];\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return module?.permissions ?? [];\r\n },\r\n [userAccess],\r\n );\r\n\r\n const hasPermission = useCallback(\r\n (moduleKey: string, permission: string): boolean => {\r\n const permissions = getModulePermissions(moduleKey);\r\n return permissions.includes(permission);\r\n },\r\n [getModulePermissions],\r\n );\r\n\r\n return {\r\n userAccess,\r\n isLoading,\r\n error,\r\n hasModuleAccess,\r\n getModulePermissions,\r\n hasPermission,\r\n refetch: fetchUserAccess,\r\n refetchSilent: () => fetchUserAccess(true),\r\n };\r\n};\r\n","import React from 'react';\r\n\r\ninterface SpinnerProps {\r\n className?: string;\r\n}\r\n\r\nexport function Spinner({ className = '' }: SpinnerProps) {\r\n return (\r\n <div\r\n className={`animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${className}`}\r\n role=\"status\"\r\n >\r\n <span className=\"!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]\">\r\n Loading...\r\n </span>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n variant?: 'default' | 'outline' | 'destructive' | 'ghost' | 'link';\r\n size?: 'default' | 'sm' | 'lg' | 'icon';\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Button({\r\n className = '',\r\n variant = 'default',\r\n size = 'default',\r\n children,\r\n ...props\r\n}: ButtonProps) {\r\n const baseStyles =\r\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';\r\n\r\n const variantStyles = {\r\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\r\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\r\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\r\n ghost: 'hover:bg-accent hover:text-accent-foreground',\r\n link: 'text-primary underline-offset-4 hover:underline',\r\n };\r\n\r\n const sizeStyles = {\r\n default: 'h-10 px-4 py-2',\r\n sm: 'h-9 rounded-md px-3',\r\n lg: 'h-11 rounded-md px-8',\r\n icon: 'h-10 w-10',\r\n };\r\n\r\n return (\r\n <button\r\n className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface CardProps extends React.HTMLAttributes<HTMLDivElement> {\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Card({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div\r\n className={`rounded-lg border bg-card text-card-foreground shadow-sm ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardHeader({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex flex-col space-y-1.5 p-6 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardTitle({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <h3 className={`text-2xl font-semibold leading-none tracking-tight ${className}`} {...props}>\r\n {children}\r\n </h3>\r\n );\r\n}\r\n\r\nexport function CardDescription({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <p className={`text-sm text-muted-foreground ${className}`} {...props}>\r\n {children}\r\n </p>\r\n );\r\n}\r\n\r\nexport function CardContent({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardFooter({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex items-center p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import { Navigate, Outlet } from 'react-router';\r\nimport { useUserAccess } from '../hooks/use-user-access';\r\nimport { Spinner } from './ui/spinner';\r\nimport { Button } from './ui/button';\r\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card';\r\nimport { ArrowLeft, ShieldAlert, Lock } from 'lucide-react';\r\n\r\ninterface PermissionGuardProps {\r\n module: string;\r\n permission?: string;\r\n requireModule?: boolean;\r\n requirePermission?: boolean;\r\n fallbackPath?: string;\r\n}\r\n\r\n/**\r\n * PermissionGuard component that checks if user has required module access and/or permissions\r\n *\r\n * @param module - The module key (e.g., 'EXID', 'EXFLOW', 'TEV')\r\n * @param permission - Optional specific permission to check (e.g., 'profile:create', 'profile:update')\r\n * @param requireModule - Whether to require module access (default: true)\r\n * @param requirePermission - Whether to require the specific permission (default: true if permission is provided)\r\n * @param fallbackPath - Path to redirect to if access is denied (default: show error page)\r\n */\r\nexport function PermissionGuard({\r\n module,\r\n permission,\r\n requireModule = true,\r\n requirePermission = true,\r\n fallbackPath,\r\n}: PermissionGuardProps) {\r\n const { isLoading, hasModuleAccess, hasPermission } = useUserAccess();\r\n\r\n // Show loading spinner while checking permissions\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Spinner className=\"size-8\" />\r\n </div>\r\n );\r\n }\r\n\r\n // Check module access\r\n const hasModule = hasModuleAccess(module);\r\n const moduleCheckFailed = requireModule && !hasModule;\r\n\r\n // Check specific permission if provided\r\n const hasSpecificPermission = permission ? hasPermission(module, permission) : true;\r\n const permissionCheckFailed = permission && requirePermission && !hasSpecificPermission;\r\n\r\n // Determine if access should be denied\r\n const accessDenied = moduleCheckFailed || permissionCheckFailed;\r\n\r\n // Redirect to fallback path if provided\r\n if (accessDenied && fallbackPath) {\r\n return <Navigate to={fallbackPath} replace />;\r\n }\r\n\r\n // Show access denied message\r\n if (accessDenied) {\r\n const denialReason = moduleCheckFailed\r\n ? {\r\n title: 'Module Access Required',\r\n description: `Access to the ${module} module is required to view this page`,\r\n detail: `Your current account permissions do not include access to the ${module} module. This module may be restricted to specific roles or user groups.`,\r\n }\r\n : {\r\n title: 'Permission Required',\r\n description: `The permission \"${permission ?? 'unknown'}\" is needed to access this resource`,\r\n detail: `Your account has access to the ${module} module but lacks the specific permission required for this action. This permission may need to be assigned to your role or user group.`,\r\n };\r\n\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[calc(100vh-4rem)] p-6\">\r\n <Card className=\"w-full max-w-lg\">\r\n <CardHeader className=\"text-center pb-4\">\r\n <div className=\"mx-auto mb-4 flex size-16 items-center justify-center rounded-full bg-destructive/10\">\r\n {moduleCheckFailed ? (\r\n <Lock className=\"size-8 text-destructive\" />\r\n ) : (\r\n <ShieldAlert className=\"size-8 text-destructive\" />\r\n )}\r\n </div>\r\n <CardTitle className=\"text-2xl\">{denialReason.title}</CardTitle>\r\n <CardDescription className=\"text-base\">{denialReason.description}</CardDescription>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n <div className=\"rounded-lg bg-muted p-4\">\r\n <p className=\"text-sm text-muted-foreground\">{denialReason.detail}</p>\r\n </div>\r\n <div className=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n window.history.back();\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n <ArrowLeft className=\"mr-2 size-4\" />\r\n Go Back\r\n </Button>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => {\r\n window.location.href = '/';\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n Return to Dashboard\r\n </Button>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n </div>\r\n );\r\n }\r\n\r\n // User has required access, render child routes\r\n return <Outlet />;\r\n}\r\n","import { io, type Socket } from 'socket.io-client';\nimport type { RealtimeEventPayload, RealtimeEventType, RealtimeEventHandler } from './realtime.types';\nimport { getExGuardApiUrl } from '../config/exguard-config';\n\nclass RealtimeClient {\n private socket: Socket | null = null;\n private listeners = new Map<string, Set<RealtimeEventHandler>>();\n private isConnected = false;\n private debug = false; // Enable/disable debug logging\n private connectionPromise: Promise<void> | null = null;\n\n constructor() {\n this.log('đŸŸĸ RealtimeClient initialized');\n }\n \n private getApiUrl(): string {\n return getExGuardApiUrl();\n }\n\n private log(message: string, data?: unknown) {\n if (this.debug) {\n console.log(`[RealtimeClient] ${message}`, data);\n }\n }\n\n private logError(message: string, error?: unknown) {\n console.error(`[RealtimeClient] ${message}`, error);\n }\n\n private logWarn(message: string, data?: unknown) {\n console.warn(`[RealtimeClient] ${message}`, data);\n }\n\n /**\n * Connect to the realtime server\n */\n connect(token: string, userId: string): Promise<void> {\n // Validate inputs\n if (!token) {\n this.logError('❌ Cannot connect - token is missing or empty');\n return Promise.reject(new Error('Missing authentication token'));\n }\n\n if (!userId) {\n this.logError('❌ Cannot connect - userId is missing or empty');\n return Promise.reject(new Error('Missing userId'));\n }\n\n // Return existing connection promise if already connecting\n if (this.connectionPromise) {\n this.log('âŗ Connection already in progress, returning existing promise');\n return this.connectionPromise;\n }\n\n this.connectionPromise = new Promise((resolve, reject) => {\n try {\n const apiUrl = this.getApiUrl();\n this.log('🔌 Attempting to connect...', { apiUrl, userId, hasToken: !!token });\n\n if (this.socket?.connected) {\n this.log('✅ Already connected');\n this.connectionPromise = null;\n resolve();\n return;\n }\n\n const socketUrl = `${apiUrl}/realtime`;\n this.log('🚀 Creating Socket.IO connection', {\n url: socketUrl,\n transports: ['websocket', 'polling'],\n userId,\n });\n\n this.socket = io(socketUrl, {\n auth: {\n token,\n userId,\n },\n transports: ['websocket', 'polling'],\n reconnection: true,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n reconnectionAttempts: 5,\n });\n\n this.socket.on('connect', () => {\n this.isConnected = true;\n this.log('✅ Connected to realtime server', {\n socketId: this.socket?.id,\n userId,\n });\n this.connectionPromise = null;\n resolve();\n });\n\n this.socket.on('disconnect', (reason: string) => {\n this.isConnected = false;\n this.log('❌ Disconnected from realtime server', { reason });\n });\n\n this.socket.on('connect_error', (error: unknown) => {\n this.logError('❌ Connection error (check token and backend)', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection error: ${errorMessage}`));\n });\n\n this.socket.on('error', (error: unknown) => {\n this.logError('❌ Realtime error', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Socket.IO error: ${errorMessage}`));\n });\n\n this.socket.on('reconnect_attempt', () => {\n this.log('🔄 Attempting to reconnect...');\n });\n\n this.socket.on('reconnect', () => {\n this.isConnected = true;\n this.log('🔁 Reconnected to realtime server', {\n socketId: this.socket?.id,\n });\n });\n\n this.socket.on('reconnect_failed', () => {\n this.logError('❌ Reconnection failed after maximum attempts');\n this.connectionPromise = null;\n reject(new Error('Reconnection failed'));\n });\n\n // Listen to all realtime events\n this.socket.onAny((eventName: string, payload: unknown) => {\n // Debug: log raw event for troubleshooting\n this.log(`📨 Raw event received`, {\n eventName,\n payloadType: typeof payload,\n payload,\n });\n\n // Normalize payload - backend sends event name separately from payload\n const payloadObj =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n\n // CRITICAL FIX: Use eventName as the primary event type (e.g., 'user:access-changed')\n // Socket.IO sends the event name as the first parameter, not nested in payload.type\n const eventType = eventName;\n\n const normalizedPayload: RealtimeEventPayload = {\n type: eventType as RealtimeEventType,\n timestamp:\n 'timestamp' in payloadObj\n ? typeof payloadObj.timestamp === 'number'\n ? payloadObj.timestamp\n : new Date(payloadObj.timestamp as string).getTime()\n : Date.now(),\n data: 'data' in payloadObj ? payloadObj.data : payload,\n };\n\n this.log(`📨 Event processed: ${eventType}`, {\n type: normalizedPayload.type,\n timestamp: normalizedPayload.timestamp,\n dataKeys:\n typeof normalizedPayload.data === 'object' && normalizedPayload.data !== null\n ? Object.keys(normalizedPayload.data as Record<string, unknown>)\n : 'N/A',\n });\n this.handleEvent(eventType as RealtimeEventType, normalizedPayload);\n });\n } catch (error) {\n this.logError('Failed to initialize connection', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection initialization failed: ${errorMessage}`));\n }\n });\n\n return this.connectionPromise;\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.log('🔌 Disconnecting from realtime server...');\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n this.isConnected = false;\n this.log('✅ Disconnected');\n }\n }\n\n /**\n * Check if connected\n */\n getIsConnected(): boolean {\n return this.isConnected && this.socket?.connected === true;\n }\n\n /**\n * Wait for connection to be ready (with timeout)\n */\n async waitForConnection(timeoutMs = 30000): Promise<void> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (this.getIsConnected()) {\n this.log('✅ Connection ready');\n return;\n }\n\n // Wait 100ms before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n this.logError('❌ Timeout waiting for connection', { timeoutMs, elapsed: Date.now() - startTime });\n throw new Error('Connection timeout - failed to establish WebSocket connection');\n }\n\n /**\n * Subscribe to a specific event type\n */\n subscribe<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n ): () => void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set());\n }\n\n this.listeners.get(eventType)?.add(handler as RealtimeEventHandler);\n const listenerCount = this.listeners.get(eventType)?.size ?? 0;\n this.log(`📌 Subscribed to event: ${eventType}`, { totalListeners: listenerCount });\n\n // Return unsubscribe function\n return () => {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler as RealtimeEventHandler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n };\n }\n\n /**\n * Unsubscribe from an event\n */\n unsubscribe(eventType: RealtimeEventType, handler: RealtimeEventHandler): void {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n }\n /**\n * Send a subscription message to the server with connection wait\n */\n async subscribeToChannel(channel: 'roles' | 'permissions' | 'rbac'): Promise<void> {\n try {\n this.log(`📡 Subscribing to channel: ${channel}`);\n\n // Wait for connection to be ready\n await this.waitForConnection(15000);\n\n // Now emit subscribe\n this.log(`📡 Emitting subscribe event for channel: ${channel}`);\n this.socket?.emit(`subscribe:${channel}`);\n this.log(`✅ Subscribed to channel: ${channel}`);\n } catch (error) {\n this.logError(`❌ Failed to subscribe to channel \"${channel}\"`, error);\n throw error;\n }\n }\n\n /**\n * Send an unsubscription message to the server\n */\n unsubscribeFromChannel(channel: 'roles' | 'permissions' | 'rbac'): void {\n if (!this.socket?.connected) {\n this.logWarn(`Cannot unsubscribe from channel \"${channel}\" - socket not connected`);\n return;\n }\n\n this.log(`📡 Unsubscribing from channel: ${channel}`);\n this.socket.emit(`unsubscribe:${channel}`);\n }\n\n /**\n * Handle incoming events\n */\n private handleEvent(eventType: RealtimeEventType, payload: RealtimeEventPayload): void {\n // Call specific event handlers\n const handlers = this.listeners.get(eventType);\n if (handlers && handlers.size > 0) {\n this.log(`🔔 Triggering ${String(handlers.size)} handler(s) for event: ${eventType}`);\n handlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError(`Error in event handler for ${eventType}`, error);\n }\n });\n }\n\n // Call wildcard handlers if any\n const wildcardHandlers = this.listeners.get('*' as RealtimeEventType);\n if (wildcardHandlers && wildcardHandlers.size > 0) {\n this.log(`🔔 Triggering ${String(wildcardHandlers.size)} wildcard handler(s)`);\n wildcardHandlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError('Error in wildcard event handler', error);\n }\n });\n }\n }\n\n /**\n * Get all connected listeners count\n */\n getListenerCount(eventType?: RealtimeEventType): number {\n if (eventType) {\n return this.listeners.get(eventType)?.size ?? 0;\n }\n let total = 0;\n this.listeners.forEach((handlers) => {\n total += handlers.size;\n });\n return total;\n }\n\n /**\n * Enable or disable debug logging\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n this.log(`Debug logging ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * Get connection status summary\n */\n getStatus() {\n const status = {\n isConnected: this.getIsConnected(),\n socketId: this.socket?.id ?? 'N/A',\n apiUrl: this.getApiUrl(),\n totalListeners: this.getListenerCount(),\n listeners: Array.from(this.listeners.entries()).map(([event, handlers]) => ({\n event,\n count: handlers.size,\n })),\n };\n this.log('📊 Connection Status', status);\n return status;\n }\n}\n\n// Create singleton instance\nexport const realtimeClient = new RealtimeClient();\n\n// Expose debug methods on window for console access\nif (typeof window !== 'undefined') {\n const w = window as unknown as Record<string, unknown>;\n w.__realtimeClient = {\n client: realtimeClient,\n connect: (token: string, userId: string) => realtimeClient.connect(token, userId),\n disconnect: () => {\n realtimeClient.disconnect();\n },\n isConnected: () => realtimeClient.getIsConnected(),\n setDebug: (enabled: boolean) => {\n realtimeClient.setDebug(enabled);\n },\n status: () => realtimeClient.getStatus(),\n getListenerCount: (eventType?: RealtimeEventType) => realtimeClient.getListenerCount(eventType),\n };\n\n}\n\nexport type { RealtimeClient };\n","/**\n * Shared Realtime Hooks\n *\n * Basic hooks for realtime functionality that wraps the realtime-client\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport type { RealtimeEventType, RealtimeEventPayload, RealtimeEventHandler } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to realtime RBAC events\n * Automatically handles subscription/unsubscription lifecycle\n */\nexport function useRealtimeRbac<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe<T>(eventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, [eventType]);\n}\n\n/**\n * Hook to manage channel subscriptions\n */\nexport function useRealtimeSubscription(channel: 'roles' | 'permissions' | 'rbac') {\n useEffect(() => {\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch(() => {\n // Silent error handling\n });\n\n return () => {\n realtimeClient.unsubscribeFromChannel(channel);\n };\n }, [channel]);\n}\n\n/**\n * Hook to listen to multiple event types\n */\nexport function useRealtimeMultiple(\n events: {\n type: RealtimeEventType;\n handler: RealtimeEventHandler;\n }[],\n) {\n useEffect(() => {\n const unsubscribers = events.map(({ type, handler }) => realtimeClient.subscribe(type, handler));\n\n return () => {\n unsubscribers.forEach((unsub) => {\n unsub();\n });\n };\n }, [events]);\n}\n\n/**\n * Hook to listen to all realtime events\n */\nexport function useRealtimeAll(handler: RealtimeEventHandler) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe('*' as RealtimeEventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, []);\n}\n\n/**\n * Hook to get the connection status\n */\nexport function useRealtimeStatus() {\n const [isConnected, setIsConnected] = useState(realtimeClient.getIsConnected());\n\n useEffect(() => {\n const checkConnection = () => {\n setIsConnected(realtimeClient.getIsConnected());\n };\n\n const interval = setInterval(checkConnection, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n return { isConnected };\n}\n","/**\n * Hook to use ExGuard Realtime Context\n */\n\nimport { use } from 'react';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\n\n/**\n * Hook to access ExGuard realtime context\n * Must be used within ExGuardRealtimeProvider\n */\nexport function useExGuardRealtime(): ExGuardRealtimeContextType {\n const context = use(ExGuardRealtimeContext);\n if (!context) {\n throw new Error('useExGuardRealtime must be used within a ExGuardRealtimeProvider');\n }\n return context;\n}\n","/**\n * ExGuard Realtime RBAC Hooks\n *\n * Custom hooks for handling ExGuard-specific realtime RBAC events\n */\n\nimport { useCallback } from 'react';\nimport { useRealtimeRbac, useRealtimeSubscription } from './use-realtime';\nimport { useExGuardRealtime } from '../providers/use-exguard-realtime';\nimport { EXGUARD_RBAC_CHANNELS, EXGUARD_RBAC_EVENTS, RBAC_RECONNECT_DELAY } from '../config/realtime-rbac-config';\nimport type { RealtimeEventPayload } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to all ExGuard RBAC channels\n */\nexport function useExGuardRbacChannels() {\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.RBAC);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.ROLES);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.PERMISSIONS);\n}\n\n/**\n * Hook to handle role updates with automatic reconnection\n */\nexport function useRoleUpdateHandler(onUpdate: () => Promise<void>, fetchUserAccess?: () => Promise<void>) {\n const { reconnect } = useExGuardRealtime();\n\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n try {\n await reconnect();\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n } catch (error) {\n // Silent error handling\n }\n })();\n },\n [reconnect, onUpdate, fetchUserAccess],\n ),\n );\n}\n\n/**\n * Hook to handle user RBAC updates (role assignments, permissions, etc.)\n */\nexport function useUserRbacUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle permission updates\n */\nexport function usePermissionUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle group updates\n */\nexport function useGroupUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle user access changes (personal notifications)\n * This is for individual user notifications received via user:{cognitoSubId} room\n */\nexport function useUserAccessChangeHandler(onAccessChange: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onAccessChange();\n })();\n },\n [onAccessChange],\n ),\n );\n}\n","/**\n * ExGuard Realtime Utilities\n *\n * Utility functions for ExGuard realtime functionality\n */\n\nimport { getUserAccess } from '../api/exguard-api';\n\n/**\n * Get current user's Cognito Sub ID from backend\n * This is used for websocket room identification (user:{cognitoSubId})\n */\nexport async function getCurrentUserId(): Promise<string | null> {\n try {\n const userAccess = await getUserAccess();\n \n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n return null;\n }\n}\n","/**\n * ExGuard Realtime Provider\n *\n * Provider for managing realtime RBAC connections and events\n */\n\nimport React, { useEffect, useRef, type ReactNode } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\nimport { getCurrentUserId } from '../utils/exguard-realtime-utils';\nimport type { UserRbacEventPayload } from '../lib/realtime.types';\n\ninterface ExGuardRealtimeProviderProps {\n children: ReactNode;\n}\n\nexport function ExGuardRealtimeProvider({ children }: ExGuardRealtimeProviderProps) {\n const [isConnected, setIsConnected] = React.useState(false);\n const connectionAttempted = useRef(false);\n const rbacRefreshCallbacks = useRef<Set<() => Promise<void>>>(new Set());\n const currentUserRef = useRef<{ token: string; userId: string } | null>(null);\n const currentUserIdRef = useRef<string | null>(null);\n\n // Register callback to refresh user access\n const registerRbacRefreshCallback = (callback: () => Promise<void>) => {\n rbacRefreshCallbacks.current.add(callback);\n return () => {\n rbacRefreshCallbacks.current.delete(callback);\n };\n };\n\n // Trigger refresh for all registered callbacks\n const triggerRbacRefresh = async (): Promise<void> => {\n \n if (rbacRefreshCallbacks.current.size === 0) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No RBAC refresh callbacks registered!');\n return;\n }\n\n const refreshPromises = Array.from(rbacRefreshCallbacks.current).map((cb, index) => {\n return cb().catch((err: unknown) => {\n console.error(`[ExGuardRealtimeProvider] ❌ Error during RBAC refresh callback ${String(index + 1)}:`, err);\n });\n });\n\n await Promise.all(refreshPromises);\n };\n\n // Manual reconnect function\n const handleReconnect = async (): Promise<void> => {\n if (!currentUserRef.current) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No user credentials available for reconnect');\n return;\n }\n const { token, userId } = currentUserRef.current;\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n const accessToken = localStorage.getItem('access_token');\n\n if (!accessToken) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No access token found in localStorage');\n return;\n }\n\n if (connectionAttempted.current) {\n return;\n }\n\n connectionAttempted.current = true;\n\n // Fetch user info from backend\n const initializeConnection = async (): Promise<void> => {\n try {\n const userId = await getCurrentUserId();\n\n if (!userId) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to get userId from backend');\n return;\n }\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n setIsConnected(true);\n\n // Listen ONLY for THIS USER's access changes (sent to user:{userId} room)\n realtimeClient.subscribe('user:access-changed', (_payload: UserRbacEventPayload): void => {\n \n // No need to check userId - if this event reached our room (user:{cognitoSubId}),\n // it's definitely for us. Backend ensures correct room targeting.\n void triggerRbacRefresh();\n });\n\n \n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to establish realtime connection:');\n const errorMessage = error instanceof Error ? error.message : String(error);\n const tokenStr = accessToken ? accessToken.substring(0, 20) + '...' : '';\n console.error('[ExGuardRealtimeProvider] Error details:', {\n message: errorMessage,\n token: tokenStr,\n });\n setIsConnected(false);\n }\n };\n\n void initializeConnection();\n\n // Monitor connection status\n let lastConnectedState = realtimeClient.getIsConnected();\n const interval = setInterval(() => {\n const currentConnectedState = realtimeClient.getIsConnected();\n if (currentConnectedState !== lastConnectedState) {\n \n lastConnectedState = currentConnectedState;\n setIsConnected(currentConnectedState);\n }\n }, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n const handleConnect = async (token: string, userId: string) => {\n try {\n \n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n \n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to connect to realtime:', error);\n setIsConnected(false);\n throw error;\n }\n };\n\n const handleDisconnect = () => {\n \n realtimeClient.disconnect();\n setIsConnected(false);\n };\n\n const value: ExGuardRealtimeContextType = {\n isConnected,\n connect: handleConnect,\n disconnect: handleDisconnect,\n reconnect: handleReconnect,\n refreshRbac: handleRefreshRbac,\n registerRbacRefreshCallback,\n };\n\n return <ExGuardRealtimeContext value={value}>{children}</ExGuardRealtimeContext>;\n}\n","/**\n * ExGuard Realtime Subscription Hook\n *\n * Hook to subscribe to realtime channels and handle RBAC events\n */\n\nimport { useEffect } from 'react';\nimport { useExGuardRealtime } from './use-exguard-realtime';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { EXGUARD_RBAC_EVENTS, EXGUARD_RBAC_CHANNELS } from '../config/realtime-rbac-config';\nimport type { RealtimeEventType } from '../lib/realtime.types';\n\ninterface UseExGuardRealtimeSubscriptionOptions {\n /** Event types to subscribe to. If not provided, subscribes to all RBAC events */\n events?: RealtimeEventType[];\n /** Whether to auto-subscribe on mount */\n autoSubscribe?: boolean;\n}\n\n/**\n * Hook to subscribe to ExGuard realtime channel and handle RBAC updates\n * @param channel - Channel name ('rbac', 'roles', 'permissions')\n * @param options - Subscription options\n */\nexport function useExGuardRealtimeSubscription(\n channel: keyof typeof EXGUARD_RBAC_CHANNELS = 'RBAC',\n options: UseExGuardRealtimeSubscriptionOptions = {},\n): void {\n const { registerRbacRefreshCallback } = useExGuardRealtime();\n const { autoSubscribe = true, events } = options;\n const channelName = EXGUARD_RBAC_CHANNELS[channel];\n\n useEffect(() => {\n if (!autoSubscribe) {\n return;\n }\n\n // Subscribe to channel on server\n void realtimeClient.subscribeToChannel(channelName);\n\n // If specific events provided, subscribe to them\n if (events && events.length > 0) {\n const unsubscribers: (() => void)[] = [];\n\n events.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }\n\n // Default: subscribe to all RBAC events\n const defaultRbacEvents: RealtimeEventType[] = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_REMOVED,\n EXGUARD_RBAC_EVENTS.USER_ONLINE,\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n ];\n\n const unsubscribers: (() => void)[] = [];\n\n defaultRbacEvents.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n \n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n \n return Promise.resolve();\n });\n\n return () => {\n \n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n unregisterCallback();\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }, [channelName, autoSubscribe, events, registerRbacRefreshCallback]);\n}\n"]}
1
+ {"version":3,"sources":["../src/config/exguard-config.ts","../src/config/realtime-rbac-config.ts","../src/api/exguard-api.ts","../src/providers/exguard-realtime-context.ts","../src/hooks/use-user-access.ts","../src/components/ui/spinner.tsx","../src/components/ui/button.tsx","../src/components/ui/card.tsx","../src/components/permission-guard.tsx","../src/lib/realtime-client.ts","../src/hooks/use-realtime.ts","../src/providers/use-exguard-realtime.ts","../src/hooks/use-exguard-rbac.ts","../src/utils/exguard-realtime-utils.ts","../src/providers/exguard-realtime-provider.tsx","../src/providers/use-exguard-realtime-subscription.ts"],"names":["axios","createContext","useState","use","useCallback","useEffect","jsx","Navigate","jsxs","Lock","ShieldAlert","ArrowLeft","Outlet","io","useRef","React","unsubscribers"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * ExGuard API Configuration\r\n * Configuration for ExGuard backend API\r\n */\r\n\r\nexport interface ExGuardConfig {\r\n apiUrl: string;\r\n withCredentials?: boolean;\r\n getAuthToken?: () => string | null;\r\n}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Auto-detects API URL based on environment\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Configuration state\r\n */\r\nlet configuredApiUrl: string = '';\r\nlet customGetAuthToken: (() => string | null) | undefined;\r\n\r\n/**\r\n * Auto-detect API URL based on current environment\r\n */\r\nconst autoDetectApiUrl = (): string => {\r\n if (typeof window !== 'undefined') {\r\n const hostname = window.location.hostname;\r\n const protocol = window.location.protocol;\r\n \r\n // Local development\r\n if (hostname === 'localhost' || hostname === '127.0.0.1') {\r\n return 'http://localhost:3000';\r\n }\r\n \r\n // Production/Staging - use same domain with /api path\r\n return `${protocol}//${hostname}/api`;\r\n }\r\n \r\n // SSR fallback\r\n return process.env.EXGUARD_API_URL || 'http://localhost:3000';\r\n};\r\n\r\n/**\r\n * Set ExGuard configuration\r\n * @param config - Partial configuration to override defaults\r\n */\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n if (config.getAuthToken) {\r\n customGetAuthToken = config.getAuthToken;\r\n }\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL\r\n * Priority: 1) Manual config, 2) Environment var, 3) Auto-detect\r\n */\r\nexport const getExGuardApiUrl = (): string => {\r\n // 1. User-configured URL\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // 2. Check environment variables (Vite/Next.js)\r\n if (typeof window !== 'undefined') {\r\n // Vite apps\r\n if ((import.meta as any).env?.VITE_GUARD_APP_URL) {\r\n return (import.meta as any).env.VITE_GUARD_APP_URL;\r\n }\r\n \r\n // Next.js or injected env\r\n if ((window as any).__EXGUARD_API_URL__) {\r\n return (window as any).__EXGUARD_API_URL__;\r\n }\r\n }\r\n \r\n // 3. Auto-detect based on hostname\r\n return autoDetectApiUrl();\r\n};\r\n\r\n/**\r\n * Get authentication token\r\n * Uses custom getter if provided, otherwise defaults to localStorage\r\n */\r\nexport const getAuthToken = (): string | null => {\r\n if (customGetAuthToken) {\r\n return customGetAuthToken();\r\n }\r\n \r\n if (typeof window !== 'undefined') {\r\n return (\r\n localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n sessionStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n null\r\n );\r\n }\r\n \r\n return null;\r\n};\r\n\r\n/**\r\n * Storage keys for ExGuard\r\n */\r\nexport const EXGUARD_STORAGE_KEYS = {\r\n ACCESS_TOKEN: 'access_token',\r\n ID_TOKEN: 'id_token',\r\n REFRESH_TOKEN: 'refresh_token',\r\n} as const;\r\n","/**\n * ExGuard Realtime RBAC Configuration\n *\n * This file contains all configuration for realtime RBAC events\n * specific to ExGuard module (users, roles, permissions management)\n */\n\n/**\n * Channels to subscribe to for ExGuard RBAC\n */\nexport const EXGUARD_RBAC_CHANNELS = {\n ROLES: 'roles',\n PERMISSIONS: 'permissions',\n RBAC: 'rbac',\n} as const;\n\n/**\n * Event types for ExGuard RBAC realtime updates\n */\nexport const EXGUARD_RBAC_EVENTS = {\n // Role events\n ROLE_CREATED: 'role:created',\n ROLE_UPDATED: 'role:updated',\n ROLE_DELETED: 'role:deleted',\n\n // Permission events\n PERMISSION_CREATED: 'permission:created',\n PERMISSION_UPDATED: 'permission:updated',\n PERMISSION_DELETED: 'permission:deleted',\n\n // Role-Permission events\n ROLE_PERMISSION_ASSIGNED: 'role-permission:assigned',\n ROLE_PERMISSION_REMOVED: 'role-permission:removed',\n\n // User RBAC events\n USER_ROLES_UPDATED: 'user:roles-updated',\n USER_PERMISSIONS_CHANGED: 'user:permissions-changed',\n USER_ACCESS_CHANGED: 'user:access-changed',\n RBAC_USER_ASSIGNED_TO_GROUP: 'rbac:user-assigned-to-group',\n RBAC_USER_REMOVED_FROM_GROUP: 'rbac:user-removed-from-group',\n RBAC_PERMISSIONS_UPDATED: 'rbac:permissions-updated',\n\n // User status events\n USER_ONLINE: 'user:online',\n USER_OFFLINE: 'user:offline',\n\n // Group events\n GROUP_UPDATED: 'group:updated',\n} as const;\n\n/**\n * Reconnection delay after RBAC updates (in milliseconds)\n * This ensures backend has fully processed the update before refetching data\n */\nexport const RBAC_RECONNECT_DELAY = 300;\n\n/**\n * Configuration for automatic reconnection after specific events\n */\nexport const RBAC_AUTO_RECONNECT_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n] as const;\n\n/**\n * Events that should trigger user data refresh\n */\nexport const USER_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_PERMISSIONS_CHANGED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n EXGUARD_RBAC_EVENTS.RBAC_USER_ASSIGNED_TO_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_USER_REMOVED_FROM_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED,\n] as const;\n\n/**\n * Events that should trigger role data refresh\n */\nexport const ROLE_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n] as const;\n\n/**\n * Events that should trigger permission data refresh\n */\nexport const PERMISSION_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n] as const;\n","import axios, { type AxiosError } from 'axios';\nimport type { VerifyTokenResponse, UserAccessData, AuthApiResponse } from '../types/exguard-types';\nimport { getExGuardApiUrl, getAuthToken, EXGUARD_STORAGE_KEYS } from '../config/exguard-config';\n\n// Create a separate axios instance for Guard API endpoints\n// Note: baseURL is set dynamically in the interceptor to support runtime configuration\nconst guardApiClient = axios.create({\n withCredentials: true,\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n\n// Add interceptor to dynamically set baseURL and include access token\nguardApiClient.interceptors.request.use(\n (config) => {\n // Set baseURL dynamically from config (supports runtime configuration)\n config.baseURL = getExGuardApiUrl();\n \n const token = getAuthToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error: unknown) => Promise.reject(error instanceof Error ? error : new Error(String(error))),\n);\n\n/**\n * Verify ID token with ExGuard backend\n */\nexport async function verifyToken(): Promise<VerifyTokenResponse> {\n try {\n const idToken = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ID_TOKEN);\n const response = await guardApiClient.post<\n AuthApiResponse<{\n user?: {\n id: string;\n username: string;\n email: string;\n givenName: string;\n familyName: string;\n };\n }>\n >('/guard/verify-token', {\n id_token: idToken,\n });\n\n if (response.data.success && response.data.data) {\n // Map backend response to frontend format\n const backendData = response.data.data;\n const mappedResponse: VerifyTokenResponse = {\n valid: true,\n user: backendData.user\n ? {\n userId: backendData.user.id,\n username: backendData.user.username,\n email: backendData.user.email,\n givenName: backendData.user.givenName,\n familyName: backendData.user.familyName,\n }\n : undefined,\n };\n return mappedResponse;\n }\n\n throw new Error(response.data.message ?? 'Token verification failed');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Token verification failed';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n\n/**\n * Flag to ensure User Access Data is logged only once\n */\nlet hasLoggedUserAccess = false;\n\n/**\n * Get user access data including roles, permissions, modules, and field offices\n */\nexport async function getUserAccess(): Promise<UserAccessData> {\n try {\n const response = await guardApiClient.get<AuthApiResponse<UserAccessData>>('/guard/me');\n\n if (response.data.success && response.data.data) {\n if (!hasLoggedUserAccess) {\n console.log('User Access Data:', response.data.data);\n hasLoggedUserAccess = true;\n }\n\n return response.data.data;\n }\n\n throw new Error(response.data.message ?? 'Failed to get user access data');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Failed to get user access data';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n","/**\n * ExGuard Realtime Context\n *\n * Context for managing realtime RBAC connections and state\n */\n\nimport { createContext } from 'react';\n\nexport interface ExGuardRealtimeContextType {\n isConnected: boolean;\n connect: (token: string, userId: string) => Promise<void>;\n disconnect: () => void;\n reconnect: () => Promise<void>;\n refreshRbac: () => Promise<void>;\n registerRbacRefreshCallback: (callback: () => Promise<void>) => () => void;\n}\n\nexport const ExGuardRealtimeContext = createContext<ExGuardRealtimeContextType | undefined>(undefined);\n","import { useEffect, useState, useCallback, use } from 'react';\r\nimport { getUserAccess } from '../api/exguard-api';\r\nimport type { UserAccessData, ModulePermissions } from '../types/exguard-types';\r\nimport { ExGuardRealtimeContext } from '../providers/exguard-realtime-context';\r\n\r\ninterface UseUserAccessOptions {\r\n enabled?: boolean;\r\n refetchInterval?: number;\r\n}\r\n\r\n/**\r\n * Custom hook to fetch and manage user access data with RBAC\r\n * Includes caching and periodic refetching for real-time RBAC\r\n */\r\nexport const useUserAccess = (options: UseUserAccessOptions = {}) => {\r\n const { enabled = true, refetchInterval = 0 } = options;\r\n const [userAccess, setUserAccess] = useState<UserAccessData | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n const realtimeContext = use(ExGuardRealtimeContext);\r\n\r\n const fetchUserAccess = useCallback(async (silent = false): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n // Only set loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(true);\r\n }\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error('Failed to fetch user access');\r\n setError(errorObj);\r\n } finally {\r\n // Only clear loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(false);\r\n }\r\n }\r\n }, [enabled]);\r\n\r\n // Register for real-time RBAC updates from the realtime provider\r\n useEffect(() => {\r\n if (!realtimeContext) {\r\n return;\r\n }\r\n\r\n // Use silent refresh for realtime updates to prevent UI disruption\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(() => fetchUserAccess(true));\r\n\r\n return () => {\r\n unsubscribe();\r\n };\r\n }, [realtimeContext, fetchUserAccess]);\r\n\r\n useEffect(() => {\r\n void fetchUserAccess();\r\n\r\n if (refetchInterval > 0) {\r\n const interval = setInterval(() => {\r\n void fetchUserAccess();\r\n }, refetchInterval);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }\r\n }, [fetchUserAccess, refetchInterval]);\r\n\r\n const hasModuleAccess = useCallback(\r\n (moduleKey: string): boolean => {\r\n if (!userAccess) return false;\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return !!module && module.permissions.length > 0;\r\n },\r\n [userAccess],\r\n );\r\n\r\n const getModulePermissions = useCallback(\r\n (moduleKey: string): string[] => {\r\n if (!userAccess) return [];\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return module?.permissions ?? [];\r\n },\r\n [userAccess],\r\n );\r\n\r\n const hasPermission = useCallback(\r\n (moduleKey: string, permission: string): boolean => {\r\n const permissions = getModulePermissions(moduleKey);\r\n return permissions.includes(permission);\r\n },\r\n [getModulePermissions],\r\n );\r\n\r\n return {\r\n userAccess,\r\n isLoading,\r\n error,\r\n hasModuleAccess,\r\n getModulePermissions,\r\n hasPermission,\r\n refetch: fetchUserAccess,\r\n refetchSilent: () => fetchUserAccess(true),\r\n };\r\n};\r\n","import React from 'react';\r\n\r\ninterface SpinnerProps {\r\n className?: string;\r\n}\r\n\r\nexport function Spinner({ className = '' }: SpinnerProps) {\r\n return (\r\n <div\r\n className={`animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${className}`}\r\n role=\"status\"\r\n >\r\n <span className=\"!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]\">\r\n Loading...\r\n </span>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n variant?: 'default' | 'outline' | 'destructive' | 'ghost' | 'link';\r\n size?: 'default' | 'sm' | 'lg' | 'icon';\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Button({\r\n className = '',\r\n variant = 'default',\r\n size = 'default',\r\n children,\r\n ...props\r\n}: ButtonProps) {\r\n const baseStyles =\r\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';\r\n\r\n const variantStyles = {\r\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\r\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\r\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\r\n ghost: 'hover:bg-accent hover:text-accent-foreground',\r\n link: 'text-primary underline-offset-4 hover:underline',\r\n };\r\n\r\n const sizeStyles = {\r\n default: 'h-10 px-4 py-2',\r\n sm: 'h-9 rounded-md px-3',\r\n lg: 'h-11 rounded-md px-8',\r\n icon: 'h-10 w-10',\r\n };\r\n\r\n return (\r\n <button\r\n className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface CardProps extends React.HTMLAttributes<HTMLDivElement> {\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Card({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div\r\n className={`rounded-lg border bg-card text-card-foreground shadow-sm ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardHeader({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex flex-col space-y-1.5 p-6 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardTitle({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <h3 className={`text-2xl font-semibold leading-none tracking-tight ${className}`} {...props}>\r\n {children}\r\n </h3>\r\n );\r\n}\r\n\r\nexport function CardDescription({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <p className={`text-sm text-muted-foreground ${className}`} {...props}>\r\n {children}\r\n </p>\r\n );\r\n}\r\n\r\nexport function CardContent({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardFooter({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex items-center p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import { Navigate, Outlet } from 'react-router';\r\nimport { useUserAccess } from '../hooks/use-user-access';\r\nimport { Spinner } from './ui/spinner';\r\nimport { Button } from './ui/button';\r\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card';\r\nimport { ArrowLeft, ShieldAlert, Lock } from 'lucide-react';\r\n\r\ninterface PermissionGuardProps {\r\n module: string;\r\n permission?: string;\r\n requireModule?: boolean;\r\n requirePermission?: boolean;\r\n fallbackPath?: string;\r\n}\r\n\r\n/**\r\n * PermissionGuard component that checks if user has required module access and/or permissions\r\n *\r\n * @param module - The module key (e.g., 'EXID', 'EXFLOW', 'TEV')\r\n * @param permission - Optional specific permission to check (e.g., 'profile:create', 'profile:update')\r\n * @param requireModule - Whether to require module access (default: true)\r\n * @param requirePermission - Whether to require the specific permission (default: true if permission is provided)\r\n * @param fallbackPath - Path to redirect to if access is denied (default: show error page)\r\n */\r\nexport function PermissionGuard({\r\n module,\r\n permission,\r\n requireModule = true,\r\n requirePermission = true,\r\n fallbackPath,\r\n}: PermissionGuardProps) {\r\n const { isLoading, hasModuleAccess, hasPermission } = useUserAccess();\r\n\r\n // Show loading spinner while checking permissions\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Spinner className=\"size-8\" />\r\n </div>\r\n );\r\n }\r\n\r\n // Check module access\r\n const hasModule = hasModuleAccess(module);\r\n const moduleCheckFailed = requireModule && !hasModule;\r\n\r\n // Check specific permission if provided\r\n const hasSpecificPermission = permission ? hasPermission(module, permission) : true;\r\n const permissionCheckFailed = permission && requirePermission && !hasSpecificPermission;\r\n\r\n // Determine if access should be denied\r\n const accessDenied = moduleCheckFailed || permissionCheckFailed;\r\n\r\n // Redirect to fallback path if provided\r\n if (accessDenied && fallbackPath) {\r\n return <Navigate to={fallbackPath} replace />;\r\n }\r\n\r\n // Show access denied message\r\n if (accessDenied) {\r\n const denialReason = moduleCheckFailed\r\n ? {\r\n title: 'Module Access Required',\r\n description: `Access to the ${module} module is required to view this page`,\r\n detail: `Your current account permissions do not include access to the ${module} module. This module may be restricted to specific roles or user groups.`,\r\n }\r\n : {\r\n title: 'Permission Required',\r\n description: `The permission \"${permission ?? 'unknown'}\" is needed to access this resource`,\r\n detail: `Your account has access to the ${module} module but lacks the specific permission required for this action. This permission may need to be assigned to your role or user group.`,\r\n };\r\n\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[calc(100vh-4rem)] p-6\">\r\n <Card className=\"w-full max-w-lg\">\r\n <CardHeader className=\"text-center pb-4\">\r\n <div className=\"mx-auto mb-4 flex size-16 items-center justify-center rounded-full bg-destructive/10\">\r\n {moduleCheckFailed ? (\r\n <Lock className=\"size-8 text-destructive\" />\r\n ) : (\r\n <ShieldAlert className=\"size-8 text-destructive\" />\r\n )}\r\n </div>\r\n <CardTitle className=\"text-2xl\">{denialReason.title}</CardTitle>\r\n <CardDescription className=\"text-base\">{denialReason.description}</CardDescription>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n <div className=\"rounded-lg bg-muted p-4\">\r\n <p className=\"text-sm text-muted-foreground\">{denialReason.detail}</p>\r\n </div>\r\n <div className=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n window.history.back();\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n <ArrowLeft className=\"mr-2 size-4\" />\r\n Go Back\r\n </Button>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => {\r\n window.location.href = '/';\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n Return to Dashboard\r\n </Button>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n </div>\r\n );\r\n }\r\n\r\n // User has required access, render child routes\r\n return <Outlet />;\r\n}\r\n","import { io, type Socket } from 'socket.io-client';\nimport type { RealtimeEventPayload, RealtimeEventType, RealtimeEventHandler } from './realtime.types';\nimport { getExGuardApiUrl } from '../config/exguard-config';\n\nclass RealtimeClient {\n private socket: Socket | null = null;\n private listeners = new Map<string, Set<RealtimeEventHandler>>();\n private isConnected = false;\n private debug = false; // Enable/disable debug logging\n private connectionPromise: Promise<void> | null = null;\n\n constructor() {\n this.log('đŸŸĸ RealtimeClient initialized');\n }\n \n private getApiUrl(): string {\n return getExGuardApiUrl();\n }\n\n private log(message: string, data?: unknown) {\n if (this.debug) {\n console.log(`[RealtimeClient] ${message}`, data);\n }\n }\n\n private logError(message: string, error?: unknown) {\n console.error(`[RealtimeClient] ${message}`, error);\n }\n\n private logWarn(message: string, data?: unknown) {\n console.warn(`[RealtimeClient] ${message}`, data);\n }\n\n /**\n * Connect to the realtime server\n */\n connect(token: string, userId: string): Promise<void> {\n // Validate inputs\n if (!token) {\n this.logError('❌ Cannot connect - token is missing or empty');\n return Promise.reject(new Error('Missing authentication token'));\n }\n\n if (!userId) {\n this.logError('❌ Cannot connect - userId is missing or empty');\n return Promise.reject(new Error('Missing userId'));\n }\n\n // Return existing connection promise if already connecting\n if (this.connectionPromise) {\n this.log('âŗ Connection already in progress, returning existing promise');\n return this.connectionPromise;\n }\n\n this.connectionPromise = new Promise((resolve, reject) => {\n try {\n const apiUrl = this.getApiUrl();\n this.log('🔌 Attempting to connect...', { apiUrl, userId, hasToken: !!token });\n\n if (this.socket?.connected) {\n this.log('✅ Already connected');\n this.connectionPromise = null;\n resolve();\n return;\n }\n\n const socketUrl = `${apiUrl}/realtime`;\n this.log('🚀 Creating Socket.IO connection', {\n url: socketUrl,\n transports: ['websocket', 'polling'],\n userId,\n });\n\n this.socket = io(socketUrl, {\n auth: {\n token,\n userId,\n },\n transports: ['websocket', 'polling'],\n reconnection: true,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n reconnectionAttempts: 5,\n });\n\n this.socket.on('connect', () => {\n this.isConnected = true;\n this.log('✅ Connected to realtime server', {\n socketId: this.socket?.id,\n userId,\n });\n this.connectionPromise = null;\n resolve();\n });\n\n this.socket.on('disconnect', (reason: string) => {\n this.isConnected = false;\n this.log('❌ Disconnected from realtime server', { reason });\n });\n\n this.socket.on('connect_error', (error: unknown) => {\n this.logError('❌ Connection error (check token and backend)', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection error: ${errorMessage}`));\n });\n\n this.socket.on('error', (error: unknown) => {\n this.logError('❌ Realtime error', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Socket.IO error: ${errorMessage}`));\n });\n\n this.socket.on('reconnect_attempt', () => {\n this.log('🔄 Attempting to reconnect...');\n });\n\n this.socket.on('reconnect', () => {\n this.isConnected = true;\n this.log('🔁 Reconnected to realtime server', {\n socketId: this.socket?.id,\n });\n });\n\n this.socket.on('reconnect_failed', () => {\n this.logError('❌ Reconnection failed after maximum attempts');\n this.connectionPromise = null;\n reject(new Error('Reconnection failed'));\n });\n\n // Listen to all realtime events\n this.socket.onAny((eventName: string, payload: unknown) => {\n // Debug: log raw event for troubleshooting\n this.log(`📨 Raw event received`, {\n eventName,\n payloadType: typeof payload,\n payload,\n });\n\n // Normalize payload - backend sends event name separately from payload\n const payloadObj =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n\n // CRITICAL FIX: Use eventName as the primary event type (e.g., 'user:access-changed')\n // Socket.IO sends the event name as the first parameter, not nested in payload.type\n const eventType = eventName;\n\n const normalizedPayload: RealtimeEventPayload = {\n type: eventType as RealtimeEventType,\n timestamp:\n 'timestamp' in payloadObj\n ? typeof payloadObj.timestamp === 'number'\n ? payloadObj.timestamp\n : new Date(payloadObj.timestamp as string).getTime()\n : Date.now(),\n data: 'data' in payloadObj ? payloadObj.data : payload,\n };\n\n this.log(`📨 Event processed: ${eventType}`, {\n type: normalizedPayload.type,\n timestamp: normalizedPayload.timestamp,\n dataKeys:\n typeof normalizedPayload.data === 'object' && normalizedPayload.data !== null\n ? Object.keys(normalizedPayload.data as Record<string, unknown>)\n : 'N/A',\n });\n this.handleEvent(eventType as RealtimeEventType, normalizedPayload);\n });\n } catch (error) {\n this.logError('Failed to initialize connection', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection initialization failed: ${errorMessage}`));\n }\n });\n\n return this.connectionPromise;\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.log('🔌 Disconnecting from realtime server...');\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n this.isConnected = false;\n this.log('✅ Disconnected');\n }\n }\n\n /**\n * Check if connected\n */\n getIsConnected(): boolean {\n return this.isConnected && this.socket?.connected === true;\n }\n\n /**\n * Wait for connection to be ready (with timeout)\n */\n async waitForConnection(timeoutMs = 30000): Promise<void> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (this.getIsConnected()) {\n this.log('✅ Connection ready');\n return;\n }\n\n // Wait 100ms before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n this.logError('❌ Timeout waiting for connection', { timeoutMs, elapsed: Date.now() - startTime });\n throw new Error('Connection timeout - failed to establish WebSocket connection');\n }\n\n /**\n * Subscribe to a specific event type\n */\n subscribe<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n ): () => void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set());\n }\n\n this.listeners.get(eventType)?.add(handler as RealtimeEventHandler);\n const listenerCount = this.listeners.get(eventType)?.size ?? 0;\n this.log(`📌 Subscribed to event: ${eventType}`, { totalListeners: listenerCount });\n\n // Return unsubscribe function\n return () => {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler as RealtimeEventHandler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n };\n }\n\n /**\n * Unsubscribe from an event\n */\n unsubscribe(eventType: RealtimeEventType, handler: RealtimeEventHandler): void {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n }\n /**\n * Send a subscription message to the server with connection wait\n */\n async subscribeToChannel(channel: 'roles' | 'permissions' | 'rbac'): Promise<void> {\n try {\n this.log(`📡 Subscribing to channel: ${channel}`);\n\n // Wait for connection to be ready\n await this.waitForConnection(15000);\n\n // Now emit subscribe\n this.log(`📡 Emitting subscribe event for channel: ${channel}`);\n this.socket?.emit(`subscribe:${channel}`);\n this.log(`✅ Subscribed to channel: ${channel}`);\n } catch (error) {\n this.logError(`❌ Failed to subscribe to channel \"${channel}\"`, error);\n throw error;\n }\n }\n\n /**\n * Send an unsubscription message to the server\n */\n unsubscribeFromChannel(channel: 'roles' | 'permissions' | 'rbac'): void {\n if (!this.socket?.connected) {\n this.logWarn(`Cannot unsubscribe from channel \"${channel}\" - socket not connected`);\n return;\n }\n\n this.log(`📡 Unsubscribing from channel: ${channel}`);\n this.socket.emit(`unsubscribe:${channel}`);\n }\n\n /**\n * Handle incoming events\n */\n private handleEvent(eventType: RealtimeEventType, payload: RealtimeEventPayload): void {\n // Call specific event handlers\n const handlers = this.listeners.get(eventType);\n if (handlers && handlers.size > 0) {\n this.log(`🔔 Triggering ${String(handlers.size)} handler(s) for event: ${eventType}`);\n handlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError(`Error in event handler for ${eventType}`, error);\n }\n });\n }\n\n // Call wildcard handlers if any\n const wildcardHandlers = this.listeners.get('*' as RealtimeEventType);\n if (wildcardHandlers && wildcardHandlers.size > 0) {\n this.log(`🔔 Triggering ${String(wildcardHandlers.size)} wildcard handler(s)`);\n wildcardHandlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError('Error in wildcard event handler', error);\n }\n });\n }\n }\n\n /**\n * Get all connected listeners count\n */\n getListenerCount(eventType?: RealtimeEventType): number {\n if (eventType) {\n return this.listeners.get(eventType)?.size ?? 0;\n }\n let total = 0;\n this.listeners.forEach((handlers) => {\n total += handlers.size;\n });\n return total;\n }\n\n /**\n * Enable or disable debug logging\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n this.log(`Debug logging ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * Get connection status summary\n */\n getStatus() {\n const status = {\n isConnected: this.getIsConnected(),\n socketId: this.socket?.id ?? 'N/A',\n apiUrl: this.getApiUrl(),\n totalListeners: this.getListenerCount(),\n listeners: Array.from(this.listeners.entries()).map(([event, handlers]) => ({\n event,\n count: handlers.size,\n })),\n };\n this.log('📊 Connection Status', status);\n return status;\n }\n}\n\n// Create singleton instance\nexport const realtimeClient = new RealtimeClient();\n\n// Expose debug methods on window for console access\nif (typeof window !== 'undefined') {\n const w = window as unknown as Record<string, unknown>;\n w.__realtimeClient = {\n client: realtimeClient,\n connect: (token: string, userId: string) => realtimeClient.connect(token, userId),\n disconnect: () => {\n realtimeClient.disconnect();\n },\n isConnected: () => realtimeClient.getIsConnected(),\n setDebug: (enabled: boolean) => {\n realtimeClient.setDebug(enabled);\n },\n status: () => realtimeClient.getStatus(),\n getListenerCount: (eventType?: RealtimeEventType) => realtimeClient.getListenerCount(eventType),\n };\n\n}\n\nexport type { RealtimeClient };\n","/**\n * Shared Realtime Hooks\n *\n * Basic hooks for realtime functionality that wraps the realtime-client\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport type { RealtimeEventType, RealtimeEventPayload, RealtimeEventHandler } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to realtime RBAC events\n * Automatically handles subscription/unsubscription lifecycle\n */\nexport function useRealtimeRbac<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe<T>(eventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, [eventType]);\n}\n\n/**\n * Hook to manage channel subscriptions\n */\nexport function useRealtimeSubscription(channel: 'roles' | 'permissions' | 'rbac') {\n useEffect(() => {\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch(() => {\n // Silent error handling\n });\n\n return () => {\n realtimeClient.unsubscribeFromChannel(channel);\n };\n }, [channel]);\n}\n\n/**\n * Hook to listen to multiple event types\n */\nexport function useRealtimeMultiple(\n events: {\n type: RealtimeEventType;\n handler: RealtimeEventHandler;\n }[],\n) {\n useEffect(() => {\n const unsubscribers = events.map(({ type, handler }) => realtimeClient.subscribe(type, handler));\n\n return () => {\n unsubscribers.forEach((unsub) => {\n unsub();\n });\n };\n }, [events]);\n}\n\n/**\n * Hook to listen to all realtime events\n */\nexport function useRealtimeAll(handler: RealtimeEventHandler) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe('*' as RealtimeEventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, []);\n}\n\n/**\n * Hook to get the connection status\n */\nexport function useRealtimeStatus() {\n const [isConnected, setIsConnected] = useState(realtimeClient.getIsConnected());\n\n useEffect(() => {\n const checkConnection = () => {\n setIsConnected(realtimeClient.getIsConnected());\n };\n\n const interval = setInterval(checkConnection, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n return { isConnected };\n}\n","/**\n * Hook to use ExGuard Realtime Context\n */\n\nimport { use } from 'react';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\n\n/**\n * Hook to access ExGuard realtime context\n * Must be used within ExGuardRealtimeProvider\n */\nexport function useExGuardRealtime(): ExGuardRealtimeContextType {\n const context = use(ExGuardRealtimeContext);\n if (!context) {\n throw new Error('useExGuardRealtime must be used within a ExGuardRealtimeProvider');\n }\n return context;\n}\n","/**\n * ExGuard Realtime RBAC Hooks\n *\n * Custom hooks for handling ExGuard-specific realtime RBAC events\n */\n\nimport { useCallback } from 'react';\nimport { useRealtimeRbac, useRealtimeSubscription } from './use-realtime';\nimport { useExGuardRealtime } from '../providers/use-exguard-realtime';\nimport { EXGUARD_RBAC_CHANNELS, EXGUARD_RBAC_EVENTS, RBAC_RECONNECT_DELAY } from '../config/realtime-rbac-config';\nimport type { RealtimeEventPayload } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to all ExGuard RBAC channels\n */\nexport function useExGuardRbacChannels() {\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.RBAC);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.ROLES);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.PERMISSIONS);\n}\n\n/**\n * Hook to handle role updates with automatic reconnection\n */\nexport function useRoleUpdateHandler(onUpdate: () => Promise<void>, fetchUserAccess?: () => Promise<void>) {\n const { reconnect } = useExGuardRealtime();\n\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n try {\n await reconnect();\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n } catch (error) {\n // Silent error handling\n }\n })();\n },\n [reconnect, onUpdate, fetchUserAccess],\n ),\n );\n}\n\n/**\n * Hook to handle user RBAC updates (role assignments, permissions, etc.)\n */\nexport function useUserRbacUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle permission updates\n */\nexport function usePermissionUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle group updates\n */\nexport function useGroupUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle user access changes (personal notifications)\n * This is for individual user notifications received via user:{cognitoSubId} room\n */\nexport function useUserAccessChangeHandler(onAccessChange: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onAccessChange();\n })();\n },\n [onAccessChange],\n ),\n );\n}\n","/**\n * ExGuard Realtime Utilities\n *\n * Utility functions for ExGuard realtime functionality\n */\n\nimport { getUserAccess } from '../api/exguard-api';\n\n/**\n * Get current user's Cognito Sub ID from backend\n * This is used for websocket room identification (user:{cognitoSubId})\n */\nexport async function getCurrentUserId(): Promise<string | null> {\n try {\n const userAccess = await getUserAccess();\n \n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n return null;\n }\n}\n","/**\n * ExGuard Realtime Provider\n *\n * Provider for managing realtime RBAC connections and events\n */\n\nimport React, { useEffect, useRef, type ReactNode } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\nimport { getCurrentUserId } from '../utils/exguard-realtime-utils';\nimport type { UserRbacEventPayload } from '../lib/realtime.types';\n\ninterface ExGuardRealtimeProviderProps {\n children: ReactNode;\n}\n\nexport function ExGuardRealtimeProvider({ children }: ExGuardRealtimeProviderProps) {\n const [isConnected, setIsConnected] = React.useState(false);\n const connectionAttempted = useRef(false);\n const rbacRefreshCallbacks = useRef<Set<() => Promise<void>>>(new Set());\n const currentUserRef = useRef<{ token: string; userId: string } | null>(null);\n const currentUserIdRef = useRef<string | null>(null);\n\n // Register callback to refresh user access\n const registerRbacRefreshCallback = (callback: () => Promise<void>) => {\n rbacRefreshCallbacks.current.add(callback);\n return () => {\n rbacRefreshCallbacks.current.delete(callback);\n };\n };\n\n // Trigger refresh for all registered callbacks\n const triggerRbacRefresh = async (): Promise<void> => {\n \n if (rbacRefreshCallbacks.current.size === 0) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No RBAC refresh callbacks registered!');\n return;\n }\n\n const refreshPromises = Array.from(rbacRefreshCallbacks.current).map((cb, index) => {\n return cb().catch((err: unknown) => {\n console.error(`[ExGuardRealtimeProvider] ❌ Error during RBAC refresh callback ${String(index + 1)}:`, err);\n });\n });\n\n await Promise.all(refreshPromises);\n };\n\n // Manual reconnect function\n const handleReconnect = async (): Promise<void> => {\n if (!currentUserRef.current) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No user credentials available for reconnect');\n return;\n }\n const { token, userId } = currentUserRef.current;\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n // Fetch user info from backend and connect\n const initializeConnection = async (): Promise<void> => {\n const accessToken = localStorage.getItem('access_token');\n\n if (!accessToken) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No access token found in localStorage');\n return;\n }\n\n // Prevent duplicate connections\n if (connectionAttempted.current) {\n console.log('[ExGuardRealtimeProvider] â„šī¸ Connection already attempted, skipping');\n return;\n }\n\n connectionAttempted.current = true;\n\n try {\n const userId = await getCurrentUserId();\n\n if (!userId) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to get userId from backend');\n connectionAttempted.current = false; // Reset to allow retry\n return;\n }\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n setIsConnected(true);\n\n // Listen ONLY for THIS USER's access changes (sent to user:{userId} room)\n realtimeClient.subscribe('user:access-changed', (_payload: UserRbacEventPayload): void => {\n // No need to check userId - if this event reached our room (user:{cognitoSubId}),\n // it's definitely for us. Backend ensures correct room targeting.\n void triggerRbacRefresh();\n });\n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to establish realtime connection:');\n const errorMessage = error instanceof Error ? error.message : String(error);\n const tokenStr = accessToken ? accessToken.substring(0, 20) + '...' : '';\n console.error('[ExGuardRealtimeProvider] Error details:', {\n message: errorMessage,\n token: tokenStr,\n });\n setIsConnected(false);\n connectionAttempted.current = false; // Reset to allow retry\n }\n };\n\n // Listen for storage events (when tokens are added/changed in other tabs or after login)\n const handleStorageChange = (e: StorageEvent) => {\n if (e.key === 'access_token' && e.newValue && !connectionAttempted.current) {\n console.log('[ExGuardRealtimeProvider] 🔑 Access token detected, initializing connection');\n void initializeConnection();\n }\n };\n\n // Listen for custom event dispatched after login in the same tab\n const handleTokenUpdate = () => {\n console.log('[ExGuardRealtimeProvider] 🔑 Token update event received, initializing connection');\n void initializeConnection();\n };\n\n // Try to connect on mount if token already exists\n void initializeConnection();\n\n // Listen for token changes\n window.addEventListener('storage', handleStorageChange);\n window.addEventListener('exguard:token-updated', handleTokenUpdate);\n\n // Monitor connection status\n let lastConnectedState = realtimeClient.getIsConnected();\n const interval = setInterval(() => {\n const currentConnectedState = realtimeClient.getIsConnected();\n if (currentConnectedState !== lastConnectedState) {\n lastConnectedState = currentConnectedState;\n setIsConnected(currentConnectedState);\n }\n }, 1000);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener('storage', handleStorageChange);\n window.removeEventListener('exguard:token-updated', handleTokenUpdate);\n };\n }, []);\n\n const handleConnect = async (token: string, userId: string) => {\n try {\n \n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n \n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to connect to realtime:', error);\n setIsConnected(false);\n throw error;\n }\n };\n\n const handleDisconnect = () => {\n \n realtimeClient.disconnect();\n setIsConnected(false);\n };\n\n const value: ExGuardRealtimeContextType = {\n isConnected,\n connect: handleConnect,\n disconnect: handleDisconnect,\n reconnect: handleReconnect,\n refreshRbac: handleRefreshRbac,\n registerRbacRefreshCallback,\n };\n\n return <ExGuardRealtimeContext value={value}>{children}</ExGuardRealtimeContext>;\n}\n","/**\n * ExGuard Realtime Subscription Hook\n *\n * Hook to subscribe to realtime channels and handle RBAC events\n */\n\nimport { useEffect } from 'react';\nimport { useExGuardRealtime } from './use-exguard-realtime';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { EXGUARD_RBAC_EVENTS, EXGUARD_RBAC_CHANNELS } from '../config/realtime-rbac-config';\nimport type { RealtimeEventType } from '../lib/realtime.types';\n\ninterface UseExGuardRealtimeSubscriptionOptions {\n /** Event types to subscribe to. If not provided, subscribes to all RBAC events */\n events?: RealtimeEventType[];\n /** Whether to auto-subscribe on mount */\n autoSubscribe?: boolean;\n}\n\n/**\n * Hook to subscribe to ExGuard realtime channel and handle RBAC updates\n * @param channel - Channel name ('rbac', 'roles', 'permissions')\n * @param options - Subscription options\n */\nexport function useExGuardRealtimeSubscription(\n channel: keyof typeof EXGUARD_RBAC_CHANNELS = 'RBAC',\n options: UseExGuardRealtimeSubscriptionOptions = {},\n): void {\n const { registerRbacRefreshCallback } = useExGuardRealtime();\n const { autoSubscribe = true, events } = options;\n const channelName = EXGUARD_RBAC_CHANNELS[channel];\n\n useEffect(() => {\n if (!autoSubscribe) {\n return;\n }\n\n // Subscribe to channel on server\n void realtimeClient.subscribeToChannel(channelName);\n\n // If specific events provided, subscribe to them\n if (events && events.length > 0) {\n const unsubscribers: (() => void)[] = [];\n\n events.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }\n\n // Default: subscribe to all RBAC events\n const defaultRbacEvents: RealtimeEventType[] = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_REMOVED,\n EXGUARD_RBAC_EVENTS.USER_ONLINE,\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n ];\n\n const unsubscribers: (() => void)[] = [];\n\n defaultRbacEvents.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n \n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n \n return Promise.resolve();\n });\n\n return () => {\n \n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n unregisterCallback();\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }, [channelName, autoSubscribe, events, registerRbacRefreshCallback]);\n}\n"]}
package/dist/index.js CHANGED
@@ -808,20 +808,22 @@ function ExGuardRealtimeProvider({ children }) {
808
808
  await triggerRbacRefresh();
809
809
  };
810
810
  useEffect(() => {
811
- const accessToken = localStorage.getItem("access_token");
812
- if (!accessToken) {
813
- console.warn("[ExGuardRealtimeProvider] \u26A0\uFE0F No access token found in localStorage");
814
- return;
815
- }
816
- if (connectionAttempted.current) {
817
- return;
818
- }
819
- connectionAttempted.current = true;
820
811
  const initializeConnection = async () => {
812
+ const accessToken = localStorage.getItem("access_token");
813
+ if (!accessToken) {
814
+ console.warn("[ExGuardRealtimeProvider] \u26A0\uFE0F No access token found in localStorage");
815
+ return;
816
+ }
817
+ if (connectionAttempted.current) {
818
+ console.log("[ExGuardRealtimeProvider] \u2139\uFE0F Connection already attempted, skipping");
819
+ return;
820
+ }
821
+ connectionAttempted.current = true;
821
822
  try {
822
823
  const userId = await getCurrentUserId();
823
824
  if (!userId) {
824
825
  console.error("[ExGuardRealtimeProvider] \u274C Failed to get userId from backend");
826
+ connectionAttempted.current = false;
825
827
  return;
826
828
  }
827
829
  currentUserRef.current = { token: accessToken, userId };
@@ -840,9 +842,22 @@ function ExGuardRealtimeProvider({ children }) {
840
842
  token: tokenStr
841
843
  });
842
844
  setIsConnected(false);
845
+ connectionAttempted.current = false;
843
846
  }
844
847
  };
848
+ const handleStorageChange = (e) => {
849
+ if (e.key === "access_token" && e.newValue && !connectionAttempted.current) {
850
+ console.log("[ExGuardRealtimeProvider] \u{1F511} Access token detected, initializing connection");
851
+ void initializeConnection();
852
+ }
853
+ };
854
+ const handleTokenUpdate = () => {
855
+ console.log("[ExGuardRealtimeProvider] \u{1F511} Token update event received, initializing connection");
856
+ void initializeConnection();
857
+ };
845
858
  void initializeConnection();
859
+ window.addEventListener("storage", handleStorageChange);
860
+ window.addEventListener("exguard:token-updated", handleTokenUpdate);
846
861
  let lastConnectedState = realtimeClient.getIsConnected();
847
862
  const interval = setInterval(() => {
848
863
  const currentConnectedState = realtimeClient.getIsConnected();
@@ -853,6 +868,8 @@ function ExGuardRealtimeProvider({ children }) {
853
868
  }, 1e3);
854
869
  return () => {
855
870
  clearInterval(interval);
871
+ window.removeEventListener("storage", handleStorageChange);
872
+ window.removeEventListener("exguard:token-updated", handleTokenUpdate);
856
873
  };
857
874
  }, []);
858
875
  const handleConnect = async (token, userId) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/exguard-config.ts","../src/config/realtime-rbac-config.ts","../src/api/exguard-api.ts","../src/providers/exguard-realtime-context.ts","../src/hooks/use-user-access.ts","../src/components/ui/spinner.tsx","../src/components/ui/button.tsx","../src/components/ui/card.tsx","../src/components/permission-guard.tsx","../src/lib/realtime-client.ts","../src/hooks/use-realtime.ts","../src/providers/use-exguard-realtime.ts","../src/hooks/use-exguard-rbac.ts","../src/utils/exguard-realtime-utils.ts","../src/providers/exguard-realtime-provider.tsx","../src/providers/use-exguard-realtime-subscription.ts"],"names":["jsx","useEffect","use","useRef","unsubscribers"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * ExGuard API Configuration\r\n * Configuration for ExGuard backend API\r\n */\r\n\r\nexport interface ExGuardConfig {\r\n apiUrl: string;\r\n withCredentials?: boolean;\r\n getAuthToken?: () => string | null;\r\n}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Auto-detects API URL based on environment\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Configuration state\r\n */\r\nlet configuredApiUrl: string = '';\r\nlet customGetAuthToken: (() => string | null) | undefined;\r\n\r\n/**\r\n * Auto-detect API URL based on current environment\r\n */\r\nconst autoDetectApiUrl = (): string => {\r\n if (typeof window !== 'undefined') {\r\n const hostname = window.location.hostname;\r\n const protocol = window.location.protocol;\r\n \r\n // Local development\r\n if (hostname === 'localhost' || hostname === '127.0.0.1') {\r\n return 'http://localhost:3000';\r\n }\r\n \r\n // Production/Staging - use same domain with /api path\r\n return `${protocol}//${hostname}/api`;\r\n }\r\n \r\n // SSR fallback\r\n return process.env.EXGUARD_API_URL || 'http://localhost:3000';\r\n};\r\n\r\n/**\r\n * Set ExGuard configuration\r\n * @param config - Partial configuration to override defaults\r\n */\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n if (config.getAuthToken) {\r\n customGetAuthToken = config.getAuthToken;\r\n }\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL\r\n * Priority: 1) Manual config, 2) Environment var, 3) Auto-detect\r\n */\r\nexport const getExGuardApiUrl = (): string => {\r\n // 1. User-configured URL\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // 2. Check environment variables (Vite/Next.js)\r\n if (typeof window !== 'undefined') {\r\n // Vite apps\r\n if ((import.meta as any).env?.VITE_GUARD_APP_URL) {\r\n return (import.meta as any).env.VITE_GUARD_APP_URL;\r\n }\r\n \r\n // Next.js or injected env\r\n if ((window as any).__EXGUARD_API_URL__) {\r\n return (window as any).__EXGUARD_API_URL__;\r\n }\r\n }\r\n \r\n // 3. Auto-detect based on hostname\r\n return autoDetectApiUrl();\r\n};\r\n\r\n/**\r\n * Get authentication token\r\n * Uses custom getter if provided, otherwise defaults to localStorage\r\n */\r\nexport const getAuthToken = (): string | null => {\r\n if (customGetAuthToken) {\r\n return customGetAuthToken();\r\n }\r\n \r\n if (typeof window !== 'undefined') {\r\n return (\r\n localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n sessionStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n null\r\n );\r\n }\r\n \r\n return null;\r\n};\r\n\r\n/**\r\n * Storage keys for ExGuard\r\n */\r\nexport const EXGUARD_STORAGE_KEYS = {\r\n ACCESS_TOKEN: 'access_token',\r\n ID_TOKEN: 'id_token',\r\n REFRESH_TOKEN: 'refresh_token',\r\n} as const;\r\n","/**\n * ExGuard Realtime RBAC Configuration\n *\n * This file contains all configuration for realtime RBAC events\n * specific to ExGuard module (users, roles, permissions management)\n */\n\n/**\n * Channels to subscribe to for ExGuard RBAC\n */\nexport const EXGUARD_RBAC_CHANNELS = {\n ROLES: 'roles',\n PERMISSIONS: 'permissions',\n RBAC: 'rbac',\n} as const;\n\n/**\n * Event types for ExGuard RBAC realtime updates\n */\nexport const EXGUARD_RBAC_EVENTS = {\n // Role events\n ROLE_CREATED: 'role:created',\n ROLE_UPDATED: 'role:updated',\n ROLE_DELETED: 'role:deleted',\n\n // Permission events\n PERMISSION_CREATED: 'permission:created',\n PERMISSION_UPDATED: 'permission:updated',\n PERMISSION_DELETED: 'permission:deleted',\n\n // Role-Permission events\n ROLE_PERMISSION_ASSIGNED: 'role-permission:assigned',\n ROLE_PERMISSION_REMOVED: 'role-permission:removed',\n\n // User RBAC events\n USER_ROLES_UPDATED: 'user:roles-updated',\n USER_PERMISSIONS_CHANGED: 'user:permissions-changed',\n USER_ACCESS_CHANGED: 'user:access-changed',\n RBAC_USER_ASSIGNED_TO_GROUP: 'rbac:user-assigned-to-group',\n RBAC_USER_REMOVED_FROM_GROUP: 'rbac:user-removed-from-group',\n RBAC_PERMISSIONS_UPDATED: 'rbac:permissions-updated',\n\n // User status events\n USER_ONLINE: 'user:online',\n USER_OFFLINE: 'user:offline',\n\n // Group events\n GROUP_UPDATED: 'group:updated',\n} as const;\n\n/**\n * Reconnection delay after RBAC updates (in milliseconds)\n * This ensures backend has fully processed the update before refetching data\n */\nexport const RBAC_RECONNECT_DELAY = 300;\n\n/**\n * Configuration for automatic reconnection after specific events\n */\nexport const RBAC_AUTO_RECONNECT_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n] as const;\n\n/**\n * Events that should trigger user data refresh\n */\nexport const USER_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_PERMISSIONS_CHANGED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n EXGUARD_RBAC_EVENTS.RBAC_USER_ASSIGNED_TO_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_USER_REMOVED_FROM_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED,\n] as const;\n\n/**\n * Events that should trigger role data refresh\n */\nexport const ROLE_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n] as const;\n\n/**\n * Events that should trigger permission data refresh\n */\nexport const PERMISSION_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n] as const;\n","import axios, { type AxiosError } from 'axios';\nimport type { VerifyTokenResponse, UserAccessData, AuthApiResponse } from '../types/exguard-types';\nimport { getExGuardApiUrl, getAuthToken, EXGUARD_STORAGE_KEYS } from '../config/exguard-config';\n\n// Create a separate axios instance for Guard API endpoints\n// Note: baseURL is set dynamically in the interceptor to support runtime configuration\nconst guardApiClient = axios.create({\n withCredentials: true,\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n\n// Add interceptor to dynamically set baseURL and include access token\nguardApiClient.interceptors.request.use(\n (config) => {\n // Set baseURL dynamically from config (supports runtime configuration)\n config.baseURL = getExGuardApiUrl();\n \n const token = getAuthToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error: unknown) => Promise.reject(error instanceof Error ? error : new Error(String(error))),\n);\n\n/**\n * Verify ID token with ExGuard backend\n */\nexport async function verifyToken(): Promise<VerifyTokenResponse> {\n try {\n const idToken = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ID_TOKEN);\n const response = await guardApiClient.post<\n AuthApiResponse<{\n user?: {\n id: string;\n username: string;\n email: string;\n givenName: string;\n familyName: string;\n };\n }>\n >('/guard/verify-token', {\n id_token: idToken,\n });\n\n if (response.data.success && response.data.data) {\n // Map backend response to frontend format\n const backendData = response.data.data;\n const mappedResponse: VerifyTokenResponse = {\n valid: true,\n user: backendData.user\n ? {\n userId: backendData.user.id,\n username: backendData.user.username,\n email: backendData.user.email,\n givenName: backendData.user.givenName,\n familyName: backendData.user.familyName,\n }\n : undefined,\n };\n return mappedResponse;\n }\n\n throw new Error(response.data.message ?? 'Token verification failed');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Token verification failed';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n\n/**\n * Flag to ensure User Access Data is logged only once\n */\nlet hasLoggedUserAccess = false;\n\n/**\n * Get user access data including roles, permissions, modules, and field offices\n */\nexport async function getUserAccess(): Promise<UserAccessData> {\n try {\n const response = await guardApiClient.get<AuthApiResponse<UserAccessData>>('/guard/me');\n\n if (response.data.success && response.data.data) {\n if (!hasLoggedUserAccess) {\n console.log('User Access Data:', response.data.data);\n hasLoggedUserAccess = true;\n }\n\n return response.data.data;\n }\n\n throw new Error(response.data.message ?? 'Failed to get user access data');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Failed to get user access data';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n","/**\n * ExGuard Realtime Context\n *\n * Context for managing realtime RBAC connections and state\n */\n\nimport { createContext } from 'react';\n\nexport interface ExGuardRealtimeContextType {\n isConnected: boolean;\n connect: (token: string, userId: string) => Promise<void>;\n disconnect: () => void;\n reconnect: () => Promise<void>;\n refreshRbac: () => Promise<void>;\n registerRbacRefreshCallback: (callback: () => Promise<void>) => () => void;\n}\n\nexport const ExGuardRealtimeContext = createContext<ExGuardRealtimeContextType | undefined>(undefined);\n","import { useEffect, useState, useCallback, use } from 'react';\r\nimport { getUserAccess } from '../api/exguard-api';\r\nimport type { UserAccessData, ModulePermissions } from '../types/exguard-types';\r\nimport { ExGuardRealtimeContext } from '../providers/exguard-realtime-context';\r\n\r\ninterface UseUserAccessOptions {\r\n enabled?: boolean;\r\n refetchInterval?: number;\r\n}\r\n\r\n/**\r\n * Custom hook to fetch and manage user access data with RBAC\r\n * Includes caching and periodic refetching for real-time RBAC\r\n */\r\nexport const useUserAccess = (options: UseUserAccessOptions = {}) => {\r\n const { enabled = true, refetchInterval = 0 } = options;\r\n const [userAccess, setUserAccess] = useState<UserAccessData | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n const realtimeContext = use(ExGuardRealtimeContext);\r\n\r\n const fetchUserAccess = useCallback(async (silent = false): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n // Only set loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(true);\r\n }\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error('Failed to fetch user access');\r\n setError(errorObj);\r\n } finally {\r\n // Only clear loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(false);\r\n }\r\n }\r\n }, [enabled]);\r\n\r\n // Register for real-time RBAC updates from the realtime provider\r\n useEffect(() => {\r\n if (!realtimeContext) {\r\n return;\r\n }\r\n\r\n // Use silent refresh for realtime updates to prevent UI disruption\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(() => fetchUserAccess(true));\r\n\r\n return () => {\r\n unsubscribe();\r\n };\r\n }, [realtimeContext, fetchUserAccess]);\r\n\r\n useEffect(() => {\r\n void fetchUserAccess();\r\n\r\n if (refetchInterval > 0) {\r\n const interval = setInterval(() => {\r\n void fetchUserAccess();\r\n }, refetchInterval);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }\r\n }, [fetchUserAccess, refetchInterval]);\r\n\r\n const hasModuleAccess = useCallback(\r\n (moduleKey: string): boolean => {\r\n if (!userAccess) return false;\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return !!module && module.permissions.length > 0;\r\n },\r\n [userAccess],\r\n );\r\n\r\n const getModulePermissions = useCallback(\r\n (moduleKey: string): string[] => {\r\n if (!userAccess) return [];\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return module?.permissions ?? [];\r\n },\r\n [userAccess],\r\n );\r\n\r\n const hasPermission = useCallback(\r\n (moduleKey: string, permission: string): boolean => {\r\n const permissions = getModulePermissions(moduleKey);\r\n return permissions.includes(permission);\r\n },\r\n [getModulePermissions],\r\n );\r\n\r\n return {\r\n userAccess,\r\n isLoading,\r\n error,\r\n hasModuleAccess,\r\n getModulePermissions,\r\n hasPermission,\r\n refetch: fetchUserAccess,\r\n refetchSilent: () => fetchUserAccess(true),\r\n };\r\n};\r\n","import React from 'react';\r\n\r\ninterface SpinnerProps {\r\n className?: string;\r\n}\r\n\r\nexport function Spinner({ className = '' }: SpinnerProps) {\r\n return (\r\n <div\r\n className={`animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${className}`}\r\n role=\"status\"\r\n >\r\n <span className=\"!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]\">\r\n Loading...\r\n </span>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n variant?: 'default' | 'outline' | 'destructive' | 'ghost' | 'link';\r\n size?: 'default' | 'sm' | 'lg' | 'icon';\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Button({\r\n className = '',\r\n variant = 'default',\r\n size = 'default',\r\n children,\r\n ...props\r\n}: ButtonProps) {\r\n const baseStyles =\r\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';\r\n\r\n const variantStyles = {\r\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\r\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\r\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\r\n ghost: 'hover:bg-accent hover:text-accent-foreground',\r\n link: 'text-primary underline-offset-4 hover:underline',\r\n };\r\n\r\n const sizeStyles = {\r\n default: 'h-10 px-4 py-2',\r\n sm: 'h-9 rounded-md px-3',\r\n lg: 'h-11 rounded-md px-8',\r\n icon: 'h-10 w-10',\r\n };\r\n\r\n return (\r\n <button\r\n className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface CardProps extends React.HTMLAttributes<HTMLDivElement> {\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Card({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div\r\n className={`rounded-lg border bg-card text-card-foreground shadow-sm ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardHeader({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex flex-col space-y-1.5 p-6 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardTitle({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <h3 className={`text-2xl font-semibold leading-none tracking-tight ${className}`} {...props}>\r\n {children}\r\n </h3>\r\n );\r\n}\r\n\r\nexport function CardDescription({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <p className={`text-sm text-muted-foreground ${className}`} {...props}>\r\n {children}\r\n </p>\r\n );\r\n}\r\n\r\nexport function CardContent({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardFooter({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex items-center p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import { Navigate, Outlet } from 'react-router';\r\nimport { useUserAccess } from '../hooks/use-user-access';\r\nimport { Spinner } from './ui/spinner';\r\nimport { Button } from './ui/button';\r\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card';\r\nimport { ArrowLeft, ShieldAlert, Lock } from 'lucide-react';\r\n\r\ninterface PermissionGuardProps {\r\n module: string;\r\n permission?: string;\r\n requireModule?: boolean;\r\n requirePermission?: boolean;\r\n fallbackPath?: string;\r\n}\r\n\r\n/**\r\n * PermissionGuard component that checks if user has required module access and/or permissions\r\n *\r\n * @param module - The module key (e.g., 'EXID', 'EXFLOW', 'TEV')\r\n * @param permission - Optional specific permission to check (e.g., 'profile:create', 'profile:update')\r\n * @param requireModule - Whether to require module access (default: true)\r\n * @param requirePermission - Whether to require the specific permission (default: true if permission is provided)\r\n * @param fallbackPath - Path to redirect to if access is denied (default: show error page)\r\n */\r\nexport function PermissionGuard({\r\n module,\r\n permission,\r\n requireModule = true,\r\n requirePermission = true,\r\n fallbackPath,\r\n}: PermissionGuardProps) {\r\n const { isLoading, hasModuleAccess, hasPermission } = useUserAccess();\r\n\r\n // Show loading spinner while checking permissions\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Spinner className=\"size-8\" />\r\n </div>\r\n );\r\n }\r\n\r\n // Check module access\r\n const hasModule = hasModuleAccess(module);\r\n const moduleCheckFailed = requireModule && !hasModule;\r\n\r\n // Check specific permission if provided\r\n const hasSpecificPermission = permission ? hasPermission(module, permission) : true;\r\n const permissionCheckFailed = permission && requirePermission && !hasSpecificPermission;\r\n\r\n // Determine if access should be denied\r\n const accessDenied = moduleCheckFailed || permissionCheckFailed;\r\n\r\n // Redirect to fallback path if provided\r\n if (accessDenied && fallbackPath) {\r\n return <Navigate to={fallbackPath} replace />;\r\n }\r\n\r\n // Show access denied message\r\n if (accessDenied) {\r\n const denialReason = moduleCheckFailed\r\n ? {\r\n title: 'Module Access Required',\r\n description: `Access to the ${module} module is required to view this page`,\r\n detail: `Your current account permissions do not include access to the ${module} module. This module may be restricted to specific roles or user groups.`,\r\n }\r\n : {\r\n title: 'Permission Required',\r\n description: `The permission \"${permission ?? 'unknown'}\" is needed to access this resource`,\r\n detail: `Your account has access to the ${module} module but lacks the specific permission required for this action. This permission may need to be assigned to your role or user group.`,\r\n };\r\n\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[calc(100vh-4rem)] p-6\">\r\n <Card className=\"w-full max-w-lg\">\r\n <CardHeader className=\"text-center pb-4\">\r\n <div className=\"mx-auto mb-4 flex size-16 items-center justify-center rounded-full bg-destructive/10\">\r\n {moduleCheckFailed ? (\r\n <Lock className=\"size-8 text-destructive\" />\r\n ) : (\r\n <ShieldAlert className=\"size-8 text-destructive\" />\r\n )}\r\n </div>\r\n <CardTitle className=\"text-2xl\">{denialReason.title}</CardTitle>\r\n <CardDescription className=\"text-base\">{denialReason.description}</CardDescription>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n <div className=\"rounded-lg bg-muted p-4\">\r\n <p className=\"text-sm text-muted-foreground\">{denialReason.detail}</p>\r\n </div>\r\n <div className=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n window.history.back();\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n <ArrowLeft className=\"mr-2 size-4\" />\r\n Go Back\r\n </Button>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => {\r\n window.location.href = '/';\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n Return to Dashboard\r\n </Button>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n </div>\r\n );\r\n }\r\n\r\n // User has required access, render child routes\r\n return <Outlet />;\r\n}\r\n","import { io, type Socket } from 'socket.io-client';\nimport type { RealtimeEventPayload, RealtimeEventType, RealtimeEventHandler } from './realtime.types';\nimport { getExGuardApiUrl } from '../config/exguard-config';\n\nclass RealtimeClient {\n private socket: Socket | null = null;\n private listeners = new Map<string, Set<RealtimeEventHandler>>();\n private isConnected = false;\n private debug = false; // Enable/disable debug logging\n private connectionPromise: Promise<void> | null = null;\n\n constructor() {\n this.log('đŸŸĸ RealtimeClient initialized');\n }\n \n private getApiUrl(): string {\n return getExGuardApiUrl();\n }\n\n private log(message: string, data?: unknown) {\n if (this.debug) {\n console.log(`[RealtimeClient] ${message}`, data);\n }\n }\n\n private logError(message: string, error?: unknown) {\n console.error(`[RealtimeClient] ${message}`, error);\n }\n\n private logWarn(message: string, data?: unknown) {\n console.warn(`[RealtimeClient] ${message}`, data);\n }\n\n /**\n * Connect to the realtime server\n */\n connect(token: string, userId: string): Promise<void> {\n // Validate inputs\n if (!token) {\n this.logError('❌ Cannot connect - token is missing or empty');\n return Promise.reject(new Error('Missing authentication token'));\n }\n\n if (!userId) {\n this.logError('❌ Cannot connect - userId is missing or empty');\n return Promise.reject(new Error('Missing userId'));\n }\n\n // Return existing connection promise if already connecting\n if (this.connectionPromise) {\n this.log('âŗ Connection already in progress, returning existing promise');\n return this.connectionPromise;\n }\n\n this.connectionPromise = new Promise((resolve, reject) => {\n try {\n const apiUrl = this.getApiUrl();\n this.log('🔌 Attempting to connect...', { apiUrl, userId, hasToken: !!token });\n\n if (this.socket?.connected) {\n this.log('✅ Already connected');\n this.connectionPromise = null;\n resolve();\n return;\n }\n\n const socketUrl = `${apiUrl}/realtime`;\n this.log('🚀 Creating Socket.IO connection', {\n url: socketUrl,\n transports: ['websocket', 'polling'],\n userId,\n });\n\n this.socket = io(socketUrl, {\n auth: {\n token,\n userId,\n },\n transports: ['websocket', 'polling'],\n reconnection: true,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n reconnectionAttempts: 5,\n });\n\n this.socket.on('connect', () => {\n this.isConnected = true;\n this.log('✅ Connected to realtime server', {\n socketId: this.socket?.id,\n userId,\n });\n this.connectionPromise = null;\n resolve();\n });\n\n this.socket.on('disconnect', (reason: string) => {\n this.isConnected = false;\n this.log('❌ Disconnected from realtime server', { reason });\n });\n\n this.socket.on('connect_error', (error: unknown) => {\n this.logError('❌ Connection error (check token and backend)', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection error: ${errorMessage}`));\n });\n\n this.socket.on('error', (error: unknown) => {\n this.logError('❌ Realtime error', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Socket.IO error: ${errorMessage}`));\n });\n\n this.socket.on('reconnect_attempt', () => {\n this.log('🔄 Attempting to reconnect...');\n });\n\n this.socket.on('reconnect', () => {\n this.isConnected = true;\n this.log('🔁 Reconnected to realtime server', {\n socketId: this.socket?.id,\n });\n });\n\n this.socket.on('reconnect_failed', () => {\n this.logError('❌ Reconnection failed after maximum attempts');\n this.connectionPromise = null;\n reject(new Error('Reconnection failed'));\n });\n\n // Listen to all realtime events\n this.socket.onAny((eventName: string, payload: unknown) => {\n // Debug: log raw event for troubleshooting\n this.log(`📨 Raw event received`, {\n eventName,\n payloadType: typeof payload,\n payload,\n });\n\n // Normalize payload - backend sends event name separately from payload\n const payloadObj =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n\n // CRITICAL FIX: Use eventName as the primary event type (e.g., 'user:access-changed')\n // Socket.IO sends the event name as the first parameter, not nested in payload.type\n const eventType = eventName;\n\n const normalizedPayload: RealtimeEventPayload = {\n type: eventType as RealtimeEventType,\n timestamp:\n 'timestamp' in payloadObj\n ? typeof payloadObj.timestamp === 'number'\n ? payloadObj.timestamp\n : new Date(payloadObj.timestamp as string).getTime()\n : Date.now(),\n data: 'data' in payloadObj ? payloadObj.data : payload,\n };\n\n this.log(`📨 Event processed: ${eventType}`, {\n type: normalizedPayload.type,\n timestamp: normalizedPayload.timestamp,\n dataKeys:\n typeof normalizedPayload.data === 'object' && normalizedPayload.data !== null\n ? Object.keys(normalizedPayload.data as Record<string, unknown>)\n : 'N/A',\n });\n this.handleEvent(eventType as RealtimeEventType, normalizedPayload);\n });\n } catch (error) {\n this.logError('Failed to initialize connection', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection initialization failed: ${errorMessage}`));\n }\n });\n\n return this.connectionPromise;\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.log('🔌 Disconnecting from realtime server...');\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n this.isConnected = false;\n this.log('✅ Disconnected');\n }\n }\n\n /**\n * Check if connected\n */\n getIsConnected(): boolean {\n return this.isConnected && this.socket?.connected === true;\n }\n\n /**\n * Wait for connection to be ready (with timeout)\n */\n async waitForConnection(timeoutMs = 30000): Promise<void> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (this.getIsConnected()) {\n this.log('✅ Connection ready');\n return;\n }\n\n // Wait 100ms before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n this.logError('❌ Timeout waiting for connection', { timeoutMs, elapsed: Date.now() - startTime });\n throw new Error('Connection timeout - failed to establish WebSocket connection');\n }\n\n /**\n * Subscribe to a specific event type\n */\n subscribe<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n ): () => void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set());\n }\n\n this.listeners.get(eventType)?.add(handler as RealtimeEventHandler);\n const listenerCount = this.listeners.get(eventType)?.size ?? 0;\n this.log(`📌 Subscribed to event: ${eventType}`, { totalListeners: listenerCount });\n\n // Return unsubscribe function\n return () => {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler as RealtimeEventHandler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n };\n }\n\n /**\n * Unsubscribe from an event\n */\n unsubscribe(eventType: RealtimeEventType, handler: RealtimeEventHandler): void {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n }\n /**\n * Send a subscription message to the server with connection wait\n */\n async subscribeToChannel(channel: 'roles' | 'permissions' | 'rbac'): Promise<void> {\n try {\n this.log(`📡 Subscribing to channel: ${channel}`);\n\n // Wait for connection to be ready\n await this.waitForConnection(15000);\n\n // Now emit subscribe\n this.log(`📡 Emitting subscribe event for channel: ${channel}`);\n this.socket?.emit(`subscribe:${channel}`);\n this.log(`✅ Subscribed to channel: ${channel}`);\n } catch (error) {\n this.logError(`❌ Failed to subscribe to channel \"${channel}\"`, error);\n throw error;\n }\n }\n\n /**\n * Send an unsubscription message to the server\n */\n unsubscribeFromChannel(channel: 'roles' | 'permissions' | 'rbac'): void {\n if (!this.socket?.connected) {\n this.logWarn(`Cannot unsubscribe from channel \"${channel}\" - socket not connected`);\n return;\n }\n\n this.log(`📡 Unsubscribing from channel: ${channel}`);\n this.socket.emit(`unsubscribe:${channel}`);\n }\n\n /**\n * Handle incoming events\n */\n private handleEvent(eventType: RealtimeEventType, payload: RealtimeEventPayload): void {\n // Call specific event handlers\n const handlers = this.listeners.get(eventType);\n if (handlers && handlers.size > 0) {\n this.log(`🔔 Triggering ${String(handlers.size)} handler(s) for event: ${eventType}`);\n handlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError(`Error in event handler for ${eventType}`, error);\n }\n });\n }\n\n // Call wildcard handlers if any\n const wildcardHandlers = this.listeners.get('*' as RealtimeEventType);\n if (wildcardHandlers && wildcardHandlers.size > 0) {\n this.log(`🔔 Triggering ${String(wildcardHandlers.size)} wildcard handler(s)`);\n wildcardHandlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError('Error in wildcard event handler', error);\n }\n });\n }\n }\n\n /**\n * Get all connected listeners count\n */\n getListenerCount(eventType?: RealtimeEventType): number {\n if (eventType) {\n return this.listeners.get(eventType)?.size ?? 0;\n }\n let total = 0;\n this.listeners.forEach((handlers) => {\n total += handlers.size;\n });\n return total;\n }\n\n /**\n * Enable or disable debug logging\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n this.log(`Debug logging ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * Get connection status summary\n */\n getStatus() {\n const status = {\n isConnected: this.getIsConnected(),\n socketId: this.socket?.id ?? 'N/A',\n apiUrl: this.getApiUrl(),\n totalListeners: this.getListenerCount(),\n listeners: Array.from(this.listeners.entries()).map(([event, handlers]) => ({\n event,\n count: handlers.size,\n })),\n };\n this.log('📊 Connection Status', status);\n return status;\n }\n}\n\n// Create singleton instance\nexport const realtimeClient = new RealtimeClient();\n\n// Expose debug methods on window for console access\nif (typeof window !== 'undefined') {\n const w = window as unknown as Record<string, unknown>;\n w.__realtimeClient = {\n client: realtimeClient,\n connect: (token: string, userId: string) => realtimeClient.connect(token, userId),\n disconnect: () => {\n realtimeClient.disconnect();\n },\n isConnected: () => realtimeClient.getIsConnected(),\n setDebug: (enabled: boolean) => {\n realtimeClient.setDebug(enabled);\n },\n status: () => realtimeClient.getStatus(),\n getListenerCount: (eventType?: RealtimeEventType) => realtimeClient.getListenerCount(eventType),\n };\n\n}\n\nexport type { RealtimeClient };\n","/**\n * Shared Realtime Hooks\n *\n * Basic hooks for realtime functionality that wraps the realtime-client\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport type { RealtimeEventType, RealtimeEventPayload, RealtimeEventHandler } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to realtime RBAC events\n * Automatically handles subscription/unsubscription lifecycle\n */\nexport function useRealtimeRbac<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe<T>(eventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, [eventType]);\n}\n\n/**\n * Hook to manage channel subscriptions\n */\nexport function useRealtimeSubscription(channel: 'roles' | 'permissions' | 'rbac') {\n useEffect(() => {\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch(() => {\n // Silent error handling\n });\n\n return () => {\n realtimeClient.unsubscribeFromChannel(channel);\n };\n }, [channel]);\n}\n\n/**\n * Hook to listen to multiple event types\n */\nexport function useRealtimeMultiple(\n events: {\n type: RealtimeEventType;\n handler: RealtimeEventHandler;\n }[],\n) {\n useEffect(() => {\n const unsubscribers = events.map(({ type, handler }) => realtimeClient.subscribe(type, handler));\n\n return () => {\n unsubscribers.forEach((unsub) => {\n unsub();\n });\n };\n }, [events]);\n}\n\n/**\n * Hook to listen to all realtime events\n */\nexport function useRealtimeAll(handler: RealtimeEventHandler) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe('*' as RealtimeEventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, []);\n}\n\n/**\n * Hook to get the connection status\n */\nexport function useRealtimeStatus() {\n const [isConnected, setIsConnected] = useState(realtimeClient.getIsConnected());\n\n useEffect(() => {\n const checkConnection = () => {\n setIsConnected(realtimeClient.getIsConnected());\n };\n\n const interval = setInterval(checkConnection, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n return { isConnected };\n}\n","/**\n * Hook to use ExGuard Realtime Context\n */\n\nimport { use } from 'react';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\n\n/**\n * Hook to access ExGuard realtime context\n * Must be used within ExGuardRealtimeProvider\n */\nexport function useExGuardRealtime(): ExGuardRealtimeContextType {\n const context = use(ExGuardRealtimeContext);\n if (!context) {\n throw new Error('useExGuardRealtime must be used within a ExGuardRealtimeProvider');\n }\n return context;\n}\n","/**\n * ExGuard Realtime RBAC Hooks\n *\n * Custom hooks for handling ExGuard-specific realtime RBAC events\n */\n\nimport { useCallback } from 'react';\nimport { useRealtimeRbac, useRealtimeSubscription } from './use-realtime';\nimport { useExGuardRealtime } from '../providers/use-exguard-realtime';\nimport { EXGUARD_RBAC_CHANNELS, EXGUARD_RBAC_EVENTS, RBAC_RECONNECT_DELAY } from '../config/realtime-rbac-config';\nimport type { RealtimeEventPayload } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to all ExGuard RBAC channels\n */\nexport function useExGuardRbacChannels() {\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.RBAC);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.ROLES);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.PERMISSIONS);\n}\n\n/**\n * Hook to handle role updates with automatic reconnection\n */\nexport function useRoleUpdateHandler(onUpdate: () => Promise<void>, fetchUserAccess?: () => Promise<void>) {\n const { reconnect } = useExGuardRealtime();\n\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n try {\n await reconnect();\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n } catch (error) {\n // Silent error handling\n }\n })();\n },\n [reconnect, onUpdate, fetchUserAccess],\n ),\n );\n}\n\n/**\n * Hook to handle user RBAC updates (role assignments, permissions, etc.)\n */\nexport function useUserRbacUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle permission updates\n */\nexport function usePermissionUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle group updates\n */\nexport function useGroupUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle user access changes (personal notifications)\n * This is for individual user notifications received via user:{cognitoSubId} room\n */\nexport function useUserAccessChangeHandler(onAccessChange: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onAccessChange();\n })();\n },\n [onAccessChange],\n ),\n );\n}\n","/**\n * ExGuard Realtime Utilities\n *\n * Utility functions for ExGuard realtime functionality\n */\n\nimport { getUserAccess } from '../api/exguard-api';\n\n/**\n * Get current user's Cognito Sub ID from backend\n * This is used for websocket room identification (user:{cognitoSubId})\n */\nexport async function getCurrentUserId(): Promise<string | null> {\n try {\n const userAccess = await getUserAccess();\n \n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n return null;\n }\n}\n","/**\n * ExGuard Realtime Provider\n *\n * Provider for managing realtime RBAC connections and events\n */\n\nimport React, { useEffect, useRef, type ReactNode } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\nimport { getCurrentUserId } from '../utils/exguard-realtime-utils';\nimport type { UserRbacEventPayload } from '../lib/realtime.types';\n\ninterface ExGuardRealtimeProviderProps {\n children: ReactNode;\n}\n\nexport function ExGuardRealtimeProvider({ children }: ExGuardRealtimeProviderProps) {\n const [isConnected, setIsConnected] = React.useState(false);\n const connectionAttempted = useRef(false);\n const rbacRefreshCallbacks = useRef<Set<() => Promise<void>>>(new Set());\n const currentUserRef = useRef<{ token: string; userId: string } | null>(null);\n const currentUserIdRef = useRef<string | null>(null);\n\n // Register callback to refresh user access\n const registerRbacRefreshCallback = (callback: () => Promise<void>) => {\n rbacRefreshCallbacks.current.add(callback);\n return () => {\n rbacRefreshCallbacks.current.delete(callback);\n };\n };\n\n // Trigger refresh for all registered callbacks\n const triggerRbacRefresh = async (): Promise<void> => {\n \n if (rbacRefreshCallbacks.current.size === 0) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No RBAC refresh callbacks registered!');\n return;\n }\n\n const refreshPromises = Array.from(rbacRefreshCallbacks.current).map((cb, index) => {\n return cb().catch((err: unknown) => {\n console.error(`[ExGuardRealtimeProvider] ❌ Error during RBAC refresh callback ${String(index + 1)}:`, err);\n });\n });\n\n await Promise.all(refreshPromises);\n };\n\n // Manual reconnect function\n const handleReconnect = async (): Promise<void> => {\n if (!currentUserRef.current) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No user credentials available for reconnect');\n return;\n }\n const { token, userId } = currentUserRef.current;\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n const accessToken = localStorage.getItem('access_token');\n\n if (!accessToken) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No access token found in localStorage');\n return;\n }\n\n if (connectionAttempted.current) {\n return;\n }\n\n connectionAttempted.current = true;\n\n // Fetch user info from backend\n const initializeConnection = async (): Promise<void> => {\n try {\n const userId = await getCurrentUserId();\n\n if (!userId) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to get userId from backend');\n return;\n }\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n setIsConnected(true);\n\n // Listen ONLY for THIS USER's access changes (sent to user:{userId} room)\n realtimeClient.subscribe('user:access-changed', (_payload: UserRbacEventPayload): void => {\n \n // No need to check userId - if this event reached our room (user:{cognitoSubId}),\n // it's definitely for us. Backend ensures correct room targeting.\n void triggerRbacRefresh();\n });\n\n \n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to establish realtime connection:');\n const errorMessage = error instanceof Error ? error.message : String(error);\n const tokenStr = accessToken ? accessToken.substring(0, 20) + '...' : '';\n console.error('[ExGuardRealtimeProvider] Error details:', {\n message: errorMessage,\n token: tokenStr,\n });\n setIsConnected(false);\n }\n };\n\n void initializeConnection();\n\n // Monitor connection status\n let lastConnectedState = realtimeClient.getIsConnected();\n const interval = setInterval(() => {\n const currentConnectedState = realtimeClient.getIsConnected();\n if (currentConnectedState !== lastConnectedState) {\n \n lastConnectedState = currentConnectedState;\n setIsConnected(currentConnectedState);\n }\n }, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n const handleConnect = async (token: string, userId: string) => {\n try {\n \n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n \n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to connect to realtime:', error);\n setIsConnected(false);\n throw error;\n }\n };\n\n const handleDisconnect = () => {\n \n realtimeClient.disconnect();\n setIsConnected(false);\n };\n\n const value: ExGuardRealtimeContextType = {\n isConnected,\n connect: handleConnect,\n disconnect: handleDisconnect,\n reconnect: handleReconnect,\n refreshRbac: handleRefreshRbac,\n registerRbacRefreshCallback,\n };\n\n return <ExGuardRealtimeContext value={value}>{children}</ExGuardRealtimeContext>;\n}\n","/**\n * ExGuard Realtime Subscription Hook\n *\n * Hook to subscribe to realtime channels and handle RBAC events\n */\n\nimport { useEffect } from 'react';\nimport { useExGuardRealtime } from './use-exguard-realtime';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { EXGUARD_RBAC_EVENTS, EXGUARD_RBAC_CHANNELS } from '../config/realtime-rbac-config';\nimport type { RealtimeEventType } from '../lib/realtime.types';\n\ninterface UseExGuardRealtimeSubscriptionOptions {\n /** Event types to subscribe to. If not provided, subscribes to all RBAC events */\n events?: RealtimeEventType[];\n /** Whether to auto-subscribe on mount */\n autoSubscribe?: boolean;\n}\n\n/**\n * Hook to subscribe to ExGuard realtime channel and handle RBAC updates\n * @param channel - Channel name ('rbac', 'roles', 'permissions')\n * @param options - Subscription options\n */\nexport function useExGuardRealtimeSubscription(\n channel: keyof typeof EXGUARD_RBAC_CHANNELS = 'RBAC',\n options: UseExGuardRealtimeSubscriptionOptions = {},\n): void {\n const { registerRbacRefreshCallback } = useExGuardRealtime();\n const { autoSubscribe = true, events } = options;\n const channelName = EXGUARD_RBAC_CHANNELS[channel];\n\n useEffect(() => {\n if (!autoSubscribe) {\n return;\n }\n\n // Subscribe to channel on server\n void realtimeClient.subscribeToChannel(channelName);\n\n // If specific events provided, subscribe to them\n if (events && events.length > 0) {\n const unsubscribers: (() => void)[] = [];\n\n events.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }\n\n // Default: subscribe to all RBAC events\n const defaultRbacEvents: RealtimeEventType[] = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_REMOVED,\n EXGUARD_RBAC_EVENTS.USER_ONLINE,\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n ];\n\n const unsubscribers: (() => void)[] = [];\n\n defaultRbacEvents.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n \n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n \n return Promise.resolve();\n });\n\n return () => {\n \n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n unregisterCallback();\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }, [channelName, autoSubscribe, events, registerRbacRefreshCallback]);\n}\n"]}
1
+ {"version":3,"sources":["../src/config/exguard-config.ts","../src/config/realtime-rbac-config.ts","../src/api/exguard-api.ts","../src/providers/exguard-realtime-context.ts","../src/hooks/use-user-access.ts","../src/components/ui/spinner.tsx","../src/components/ui/button.tsx","../src/components/ui/card.tsx","../src/components/permission-guard.tsx","../src/lib/realtime-client.ts","../src/hooks/use-realtime.ts","../src/providers/use-exguard-realtime.ts","../src/hooks/use-exguard-rbac.ts","../src/utils/exguard-realtime-utils.ts","../src/providers/exguard-realtime-provider.tsx","../src/providers/use-exguard-realtime-subscription.ts"],"names":["jsx","useEffect","use","useRef","unsubscribers"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * ExGuard API Configuration\r\n * Configuration for ExGuard backend API\r\n */\r\n\r\nexport interface ExGuardConfig {\r\n apiUrl: string;\r\n withCredentials?: boolean;\r\n getAuthToken?: () => string | null;\r\n}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Auto-detects API URL based on environment\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Configuration state\r\n */\r\nlet configuredApiUrl: string = '';\r\nlet customGetAuthToken: (() => string | null) | undefined;\r\n\r\n/**\r\n * Auto-detect API URL based on current environment\r\n */\r\nconst autoDetectApiUrl = (): string => {\r\n if (typeof window !== 'undefined') {\r\n const hostname = window.location.hostname;\r\n const protocol = window.location.protocol;\r\n \r\n // Local development\r\n if (hostname === 'localhost' || hostname === '127.0.0.1') {\r\n return 'http://localhost:3000';\r\n }\r\n \r\n // Production/Staging - use same domain with /api path\r\n return `${protocol}//${hostname}/api`;\r\n }\r\n \r\n // SSR fallback\r\n return process.env.EXGUARD_API_URL || 'http://localhost:3000';\r\n};\r\n\r\n/**\r\n * Set ExGuard configuration\r\n * @param config - Partial configuration to override defaults\r\n */\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n if (config.getAuthToken) {\r\n customGetAuthToken = config.getAuthToken;\r\n }\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL\r\n * Priority: 1) Manual config, 2) Environment var, 3) Auto-detect\r\n */\r\nexport const getExGuardApiUrl = (): string => {\r\n // 1. User-configured URL\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // 2. Check environment variables (Vite/Next.js)\r\n if (typeof window !== 'undefined') {\r\n // Vite apps\r\n if ((import.meta as any).env?.VITE_GUARD_APP_URL) {\r\n return (import.meta as any).env.VITE_GUARD_APP_URL;\r\n }\r\n \r\n // Next.js or injected env\r\n if ((window as any).__EXGUARD_API_URL__) {\r\n return (window as any).__EXGUARD_API_URL__;\r\n }\r\n }\r\n \r\n // 3. Auto-detect based on hostname\r\n return autoDetectApiUrl();\r\n};\r\n\r\n/**\r\n * Get authentication token\r\n * Uses custom getter if provided, otherwise defaults to localStorage\r\n */\r\nexport const getAuthToken = (): string | null => {\r\n if (customGetAuthToken) {\r\n return customGetAuthToken();\r\n }\r\n \r\n if (typeof window !== 'undefined') {\r\n return (\r\n localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n sessionStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN) ||\r\n null\r\n );\r\n }\r\n \r\n return null;\r\n};\r\n\r\n/**\r\n * Storage keys for ExGuard\r\n */\r\nexport const EXGUARD_STORAGE_KEYS = {\r\n ACCESS_TOKEN: 'access_token',\r\n ID_TOKEN: 'id_token',\r\n REFRESH_TOKEN: 'refresh_token',\r\n} as const;\r\n","/**\n * ExGuard Realtime RBAC Configuration\n *\n * This file contains all configuration for realtime RBAC events\n * specific to ExGuard module (users, roles, permissions management)\n */\n\n/**\n * Channels to subscribe to for ExGuard RBAC\n */\nexport const EXGUARD_RBAC_CHANNELS = {\n ROLES: 'roles',\n PERMISSIONS: 'permissions',\n RBAC: 'rbac',\n} as const;\n\n/**\n * Event types for ExGuard RBAC realtime updates\n */\nexport const EXGUARD_RBAC_EVENTS = {\n // Role events\n ROLE_CREATED: 'role:created',\n ROLE_UPDATED: 'role:updated',\n ROLE_DELETED: 'role:deleted',\n\n // Permission events\n PERMISSION_CREATED: 'permission:created',\n PERMISSION_UPDATED: 'permission:updated',\n PERMISSION_DELETED: 'permission:deleted',\n\n // Role-Permission events\n ROLE_PERMISSION_ASSIGNED: 'role-permission:assigned',\n ROLE_PERMISSION_REMOVED: 'role-permission:removed',\n\n // User RBAC events\n USER_ROLES_UPDATED: 'user:roles-updated',\n USER_PERMISSIONS_CHANGED: 'user:permissions-changed',\n USER_ACCESS_CHANGED: 'user:access-changed',\n RBAC_USER_ASSIGNED_TO_GROUP: 'rbac:user-assigned-to-group',\n RBAC_USER_REMOVED_FROM_GROUP: 'rbac:user-removed-from-group',\n RBAC_PERMISSIONS_UPDATED: 'rbac:permissions-updated',\n\n // User status events\n USER_ONLINE: 'user:online',\n USER_OFFLINE: 'user:offline',\n\n // Group events\n GROUP_UPDATED: 'group:updated',\n} as const;\n\n/**\n * Reconnection delay after RBAC updates (in milliseconds)\n * This ensures backend has fully processed the update before refetching data\n */\nexport const RBAC_RECONNECT_DELAY = 300;\n\n/**\n * Configuration for automatic reconnection after specific events\n */\nexport const RBAC_AUTO_RECONNECT_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n] as const;\n\n/**\n * Events that should trigger user data refresh\n */\nexport const USER_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n EXGUARD_RBAC_EVENTS.USER_PERMISSIONS_CHANGED,\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n EXGUARD_RBAC_EVENTS.RBAC_USER_ASSIGNED_TO_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_USER_REMOVED_FROM_GROUP,\n EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED,\n] as const;\n\n/**\n * Events that should trigger role data refresh\n */\nexport const ROLE_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n] as const;\n\n/**\n * Events that should trigger permission data refresh\n */\nexport const PERMISSION_REFRESH_EVENTS = [\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n] as const;\n","import axios, { type AxiosError } from 'axios';\nimport type { VerifyTokenResponse, UserAccessData, AuthApiResponse } from '../types/exguard-types';\nimport { getExGuardApiUrl, getAuthToken, EXGUARD_STORAGE_KEYS } from '../config/exguard-config';\n\n// Create a separate axios instance for Guard API endpoints\n// Note: baseURL is set dynamically in the interceptor to support runtime configuration\nconst guardApiClient = axios.create({\n withCredentials: true,\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n\n// Add interceptor to dynamically set baseURL and include access token\nguardApiClient.interceptors.request.use(\n (config) => {\n // Set baseURL dynamically from config (supports runtime configuration)\n config.baseURL = getExGuardApiUrl();\n \n const token = getAuthToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error: unknown) => Promise.reject(error instanceof Error ? error : new Error(String(error))),\n);\n\n/**\n * Verify ID token with ExGuard backend\n */\nexport async function verifyToken(): Promise<VerifyTokenResponse> {\n try {\n const idToken = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ID_TOKEN);\n const response = await guardApiClient.post<\n AuthApiResponse<{\n user?: {\n id: string;\n username: string;\n email: string;\n givenName: string;\n familyName: string;\n };\n }>\n >('/guard/verify-token', {\n id_token: idToken,\n });\n\n if (response.data.success && response.data.data) {\n // Map backend response to frontend format\n const backendData = response.data.data;\n const mappedResponse: VerifyTokenResponse = {\n valid: true,\n user: backendData.user\n ? {\n userId: backendData.user.id,\n username: backendData.user.username,\n email: backendData.user.email,\n givenName: backendData.user.givenName,\n familyName: backendData.user.familyName,\n }\n : undefined,\n };\n return mappedResponse;\n }\n\n throw new Error(response.data.message ?? 'Token verification failed');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Token verification failed';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n\n/**\n * Flag to ensure User Access Data is logged only once\n */\nlet hasLoggedUserAccess = false;\n\n/**\n * Get user access data including roles, permissions, modules, and field offices\n */\nexport async function getUserAccess(): Promise<UserAccessData> {\n try {\n const response = await guardApiClient.get<AuthApiResponse<UserAccessData>>('/guard/me');\n\n if (response.data.success && response.data.data) {\n if (!hasLoggedUserAccess) {\n console.log('User Access Data:', response.data.data);\n hasLoggedUserAccess = true;\n }\n\n return response.data.data;\n }\n\n throw new Error(response.data.message ?? 'Failed to get user access data');\n } catch (error) {\n const axiosError = error as AxiosError<AuthApiResponse<never>>;\n\n if (axiosError.response?.data) {\n const errorData = axiosError.response.data;\n const errorMessage = errorData.message ?? 'Failed to get user access data';\n throw new Error(errorMessage);\n }\n\n throw error;\n }\n}\n","/**\n * ExGuard Realtime Context\n *\n * Context for managing realtime RBAC connections and state\n */\n\nimport { createContext } from 'react';\n\nexport interface ExGuardRealtimeContextType {\n isConnected: boolean;\n connect: (token: string, userId: string) => Promise<void>;\n disconnect: () => void;\n reconnect: () => Promise<void>;\n refreshRbac: () => Promise<void>;\n registerRbacRefreshCallback: (callback: () => Promise<void>) => () => void;\n}\n\nexport const ExGuardRealtimeContext = createContext<ExGuardRealtimeContextType | undefined>(undefined);\n","import { useEffect, useState, useCallback, use } from 'react';\r\nimport { getUserAccess } from '../api/exguard-api';\r\nimport type { UserAccessData, ModulePermissions } from '../types/exguard-types';\r\nimport { ExGuardRealtimeContext } from '../providers/exguard-realtime-context';\r\n\r\ninterface UseUserAccessOptions {\r\n enabled?: boolean;\r\n refetchInterval?: number;\r\n}\r\n\r\n/**\r\n * Custom hook to fetch and manage user access data with RBAC\r\n * Includes caching and periodic refetching for real-time RBAC\r\n */\r\nexport const useUserAccess = (options: UseUserAccessOptions = {}) => {\r\n const { enabled = true, refetchInterval = 0 } = options;\r\n const [userAccess, setUserAccess] = useState<UserAccessData | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n const realtimeContext = use(ExGuardRealtimeContext);\r\n\r\n const fetchUserAccess = useCallback(async (silent = false): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n // Only set loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(true);\r\n }\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error('Failed to fetch user access');\r\n setError(errorObj);\r\n } finally {\r\n // Only clear loading state if not silent refresh\r\n if (!silent) {\r\n setIsLoading(false);\r\n }\r\n }\r\n }, [enabled]);\r\n\r\n // Register for real-time RBAC updates from the realtime provider\r\n useEffect(() => {\r\n if (!realtimeContext) {\r\n return;\r\n }\r\n\r\n // Use silent refresh for realtime updates to prevent UI disruption\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(() => fetchUserAccess(true));\r\n\r\n return () => {\r\n unsubscribe();\r\n };\r\n }, [realtimeContext, fetchUserAccess]);\r\n\r\n useEffect(() => {\r\n void fetchUserAccess();\r\n\r\n if (refetchInterval > 0) {\r\n const interval = setInterval(() => {\r\n void fetchUserAccess();\r\n }, refetchInterval);\r\n\r\n return () => {\r\n clearInterval(interval);\r\n };\r\n }\r\n }, [fetchUserAccess, refetchInterval]);\r\n\r\n const hasModuleAccess = useCallback(\r\n (moduleKey: string): boolean => {\r\n if (!userAccess) return false;\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return !!module && module.permissions.length > 0;\r\n },\r\n [userAccess],\r\n );\r\n\r\n const getModulePermissions = useCallback(\r\n (moduleKey: string): string[] => {\r\n if (!userAccess) return [];\r\n const module = userAccess.modules.find((m: ModulePermissions) => m.key.toLowerCase() === moduleKey.toLowerCase());\r\n return module?.permissions ?? [];\r\n },\r\n [userAccess],\r\n );\r\n\r\n const hasPermission = useCallback(\r\n (moduleKey: string, permission: string): boolean => {\r\n const permissions = getModulePermissions(moduleKey);\r\n return permissions.includes(permission);\r\n },\r\n [getModulePermissions],\r\n );\r\n\r\n return {\r\n userAccess,\r\n isLoading,\r\n error,\r\n hasModuleAccess,\r\n getModulePermissions,\r\n hasPermission,\r\n refetch: fetchUserAccess,\r\n refetchSilent: () => fetchUserAccess(true),\r\n };\r\n};\r\n","import React from 'react';\r\n\r\ninterface SpinnerProps {\r\n className?: string;\r\n}\r\n\r\nexport function Spinner({ className = '' }: SpinnerProps) {\r\n return (\r\n <div\r\n className={`animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${className}`}\r\n role=\"status\"\r\n >\r\n <span className=\"!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]\">\r\n Loading...\r\n </span>\r\n </div>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n variant?: 'default' | 'outline' | 'destructive' | 'ghost' | 'link';\r\n size?: 'default' | 'sm' | 'lg' | 'icon';\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Button({\r\n className = '',\r\n variant = 'default',\r\n size = 'default',\r\n children,\r\n ...props\r\n}: ButtonProps) {\r\n const baseStyles =\r\n 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50';\r\n\r\n const variantStyles = {\r\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\r\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\r\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\r\n ghost: 'hover:bg-accent hover:text-accent-foreground',\r\n link: 'text-primary underline-offset-4 hover:underline',\r\n };\r\n\r\n const sizeStyles = {\r\n default: 'h-10 px-4 py-2',\r\n sm: 'h-9 rounded-md px-3',\r\n lg: 'h-11 rounded-md px-8',\r\n icon: 'h-10 w-10',\r\n };\r\n\r\n return (\r\n <button\r\n className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}\r\n","import React from 'react';\r\n\r\ninterface CardProps extends React.HTMLAttributes<HTMLDivElement> {\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport function Card({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div\r\n className={`rounded-lg border bg-card text-card-foreground shadow-sm ${className}`}\r\n {...props}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardHeader({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex flex-col space-y-1.5 p-6 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardTitle({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <h3 className={`text-2xl font-semibold leading-none tracking-tight ${className}`} {...props}>\r\n {children}\r\n </h3>\r\n );\r\n}\r\n\r\nexport function CardDescription({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <p className={`text-sm text-muted-foreground ${className}`} {...props}>\r\n {children}\r\n </p>\r\n );\r\n}\r\n\r\nexport function CardContent({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n\r\nexport function CardFooter({ className = '', children, ...props }: CardProps) {\r\n return (\r\n <div className={`flex items-center p-6 pt-0 ${className}`} {...props}>\r\n {children}\r\n </div>\r\n );\r\n}\r\n","import { Navigate, Outlet } from 'react-router';\r\nimport { useUserAccess } from '../hooks/use-user-access';\r\nimport { Spinner } from './ui/spinner';\r\nimport { Button } from './ui/button';\r\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card';\r\nimport { ArrowLeft, ShieldAlert, Lock } from 'lucide-react';\r\n\r\ninterface PermissionGuardProps {\r\n module: string;\r\n permission?: string;\r\n requireModule?: boolean;\r\n requirePermission?: boolean;\r\n fallbackPath?: string;\r\n}\r\n\r\n/**\r\n * PermissionGuard component that checks if user has required module access and/or permissions\r\n *\r\n * @param module - The module key (e.g., 'EXID', 'EXFLOW', 'TEV')\r\n * @param permission - Optional specific permission to check (e.g., 'profile:create', 'profile:update')\r\n * @param requireModule - Whether to require module access (default: true)\r\n * @param requirePermission - Whether to require the specific permission (default: true if permission is provided)\r\n * @param fallbackPath - Path to redirect to if access is denied (default: show error page)\r\n */\r\nexport function PermissionGuard({\r\n module,\r\n permission,\r\n requireModule = true,\r\n requirePermission = true,\r\n fallbackPath,\r\n}: PermissionGuardProps) {\r\n const { isLoading, hasModuleAccess, hasPermission } = useUserAccess();\r\n\r\n // Show loading spinner while checking permissions\r\n if (isLoading) {\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[400px]\">\r\n <Spinner className=\"size-8\" />\r\n </div>\r\n );\r\n }\r\n\r\n // Check module access\r\n const hasModule = hasModuleAccess(module);\r\n const moduleCheckFailed = requireModule && !hasModule;\r\n\r\n // Check specific permission if provided\r\n const hasSpecificPermission = permission ? hasPermission(module, permission) : true;\r\n const permissionCheckFailed = permission && requirePermission && !hasSpecificPermission;\r\n\r\n // Determine if access should be denied\r\n const accessDenied = moduleCheckFailed || permissionCheckFailed;\r\n\r\n // Redirect to fallback path if provided\r\n if (accessDenied && fallbackPath) {\r\n return <Navigate to={fallbackPath} replace />;\r\n }\r\n\r\n // Show access denied message\r\n if (accessDenied) {\r\n const denialReason = moduleCheckFailed\r\n ? {\r\n title: 'Module Access Required',\r\n description: `Access to the ${module} module is required to view this page`,\r\n detail: `Your current account permissions do not include access to the ${module} module. This module may be restricted to specific roles or user groups.`,\r\n }\r\n : {\r\n title: 'Permission Required',\r\n description: `The permission \"${permission ?? 'unknown'}\" is needed to access this resource`,\r\n detail: `Your account has access to the ${module} module but lacks the specific permission required for this action. This permission may need to be assigned to your role or user group.`,\r\n };\r\n\r\n return (\r\n <div className=\"flex items-center justify-center min-h-[calc(100vh-4rem)] p-6\">\r\n <Card className=\"w-full max-w-lg\">\r\n <CardHeader className=\"text-center pb-4\">\r\n <div className=\"mx-auto mb-4 flex size-16 items-center justify-center rounded-full bg-destructive/10\">\r\n {moduleCheckFailed ? (\r\n <Lock className=\"size-8 text-destructive\" />\r\n ) : (\r\n <ShieldAlert className=\"size-8 text-destructive\" />\r\n )}\r\n </div>\r\n <CardTitle className=\"text-2xl\">{denialReason.title}</CardTitle>\r\n <CardDescription className=\"text-base\">{denialReason.description}</CardDescription>\r\n </CardHeader>\r\n <CardContent className=\"space-y-4\">\r\n <div className=\"rounded-lg bg-muted p-4\">\r\n <p className=\"text-sm text-muted-foreground\">{denialReason.detail}</p>\r\n </div>\r\n <div className=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n window.history.back();\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n <ArrowLeft className=\"mr-2 size-4\" />\r\n Go Back\r\n </Button>\r\n <Button\r\n variant=\"default\"\r\n onClick={() => {\r\n window.location.href = '/';\r\n }}\r\n className=\"w-full sm:w-auto\"\r\n >\r\n Return to Dashboard\r\n </Button>\r\n </div>\r\n </CardContent>\r\n </Card>\r\n </div>\r\n );\r\n }\r\n\r\n // User has required access, render child routes\r\n return <Outlet />;\r\n}\r\n","import { io, type Socket } from 'socket.io-client';\nimport type { RealtimeEventPayload, RealtimeEventType, RealtimeEventHandler } from './realtime.types';\nimport { getExGuardApiUrl } from '../config/exguard-config';\n\nclass RealtimeClient {\n private socket: Socket | null = null;\n private listeners = new Map<string, Set<RealtimeEventHandler>>();\n private isConnected = false;\n private debug = false; // Enable/disable debug logging\n private connectionPromise: Promise<void> | null = null;\n\n constructor() {\n this.log('đŸŸĸ RealtimeClient initialized');\n }\n \n private getApiUrl(): string {\n return getExGuardApiUrl();\n }\n\n private log(message: string, data?: unknown) {\n if (this.debug) {\n console.log(`[RealtimeClient] ${message}`, data);\n }\n }\n\n private logError(message: string, error?: unknown) {\n console.error(`[RealtimeClient] ${message}`, error);\n }\n\n private logWarn(message: string, data?: unknown) {\n console.warn(`[RealtimeClient] ${message}`, data);\n }\n\n /**\n * Connect to the realtime server\n */\n connect(token: string, userId: string): Promise<void> {\n // Validate inputs\n if (!token) {\n this.logError('❌ Cannot connect - token is missing or empty');\n return Promise.reject(new Error('Missing authentication token'));\n }\n\n if (!userId) {\n this.logError('❌ Cannot connect - userId is missing or empty');\n return Promise.reject(new Error('Missing userId'));\n }\n\n // Return existing connection promise if already connecting\n if (this.connectionPromise) {\n this.log('âŗ Connection already in progress, returning existing promise');\n return this.connectionPromise;\n }\n\n this.connectionPromise = new Promise((resolve, reject) => {\n try {\n const apiUrl = this.getApiUrl();\n this.log('🔌 Attempting to connect...', { apiUrl, userId, hasToken: !!token });\n\n if (this.socket?.connected) {\n this.log('✅ Already connected');\n this.connectionPromise = null;\n resolve();\n return;\n }\n\n const socketUrl = `${apiUrl}/realtime`;\n this.log('🚀 Creating Socket.IO connection', {\n url: socketUrl,\n transports: ['websocket', 'polling'],\n userId,\n });\n\n this.socket = io(socketUrl, {\n auth: {\n token,\n userId,\n },\n transports: ['websocket', 'polling'],\n reconnection: true,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n reconnectionAttempts: 5,\n });\n\n this.socket.on('connect', () => {\n this.isConnected = true;\n this.log('✅ Connected to realtime server', {\n socketId: this.socket?.id,\n userId,\n });\n this.connectionPromise = null;\n resolve();\n });\n\n this.socket.on('disconnect', (reason: string) => {\n this.isConnected = false;\n this.log('❌ Disconnected from realtime server', { reason });\n });\n\n this.socket.on('connect_error', (error: unknown) => {\n this.logError('❌ Connection error (check token and backend)', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection error: ${errorMessage}`));\n });\n\n this.socket.on('error', (error: unknown) => {\n this.logError('❌ Realtime error', error);\n this.connectionPromise = null;\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Socket.IO error: ${errorMessage}`));\n });\n\n this.socket.on('reconnect_attempt', () => {\n this.log('🔄 Attempting to reconnect...');\n });\n\n this.socket.on('reconnect', () => {\n this.isConnected = true;\n this.log('🔁 Reconnected to realtime server', {\n socketId: this.socket?.id,\n });\n });\n\n this.socket.on('reconnect_failed', () => {\n this.logError('❌ Reconnection failed after maximum attempts');\n this.connectionPromise = null;\n reject(new Error('Reconnection failed'));\n });\n\n // Listen to all realtime events\n this.socket.onAny((eventName: string, payload: unknown) => {\n // Debug: log raw event for troubleshooting\n this.log(`📨 Raw event received`, {\n eventName,\n payloadType: typeof payload,\n payload,\n });\n\n // Normalize payload - backend sends event name separately from payload\n const payloadObj =\n typeof payload === 'object' && payload !== null ? (payload as Record<string, unknown>) : {};\n\n // CRITICAL FIX: Use eventName as the primary event type (e.g., 'user:access-changed')\n // Socket.IO sends the event name as the first parameter, not nested in payload.type\n const eventType = eventName;\n\n const normalizedPayload: RealtimeEventPayload = {\n type: eventType as RealtimeEventType,\n timestamp:\n 'timestamp' in payloadObj\n ? typeof payloadObj.timestamp === 'number'\n ? payloadObj.timestamp\n : new Date(payloadObj.timestamp as string).getTime()\n : Date.now(),\n data: 'data' in payloadObj ? payloadObj.data : payload,\n };\n\n this.log(`📨 Event processed: ${eventType}`, {\n type: normalizedPayload.type,\n timestamp: normalizedPayload.timestamp,\n dataKeys:\n typeof normalizedPayload.data === 'object' && normalizedPayload.data !== null\n ? Object.keys(normalizedPayload.data as Record<string, unknown>)\n : 'N/A',\n });\n this.handleEvent(eventType as RealtimeEventType, normalizedPayload);\n });\n } catch (error) {\n this.logError('Failed to initialize connection', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Connection initialization failed: ${errorMessage}`));\n }\n });\n\n return this.connectionPromise;\n }\n\n /**\n * Disconnect from the realtime server\n */\n disconnect(): void {\n this.log('🔌 Disconnecting from realtime server...');\n if (this.socket) {\n this.socket.disconnect();\n this.socket = null;\n this.isConnected = false;\n this.log('✅ Disconnected');\n }\n }\n\n /**\n * Check if connected\n */\n getIsConnected(): boolean {\n return this.isConnected && this.socket?.connected === true;\n }\n\n /**\n * Wait for connection to be ready (with timeout)\n */\n async waitForConnection(timeoutMs = 30000): Promise<void> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (this.getIsConnected()) {\n this.log('✅ Connection ready');\n return;\n }\n\n // Wait 100ms before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n this.logError('❌ Timeout waiting for connection', { timeoutMs, elapsed: Date.now() - startTime });\n throw new Error('Connection timeout - failed to establish WebSocket connection');\n }\n\n /**\n * Subscribe to a specific event type\n */\n subscribe<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n ): () => void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set());\n }\n\n this.listeners.get(eventType)?.add(handler as RealtimeEventHandler);\n const listenerCount = this.listeners.get(eventType)?.size ?? 0;\n this.log(`📌 Subscribed to event: ${eventType}`, { totalListeners: listenerCount });\n\n // Return unsubscribe function\n return () => {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler as RealtimeEventHandler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n };\n }\n\n /**\n * Unsubscribe from an event\n */\n unsubscribe(eventType: RealtimeEventType, handler: RealtimeEventHandler): void {\n const handlers = this.listeners.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n this.log(`📍 Unsubscribed from event: ${eventType}`, {\n remainingListeners: handlers.size,\n });\n }\n }\n /**\n * Send a subscription message to the server with connection wait\n */\n async subscribeToChannel(channel: 'roles' | 'permissions' | 'rbac'): Promise<void> {\n try {\n this.log(`📡 Subscribing to channel: ${channel}`);\n\n // Wait for connection to be ready\n await this.waitForConnection(15000);\n\n // Now emit subscribe\n this.log(`📡 Emitting subscribe event for channel: ${channel}`);\n this.socket?.emit(`subscribe:${channel}`);\n this.log(`✅ Subscribed to channel: ${channel}`);\n } catch (error) {\n this.logError(`❌ Failed to subscribe to channel \"${channel}\"`, error);\n throw error;\n }\n }\n\n /**\n * Send an unsubscription message to the server\n */\n unsubscribeFromChannel(channel: 'roles' | 'permissions' | 'rbac'): void {\n if (!this.socket?.connected) {\n this.logWarn(`Cannot unsubscribe from channel \"${channel}\" - socket not connected`);\n return;\n }\n\n this.log(`📡 Unsubscribing from channel: ${channel}`);\n this.socket.emit(`unsubscribe:${channel}`);\n }\n\n /**\n * Handle incoming events\n */\n private handleEvent(eventType: RealtimeEventType, payload: RealtimeEventPayload): void {\n // Call specific event handlers\n const handlers = this.listeners.get(eventType);\n if (handlers && handlers.size > 0) {\n this.log(`🔔 Triggering ${String(handlers.size)} handler(s) for event: ${eventType}`);\n handlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError(`Error in event handler for ${eventType}`, error);\n }\n });\n }\n\n // Call wildcard handlers if any\n const wildcardHandlers = this.listeners.get('*' as RealtimeEventType);\n if (wildcardHandlers && wildcardHandlers.size > 0) {\n this.log(`🔔 Triggering ${String(wildcardHandlers.size)} wildcard handler(s)`);\n wildcardHandlers.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n this.logError('Error in wildcard event handler', error);\n }\n });\n }\n }\n\n /**\n * Get all connected listeners count\n */\n getListenerCount(eventType?: RealtimeEventType): number {\n if (eventType) {\n return this.listeners.get(eventType)?.size ?? 0;\n }\n let total = 0;\n this.listeners.forEach((handlers) => {\n total += handlers.size;\n });\n return total;\n }\n\n /**\n * Enable or disable debug logging\n */\n setDebug(enabled: boolean): void {\n this.debug = enabled;\n this.log(`Debug logging ${enabled ? 'enabled' : 'disabled'}`);\n }\n\n /**\n * Get connection status summary\n */\n getStatus() {\n const status = {\n isConnected: this.getIsConnected(),\n socketId: this.socket?.id ?? 'N/A',\n apiUrl: this.getApiUrl(),\n totalListeners: this.getListenerCount(),\n listeners: Array.from(this.listeners.entries()).map(([event, handlers]) => ({\n event,\n count: handlers.size,\n })),\n };\n this.log('📊 Connection Status', status);\n return status;\n }\n}\n\n// Create singleton instance\nexport const realtimeClient = new RealtimeClient();\n\n// Expose debug methods on window for console access\nif (typeof window !== 'undefined') {\n const w = window as unknown as Record<string, unknown>;\n w.__realtimeClient = {\n client: realtimeClient,\n connect: (token: string, userId: string) => realtimeClient.connect(token, userId),\n disconnect: () => {\n realtimeClient.disconnect();\n },\n isConnected: () => realtimeClient.getIsConnected(),\n setDebug: (enabled: boolean) => {\n realtimeClient.setDebug(enabled);\n },\n status: () => realtimeClient.getStatus(),\n getListenerCount: (eventType?: RealtimeEventType) => realtimeClient.getListenerCount(eventType),\n };\n\n}\n\nexport type { RealtimeClient };\n","/**\n * Shared Realtime Hooks\n *\n * Basic hooks for realtime functionality that wraps the realtime-client\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport type { RealtimeEventType, RealtimeEventPayload, RealtimeEventHandler } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to realtime RBAC events\n * Automatically handles subscription/unsubscription lifecycle\n */\nexport function useRealtimeRbac<T extends RealtimeEventPayload = RealtimeEventPayload>(\n eventType: RealtimeEventType,\n handler: RealtimeEventHandler<T>,\n) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe<T>(eventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, [eventType]);\n}\n\n/**\n * Hook to manage channel subscriptions\n */\nexport function useRealtimeSubscription(channel: 'roles' | 'permissions' | 'rbac') {\n useEffect(() => {\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch(() => {\n // Silent error handling\n });\n\n return () => {\n realtimeClient.unsubscribeFromChannel(channel);\n };\n }, [channel]);\n}\n\n/**\n * Hook to listen to multiple event types\n */\nexport function useRealtimeMultiple(\n events: {\n type: RealtimeEventType;\n handler: RealtimeEventHandler;\n }[],\n) {\n useEffect(() => {\n const unsubscribers = events.map(({ type, handler }) => realtimeClient.subscribe(type, handler));\n\n return () => {\n unsubscribers.forEach((unsub) => {\n unsub();\n });\n };\n }, [events]);\n}\n\n/**\n * Hook to listen to all realtime events\n */\nexport function useRealtimeAll(handler: RealtimeEventHandler) {\n const handlerRef = useRef(handler);\n\n useEffect(() => {\n handlerRef.current = handler;\n }, [handler]);\n\n useEffect(() => {\n const unsubscribe = realtimeClient.subscribe('*' as RealtimeEventType, (payload) => {\n handlerRef.current(payload);\n });\n\n return () => {\n unsubscribe();\n };\n }, []);\n}\n\n/**\n * Hook to get the connection status\n */\nexport function useRealtimeStatus() {\n const [isConnected, setIsConnected] = useState(realtimeClient.getIsConnected());\n\n useEffect(() => {\n const checkConnection = () => {\n setIsConnected(realtimeClient.getIsConnected());\n };\n\n const interval = setInterval(checkConnection, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n return { isConnected };\n}\n","/**\n * Hook to use ExGuard Realtime Context\n */\n\nimport { use } from 'react';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\n\n/**\n * Hook to access ExGuard realtime context\n * Must be used within ExGuardRealtimeProvider\n */\nexport function useExGuardRealtime(): ExGuardRealtimeContextType {\n const context = use(ExGuardRealtimeContext);\n if (!context) {\n throw new Error('useExGuardRealtime must be used within a ExGuardRealtimeProvider');\n }\n return context;\n}\n","/**\n * ExGuard Realtime RBAC Hooks\n *\n * Custom hooks for handling ExGuard-specific realtime RBAC events\n */\n\nimport { useCallback } from 'react';\nimport { useRealtimeRbac, useRealtimeSubscription } from './use-realtime';\nimport { useExGuardRealtime } from '../providers/use-exguard-realtime';\nimport { EXGUARD_RBAC_CHANNELS, EXGUARD_RBAC_EVENTS, RBAC_RECONNECT_DELAY } from '../config/realtime-rbac-config';\nimport type { RealtimeEventPayload } from '../lib/realtime.types';\n\n/**\n * Hook to subscribe to all ExGuard RBAC channels\n */\nexport function useExGuardRbacChannels() {\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.RBAC);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.ROLES);\n useRealtimeSubscription(EXGUARD_RBAC_CHANNELS.PERMISSIONS);\n}\n\n/**\n * Hook to handle role updates with automatic reconnection\n */\nexport function useRoleUpdateHandler(onUpdate: () => Promise<void>, fetchUserAccess?: () => Promise<void>) {\n const { reconnect } = useExGuardRealtime();\n\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n try {\n await reconnect();\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n } catch (error) {\n // Silent error handling\n }\n })();\n },\n [reconnect, onUpdate, fetchUserAccess],\n ),\n );\n}\n\n/**\n * Hook to handle user RBAC updates (role assignments, permissions, etc.)\n */\nexport function useUserRbacUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle permission updates\n */\nexport function usePermissionUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle group updates\n */\nexport function useGroupUpdateHandler(onUpdate: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onUpdate();\n })();\n },\n [onUpdate],\n ),\n );\n}\n\n/**\n * Hook to handle user access changes (personal notifications)\n * This is for individual user notifications received via user:{cognitoSubId} room\n */\nexport function useUserAccessChangeHandler(onAccessChange: () => Promise<void>) {\n return useRealtimeRbac(\n EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED,\n useCallback(\n (_payload: RealtimeEventPayload) => {\n void (async () => {\n await onAccessChange();\n })();\n },\n [onAccessChange],\n ),\n );\n}\n","/**\n * ExGuard Realtime Utilities\n *\n * Utility functions for ExGuard realtime functionality\n */\n\nimport { getUserAccess } from '../api/exguard-api';\n\n/**\n * Get current user's Cognito Sub ID from backend\n * This is used for websocket room identification (user:{cognitoSubId})\n */\nexport async function getCurrentUserId(): Promise<string | null> {\n try {\n const userAccess = await getUserAccess();\n \n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n return null;\n }\n}\n","/**\n * ExGuard Realtime Provider\n *\n * Provider for managing realtime RBAC connections and events\n */\n\nimport React, { useEffect, useRef, type ReactNode } from 'react';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { ExGuardRealtimeContext, type ExGuardRealtimeContextType } from './exguard-realtime-context';\nimport { getCurrentUserId } from '../utils/exguard-realtime-utils';\nimport type { UserRbacEventPayload } from '../lib/realtime.types';\n\ninterface ExGuardRealtimeProviderProps {\n children: ReactNode;\n}\n\nexport function ExGuardRealtimeProvider({ children }: ExGuardRealtimeProviderProps) {\n const [isConnected, setIsConnected] = React.useState(false);\n const connectionAttempted = useRef(false);\n const rbacRefreshCallbacks = useRef<Set<() => Promise<void>>>(new Set());\n const currentUserRef = useRef<{ token: string; userId: string } | null>(null);\n const currentUserIdRef = useRef<string | null>(null);\n\n // Register callback to refresh user access\n const registerRbacRefreshCallback = (callback: () => Promise<void>) => {\n rbacRefreshCallbacks.current.add(callback);\n return () => {\n rbacRefreshCallbacks.current.delete(callback);\n };\n };\n\n // Trigger refresh for all registered callbacks\n const triggerRbacRefresh = async (): Promise<void> => {\n \n if (rbacRefreshCallbacks.current.size === 0) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No RBAC refresh callbacks registered!');\n return;\n }\n\n const refreshPromises = Array.from(rbacRefreshCallbacks.current).map((cb, index) => {\n return cb().catch((err: unknown) => {\n console.error(`[ExGuardRealtimeProvider] ❌ Error during RBAC refresh callback ${String(index + 1)}:`, err);\n });\n });\n\n await Promise.all(refreshPromises);\n };\n\n // Manual reconnect function\n const handleReconnect = async (): Promise<void> => {\n if (!currentUserRef.current) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No user credentials available for reconnect');\n return;\n }\n const { token, userId } = currentUserRef.current;\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n // Fetch user info from backend and connect\n const initializeConnection = async (): Promise<void> => {\n const accessToken = localStorage.getItem('access_token');\n\n if (!accessToken) {\n console.warn('[ExGuardRealtimeProvider] âš ī¸ No access token found in localStorage');\n return;\n }\n\n // Prevent duplicate connections\n if (connectionAttempted.current) {\n console.log('[ExGuardRealtimeProvider] â„šī¸ Connection already attempted, skipping');\n return;\n }\n\n connectionAttempted.current = true;\n\n try {\n const userId = await getCurrentUserId();\n\n if (!userId) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to get userId from backend');\n connectionAttempted.current = false; // Reset to allow retry\n return;\n }\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n setIsConnected(true);\n\n // Listen ONLY for THIS USER's access changes (sent to user:{userId} room)\n realtimeClient.subscribe('user:access-changed', (_payload: UserRbacEventPayload): void => {\n // No need to check userId - if this event reached our room (user:{cognitoSubId}),\n // it's definitely for us. Backend ensures correct room targeting.\n void triggerRbacRefresh();\n });\n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to establish realtime connection:');\n const errorMessage = error instanceof Error ? error.message : String(error);\n const tokenStr = accessToken ? accessToken.substring(0, 20) + '...' : '';\n console.error('[ExGuardRealtimeProvider] Error details:', {\n message: errorMessage,\n token: tokenStr,\n });\n setIsConnected(false);\n connectionAttempted.current = false; // Reset to allow retry\n }\n };\n\n // Listen for storage events (when tokens are added/changed in other tabs or after login)\n const handleStorageChange = (e: StorageEvent) => {\n if (e.key === 'access_token' && e.newValue && !connectionAttempted.current) {\n console.log('[ExGuardRealtimeProvider] 🔑 Access token detected, initializing connection');\n void initializeConnection();\n }\n };\n\n // Listen for custom event dispatched after login in the same tab\n const handleTokenUpdate = () => {\n console.log('[ExGuardRealtimeProvider] 🔑 Token update event received, initializing connection');\n void initializeConnection();\n };\n\n // Try to connect on mount if token already exists\n void initializeConnection();\n\n // Listen for token changes\n window.addEventListener('storage', handleStorageChange);\n window.addEventListener('exguard:token-updated', handleTokenUpdate);\n\n // Monitor connection status\n let lastConnectedState = realtimeClient.getIsConnected();\n const interval = setInterval(() => {\n const currentConnectedState = realtimeClient.getIsConnected();\n if (currentConnectedState !== lastConnectedState) {\n lastConnectedState = currentConnectedState;\n setIsConnected(currentConnectedState);\n }\n }, 1000);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener('storage', handleStorageChange);\n window.removeEventListener('exguard:token-updated', handleTokenUpdate);\n };\n }, []);\n\n const handleConnect = async (token: string, userId: string) => {\n try {\n \n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n \n } catch (error: unknown) {\n console.error('[ExGuardRealtimeProvider] ❌ Failed to connect to realtime:', error);\n setIsConnected(false);\n throw error;\n }\n };\n\n const handleDisconnect = () => {\n \n realtimeClient.disconnect();\n setIsConnected(false);\n };\n\n const value: ExGuardRealtimeContextType = {\n isConnected,\n connect: handleConnect,\n disconnect: handleDisconnect,\n reconnect: handleReconnect,\n refreshRbac: handleRefreshRbac,\n registerRbacRefreshCallback,\n };\n\n return <ExGuardRealtimeContext value={value}>{children}</ExGuardRealtimeContext>;\n}\n","/**\n * ExGuard Realtime Subscription Hook\n *\n * Hook to subscribe to realtime channels and handle RBAC events\n */\n\nimport { useEffect } from 'react';\nimport { useExGuardRealtime } from './use-exguard-realtime';\nimport { realtimeClient } from '../lib/realtime-client';\nimport { EXGUARD_RBAC_EVENTS, EXGUARD_RBAC_CHANNELS } from '../config/realtime-rbac-config';\nimport type { RealtimeEventType } from '../lib/realtime.types';\n\ninterface UseExGuardRealtimeSubscriptionOptions {\n /** Event types to subscribe to. If not provided, subscribes to all RBAC events */\n events?: RealtimeEventType[];\n /** Whether to auto-subscribe on mount */\n autoSubscribe?: boolean;\n}\n\n/**\n * Hook to subscribe to ExGuard realtime channel and handle RBAC updates\n * @param channel - Channel name ('rbac', 'roles', 'permissions')\n * @param options - Subscription options\n */\nexport function useExGuardRealtimeSubscription(\n channel: keyof typeof EXGUARD_RBAC_CHANNELS = 'RBAC',\n options: UseExGuardRealtimeSubscriptionOptions = {},\n): void {\n const { registerRbacRefreshCallback } = useExGuardRealtime();\n const { autoSubscribe = true, events } = options;\n const channelName = EXGUARD_RBAC_CHANNELS[channel];\n\n useEffect(() => {\n if (!autoSubscribe) {\n return;\n }\n\n // Subscribe to channel on server\n void realtimeClient.subscribeToChannel(channelName);\n\n // If specific events provided, subscribe to them\n if (events && events.length > 0) {\n const unsubscribers: (() => void)[] = [];\n\n events.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }\n\n // Default: subscribe to all RBAC events\n const defaultRbacEvents: RealtimeEventType[] = [\n EXGUARD_RBAC_EVENTS.ROLE_CREATED,\n EXGUARD_RBAC_EVENTS.ROLE_UPDATED,\n EXGUARD_RBAC_EVENTS.ROLE_DELETED,\n EXGUARD_RBAC_EVENTS.PERMISSION_CREATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED,\n EXGUARD_RBAC_EVENTS.PERMISSION_DELETED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_ASSIGNED,\n EXGUARD_RBAC_EVENTS.ROLE_PERMISSION_REMOVED,\n EXGUARD_RBAC_EVENTS.USER_ONLINE,\n EXGUARD_RBAC_EVENTS.GROUP_UPDATED,\n ];\n\n const unsubscribers: (() => void)[] = [];\n\n defaultRbacEvents.forEach((eventType) => {\n const unsubscribe = realtimeClient.subscribe(eventType, (): void => {\n \n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n \n return Promise.resolve();\n });\n\n return () => {\n \n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n unregisterCallback();\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }, [channelName, autoSubscribe, events, registerRbacRefreshCallback]);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exguard-client",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"