@lazarevic_00/license-sdk
v0.1.0
Published
License validation SDK for NestJS/TypeORM apps - validates against a license-server, blocks the app when the key is invalid or expired.
Maintainers
Readme
@lazarevic_00/license-sdk
License validation for NestJS/TypeORM apps. Validates a license key against a
license-server deployment, tracks its state, and (by
default) blocks every request with 503 while the license is invalid.
Install
npm install @lazarevic_00/license-sdkFor local development against an unpublished/in-progress version, reference it
via file: instead:
"dependencies": {
"@lazarevic_00/license-sdk": "file:../license-sdk-node"
}
file:local testing note: if younpm installinsidelicense-sdk-nodeitself (e.g. to build/typecheck it) and link it into another app viafile:, both projects end up with their own copy of@nestjs/common. SinceHttpExceptionidentity is checked withinstanceof, Nest's built-in exception filter won't recognize exceptions thrown from the SDK's copy and falls back to a generic500instead of the guard's real503. This only happens with localfile:links during development - a realnpm install @lazarevic_00/license-sdkfrom a published package never hits this, since peer dependencies resolve to the host app's own copy. If you do need to test viafile:, run the consuming app withnode --preserve-symlinks.
Usage
// app.module.ts
import { LicenseModule } from '@lazarevic_00/license-sdk';
@Module({
imports: [
LicenseModule.forRoot({
licenseKey: process.env.LICENSE_KEY!,
serverUrl: process.env.LICENSE_SERVER_URL!, // e.g. http://localhost:8020
appVersion: process.env.APP_VERSION,
}),
// ...the rest of your app modules
],
})
export class AppModule {}That's the whole integration - LicenseModule.forRoot() registers a global
APP_GUARD automatically, so every route in the app starts rejecting requests
with 503 Service Unavailable the moment the license becomes invalid. No
guard wiring, no per-controller decorators.
What "invalid" means
- The key doesn't exist on the license server
- The key was revoked
- The key expired and the offline grace period (see below) has elapsed
A license that's merely expiring soon (inside the server's warning window) stays valid - the app keeps working, only a warning is logged. The license server itself emails the vendor (not the customer) when a key is expiring or expired; the SDK's job is enforcement, not notification.
Offline resilience
The SDK re-validates on an interval (default: every 6 hours) and caches the last confirmed-valid timestamp. If the license server is unreachable (network outage, server down), the app keeps running on the cached valid state for an offline grace period (default: 48 hours) before failing closed. This is deliberate - a customer's app must not go down just because their network blipped or the license server had a bad five minutes.
Options
interface LicenseModuleOptions {
licenseKey: string;
serverUrl: string;
appVersion?: string;
checkIntervalMs?: number; // default 6h
requestTimeoutMs?: number; // default 5s
offlineGracePeriodMs?: number; // default 48h
autoBlock?: boolean; // default true - set false to only track state yourself
}Reading state yourself
constructor(private readonly licenseService: LicenseService) {}
someHealthCheck() {
const state = this.licenseService.getState();
// { valid, reason, expiresAt, daysRemaining, projectName, customerName, source }
}Scope
Node/NestJS/TypeORM apps only for now. A React/frontend SDK is a separate, future package.
