exguard-client 1.0.2 โ 1.0.4
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 +9 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -393,16 +393,17 @@ function PermissionGuard({
|
|
|
393
393
|
return /* @__PURE__ */ jsxRuntime.jsx(reactRouter.Outlet, {});
|
|
394
394
|
}
|
|
395
395
|
var RealtimeClient = class {
|
|
396
|
-
constructor(
|
|
396
|
+
constructor() {
|
|
397
397
|
__publicField(this, "socket", null);
|
|
398
|
-
__publicField(this, "apiUrl");
|
|
399
398
|
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
400
399
|
__publicField(this, "isConnected", false);
|
|
401
400
|
__publicField(this, "debug", true);
|
|
402
401
|
// Enable/disable debug logging
|
|
403
402
|
__publicField(this, "connectionPromise", null);
|
|
404
|
-
this.
|
|
405
|
-
|
|
403
|
+
this.log("\u{1F7E2} RealtimeClient initialized");
|
|
404
|
+
}
|
|
405
|
+
getApiUrl() {
|
|
406
|
+
return getExGuardApiUrl();
|
|
406
407
|
}
|
|
407
408
|
log(message, data) {
|
|
408
409
|
if (this.debug) {
|
|
@@ -433,14 +434,15 @@ var RealtimeClient = class {
|
|
|
433
434
|
}
|
|
434
435
|
this.connectionPromise = new Promise((resolve, reject) => {
|
|
435
436
|
try {
|
|
436
|
-
|
|
437
|
+
const apiUrl = this.getApiUrl();
|
|
438
|
+
this.log("\u{1F50C} Attempting to connect...", { apiUrl, userId, hasToken: !!token });
|
|
437
439
|
if (this.socket?.connected) {
|
|
438
440
|
this.log("\u2705 Already connected");
|
|
439
441
|
this.connectionPromise = null;
|
|
440
442
|
resolve();
|
|
441
443
|
return;
|
|
442
444
|
}
|
|
443
|
-
const socketUrl = `${
|
|
445
|
+
const socketUrl = `${apiUrl}/realtime`;
|
|
444
446
|
this.log("\u{1F680} Creating Socket.IO connection", {
|
|
445
447
|
url: socketUrl,
|
|
446
448
|
transports: ["websocket", "polling"],
|
|
@@ -669,7 +671,7 @@ var RealtimeClient = class {
|
|
|
669
671
|
const status = {
|
|
670
672
|
isConnected: this.getIsConnected(),
|
|
671
673
|
socketId: this.socket?.id ?? "N/A",
|
|
672
|
-
apiUrl: this.
|
|
674
|
+
apiUrl: this.getApiUrl(),
|
|
673
675
|
totalListeners: this.getListenerCount(),
|
|
674
676
|
listeners: Array.from(this.listeners.entries()).map(([event, handlers]) => ({
|
|
675
677
|
event,
|
package/dist/index.cjs.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":["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}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Note: apiUrl should be provided by the consuming application\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL from environment or provided config\r\n * For Vite apps: import.meta.env.VITE_GUARD_APP_URL\r\n * For Next.js: process.env.NEXT_PUBLIC_GUARD_APP_URL\r\n * Or provide via setExGuardConfig()\r\n */\r\nlet configuredApiUrl: string = '';\r\n\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n};\r\n\r\nexport const getExGuardApiUrl = (): string => {\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // Try to get from global environment\r\n if (typeof window !== 'undefined') {\r\n // Check for injected env vars\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 // Fallback to localhost for development\r\n return 'http://localhost:3000';\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, 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 = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN);\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 console.log('Token verification response:', response.data.data);\n\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\n console.log('Mapped user data:', mappedResponse.user);\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 * 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 console.log('User Access Data:', response.data.data);\n console.log('User Details:', response.data.data.user);\n console.log('User Roles:', response.data.data.roles);\n console.log('User Groups:', response.data.data.groups);\n console.log('User Modules:', response.data.data.modules);\n console.log('User Field Offices:', response.data.data.fieldOffices);\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 (): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n console.log('[useUserAccess] ๐ Fetching user access data...');\r\n setIsLoading(true);\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n console.log('[useUserAccess] โ
User access refreshed successfully', {\r\n userId: data.user.id,\r\n username: data.user.username,\r\n modulesCount: data.modules.length,\r\n modules: data.modules.map((m) => m.key),\r\n });\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 console.error('[useUserAccess] โ Failed to fetch user access:', errorObj);\r\n } finally {\r\n setIsLoading(false);\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 console.warn('[useUserAccess] โ ๏ธ RealtimeContext not available');\r\n return;\r\n }\r\n\r\n console.log('[useUserAccess] ๐ก Registering RBAC refresh callback');\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(fetchUserAccess);\r\n console.log('[useUserAccess] โ
RBAC refresh callback registered');\r\n\r\n return () => {\r\n console.log('[useUserAccess] ๐ Unregistering RBAC refresh callback');\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 };\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 readonly apiUrl: string;\n private listeners = new Map<string, Set<RealtimeEventHandler>>();\n private isConnected = false;\n private debug = true; // Enable/disable debug logging\n private connectionPromise: Promise<void> | null = null;\n\n constructor(apiUrl?: string) {\n this.apiUrl = apiUrl ?? getExGuardApiUrl();\n this.log('๐ข RealtimeClient initialized', { apiUrl: this.apiUrl });\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 this.log('๐ Attempting to connect...', { apiUrl: this.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 = `${this.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.apiUrl,\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 console.log('๐ฏ RealtimeClient debug tools available at: window.__realtimeClient');\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 let isMounted = true;\n\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch((error: unknown) => {\n if (isMounted) {\n console.error(`Failed to subscribe to channel \"${channel}\":`, error);\n }\n });\n\n return () => {\n isMounted = false;\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 console.log('[ExGuard] ๐ Role updated:', (payload.data as { id?: string })?.id ?? payload.data);\n\n try {\n console.log('[ExGuard] ๐ Reconnecting after role update...');\n await reconnect();\n console.log('[ExGuard] โ
Reconnected successfully');\n\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n\n console.log('[ExGuard] โ
Data refreshed after role update');\n } catch (error) {\n console.error('[ExGuard] โ Error handling role update:', error);\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 console.log('[ExGuard] ๐ User roles updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
User data refreshed');\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 console.log('[ExGuard] ๐ Permission updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Permission data refreshed');\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 console.log('[ExGuard] ๐ Group updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Group data refreshed');\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 console.log('[ExGuard] ๐ฏ Your access has changed:', payload.data);\n await onAccessChange();\n console.log('[ExGuard] โ
User access refreshed');\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 console.log('[ExGuardRealtimeUtils] ๐ก Fetched user access:', {\n id: userAccess.user.id,\n cognitoSubId: userAccess.user.cognitoSubId,\n email: userAccess.user.email,\n });\n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n console.error('[ExGuardRealtimeUtils] Failed to fetch user:', 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 console.log('[ExGuardRealtimeProvider] ๐ Triggering RBAC refresh for all listeners', {\n callbackCount: rbacRefreshCallbacks.current.size,\n });\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 console.log(\n `[ExGuardRealtimeProvider] ๐ Executing callback ${String(index + 1)}/${String(rbacRefreshCallbacks.current.size)}`,\n );\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 console.log('[ExGuardRealtimeProvider] โ
All RBAC refresh callbacks completed');\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 console.log('[ExGuardRealtimeProvider] ๐ Manual reconnect requested for', { userId });\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n console.log('[ExGuardRealtimeProvider] ๐ Manual RBAC refresh requested');\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n const accessToken = localStorage.getItem('access_token');\n\n console.log('[ExGuardRealtimeProvider] ๐ Checking credentials on mount:', {\n hasAccessToken: Boolean(accessToken),\n tokenLength: accessToken?.length,\n });\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 console.log('[ExGuardRealtimeProvider] ๐ Initiating realtime connection', {\n userId,\n });\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n console.log('[ExGuardRealtimeProvider] โ
Auto-connection successful');\n setIsConnected(true);\n\n // INDIVIDUAL user event listener - NO GLOBAL LISTENERS\n console.log('[ExGuardRealtimeProvider] ๐ง Setting up INDIVIDUAL user notification listener');\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 const { userId: eventUserId, roleId, action } = payload.data;\n console.log('[ExGuardRealtimeProvider] ๐ฏ INDIVIDUAL: Your access has been changed!', {\n eventUserId,\n roleId,\n action,\n currentUserId: currentUserIdRef.current,\n });\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 console.log('[ExGuardRealtimeProvider] โ
Event received in our personal room! Refreshing access...');\n console.log(\n `[ExGuardRealtimeProvider] ๐ข Triggering RBAC refresh for ${String(rbacRefreshCallbacks.current.size)} registered callbacks`,\n );\n void triggerRbacRefresh();\n });\n\n console.log('[ExGuardRealtimeProvider] โ
Individual user event listener registered');\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 console.log('[ExGuardRealtimeProvider] ๐ Connection status changed:', {\n from: lastConnectedState,\n to: currentConnectedState,\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 console.log('[ExGuardRealtimeProvider] ๐ Manual connection requested', { userId });\n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n console.log('[ExGuardRealtimeProvider] โ
Manual connection successful');\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 console.log('[ExGuardRealtimeProvider] ๐ Disconnection requested');\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 console.log(`[useExGuardRealtimeSubscription] ๐ก Subscribing to channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n console.log(`[useExGuardRealtimeSubscription] ๐ RBAC refresh triggered for channel: ${channelName}`);\n return Promise.resolve();\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Note: apiUrl should be provided by the consuming application\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL from environment or provided config\r\n * For Vite apps: import.meta.env.VITE_GUARD_APP_URL\r\n * For Next.js: process.env.NEXT_PUBLIC_GUARD_APP_URL\r\n * Or provide via setExGuardConfig()\r\n */\r\nlet configuredApiUrl: string = '';\r\n\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n};\r\n\r\nexport const getExGuardApiUrl = (): string => {\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // Try to get from global environment\r\n if (typeof window !== 'undefined') {\r\n // Check for injected env vars\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 // Fallback to localhost for development\r\n return 'http://localhost:3000';\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, 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 = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN);\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 console.log('Token verification response:', response.data.data);\n\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\n console.log('Mapped user data:', mappedResponse.user);\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 * 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 console.log('User Access Data:', response.data.data);\n console.log('User Details:', response.data.data.user);\n console.log('User Roles:', response.data.data.roles);\n console.log('User Groups:', response.data.data.groups);\n console.log('User Modules:', response.data.data.modules);\n console.log('User Field Offices:', response.data.data.fieldOffices);\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 (): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n console.log('[useUserAccess] ๐ Fetching user access data...');\r\n setIsLoading(true);\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n console.log('[useUserAccess] โ
User access refreshed successfully', {\r\n userId: data.user.id,\r\n username: data.user.username,\r\n modulesCount: data.modules.length,\r\n modules: data.modules.map((m) => m.key),\r\n });\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 console.error('[useUserAccess] โ Failed to fetch user access:', errorObj);\r\n } finally {\r\n setIsLoading(false);\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 console.warn('[useUserAccess] โ ๏ธ RealtimeContext not available');\r\n return;\r\n }\r\n\r\n console.log('[useUserAccess] ๐ก Registering RBAC refresh callback');\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(fetchUserAccess);\r\n console.log('[useUserAccess] โ
RBAC refresh callback registered');\r\n\r\n return () => {\r\n console.log('[useUserAccess] ๐ Unregistering RBAC refresh callback');\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 };\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 = true; // 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 console.log('๐ฏ RealtimeClient debug tools available at: window.__realtimeClient');\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 let isMounted = true;\n\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch((error: unknown) => {\n if (isMounted) {\n console.error(`Failed to subscribe to channel \"${channel}\":`, error);\n }\n });\n\n return () => {\n isMounted = false;\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 console.log('[ExGuard] ๐ Role updated:', (payload.data as { id?: string })?.id ?? payload.data);\n\n try {\n console.log('[ExGuard] ๐ Reconnecting after role update...');\n await reconnect();\n console.log('[ExGuard] โ
Reconnected successfully');\n\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n\n console.log('[ExGuard] โ
Data refreshed after role update');\n } catch (error) {\n console.error('[ExGuard] โ Error handling role update:', error);\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 console.log('[ExGuard] ๐ User roles updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
User data refreshed');\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 console.log('[ExGuard] ๐ Permission updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Permission data refreshed');\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 console.log('[ExGuard] ๐ Group updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Group data refreshed');\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 console.log('[ExGuard] ๐ฏ Your access has changed:', payload.data);\n await onAccessChange();\n console.log('[ExGuard] โ
User access refreshed');\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 console.log('[ExGuardRealtimeUtils] ๐ก Fetched user access:', {\n id: userAccess.user.id,\n cognitoSubId: userAccess.user.cognitoSubId,\n email: userAccess.user.email,\n });\n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n console.error('[ExGuardRealtimeUtils] Failed to fetch user:', 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 console.log('[ExGuardRealtimeProvider] ๐ Triggering RBAC refresh for all listeners', {\n callbackCount: rbacRefreshCallbacks.current.size,\n });\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 console.log(\n `[ExGuardRealtimeProvider] ๐ Executing callback ${String(index + 1)}/${String(rbacRefreshCallbacks.current.size)}`,\n );\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 console.log('[ExGuardRealtimeProvider] โ
All RBAC refresh callbacks completed');\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 console.log('[ExGuardRealtimeProvider] ๐ Manual reconnect requested for', { userId });\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n console.log('[ExGuardRealtimeProvider] ๐ Manual RBAC refresh requested');\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n const accessToken = localStorage.getItem('access_token');\n\n console.log('[ExGuardRealtimeProvider] ๐ Checking credentials on mount:', {\n hasAccessToken: Boolean(accessToken),\n tokenLength: accessToken?.length,\n });\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 console.log('[ExGuardRealtimeProvider] ๐ Initiating realtime connection', {\n userId,\n });\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n console.log('[ExGuardRealtimeProvider] โ
Auto-connection successful');\n setIsConnected(true);\n\n // INDIVIDUAL user event listener - NO GLOBAL LISTENERS\n console.log('[ExGuardRealtimeProvider] ๐ง Setting up INDIVIDUAL user notification listener');\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 const { userId: eventUserId, roleId, action } = payload.data;\n console.log('[ExGuardRealtimeProvider] ๐ฏ INDIVIDUAL: Your access has been changed!', {\n eventUserId,\n roleId,\n action,\n currentUserId: currentUserIdRef.current,\n });\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 console.log('[ExGuardRealtimeProvider] โ
Event received in our personal room! Refreshing access...');\n console.log(\n `[ExGuardRealtimeProvider] ๐ข Triggering RBAC refresh for ${String(rbacRefreshCallbacks.current.size)} registered callbacks`,\n );\n void triggerRbacRefresh();\n });\n\n console.log('[ExGuardRealtimeProvider] โ
Individual user event listener registered');\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 console.log('[ExGuardRealtimeProvider] ๐ Connection status changed:', {\n from: lastConnectedState,\n to: currentConnectedState,\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 console.log('[ExGuardRealtimeProvider] ๐ Manual connection requested', { userId });\n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n console.log('[ExGuardRealtimeProvider] โ
Manual connection successful');\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 console.log('[ExGuardRealtimeProvider] ๐ Disconnection requested');\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 console.log(`[useExGuardRealtimeSubscription] ๐ก Subscribing to channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n console.log(`[useExGuardRealtimeSubscription] ๐ RBAC refresh triggered for channel: ${channelName}`);\n return Promise.resolve();\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\n unsubscribers.forEach((unsubscribe) => {\n unsubscribe();\n });\n unregisterCallback();\n realtimeClient.unsubscribeFromChannel(channelName);\n };\n }, [channelName, autoSubscribe, events, registerRbacRefreshCallback]);\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -355,12 +355,12 @@ declare function useExGuardRealtimeSubscription(channel?: keyof typeof EXGUARD_R
|
|
|
355
355
|
|
|
356
356
|
declare class RealtimeClient {
|
|
357
357
|
private socket;
|
|
358
|
-
private readonly apiUrl;
|
|
359
358
|
private listeners;
|
|
360
359
|
private isConnected;
|
|
361
360
|
private debug;
|
|
362
361
|
private connectionPromise;
|
|
363
|
-
constructor(
|
|
362
|
+
constructor();
|
|
363
|
+
private getApiUrl;
|
|
364
364
|
private log;
|
|
365
365
|
private logError;
|
|
366
366
|
private logWarn;
|
package/dist/index.d.ts
CHANGED
|
@@ -355,12 +355,12 @@ declare function useExGuardRealtimeSubscription(channel?: keyof typeof EXGUARD_R
|
|
|
355
355
|
|
|
356
356
|
declare class RealtimeClient {
|
|
357
357
|
private socket;
|
|
358
|
-
private readonly apiUrl;
|
|
359
358
|
private listeners;
|
|
360
359
|
private isConnected;
|
|
361
360
|
private debug;
|
|
362
361
|
private connectionPromise;
|
|
363
|
-
constructor(
|
|
362
|
+
constructor();
|
|
363
|
+
private getApiUrl;
|
|
364
364
|
private log;
|
|
365
365
|
private logError;
|
|
366
366
|
private logWarn;
|
package/dist/index.js
CHANGED
|
@@ -386,16 +386,17 @@ function PermissionGuard({
|
|
|
386
386
|
return /* @__PURE__ */ jsx(Outlet, {});
|
|
387
387
|
}
|
|
388
388
|
var RealtimeClient = class {
|
|
389
|
-
constructor(
|
|
389
|
+
constructor() {
|
|
390
390
|
__publicField(this, "socket", null);
|
|
391
|
-
__publicField(this, "apiUrl");
|
|
392
391
|
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
393
392
|
__publicField(this, "isConnected", false);
|
|
394
393
|
__publicField(this, "debug", true);
|
|
395
394
|
// Enable/disable debug logging
|
|
396
395
|
__publicField(this, "connectionPromise", null);
|
|
397
|
-
this.
|
|
398
|
-
|
|
396
|
+
this.log("\u{1F7E2} RealtimeClient initialized");
|
|
397
|
+
}
|
|
398
|
+
getApiUrl() {
|
|
399
|
+
return getExGuardApiUrl();
|
|
399
400
|
}
|
|
400
401
|
log(message, data) {
|
|
401
402
|
if (this.debug) {
|
|
@@ -426,14 +427,15 @@ var RealtimeClient = class {
|
|
|
426
427
|
}
|
|
427
428
|
this.connectionPromise = new Promise((resolve, reject) => {
|
|
428
429
|
try {
|
|
429
|
-
|
|
430
|
+
const apiUrl = this.getApiUrl();
|
|
431
|
+
this.log("\u{1F50C} Attempting to connect...", { apiUrl, userId, hasToken: !!token });
|
|
430
432
|
if (this.socket?.connected) {
|
|
431
433
|
this.log("\u2705 Already connected");
|
|
432
434
|
this.connectionPromise = null;
|
|
433
435
|
resolve();
|
|
434
436
|
return;
|
|
435
437
|
}
|
|
436
|
-
const socketUrl = `${
|
|
438
|
+
const socketUrl = `${apiUrl}/realtime`;
|
|
437
439
|
this.log("\u{1F680} Creating Socket.IO connection", {
|
|
438
440
|
url: socketUrl,
|
|
439
441
|
transports: ["websocket", "polling"],
|
|
@@ -662,7 +664,7 @@ var RealtimeClient = class {
|
|
|
662
664
|
const status = {
|
|
663
665
|
isConnected: this.getIsConnected(),
|
|
664
666
|
socketId: this.socket?.id ?? "N/A",
|
|
665
|
-
apiUrl: this.
|
|
667
|
+
apiUrl: this.getApiUrl(),
|
|
666
668
|
totalListeners: this.getListenerCount(),
|
|
667
669
|
listeners: Array.from(this.listeners.entries()).map(([event, handlers]) => ({
|
|
668
670
|
event,
|
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}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Note: apiUrl should be provided by the consuming application\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL from environment or provided config\r\n * For Vite apps: import.meta.env.VITE_GUARD_APP_URL\r\n * For Next.js: process.env.NEXT_PUBLIC_GUARD_APP_URL\r\n * Or provide via setExGuardConfig()\r\n */\r\nlet configuredApiUrl: string = '';\r\n\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n};\r\n\r\nexport const getExGuardApiUrl = (): string => {\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // Try to get from global environment\r\n if (typeof window !== 'undefined') {\r\n // Check for injected env vars\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 // Fallback to localhost for development\r\n return 'http://localhost:3000';\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, 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 = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN);\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 console.log('Token verification response:', response.data.data);\n\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\n console.log('Mapped user data:', mappedResponse.user);\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 * 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 console.log('User Access Data:', response.data.data);\n console.log('User Details:', response.data.data.user);\n console.log('User Roles:', response.data.data.roles);\n console.log('User Groups:', response.data.data.groups);\n console.log('User Modules:', response.data.data.modules);\n console.log('User Field Offices:', response.data.data.fieldOffices);\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 (): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n console.log('[useUserAccess] ๐ Fetching user access data...');\r\n setIsLoading(true);\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n console.log('[useUserAccess] โ
User access refreshed successfully', {\r\n userId: data.user.id,\r\n username: data.user.username,\r\n modulesCount: data.modules.length,\r\n modules: data.modules.map((m) => m.key),\r\n });\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 console.error('[useUserAccess] โ Failed to fetch user access:', errorObj);\r\n } finally {\r\n setIsLoading(false);\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 console.warn('[useUserAccess] โ ๏ธ RealtimeContext not available');\r\n return;\r\n }\r\n\r\n console.log('[useUserAccess] ๐ก Registering RBAC refresh callback');\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(fetchUserAccess);\r\n console.log('[useUserAccess] โ
RBAC refresh callback registered');\r\n\r\n return () => {\r\n console.log('[useUserAccess] ๐ Unregistering RBAC refresh callback');\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 };\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 readonly apiUrl: string;\n private listeners = new Map<string, Set<RealtimeEventHandler>>();\n private isConnected = false;\n private debug = true; // Enable/disable debug logging\n private connectionPromise: Promise<void> | null = null;\n\n constructor(apiUrl?: string) {\n this.apiUrl = apiUrl ?? getExGuardApiUrl();\n this.log('๐ข RealtimeClient initialized', { apiUrl: this.apiUrl });\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 this.log('๐ Attempting to connect...', { apiUrl: this.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 = `${this.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.apiUrl,\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 console.log('๐ฏ RealtimeClient debug tools available at: window.__realtimeClient');\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 let isMounted = true;\n\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch((error: unknown) => {\n if (isMounted) {\n console.error(`Failed to subscribe to channel \"${channel}\":`, error);\n }\n });\n\n return () => {\n isMounted = false;\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 console.log('[ExGuard] ๐ Role updated:', (payload.data as { id?: string })?.id ?? payload.data);\n\n try {\n console.log('[ExGuard] ๐ Reconnecting after role update...');\n await reconnect();\n console.log('[ExGuard] โ
Reconnected successfully');\n\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n\n console.log('[ExGuard] โ
Data refreshed after role update');\n } catch (error) {\n console.error('[ExGuard] โ Error handling role update:', error);\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 console.log('[ExGuard] ๐ User roles updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
User data refreshed');\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 console.log('[ExGuard] ๐ Permission updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Permission data refreshed');\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 console.log('[ExGuard] ๐ Group updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Group data refreshed');\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 console.log('[ExGuard] ๐ฏ Your access has changed:', payload.data);\n await onAccessChange();\n console.log('[ExGuard] โ
User access refreshed');\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 console.log('[ExGuardRealtimeUtils] ๐ก Fetched user access:', {\n id: userAccess.user.id,\n cognitoSubId: userAccess.user.cognitoSubId,\n email: userAccess.user.email,\n });\n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n console.error('[ExGuardRealtimeUtils] Failed to fetch user:', 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 console.log('[ExGuardRealtimeProvider] ๐ Triggering RBAC refresh for all listeners', {\n callbackCount: rbacRefreshCallbacks.current.size,\n });\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 console.log(\n `[ExGuardRealtimeProvider] ๐ Executing callback ${String(index + 1)}/${String(rbacRefreshCallbacks.current.size)}`,\n );\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 console.log('[ExGuardRealtimeProvider] โ
All RBAC refresh callbacks completed');\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 console.log('[ExGuardRealtimeProvider] ๐ Manual reconnect requested for', { userId });\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n console.log('[ExGuardRealtimeProvider] ๐ Manual RBAC refresh requested');\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n const accessToken = localStorage.getItem('access_token');\n\n console.log('[ExGuardRealtimeProvider] ๐ Checking credentials on mount:', {\n hasAccessToken: Boolean(accessToken),\n tokenLength: accessToken?.length,\n });\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 console.log('[ExGuardRealtimeProvider] ๐ Initiating realtime connection', {\n userId,\n });\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n console.log('[ExGuardRealtimeProvider] โ
Auto-connection successful');\n setIsConnected(true);\n\n // INDIVIDUAL user event listener - NO GLOBAL LISTENERS\n console.log('[ExGuardRealtimeProvider] ๐ง Setting up INDIVIDUAL user notification listener');\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 const { userId: eventUserId, roleId, action } = payload.data;\n console.log('[ExGuardRealtimeProvider] ๐ฏ INDIVIDUAL: Your access has been changed!', {\n eventUserId,\n roleId,\n action,\n currentUserId: currentUserIdRef.current,\n });\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 console.log('[ExGuardRealtimeProvider] โ
Event received in our personal room! Refreshing access...');\n console.log(\n `[ExGuardRealtimeProvider] ๐ข Triggering RBAC refresh for ${String(rbacRefreshCallbacks.current.size)} registered callbacks`,\n );\n void triggerRbacRefresh();\n });\n\n console.log('[ExGuardRealtimeProvider] โ
Individual user event listener registered');\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 console.log('[ExGuardRealtimeProvider] ๐ Connection status changed:', {\n from: lastConnectedState,\n to: currentConnectedState,\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 console.log('[ExGuardRealtimeProvider] ๐ Manual connection requested', { userId });\n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n console.log('[ExGuardRealtimeProvider] โ
Manual connection successful');\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 console.log('[ExGuardRealtimeProvider] ๐ Disconnection requested');\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 console.log(`[useExGuardRealtimeSubscription] ๐ก Subscribing to channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n console.log(`[useExGuardRealtimeSubscription] ๐ RBAC refresh triggered for channel: ${channelName}`);\n return Promise.resolve();\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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}\r\n\r\n/**\r\n * Default ExGuard API configuration\r\n * Note: apiUrl should be provided by the consuming application\r\n */\r\nexport const DEFAULT_EXGUARD_CONFIG: ExGuardConfig = {\r\n apiUrl: '',\r\n withCredentials: true,\r\n};\r\n\r\n/**\r\n * Get ExGuard API URL from environment or provided config\r\n * For Vite apps: import.meta.env.VITE_GUARD_APP_URL\r\n * For Next.js: process.env.NEXT_PUBLIC_GUARD_APP_URL\r\n * Or provide via setExGuardConfig()\r\n */\r\nlet configuredApiUrl: string = '';\r\n\r\nexport const setExGuardConfig = (config: Partial<ExGuardConfig>): void => {\r\n if (config.apiUrl) {\r\n configuredApiUrl = config.apiUrl;\r\n }\r\n};\r\n\r\nexport const getExGuardApiUrl = (): string => {\r\n if (configuredApiUrl) {\r\n return configuredApiUrl;\r\n }\r\n \r\n // Try to get from global environment\r\n if (typeof window !== 'undefined') {\r\n // Check for injected env vars\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 // Fallback to localhost for development\r\n return 'http://localhost:3000';\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, 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 = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN);\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 console.log('Token verification response:', response.data.data);\n\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\n console.log('Mapped user data:', mappedResponse.user);\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 * 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 console.log('User Access Data:', response.data.data);\n console.log('User Details:', response.data.data.user);\n console.log('User Roles:', response.data.data.roles);\n console.log('User Groups:', response.data.data.groups);\n console.log('User Modules:', response.data.data.modules);\n console.log('User Field Offices:', response.data.data.fieldOffices);\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 (): Promise<void> => {\r\n if (!enabled) return;\r\n\r\n try {\r\n console.log('[useUserAccess] ๐ Fetching user access data...');\r\n setIsLoading(true);\r\n setError(null);\r\n const data = await getUserAccess();\r\n setUserAccess(data);\r\n console.log('[useUserAccess] โ
User access refreshed successfully', {\r\n userId: data.user.id,\r\n username: data.user.username,\r\n modulesCount: data.modules.length,\r\n modules: data.modules.map((m) => m.key),\r\n });\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 console.error('[useUserAccess] โ Failed to fetch user access:', errorObj);\r\n } finally {\r\n setIsLoading(false);\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 console.warn('[useUserAccess] โ ๏ธ RealtimeContext not available');\r\n return;\r\n }\r\n\r\n console.log('[useUserAccess] ๐ก Registering RBAC refresh callback');\r\n const unsubscribe = realtimeContext.registerRbacRefreshCallback(fetchUserAccess);\r\n console.log('[useUserAccess] โ
RBAC refresh callback registered');\r\n\r\n return () => {\r\n console.log('[useUserAccess] ๐ Unregistering RBAC refresh callback');\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 };\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 = true; // 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 console.log('๐ฏ RealtimeClient debug tools available at: window.__realtimeClient');\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 let isMounted = true;\n\n // Subscribe asynchronously\n realtimeClient.subscribeToChannel(channel).catch((error: unknown) => {\n if (isMounted) {\n console.error(`Failed to subscribe to channel \"${channel}\":`, error);\n }\n });\n\n return () => {\n isMounted = false;\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 console.log('[ExGuard] ๐ Role updated:', (payload.data as { id?: string })?.id ?? payload.data);\n\n try {\n console.log('[ExGuard] ๐ Reconnecting after role update...');\n await reconnect();\n console.log('[ExGuard] โ
Reconnected successfully');\n\n // Delay to ensure backend has processed\n await new Promise((resolve) => setTimeout(resolve, RBAC_RECONNECT_DELAY));\n\n // Refresh data\n const promises = [onUpdate()];\n if (fetchUserAccess) {\n promises.push(fetchUserAccess());\n }\n await Promise.all(promises);\n\n console.log('[ExGuard] โ
Data refreshed after role update');\n } catch (error) {\n console.error('[ExGuard] โ Error handling role update:', error);\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 console.log('[ExGuard] ๐ User roles updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
User data refreshed');\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 console.log('[ExGuard] ๐ Permission updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Permission data refreshed');\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 console.log('[ExGuard] ๐ Group updated:', payload.data);\n await onUpdate();\n console.log('[ExGuard] โ
Group data refreshed');\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 console.log('[ExGuard] ๐ฏ Your access has changed:', payload.data);\n await onAccessChange();\n console.log('[ExGuard] โ
User access refreshed');\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 console.log('[ExGuardRealtimeUtils] ๐ก Fetched user access:', {\n id: userAccess.user.id,\n cognitoSubId: userAccess.user.cognitoSubId,\n email: userAccess.user.email,\n });\n // CRITICAL: Use cognitoSubId for websocket room targeting, not database UUID\n return userAccess.user.cognitoSubId;\n } catch (error) {\n console.error('[ExGuardRealtimeUtils] Failed to fetch user:', 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 console.log('[ExGuardRealtimeProvider] ๐ Triggering RBAC refresh for all listeners', {\n callbackCount: rbacRefreshCallbacks.current.size,\n });\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 console.log(\n `[ExGuardRealtimeProvider] ๐ Executing callback ${String(index + 1)}/${String(rbacRefreshCallbacks.current.size)}`,\n );\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 console.log('[ExGuardRealtimeProvider] โ
All RBAC refresh callbacks completed');\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 console.log('[ExGuardRealtimeProvider] ๐ Manual reconnect requested for', { userId });\n await handleConnect(token, userId);\n };\n\n // Manual RBAC refresh function\n const handleRefreshRbac = async (): Promise<void> => {\n console.log('[ExGuardRealtimeProvider] ๐ Manual RBAC refresh requested');\n await triggerRbacRefresh();\n };\n\n useEffect(() => {\n const accessToken = localStorage.getItem('access_token');\n\n console.log('[ExGuardRealtimeProvider] ๐ Checking credentials on mount:', {\n hasAccessToken: Boolean(accessToken),\n tokenLength: accessToken?.length,\n });\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 console.log('[ExGuardRealtimeProvider] ๐ Initiating realtime connection', {\n userId,\n });\n\n currentUserRef.current = { token: accessToken, userId };\n currentUserIdRef.current = userId;\n await realtimeClient.connect(accessToken, userId);\n console.log('[ExGuardRealtimeProvider] โ
Auto-connection successful');\n setIsConnected(true);\n\n // INDIVIDUAL user event listener - NO GLOBAL LISTENERS\n console.log('[ExGuardRealtimeProvider] ๐ง Setting up INDIVIDUAL user notification listener');\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 const { userId: eventUserId, roleId, action } = payload.data;\n console.log('[ExGuardRealtimeProvider] ๐ฏ INDIVIDUAL: Your access has been changed!', {\n eventUserId,\n roleId,\n action,\n currentUserId: currentUserIdRef.current,\n });\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 console.log('[ExGuardRealtimeProvider] โ
Event received in our personal room! Refreshing access...');\n console.log(\n `[ExGuardRealtimeProvider] ๐ข Triggering RBAC refresh for ${String(rbacRefreshCallbacks.current.size)} registered callbacks`,\n );\n void triggerRbacRefresh();\n });\n\n console.log('[ExGuardRealtimeProvider] โ
Individual user event listener registered');\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 console.log('[ExGuardRealtimeProvider] ๐ Connection status changed:', {\n from: lastConnectedState,\n to: currentConnectedState,\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 console.log('[ExGuardRealtimeProvider] ๐ Manual connection requested', { userId });\n currentUserRef.current = { token, userId };\n await realtimeClient.connect(token, userId);\n setIsConnected(true);\n console.log('[ExGuardRealtimeProvider] โ
Manual connection successful');\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 console.log('[ExGuardRealtimeProvider] ๐ Disconnection requested');\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 console.log(`[useExGuardRealtimeSubscription] ๐ก Subscribing to channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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 console.log(`[useExGuardRealtimeSubscription] ๐ Received event: ${eventType}`);\n });\n unsubscribers.push(unsubscribe);\n });\n\n // Register callback to trigger RBAC refresh\n const unregisterCallback = registerRbacRefreshCallback(() => {\n console.log(`[useExGuardRealtimeSubscription] ๐ RBAC refresh triggered for channel: ${channelName}`);\n return Promise.resolve();\n });\n\n return () => {\n console.log(`[useExGuardRealtimeSubscription] ๐งน Cleaning up subscriptions for channel: ${channelName}`);\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,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "exguard-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ExGuard RBAC client with realtime WebSocket support for EmpowerX applications",
|
|
6
|
-
"main": "./dist/index.
|
|
7
|
-
"module": "./dist/index.
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"bin": {
|
|
10
10
|
"exguard-setup": "./scripts/setup.js"
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
|
-
"import": "./dist/index.
|
|
16
|
-
"require": "./dist/index.
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"require": "./dist/index.cjs"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"files": [
|