npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

exguard-client

v1.0.41

Published

ExGuard RBAC client with realtime WebSocket support for EmpowerX applications

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

Installation

pnpm add exguard-client

Automated Setup (Recommended)

Run the setup command to automatically configure your project:

pnpm exec exguard-setup

This will:

  • ✅ Create src/features/exguard/ module structure
  • ✅ Update protected-route.tsx to wrap <Outlet /> with ExGuardRealtimeProvider
  • ✅ Update auth-utils.ts with 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-client

Quick 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)

  1. Manual Configuration: setExGuardConfig({ apiUrl: '...' })
  2. Environment Variables:
    • Vite: VITE_GUARD_APP_URL
    • Next.js: NEXT_PUBLIC_GUARD_APP_URL
    • Window: window.__EXGUARD_API_URL__
  3. Auto-Detection:
    • localhost/127.0.0.1 → http://localhost:3000
    • Other domains → ${protocol}//${hostname}/api

Authentication Token

Automatically reads from:

  1. Custom getter if provided via setExGuardConfig
  2. localStorage.getItem('access_token')
  3. 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-changed event
  • Set refetchInterval > 0 to force periodic refetches

Methods:

  • hasModuleAccess(moduleKey: string): boolean - Check if user has access to a module
  • hasPermission(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 more

EXGUARD_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_TOKEN

Types

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.com

Next.js

NEXT_PUBLIC_GUARD_APP_URL=https://your-exguard-api.com

Or set it programmatically using setExGuardConfig().

Storage

ExGuard uses localStorage for token management:

  • access_token - Access token for API authentication
  • id_token - ID token for user verification
  • refresh_token - Refresh token for token renewal

License

MIT

Support

For issues or questions, please contact the EmpowerX development team.