exguard-client 1.0.0 โ†’ 1.0.1

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @empowerx/exguard-client
1
+ # exguard-client
2
2
 
3
3
  ExGuard RBAC (Role-Based Access Control) client library with realtime WebSocket support for EmpowerX applications.
4
4
 
@@ -14,7 +14,7 @@ ExGuard RBAC (Role-Based Access Control) client library with realtime WebSocket
14
14
  ## Installation
15
15
 
16
16
  ```bash
17
- pnpm add @empowerx/exguard-client
17
+ pnpm add exguard-client
18
18
  ```
19
19
 
20
20
  ### Peer Dependencies
@@ -51,7 +51,7 @@ import { PermissionGuard, useUserAccess } from '@/features/exguard';
51
51
 
52
52
  Or import directly from the package:
53
53
  ```tsx
54
- import { PermissionGuard, useUserAccess } from '@empowerx/exguard-client';
54
+ import { PermissionGuard, useUserAccess } from 'exguard-client';
55
55
  ```
56
56
 
57
57
  ## Quick Start
@@ -59,7 +59,7 @@ import { PermissionGuard, useUserAccess } from '@empowerx/exguard-client';
59
59
  ### 1. Install the Package
60
60
 
61
61
  ```bash
62
- pnpm add @empowerx/exguard-client
62
+ pnpm add exguard-client
63
63
  ```
64
64
 
65
65
  ### 2. Generate ExGuard Module (Recommended)
@@ -131,7 +131,7 @@ function MyComponent() {
131
131
  Configure the ExGuard API URL and other settings.
132
132
 
133
133
  ```tsx
134
- import { setExGuardConfig } from '@empowerx/exguard-client';
134
+ import { setExGuardConfig } from 'exguard-client';
135
135
 
136
136
  setExGuardConfig({
137
137
  apiUrl: 'https://your-exguard-api.com',
@@ -207,7 +207,7 @@ const {
207
207
  Hook to subscribe to specific realtime events.
208
208
 
209
209
  ```tsx
210
- import { useExGuardRealtimeSubscription, EXGUARD_RBAC_EVENTS } from '@empowerx/exguard-client';
210
+ import { useExGuardRealtimeSubscription, EXGUARD_RBAC_EVENTS } from 'exguard-client';
211
211
 
212
212
  useExGuardRealtimeSubscription(
213
213
  EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED,
@@ -225,7 +225,7 @@ useExGuardRealtimeSubscription(
225
225
  Verify the current ID token with the ExGuard backend.
226
226
 
227
227
  ```tsx
228
- import { verifyToken } from '@empowerx/exguard-client';
228
+ import { verifyToken } from 'exguard-client';
229
229
 
230
230
  const result = await verifyToken();
231
231
  if (result.isValid && result.user) {
@@ -238,7 +238,7 @@ if (result.isValid && result.user) {
238
238
  Fetch the current user's access data (roles, permissions, modules).
239
239
 
240
240
  ```tsx
241
- import { getUserAccess } from '@empowerx/exguard-client';
241
+ import { getUserAccess } from 'exguard-client';
242
242
 
243
243
  const userAccess = await getUserAccess();
244
244
  console.log('Modules:', userAccess.modules);
@@ -252,7 +252,7 @@ console.log('Roles:', userAccess.roles);
252
252
  Constants for ExGuard RBAC event types.
253
253
 
254
254
  ```tsx
255
- import { EXGUARD_RBAC_EVENTS } from '@empowerx/exguard-client';
255
+ import { EXGUARD_RBAC_EVENTS } from 'exguard-client';
256
256
 
257
257
  // Available events:
258
258
  EXGUARD_RBAC_EVENTS.ROLE_CREATED
@@ -273,7 +273,7 @@ EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED
273
273
  Constants for localStorage keys used by ExGuard.
274
274
 
275
275
  ```tsx
276
- import { EXGUARD_STORAGE_KEYS } from '@empowerx/exguard-client';
276
+ import { EXGUARD_STORAGE_KEYS } from 'exguard-client';
277
277
 
278
278
  // Available keys:
279
279
  EXGUARD_STORAGE_KEYS.ACCESS_TOKEN
@@ -294,7 +294,7 @@ import type {
294
294
  RealtimeEventType,
295
295
  RealtimeEventPayload,
296
296
  ExGuardConfig,
297
- } from '@empowerx/exguard-client';
297
+ } from 'exguard-client';
298
298
  ```
299
299
 
300
300
  ## Environment Variables
package/dist/index.cjs CHANGED
@@ -101,7 +101,6 @@ var RBAC_RECONNECT_DELAY = 300;
101
101
  EXGUARD_RBAC_EVENTS.PERMISSION_DELETED
102
102
  ];
103
103
  var guardApiClient = axios__default.default.create({
104
- baseURL: getExGuardApiUrl(),
105
104
  withCredentials: true,
106
105
  headers: {
107
106
  "Content-Type": "application/json"
@@ -109,6 +108,7 @@ var guardApiClient = axios__default.default.create({
109
108
  });
110
109
  guardApiClient.interceptors.request.use(
111
110
  (config) => {
111
+ config.baseURL = getExGuardApiUrl();
112
112
  const token = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN);
113
113
  if (token) {
114
114
  config.headers.Authorization = `Bearer ${token}`;
@@ -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\nconst guardApiClient = axios.create({\n baseURL: getExGuardApiUrl(),\n withCredentials: true,\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n\n// Add interceptor to include access token in Guard API requests\nguardApiClient.interceptors.request.use(\n (config) => {\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 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"]}
package/dist/index.js CHANGED
@@ -94,7 +94,6 @@ var RBAC_RECONNECT_DELAY = 300;
94
94
  EXGUARD_RBAC_EVENTS.PERMISSION_DELETED
95
95
  ];
96
96
  var guardApiClient = axios.create({
97
- baseURL: getExGuardApiUrl(),
98
97
  withCredentials: true,
99
98
  headers: {
100
99
  "Content-Type": "application/json"
@@ -102,6 +101,7 @@ var guardApiClient = axios.create({
102
101
  });
103
102
  guardApiClient.interceptors.request.use(
104
103
  (config) => {
104
+ config.baseURL = getExGuardApiUrl();
105
105
  const token = window.localStorage.getItem(EXGUARD_STORAGE_KEYS.ACCESS_TOKEN);
106
106
  if (token) {
107
107
  config.headers.Authorization = `Bearer ${token}`;
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\nconst guardApiClient = axios.create({\n baseURL: getExGuardApiUrl(),\n withCredentials: true,\n headers: {\n 'Content-Type': 'application/json',\n },\n});\n\n// Add interceptor to include access token in Guard API requests\nguardApiClient.interceptors.request.use(\n (config) => {\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 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exguard-client",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "ExGuard RBAC client with realtime WebSocket support for EmpowerX applications",
6
6
  "main": "./dist/index.js",
@@ -11,9 +11,9 @@
11
11
  },
12
12
  "exports": {
13
13
  ".": {
14
+ "types": "./dist/index.d.ts",
14
15
  "import": "./dist/index.mjs",
15
- "require": "./dist/index.js",
16
- "types": "./dist/index.d.ts"
16
+ "require": "./dist/index.js"
17
17
  }
18
18
  },
19
19
  "files": [