leocense
v1.1.1
Published
Official Node.js SDK for LEOCENSE - Software Licensing & Distribution Platform
Downloads
29
Maintainers
Readme
Leocense Node.js SDK
The official Node.js SDK for Leocense, the complete software licensing and distribution platform. This SDK allows you to verify licenses, implement hardware-locked device fingerprinting, and manage licenses/products programmatically.
Table of Contents
- Installation
- Getting Started
- Client-Side Usage (Verification)
- Server-Side Usage (Management)
- Type Definitions
- Integration Best Practices
- Changelog
Installation
Install the package via npm or yarn:
npm install leocense
# or
yarn add leocenseGetting Started
Import LeocenseClient from the package.
import { LeocenseClient } from 'leocense';There are two main ways to initialize the client:
Public/Client Mode: No API key required. Used inside your desktop or CLI application to verify licenses.
const client = new LeocenseClient();Management/Admin Mode: API Key required. Used on your backend server to create/manage licenses.
const client = new LeocenseClient('YOUR_SECRET_API_KEY');
Note: You can also specify a custom base URL if you are using a self-hosted instance:
const client = new LeocenseClient('API_KEY', 'https://your-custom-domain.com');Client-Side Usage (Verification)
These methods are safe to use in your distributed application. They do NOT require an API Key.
Verify License
Checks if a license key is valid, active, and not expired. This does not bind the license to a specific device.
Use Case: Lightweight check on app startup or web portal login.
const result = await client.verifyLicense('LICENSE-KEY-123', 'PRODUCT-ID-456');
if (result.success && result.valid) {
console.log('License is valid!');
console.log('App:', result.appName);
console.log('Owner:', result.ownerName);
console.log('Expiry:', result.expiryDate);
// You can also access raw data object:
// console.log('Data:', result.data);
} else {
console.error('Verification failed:', result.message);
}Verify with Hardware Locking
This is the recommended method for desktop/CLI apps. It generates a unique, weighted hardware fingerprint (Motherboard, Disk, CPU, MAC) of the user's machine, sends it to Leocense, and binds the license to that device.
Use Case: Preventing license sharing. The license will be locked to the first device(s) it is used on, up to the allowedDevices limit.
try {
const result = await client.verifyLicenseWithDevice('LICENSE-KEY-123', 'PRODUCT-ID-456');
if (result.success && result.valid) {
console.log('License active on this device.');
console.log('Variant:', result.variantName); // e.g., "Pro Version"
console.log('Properties:', result.properties);
} else {
// Handle specific failure reasons
switch (result.reason) {
case 'device_limit_blocked':
console.error('License used on too many devices.');
break;
case 'expired':
console.error('License has expired.');
break;
case 'blocked':
console.error('License has been blocked by the vendor.');
break;
default:
console.error('Invalid license:', result.message);
}
}
} catch (error) {
console.error('Network or System Error:', error);
}Check for Updates
Checks if a newer version of your product is available.
Use Case: Showing an "Update Available" notification in your app.
const update = await client.checkUpdate('PRODUCT-ID-456', '1.0.0'); // Current App Version
if (update && update.updateAvailable) {
console.log('New version found:', update.latestVersion);
console.log('Changelog:', update.changelog);
console.log('Download here:', update.downloadUrl);
}Server-Side Usage (Management)
These methods require an API Key with write permissions. NEVER use these in your client-side code distributed to users.
Create License
Generates a new license key for a customer.
Use Case: Automating license creation after a Stripe/PayPal payment webhook.
import { LeocenseClient, License } from 'leocense';
const adminClient = new LeocenseClient('YOUR_ADMIN_API_KEY');
async function generateLicenseForCustomer() {
try {
const newLicense = await adminClient.createLicense({
productId: 'PRODUCT-ID-456',
ownerName: 'John Doe',
email: '[email protected]', // Optional: Customer email
expiryDate: '2025-12-31T23:59:59Z', // Optional: Set expiration
limitDevices: true, // Enable hardware locking
allowedDevices: 2, // Allow use on 2 devices
metadata: { // Custom data
plan: 'pro',
source: 'stripe'
}
});
console.log('Created License:', newLicense.licenseKey);
} catch (err) {
console.error('Failed to create license:', err.message);
}
}Get/List Licenses
Retrieve details about specific licenses or list all licenses.
// Get single license
const license = await adminClient.getLicense('LICENSE-ID');
// List all licenses
const allLicenses = await adminClient.getLicenses();Activate/Block License
Control the status of issued licenses (e.g., if a refund occurs or a subscription is cancelled).
// Block a license (Prevent further verifications)
await adminClient.blockLicense('LICENSE-ID');
// Reactivate a blocked license
await adminClient.activateLicense('LICENSE-ID');
// Delete a license permanently
await adminClient.deleteLicense('LICENSE-ID');Manage Products
Create and retrieve products programmatically.
const newProduct = await adminClient.createProduct({
name: 'My Awesome App',
version: '1.0.0',
downloadUrl: 'https://example.com/download/app-v1.zip'
});Type Definitions
The SDK uses generic ApiResponse<T> types for all method returns.
LicenseResult
Returned by verification methods. Includes top-level access to license details.
interface LicenseResult {
success: boolean; // True if request succeeded
valid: boolean; // True if license is valid
message?: string; // Error message if any
data?: LicenseData; // Full license details object
// Convenience properties (merged from data):
reason?: string;
accessToken?: string;
appName?: string;
variantName?: string;
ownerName?: string;
ownerEmail?: string;
expiryDate?: string;
downloadUrl?: string;
properties?: string;
[key: string]: any; // Any other properties (e.g. flattened variant props)
}License
Standard License Interface.
interface License {
id: string;
licenseKey: string;
productId: string;
status: 'active' | 'blocked' | 'expired';
deviceIds?: string; // JSON string of bound devices
allowedDevices?: number;
metadata?: Record<string, any>;
// ... other standard fields
}
export interface AccessTokenData {
token: {
licenseId: string;
productId: string;
issuedAt: string;
};
license: Partial<License>;
properties?: string;
downloadUrl?: string;
}Integration Best Practices
- Local Caching: After a successful
verifyLicenseWithDevice, you should cache the result (and potentially theaccessTokenorexpiryDate) locally in a secure file. This allows your app to work offline for a grace period. - Graceful Failures: Always handle network errors (
try/catch). If the Leocense server is unreachable, decide if you want to allow access (soft fail) or block access (hard fail) based on your security needs. - Security: Obfuscate your
productIdin your client code. Do NOT ship your Admin API Key in your client application.
Changelog
v1.1.1
- Enhanced Device Fingerprinting: Added
hostnamecapture toverifyLicenseWithDevice(). - Robust Hostname Detection: Supports
os.hostname()with fallback to shellexec('hostname')for improved Linux/Kali/macOS support.
