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

@empowerx/exguard-api

v1.2.0

Published

ExGuard Backend Authorization Package - Auto-configurable JWT-based access control with comprehensive decorators and user permission data access for Node.js APIs

Readme

ExGuard RBAC Backend - EmpowerX

🛡️ Auto-configurable JWT-based access control for Node.js APIs with simplified permission management.

🚀 Features

  • Simplified Setup - Only requires EXGUARD_API_URL to get started
  • Auto-Configuration - Generates framework-specific files automatically
  • Optional JWT Verification - Skip JWT verification and rely on your ExGuard API
  • Role-Based Access Control (RBAC) - Check user permissions and roles
  • Framework Agnostic - Works with Express, NestJS, Fastify, and more
  • Built-in Caching - Reduce API calls with configurable TTL cache
  • Module-Based Permissions - Organize permissions by functional modules
  • Field Office Support - Handle regional/office-based access control
  • TypeScript Support - Full type definitions included

📦 Installation

# Install with pnpm (recommended)
pnpm add @empowerx/exguard-api

# Install with npm
npm install @empowerx/exguard-api

# Install with yarn
yarn add @empowerx/exguard-api

🚀 Quick Setup (Auto-Configuration)

Method 1: Automatic Setup (Recommended)

The package includes an automatic setup script that runs during installation:

# Install package (auto-setup runs automatically)
pnpm add @empowerx/exguard-api

What happens automatically:

  • ✅ Detects your framework (NestJS, Express, etc.)
  • ✅ Creates .env.example with required environment variables
  • ✅ Generates framework-specific configuration files
  • ✅ Adds exguard:setup script to your package.json
  • ✅ Configures app.module.ts for NestJS projects

Method 2: Manual Setup (If auto-setup doesn't run)

If the automatic setup doesn't execute, run it manually:

# First time setup (adds exguard:setup script to package.json)
node node_modules/@empowerx/exguard-api/scripts/setup.js

# Or use the convenient script after first setup
pnpm exguard:setup

Method 3: Alternative Package Managers

# For npm
npm install @empowerx/exguard-api
npm run exguard:setup

# For yarn
yarn add @empowerx/exguard-api
yarn exguard:setup

📋 Environment Configuration

Create a .env file from the generated .env.example:

# Required
EXGUARD_API_URL=http://localhost:3001

# JWT Configuration (Optional - for local verification)
# JWT_SECRET=your-jwt-secret-here
# JWKS_URI=https://cognito-idp.region.amazonaws.com/your-user-pool/.well-known/jwks.json
# JWT_ISSUER=https://cognito-idp.region.amazonaws.com/your-user-pool
# JWT_AUDIENCE=your-client-id

🛠️ Framework Implementation

NestJS Implementation ⭐ Recommended

After running the setup script, you'll have generated files in src/exguard/:

1. Import ExGuard Module

// src/app.module.ts
import { Module } from '@nestjs/common';
import { ExGuardModule } from './exguard';

@Module({
  imports: [
    ExGuardModule.forRoot({
      exguardApiUrl: process.env.EXGUARD_API_URL,
      skipJwtVerification: true,
      cacheEnabled: true,
      cacheTtl: 300,
    }),
    // ... other modules
  ],
})
export class AppModule {}

2. Use Guards in Controllers

// src/roles/roles.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { ExGuardGuard, PermissionsGuard, RequirePermissions } from '../exguard';

@Controller('roles')
@UseGuards(ExGuardGuard, PermissionsGuard)
export class RolesController {
  
  @Get()
  @RequirePermissions({ module: 'exGUARD', action: 'roles:view_role_list' })
  async findAll() {
    // Your controller logic
    return { roles: [] };
  }

  @Get(':id')
  @RequirePermissions({ module: 'exGUARD', action: 'roles:view_role_details' })
  async findOne(@Param('id') id: string) {
    // Your controller logic
    return { role: null };
  }
}

3. Access User Information

// In any controller method
@Get('profile')
async getProfile(@Request() req) {
  // User info is automatically attached by ExGuardGuard
  return {
    user: req.user,
    permissions: req.user.modules,
    roles: req.user.roles,
    fieldOffices: req.user.fieldOffices,
  };
}

Express.js Implementation

After running the setup script, you'll have generated middleware in src/middleware/:

1. Use Middleware in Your App

// src/app.js
const express = require('express');
const { exGuardMiddleware, requirePermission } = require('./middleware/exguard.middleware');

const app = express();

// Apply ExGuard authentication middleware
app.use('/api', exGuardMiddleware());

// Your routes with permission checks
app.get('/api/roles', requirePermission('exGUARD', 'roles:view_role_list'), (req, res) => {
  res.json({ roles: [] });
});

app.get('/api/users', requirePermission('exGUARD', 'users:view_user_list'), (req, res) => {
  res.json({ users: [] });
});

2. Access User Information

// User info is attached to request by exGuardMiddleware
app.get('/api/profile', (req, res) => {
  res.json({
    user: req.user,
    permissions: req.user.modules,
    roles: req.user.roles,
  });
});

🔐 API Reference

ExGuardService

Constructor

new ExGuardService(config: ExGuardConfig)

Configuration Options:

// exguard.config.js
module.exports = {
  // API Configuration - REQUIRED
  exguardApiUrl: process.env.EXGUARD_API_URL || 'http://localhost:3001',
  
  // Optional JWT Configuration
  jwtSecret: process.env.JWT_SECRET,
  jwksUri: process.env.JWKS_URI,
  issuer: process.env.JWT_ISSUER,
  audience: process.env.JWT_AUDIENCE,
  
  // Cache Configuration
  cacheEnabled: true,
  cacheTtl: 300, // 5 minutes
  
  // Skip JWT verification (recommended for simplified setup)
  skipJwtVerification: true,
};

Core Methods

getUserAccess(accessToken: string): Promise<UserAccess | null>

Get complete user access data including roles, permissions, and groups.

const userAccess = await exGuard.getUserAccess(access_token);

if (userAccess) {
  console.log('User:', userAccess.user);
  console.log('Roles:', userAccess.roles);
  console.log('Groups:', userAccess.groups);
  console.log('Modules:', userAccess.modules);
  console.log('Field Offices:', userAccess.fieldOffices);
}

hasPermission(accessToken: string, permission: PermissionCheck): Promise<boolean>

Check if user has a specific permission.

const canViewRoles = await exGuard.hasPermission(access_token, {
  module: 'exGUARD',
  action: 'roles:view_role_list'
});

if (canViewRoles) {
  // Allow access
} else {
  // Deny access
}

isInRole(accessToken: string, role: string): Promise<boolean>

Check if user has a specific role.

const isAdmin = await exGuard.isInRole(access_token, 'Administrator');

isInGroup(accessToken: string, group: string): Promise<boolean>

Check if user belongs to a specific group.

const isInManagement = await exGuard.isInGroup(access_token, 'Management');

getFieldOffices(accessToken: string): Promise<string[]>

Get user's assigned field offices.

const fieldOffices = await exGuard.getFieldOffices(access_token);
console.log('User can access offices:', fieldOffices);

📊 Data Models

UserAccess

interface UserAccess {
  user: {
    id: string;
    cognitoSubId: string;
    username: string | null;
    email: string | null;
    emailVerified: boolean;
    givenName: string | null;
    familyName: string | null;
    employeeNumber: string | null;
    regionId: string | null;
    createdAt: string;
    updatedAt: string;
    lastLoginAt: string;
    fieldOffice?: FieldOffice | null;
  };
  groups: string[];
  roles: string[];
  modules: ModulePermission[];
  fieldOffices: string[];
}

ModulePermission

interface ModulePermission {
  key: string;
  name: string;
  permissions: string[];
}

PermissionCheck

interface PermissionCheck {
  module: string;
  action: string;
}

🔄 Caching

The package includes built-in caching to reduce API calls:

const exGuard = new ExGuardService({
  exguardApiUrl: 'https://your-exguard-api.com',
  cacheEnabled: true,
  cacheTtl: 300 // Cache for 5 minutes
});

// First call - hits API
const userAccess1 = await exGuard.getUserAccess(token);

// Second call within 5 minutes - uses cache
const userAccess2 = await exGuard.getUserAccess(token);

🚨 Error Handling

const exGuard = new ExGuardService({
  exguardApiUrl: 'https://your-exguard-api.com',
  onUnauthorized: (error) => {
    console.error('Access denied:', error.message);
    // Redirect to login or handle error
  }
});

try {
  const userAccess = await exGuard.getUserAccess(token);
  if (!userAccess) {
    // Handle unauthorized access
  }
} catch (error) {
  console.error('ExGuard error:', error);
}

📝 File Structure After Auto-Setup

NestJS Project

src/
├── exguard/
│   ├── index.ts                 # Main exports
│   ├── exguard.config.ts        # Configuration
│   ├── exguard.module.ts        # NestJS module
│   ├── exguard.guard.ts         # Authentication guard
│   ├── permissions.guard.ts     # Permission checking guard
│   └── permission.decorator.ts  # Permission decorator
├── app.module.ts                # Import ExGuardModule here
└── your.controllers.ts          # Use guards and decorators

Express Project

src/
├── middleware/
│   └── exguard.middleware.js    # Express middleware
├── app.js                       # Use middleware here
└── routes/                      # Apply permission checks

🎯 Best Practices

  1. Use Auto-Setup - Run pnpm exguard:setup for automatic configuration
  2. Environment Variables - Keep sensitive data in .env files
  3. Permission Naming - Use consistent naming: module:action format
  4. Error Handling - Implement proper error responses for unauthorized access
  5. Caching - Enable caching for better performance
  6. Field Office Access - Use field office permissions for regional access control

📝 License

MIT License - see LICENSE file for details.

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📞 Support

For issues and questions:

  • Create an issue on GitHub
  • Check the troubleshooting section
  • Review the API documentation

🚀 Get started in seconds with pnpm exguard:setup!