@eventcatalog/license
v0.0.7
Published
License verification for EventCatalog
Downloads
15,131
Maintainers
Readme
@eventcatalog/license
License verification library for EventCatalog supporting both offline JWT verification and online license key validation.
Features
- Dual verification modes - Offline JWT tokens and online license keys
- Ed25519 signatures - Using industry-standard elliptic curve cryptography for offline verification
- JWT-based offline licensing - Standard token format with custom EventCatalog claims
- Online license key validation - Real-time verification with EventCatalog API
- Input validation - Secure license key format validation
- Caching - Verification results cached for performance
- Machine binding - Optional fingerprint-based license binding (offline mode)
- Enhanced error handling - Structured error codes for different failure scenarios
- TypeScript - Full type safety and IntelliSense support
Installation
npm install @eventcatalog/licenseQuick Start
Offline JWT Verification
import { verifyOfflineLicense, isFeatureEnabled } from '@eventcatalog/license';
// Verify offline JWT license (auto-locates license file)
try {
const entitlements = await verifyOfflineLicense();
console.log('License valid for:', entitlements.org);
} catch (error) {
console.error('License verification failed:', error.message);
}
// Check if a plugin is enabled
if (isFeatureEnabled('@eventcatalog/generator-asyncapi')) {
console.log('AsyncAPI generator is licensed');
}Online License Key Verification
import { verifyOnlineLicense } from '@eventcatalog/license';
// Verify online license key
try {
const isValid = await verifyOnlineLicense('XXXX-XXXX-XXXX-XXXX-XXXX-XXXX', '@eventcatalog/eventcatalog-scale');
if (isValid) {
console.log('License key is valid');
}
} catch (error) {
console.error('License key verification failed:', error.message);
}API Reference
verifyOfflineLicense(opts?: VerifyOptions): Promise<Entitlements>
Verifies an offline JWT license and returns entitlements. Results are cached after first successful verification.
Options:
licensePath?: string- Custom path to license file (overrides auto-discovery)audience?: string- Expected JWT audience (default: "EventCatalog")issuer?: string- Expected JWT issuer (default: "EventCatalog Ltd")clockTolerance?: string- Clock skew tolerance (default: "12h")currentVersion?: string- EventCatalog version for range validationfingerprintProvider?: () => string | null- Machine fingerprint provider
Example with options:
const entitlements = await verifyOfflineLicense({
licensePath: '/custom/path/license.jwt',
audience: 'MyEventCatalog',
clockTolerance: '24h',
fingerprintProvider: () => getMachineId(),
});verifyOnlineLicense(key: string, plugin: string): Promise<boolean>
Verifies a license key online using the EventCatalog API.
Parameters:
key: string- License key in formatXXXX-XXXX-XXXX-XXXX-XXXX-XXXXplugin: string- Plugin identifier to verify against
Supported plugins:
@eventcatalog/eventcatalog-starter@eventcatalog/eventcatalog-scale@eventcatalog/eventcatalog-enterprise
Example:
const isValid = await verifyOnlineLicense('XXXX-XXXX-XXXX-XXXX-XXXX-XXXX', '@eventcatalog/eventcatalog-scale');isFeatureEnabled(name: string): boolean
Checks if a plugin or feature is enabled in the current license.
// Check string plugin names
if (isFeatureEnabled('@eventcatalog/generator-openapi')) {
// Enable OpenAPI generator
}
// Also works with object-style plugin specs in licensegetEntitlements(): Entitlements | null
Returns currently cached entitlements without re-verification.
const entitlements = getEntitlements();
if (entitlements?.org) {
console.log(`License for: ${entitlements.org}`);
}License Discovery
License files are located in this order:
EC_LICENSEenvironment variable (file path)./license.jwt(current directory)/etc/eventcatalog/license.jwt(system-wide)
Environment Variables
EC_LICENSE
Path to license file (overrides auto-discovery).
export EC_LICENSE="/path/to/my/license.jwt"EC_PUBLIC_KEY_PATH
Path to custom public key PEM file (overrides bundled key).
export EC_PUBLIC_KEY_PATH="/path/to/custom/public.pem"License Format
Licenses are JWT tokens with standard and EventCatalog-specific claims:
Standard Claims:
iss- Issuer ("EventCatalog Ltd")aud- Audience ("EventCatalog")iat- Issued at timestampnbf- Not before timestampexp- Expiration timestamp
EventCatalog Claims:
licenseId- Unique license identifierorg- Organization nameplugins- Enabled plugins arrayfingerprint- Machine binding fingerprint (optional)
Example payload:
{
"iss": "EventCatalog Ltd",
"aud": "EventCatalog",
"iat": 1672531200,
"nbf": 1672531200,
"exp": 1735689600,
"licenseId": "ec_2025_000001",
"org": "Acme Corp",
"plugins": [
"@eventcatalog/generator-asyncapi",
{
"name": "@eventcatalog/generator-openapi",
"versionRange": "^1.0.0"
}
]
}Offline License Errors
| Error Code | Message | Description |
| ------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------- |
| LICENSE_EXPIRED | License has expired | JWT token past expiration time |
| LICENSE_NOT_YET_VALID | License is not yet valid | JWT token not yet active |
| LICENSE_VALIDATION_FAILED | License validation failed - invalid issuer or audience | JWT claims validation failed |
| LICENSE_SIGNATURE_INVALID | License signature verification failed - invalid or tampered license | Digital signature verification failed |
| LICENSE_FILE_NOT_FOUND | License file not found | No license file found in discovery locations |
| LICENSE_FILE_EMPTY | License file is empty | License file exists but contains no content |
| LICENSE_FINGERPRINT_MISMATCH | License fingerprint mismatch - license is bound to a different machine | Machine binding violation |
Online License Errors
| Error Code | Message | Description |
| ---------------------------- | -------------------------------------------------------------------------- | ----------------------------------------- |
| INVALID_LICENSE_KEY_FORMAT | Invalid license key format. Expected format: XXXX-XXXX-XXXX-XXXX-XXXX-XXXX | License key doesn't match required format |
Building
# Install dependencies
npm install
# Build TypeScript
npm run build
# The compiled package will be in ./dist/Development
The package structure:
eventcatalog-license/
├── src/
│ ├── index.ts # Public API exports
│ ├── types.ts # TypeScript type definitions
│ ├── key.ts # Public key loading & validation
│ └── verify.ts # Verification logic (offline & online)
├── assets/
│ └── ec-ed25519-public.pem # Public key for offline verification
└── dist/ # Compiled outputTesting License Verification
Offline JWT Testing
Create a test license file:
echo "your.jwt.token.here" > license.jwtTest programmatically:
import { verifyOfflineLicense } from '@eventcatalog/license'; try { const entitlements = await verifyOfflineLicense(); console.log('✓ Valid license:', entitlements); } catch (error) { console.error('✗ Invalid license:', error.message); }
Online License Key Testing
import { verifyOnlineLicense } from '@eventcatalog/license';
try {
const isValid = await verifyOnlineLicense('XXXX-XXXX-XXXX-XXXX-XXXX-XXXX', '@eventcatalog/eventcatalog-scale');
console.log('✓ License key valid:', isValid);
} catch (error) {
console.error('✗ License key invalid:', error.message);
}License
MIT
