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

@atlashub/license-validator

v1.0.1

Published

License validator for AtlasHub products - validates JWT licenses signed by AtlasHub License Generator

Readme

@atlashub/license-validator

Validate JWT licenses signed by AtlasHub License Generator. Use this package to protect your CLI tools, npm packages, and Node.js applications with license-based access control.

Installation

npm install @atlashub/license-validator

Quick Start

import { validateLicense, hasFeature } from '@atlashub/license-validator';

const result = validateLicense(process.env.LICENSE_KEY, {
  productId: 'my-cli-tool'
});

if (!result.valid) {
  console.error('License error:', result.error);
  process.exit(1);
}

console.log('Licensed to:', result.license.company);
console.log('Edition:', result.license.edition);
console.log('Expires in:', result.license.daysRemaining, 'days');

API Reference

validateLicense(licenseKey, options)

Validates a license key and returns detailed license information.

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | licenseKey | string \| undefined | The JWT license key to validate | | options.productId | string | (Optional) Expected product ID - validates the audience claim | | options.gracePeriodDays | number | (Optional) Days to allow after expiration (default: 0) |

Returns: ValidationResult

interface ValidationResult {
  valid: boolean;
  license?: License;
  error?: string;
}

interface License {
  company: string;          // Company/tenant identifier
  productId: string;        // Product identifier
  edition: string;          // starter | professional | enterprise
  features: string[];       // Enabled features (or ['*'] for all)
  limits: {
    users: number;
    storage_gb: number;
    api_calls_per_day: number;
  };
  issuedAt: Date;
  expiresAt: Date;
  daysRemaining: number;
  isExpired: boolean;
  isValid: boolean;
}

hasFeature(license, featureName)

Checks if a specific feature is enabled in the license.

import { validateLicense, hasFeature } from '@atlashub/license-validator';

const { license } = validateLicense(licenseKey);

if (hasFeature(license, 'premium')) {
  // Enable premium functionality
}

if (hasFeature(license, 'ai')) {
  // Enable AI features
}

Note: Returns true if features includes '*' (enterprise licenses).

isWithinLimits(license, type, currentUsage)

Checks if usage is within license limits.

import { isWithinLimits } from '@atlashub/license-validator';

if (!isWithinLimits(license, 'users', currentUserCount)) {
  console.error('User limit exceeded');
}

if (!isWithinLimits(license, 'api_calls_per_day', todaysCalls)) {
  console.error('API rate limit exceeded');
}

decodeLicenseUnsafe(licenseKey)

Decodes a license key without signature verification. For debugging only.

import { decodeLicenseUnsafe } from '@atlashub/license-validator';

const payload = decodeLicenseUnsafe(licenseKey);
console.log(payload);
// { sub: 'acme-corp', product_id: 'my-cli', edition: 'professional', ... }

Complete Integration Example

// src/license.ts
import { validateLicense, hasFeature, License } from '@atlashub/license-validator';
import fs from 'fs';
import path from 'path';
import os from 'os';

const PRODUCT_ID = 'my-awesome-cli';

/**
 * Load license from multiple sources
 */
function loadLicenseKey(): string | undefined {
  // 1. Environment variable
  if (process.env.ATLASHUB_LICENSE) {
    return process.env.ATLASHUB_LICENSE;
  }

  // 2. Home directory file
  const homeFile = path.join(os.homedir(), '.atlashub-license');
  if (fs.existsSync(homeFile)) {
    return fs.readFileSync(homeFile, 'utf-8').trim();
  }

  // 3. Current directory file
  if (fs.existsSync('license.key')) {
    return fs.readFileSync('license.key', 'utf-8').trim();
  }

  return undefined;
}

/**
 * Validate license at startup
 */
export function requireLicense(): License {
  const licenseKey = loadLicenseKey();

  const result = validateLicense(licenseKey, {
    productId: PRODUCT_ID,
    gracePeriodDays: 7
  });

  if (!result.valid) {
    console.error('\n╔════════════════════════════════════════╗');
    console.error('║         LICENSE VALIDATION FAILED       ║');
    console.error('╚════════════════════════════════════════╝\n');
    console.error('Error:', result.error);
    console.error('\nTo obtain a license:');
    console.error('  1. Contact: [email protected]');
    console.error('  2. Set via: export ATLASHUB_LICENSE="your-key"');
    console.error('  3. Or save to: ~/.atlashub-license\n');
    process.exit(1);
  }

  const { license } = result;

  // Expiration warning
  if (license.daysRemaining <= 30) {
    console.warn(`\n⚠️  Warning: License expires in ${license.daysRemaining} days!\n`);
  }

  return license;
}

/**
 * Require a specific feature
 */
export function requireFeature(license: License, feature: string): void {
  if (!hasFeature(license, feature)) {
    console.error(`\n❌ Feature "${feature}" is not available in your ${license.edition} license.`);
    console.error('Please upgrade to access this feature.\n');
    process.exit(1);
  }
}

/**
 * Display license info
 */
export function showLicenseInfo(license: License): void {
  console.log('\n┌────────────────────────────────────────┐');
  console.log('│            LICENSE INFORMATION          │');
  console.log('├────────────────────────────────────────┤');
  console.log(`│ Company:    ${license.company.padEnd(26)}│`);
  console.log(`│ Edition:    ${license.edition.padEnd(26)}│`);
  console.log(`│ Features:   ${license.features.join(', ').padEnd(26).slice(0, 26)}│`);
  console.log(`│ Expires:    ${license.expiresAt.toLocaleDateString().padEnd(26)}│`);
  console.log(`│ Remaining:  ${(license.daysRemaining + ' days').padEnd(26)}│`);
  console.log('└────────────────────────────────────────┘\n');
}

Usage in your CLI:

// src/cli.ts
import { requireLicense, requireFeature, showLicenseInfo } from './license';

// Validate at startup
const license = requireLicense();

// Show info
showLicenseInfo(license);

// Check features for specific commands
if (command === 'advanced-export') {
  requireFeature(license, 'export');
  // ... run export
}

if (command === 'ai-assist') {
  requireFeature(license, 'ai');
  // ... run AI features
}

License Editions

| Edition | Features | Typical Limits | |---------|----------|----------------| | Starter | core, basic-reports | 10 users, 5 GB, 1K API/day | | Professional | core, ai, workflows, reports, entra, support | 50 users, 25 GB, 10K API/day | | Enterprise | * (all features) | Unlimited |

Generating Licenses

Licenses are generated using the AtlasHub License Generator (internal tool):

# Generate a professional license for 1 year
license-generator generate \
  --company "acme-corp" \
  --product "my-awesome-cli" \
  --edition professional \
  --days 365

# Generate an enterprise license with custom features
license-generator generate \
  --company "big-corp" \
  --product "my-awesome-cli" \
  --edition enterprise \
  --features "*" \
  --users 1000 \
  --days 730

Security

This package uses RSA-SHA256 asymmetric cryptography:

  • Public key (included): Can only verify signatures
  • Private key (secret): Required to create valid licenses

The public key cannot be used to forge licenses. This is the same security model used by SSL/TLS certificates.

Error Handling

const result = validateLicense(licenseKey, { productId: 'my-cli' });

if (!result.valid) {
  switch (true) {
    case result.error?.includes('No license key'):
      // License not provided
      break;
    case result.error?.includes('expired'):
      // License has expired
      console.log('Expired on:', result.license?.expiresAt);
      break;
    case result.error?.includes('Invalid license'):
      // Signature verification failed (tampered or wrong key)
      break;
    default:
      // Other error
      console.error(result.error);
  }
}

TypeScript Support

Full TypeScript support with exported types:

import type {
  License,
  LicenseLimits,
  ValidationResult,
  ValidateOptions
} from '@atlashub/license-validator';

License

MIT - Free to use in commercial and open-source projects.

Support