exguard-client
v1.0.41
Published
ExGuard RBAC client with realtime WebSocket support for EmpowerX applications
Maintainers
Readme
exguard-client
ExGuard RBAC (Role-Based Access Control) client library with realtime WebSocket support for EmpowerX applications.
📦 Public Package: Available on npm for easy integration into React applications.
Features
- 🔐 RBAC Authentication: Token verification and user access management
- 🔄 Realtime Updates: WebSocket-based real-time RBAC changes
- 🎯 Permission Guards: React components for route and feature protection
- 🪝 React Hooks: Easy-to-use hooks for permission checking
- 📦 TypeScript: Full type safety with TypeScript definitions
- ⚡ Auto-Configuration: Automatically detects API URL based on environment
- 🚀 Zero Setup: Works out of the box with sensible defaults
- 💾 Smart Caching: Caches user access data for 5 minutes, auto-invalidates on permission changes
Documentation
- FRONTEND_INTEGRATION_GUIDE.md - Step-by-step integration guide (START HERE)
- PAGE_IMPLEMENTATION_GUIDE.md - Advanced page protection patterns
- IMPLEMENTATION_GUIDE.md - Technical implementation details
Installation
pnpm add exguard-clientAutomated Setup (Recommended)
Run the setup command to automatically configure your project:
pnpm exec exguard-setupThis will:
- ✅ Create
src/features/exguard/module structure - ✅ Update
protected-route.tsxto wrap<Outlet />withExGuardRealtimeProvider - ✅ Update
auth-utils.tswith token event dispatch
Result in your protected-route.tsx:
return (
<ExGuardRealtimeProvider>
<Outlet />
</ExGuardRealtimeProvider>
);Then skip to Step 3 in FRONTEND_INTEGRATION_GUIDE.md!
Peer Dependencies
Make sure you have the required peer dependencies installed:
pnpm add react react-dom react-router axios socket.io-clientQuick Start
1. Add Provider to Protected Route
In your protected-route.tsx:
import { ExGuardRealtimeProvider } from '@/features/exguard';
return (
<ExGuardRealtimeProvider>
<Outlet />
</ExGuardRealtimeProvider>
);That's it! The package automatically:
- Connects to ExGuard WebSocket when user is authenticated
- Detects API URL based on your hostname (localhost → http://localhost:3000, production → https://yourdomain.com/api)
- Reads auth tokens from localStorage/sessionStorage
- Provides RBAC context to all protected routes
2. Use Permission Guards
import { PermissionGuard } from '@/features/exguard';
<PermissionGuard module="EXID">
<ProfilesPage />
</PermissionGuard>3. Check Permissions in Components
import { useUserAccess } from '@/features/exguard';
function MyComponent() {
const { hasModuleAccess, hasPermission } = useUserAccess();
return (
<div>
{hasModuleAccess('EXID') && <div>EXID Module</div>}
{hasPermission('EXID', 'profile:create') && <button>Create</button>}
</div>
);
}4. Caching (Automatic)
The package automatically caches /guard/me responses for 5 minutes to reduce API calls:
- Single API Call: First call fetches data, subsequent calls use cache
- Auto-Invalidation: Cache clears automatically when permissions change via WebSocket
- No Manual Management: Works out of the box
Manual Cache Control (if needed):
import { useUserAccessSingleton } from '@/features/exguard';
function MyComponent() {
const { refetch, invalidateCache, isLoading } = useUserAccessSingleton();
// Force refetch (bypasses cache)
const handleRefresh = async () => {
await refetch(true);
};
// Manual cache bust + refetch
const handleForceRefresh = () => {
invalidateCache();
refetch();
};
}📖 For complete examples and advanced usage, see FRONTEND_INTEGRATION_GUIDE.md
3. Optional: Custom Configuration
Only needed if you want to override defaults:
import { setExGuardConfig, ExGuardRealtimeProvider } from 'exguard-client';
// Optional: Override auto-detection
setExGuardConfig({
apiUrl: 'https://custom-api.example.com',
getAuthToken: () => localStorage.getItem('custom_token_key')
});
<ExGuardRealtimeProvider>
<App />
</ExGuardRealtimeProvider>Auto-Configuration
The package automatically configures itself based on your environment:
API URL Detection (Priority Order)
- Manual Configuration:
setExGuardConfig({ apiUrl: '...' }) - Environment Variables:
- Vite:
VITE_GUARD_APP_URL - Next.js:
NEXT_PUBLIC_GUARD_APP_URL - Window:
window.__EXGUARD_API_URL__
- Vite:
- Auto-Detection:
- localhost/127.0.0.1 →
http://localhost:3000 - Other domains →
${protocol}//${hostname}/api
- localhost/127.0.0.1 →
Authentication Token
Automatically reads from:
- Custom getter if provided via
setExGuardConfig localStorage.getItem('access_token')sessionStorage.getItem('access_token')
4. Use ExGuard Components
import { PermissionGuard, useUserAccess } from '@/features/exguard';
// Route protection
<PermissionGuard module="EXID">
<ProfilesPage />
</PermissionGuard>
// Permission checking
function MyComponent() {
const { hasModuleAccess, hasPermission } = useUserAccess();
return (
<div>
{hasModuleAccess('EXID') && <div>EXID Module</div>}
{hasPermission('EXID', 'profile:create') && <button>Create</button>}
</div>
);
}API Reference
Configuration
setExGuardConfig(config)
Configure the ExGuard API URL and other settings.
import { setExGuardConfig } from 'exguard-client';
setExGuardConfig({
apiUrl: 'https://your-exguard-api.com',
withCredentials: true, // default: true
});Components
ExGuardRealtimeProvider
Provider component that manages WebSocket connections and RBAC state.
<ExGuardRealtimeProvider>
{/* Your app */}
</ExGuardRealtimeProvider>PermissionGuard
Route guard component for RBAC permission checking.
<PermissionGuard
module="EXID" // Required: Module key
permission="profile:create" // Optional: Specific permission
requireModule={true} // Optional: Require module access (default: true)
requirePermission={true} // Optional: Require permission (default: true if permission provided)
fallbackPath="/unauthorized" // Optional: Redirect path on access denied
>
<YourProtectedComponent />
</PermissionGuard>Hooks
useUserAccess(options?)
Hook to fetch and manage user access data with RBAC. Uses singleton pattern with caching.
const {
userAccess, // Full user access data
isLoading, // Loading state
error, // Error state
hasModuleAccess, // Function to check module access
hasPermission, // Function to check specific permission
} = useUserAccess({
enabled: true, // Optional: Enable/disable fetching (default: true)
refetchInterval: 30000, // Optional: Refetch interval in ms (default: 0, uses cache)
});Caching Behavior:
- Caches response for 5 minutes
- Multiple components share the same cached data
- Cache auto-invalidates when WebSocket sends
user:access-changedevent - Set
refetchInterval> 0 to force periodic refetches
Methods:
hasModuleAccess(moduleKey: string): boolean- Check if user has access to a modulehasPermission(moduleKey: string, permission: string): boolean- Check if user has a specific permission
useUserAccessSingleton()
Singleton hook for accessing user access data. Best for components that need user info (e.g., layout, sidebar).
const {
userAccess, // Full user access data
isLoading, // Loading state
isFetching, // Currently fetching (including cache checks)
error, // Error state
refetch, // Function to refetch (accepts force param)
refetchSilent, // Refetch without loading state
invalidateCache, // Manually invalidate cache
} = useUserAccessSingleton();
// Refetch with cache (uses cached data if < 5 min old)
await refetch();
// Force refetch (ignores cache)
await refetch(true);
// Manual cache control
invalidateCache();
await refetch();When to use:
useUserAccessSingleton- Layouts, headers, sidebars (single user context)useUserAccess- Feature components, pages (isolated usage)
useExGuardRealtime()
Hook to access the ExGuard realtime context.
const {
isConnected, // WebSocket connection state
registerRbacRefreshCallback, // Register callback for RBAC updates
} = useExGuardRealtime();useExGuardRealtimeSubscription(eventType, handler)
Hook to subscribe to specific realtime events.
import { useExGuardRealtimeSubscription, EXGUARD_RBAC_EVENTS } from 'exguard-client';
useExGuardRealtimeSubscription(
EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED,
(payload) => {
console.log('Permissions updated:', payload);
// Handle the event
}
);API Functions
verifyToken()
Verify the current ID token with the ExGuard backend.
import { verifyToken } from 'exguard-client';
const result = await verifyToken();
if (result.isValid && result.user) {
console.log('User:', result.user);
}getUserAccess()
Fetch the current user's access data (roles, permissions, modules).
import { getUserAccess } from 'exguard-client';
const userAccess = await getUserAccess();
console.log('Modules:', userAccess.modules);
console.log('Roles:', userAccess.roles);Constants
EXGUARD_RBAC_EVENTS
Constants for ExGuard RBAC event types.
import { EXGUARD_RBAC_EVENTS } from 'exguard-client';
// Available events:
EXGUARD_RBAC_EVENTS.ROLE_CREATED
EXGUARD_RBAC_EVENTS.ROLE_UPDATED
EXGUARD_RBAC_EVENTS.ROLE_DELETED
EXGUARD_RBAC_EVENTS.PERMISSION_CREATED
EXGUARD_RBAC_EVENTS.PERMISSION_UPDATED
EXGUARD_RBAC_EVENTS.PERMISSION_DELETED
EXGUARD_RBAC_EVENTS.USER_ROLES_UPDATED
EXGUARD_RBAC_EVENTS.USER_PERMISSIONS_CHANGED
EXGUARD_RBAC_EVENTS.USER_ACCESS_CHANGED
EXGUARD_RBAC_EVENTS.RBAC_PERMISSIONS_UPDATED
// ... and moreEXGUARD_STORAGE_KEYS
Constants for localStorage keys used by ExGuard.
import { EXGUARD_STORAGE_KEYS } from 'exguard-client';
// Available keys:
EXGUARD_STORAGE_KEYS.ACCESS_TOKEN
EXGUARD_STORAGE_KEYS.ID_TOKEN
EXGUARD_STORAGE_KEYS.REFRESH_TOKENTypes
The package exports all necessary TypeScript types:
import type {
UserAccessData,
ModulePermissions,
UserDetails,
VerifyTokenResponse,
RealtimeEventType,
RealtimeEventPayload,
ExGuardConfig,
} from 'exguard-client';Environment Variables
The package automatically detects environment variables in consuming applications:
Vite
VITE_GUARD_APP_URL=https://your-exguard-api.comNext.js
NEXT_PUBLIC_GUARD_APP_URL=https://your-exguard-api.comOr set it programmatically using setExGuardConfig().
Storage
ExGuard uses localStorage for token management:
access_token- Access token for API authenticationid_token- ID token for user verificationrefresh_token- Refresh token for token renewal
License
MIT
Support
For issues or questions, please contact the EmpowerX development team.
