{"_id":"@atlashub/license-validator","_rev":"2-ee22fe796b7fb094904c868d0ed20098","name":"@atlashub/license-validator","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@atlashub/license-validator","version":"1.0.0","keywords":["atlashub","license","validator","jwt"],"author":{"name":"AtlasHub"},"license":"MIT","_id":"@atlashub/license-validator@1.0.0","maintainers":[{"name":"atashub","email":"dsi@atlashub.ch"}],"homepage":"https://github.com/atlashub/license-validator#readme","bugs":{"url":"https://github.com/atlashub/license-validator/issues"},"dist":{"shasum":"a69682f9e2c65f80653af5b814a1d191c59b2623","tarball":"https://registry.npmjs.org/@atlashub/license-validator/-/license-validator-1.0.0.tgz","fileCount":5,"integrity":"sha512-7PRgeggQVWeX8hoCWHJXmEEP8VKMhLMeOchtTqgNDsXbzwdPnny/3ytppiwfSAM2zQXxO0cmFa63mYiLQ3lRcA==","signatures":[{"sig":"MEUCIQDcHKU9+MS52MdWkMGndhmslb7Xx/bUwRPxcmAlFl9MYwIgQ5qX/auRD4us477lKVrPWYvqiBOulirpEMdc1U8LTN4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16013},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"build":"tsup src/index.ts --format cjs,esm --dts","prepublishOnly":"npm run build"},"_npmUser":{"name":"atashub","email":"dsi@atlashub.ch"},"repository":{"url":"git+https://github.com/atlashub/license-validator.git","type":"git"},"_npmVersion":"10.9.3","description":"License validator for AtlasHub products - validates JWT licenses signed by AtlasHub License Generator","directories":{},"_nodeVersion":"22.20.0","dependencies":{"jsonwebtoken":"^9.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0","@types/node":"^22.0.0","@types/jsonwebtoken":"^9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/license-validator_1.0.0_1768560188043_0.7171146439044003","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@atlashub/license-validator","version":"1.0.1","description":"License validator for AtlasHub products - validates JWT licenses signed by AtlasHub License Generator","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs","types":"./dist/index.d.ts"}},"scripts":{"build":"tsup src/index.ts --format cjs,esm --dts","prepublishOnly":"npm run build"},"dependencies":{"jsonwebtoken":"^9.0.0"},"devDependencies":{"@types/jsonwebtoken":"^9.0.0","@types/node":"^22.0.0","tsup":"^8.0.0","typescript":"^5.0.0"},"keywords":["atlashub","license","validator","jwt"],"author":{"name":"AtlasHub"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/atlashub/license-validator.git"},"_id":"@atlashub/license-validator@1.0.1","bugs":{"url":"https://github.com/atlashub/license-validator/issues"},"homepage":"https://github.com/atlashub/license-validator#readme","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-heMCpx5CYLAUHS9O/RKF4iC+9fEnowtP2r0pjNFWpNed5eEv3q3dgHptaAlG81YzaifAmadNPAh+kkQk4ZOxYQ==","shasum":"a52d1fe61e1631b9b74f39a9e8ff9b07760edc50","tarball":"https://registry.npmjs.org/@atlashub/license-validator/-/license-validator-1.0.1.tgz","fileCount":6,"unpackedSize":25249,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGmJhQlq0yqal9J0q9lD2OJ7SlAUAZc1DkVmLqoMWwToAiEA76FTGSWjNh/rmsQSo+9W9OzSsCCXcKgq4jnFjTqJukE="}]},"_npmUser":{"name":"atashub","email":"dsi@atlashub.ch"},"directories":{},"maintainers":[{"name":"atashub","email":"dsi@atlashub.ch"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/license-validator_1.0.1_1768560674406_0.07953357517688886"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-16T10:43:07.959Z","modified":"2026-01-16T10:51:14.675Z","1.0.0":"2026-01-16T10:43:08.183Z","1.0.1":"2026-01-16T10:51:14.559Z"},"bugs":{"url":"https://github.com/atlashub/license-validator/issues"},"author":{"name":"AtlasHub"},"license":"MIT","homepage":"https://github.com/atlashub/license-validator#readme","keywords":["atlashub","license","validator","jwt"],"repository":{"type":"git","url":"git+https://github.com/atlashub/license-validator.git"},"description":"License validator for AtlasHub products - validates JWT licenses signed by AtlasHub License Generator","maintainers":[{"name":"atashub","email":"dsi@atlashub.ch"}],"readme":"# @atlashub/license-validator\r\n\r\nValidate 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.\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @atlashub/license-validator\r\n```\r\n\r\n## Quick Start\r\n\r\n```typescript\r\nimport { validateLicense, hasFeature } from '@atlashub/license-validator';\r\n\r\nconst result = validateLicense(process.env.LICENSE_KEY, {\r\n  productId: 'my-cli-tool'\r\n});\r\n\r\nif (!result.valid) {\r\n  console.error('License error:', result.error);\r\n  process.exit(1);\r\n}\r\n\r\nconsole.log('Licensed to:', result.license.company);\r\nconsole.log('Edition:', result.license.edition);\r\nconsole.log('Expires in:', result.license.daysRemaining, 'days');\r\n```\r\n\r\n## API Reference\r\n\r\n### `validateLicense(licenseKey, options)`\r\n\r\nValidates a license key and returns detailed license information.\r\n\r\n**Parameters:**\r\n\r\n| Parameter | Type | Description |\r\n|-----------|------|-------------|\r\n| `licenseKey` | `string \\| undefined` | The JWT license key to validate |\r\n| `options.productId` | `string` | (Optional) Expected product ID - validates the audience claim |\r\n| `options.gracePeriodDays` | `number` | (Optional) Days to allow after expiration (default: 0) |\r\n\r\n**Returns:** `ValidationResult`\r\n\r\n```typescript\r\ninterface ValidationResult {\r\n  valid: boolean;\r\n  license?: License;\r\n  error?: string;\r\n}\r\n\r\ninterface License {\r\n  company: string;          // Company/tenant identifier\r\n  productId: string;        // Product identifier\r\n  edition: string;          // starter | professional | enterprise\r\n  features: string[];       // Enabled features (or ['*'] for all)\r\n  limits: {\r\n    users: number;\r\n    storage_gb: number;\r\n    api_calls_per_day: number;\r\n  };\r\n  issuedAt: Date;\r\n  expiresAt: Date;\r\n  daysRemaining: number;\r\n  isExpired: boolean;\r\n  isValid: boolean;\r\n}\r\n```\r\n\r\n### `hasFeature(license, featureName)`\r\n\r\nChecks if a specific feature is enabled in the license.\r\n\r\n```typescript\r\nimport { validateLicense, hasFeature } from '@atlashub/license-validator';\r\n\r\nconst { license } = validateLicense(licenseKey);\r\n\r\nif (hasFeature(license, 'premium')) {\r\n  // Enable premium functionality\r\n}\r\n\r\nif (hasFeature(license, 'ai')) {\r\n  // Enable AI features\r\n}\r\n```\r\n\r\n**Note:** Returns `true` if features includes `'*'` (enterprise licenses).\r\n\r\n### `isWithinLimits(license, type, currentUsage)`\r\n\r\nChecks if usage is within license limits.\r\n\r\n```typescript\r\nimport { isWithinLimits } from '@atlashub/license-validator';\r\n\r\nif (!isWithinLimits(license, 'users', currentUserCount)) {\r\n  console.error('User limit exceeded');\r\n}\r\n\r\nif (!isWithinLimits(license, 'api_calls_per_day', todaysCalls)) {\r\n  console.error('API rate limit exceeded');\r\n}\r\n```\r\n\r\n### `decodeLicenseUnsafe(licenseKey)`\r\n\r\nDecodes a license key without signature verification. **For debugging only.**\r\n\r\n```typescript\r\nimport { decodeLicenseUnsafe } from '@atlashub/license-validator';\r\n\r\nconst payload = decodeLicenseUnsafe(licenseKey);\r\nconsole.log(payload);\r\n// { sub: 'acme-corp', product_id: 'my-cli', edition: 'professional', ... }\r\n```\r\n\r\n## Complete Integration Example\r\n\r\n```typescript\r\n// src/license.ts\r\nimport { validateLicense, hasFeature, License } from '@atlashub/license-validator';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport os from 'os';\r\n\r\nconst PRODUCT_ID = 'my-awesome-cli';\r\n\r\n/**\r\n * Load license from multiple sources\r\n */\r\nfunction loadLicenseKey(): string | undefined {\r\n  // 1. Environment variable\r\n  if (process.env.ATLASHUB_LICENSE) {\r\n    return process.env.ATLASHUB_LICENSE;\r\n  }\r\n\r\n  // 2. Home directory file\r\n  const homeFile = path.join(os.homedir(), '.atlashub-license');\r\n  if (fs.existsSync(homeFile)) {\r\n    return fs.readFileSync(homeFile, 'utf-8').trim();\r\n  }\r\n\r\n  // 3. Current directory file\r\n  if (fs.existsSync('license.key')) {\r\n    return fs.readFileSync('license.key', 'utf-8').trim();\r\n  }\r\n\r\n  return undefined;\r\n}\r\n\r\n/**\r\n * Validate license at startup\r\n */\r\nexport function requireLicense(): License {\r\n  const licenseKey = loadLicenseKey();\r\n\r\n  const result = validateLicense(licenseKey, {\r\n    productId: PRODUCT_ID,\r\n    gracePeriodDays: 7\r\n  });\r\n\r\n  if (!result.valid) {\r\n    console.error('\\n╔════════════════════════════════════════╗');\r\n    console.error('║         LICENSE VALIDATION FAILED       ║');\r\n    console.error('╚════════════════════════════════════════╝\\n');\r\n    console.error('Error:', result.error);\r\n    console.error('\\nTo obtain a license:');\r\n    console.error('  1. Contact: license@atlashub.io');\r\n    console.error('  2. Set via: export ATLASHUB_LICENSE=\"your-key\"');\r\n    console.error('  3. Or save to: ~/.atlashub-license\\n');\r\n    process.exit(1);\r\n  }\r\n\r\n  const { license } = result;\r\n\r\n  // Expiration warning\r\n  if (license.daysRemaining <= 30) {\r\n    console.warn(`\\n⚠️  Warning: License expires in ${license.daysRemaining} days!\\n`);\r\n  }\r\n\r\n  return license;\r\n}\r\n\r\n/**\r\n * Require a specific feature\r\n */\r\nexport function requireFeature(license: License, feature: string): void {\r\n  if (!hasFeature(license, feature)) {\r\n    console.error(`\\n❌ Feature \"${feature}\" is not available in your ${license.edition} license.`);\r\n    console.error('Please upgrade to access this feature.\\n');\r\n    process.exit(1);\r\n  }\r\n}\r\n\r\n/**\r\n * Display license info\r\n */\r\nexport function showLicenseInfo(license: License): void {\r\n  console.log('\\n┌────────────────────────────────────────┐');\r\n  console.log('│            LICENSE INFORMATION          │');\r\n  console.log('├────────────────────────────────────────┤');\r\n  console.log(`│ Company:    ${license.company.padEnd(26)}│`);\r\n  console.log(`│ Edition:    ${license.edition.padEnd(26)}│`);\r\n  console.log(`│ Features:   ${license.features.join(', ').padEnd(26).slice(0, 26)}│`);\r\n  console.log(`│ Expires:    ${license.expiresAt.toLocaleDateString().padEnd(26)}│`);\r\n  console.log(`│ Remaining:  ${(license.daysRemaining + ' days').padEnd(26)}│`);\r\n  console.log('└────────────────────────────────────────┘\\n');\r\n}\r\n```\r\n\r\n**Usage in your CLI:**\r\n\r\n```typescript\r\n// src/cli.ts\r\nimport { requireLicense, requireFeature, showLicenseInfo } from './license';\r\n\r\n// Validate at startup\r\nconst license = requireLicense();\r\n\r\n// Show info\r\nshowLicenseInfo(license);\r\n\r\n// Check features for specific commands\r\nif (command === 'advanced-export') {\r\n  requireFeature(license, 'export');\r\n  // ... run export\r\n}\r\n\r\nif (command === 'ai-assist') {\r\n  requireFeature(license, 'ai');\r\n  // ... run AI features\r\n}\r\n```\r\n\r\n## License Editions\r\n\r\n| Edition | Features | Typical Limits |\r\n|---------|----------|----------------|\r\n| **Starter** | `core`, `basic-reports` | 10 users, 5 GB, 1K API/day |\r\n| **Professional** | `core`, `ai`, `workflows`, `reports`, `entra`, `support` | 50 users, 25 GB, 10K API/day |\r\n| **Enterprise** | `*` (all features) | Unlimited |\r\n\r\n## Generating Licenses\r\n\r\nLicenses are generated using the AtlasHub License Generator (internal tool):\r\n\r\n```bash\r\n# Generate a professional license for 1 year\r\nlicense-generator generate \\\r\n  --company \"acme-corp\" \\\r\n  --product \"my-awesome-cli\" \\\r\n  --edition professional \\\r\n  --days 365\r\n\r\n# Generate an enterprise license with custom features\r\nlicense-generator generate \\\r\n  --company \"big-corp\" \\\r\n  --product \"my-awesome-cli\" \\\r\n  --edition enterprise \\\r\n  --features \"*\" \\\r\n  --users 1000 \\\r\n  --days 730\r\n```\r\n\r\n## Security\r\n\r\nThis package uses **RSA-SHA256** asymmetric cryptography:\r\n\r\n- **Public key** (included): Can only verify signatures\r\n- **Private key** (secret): Required to create valid licenses\r\n\r\nThe public key cannot be used to forge licenses. This is the same security model used by SSL/TLS certificates.\r\n\r\n## Error Handling\r\n\r\n```typescript\r\nconst result = validateLicense(licenseKey, { productId: 'my-cli' });\r\n\r\nif (!result.valid) {\r\n  switch (true) {\r\n    case result.error?.includes('No license key'):\r\n      // License not provided\r\n      break;\r\n    case result.error?.includes('expired'):\r\n      // License has expired\r\n      console.log('Expired on:', result.license?.expiresAt);\r\n      break;\r\n    case result.error?.includes('Invalid license'):\r\n      // Signature verification failed (tampered or wrong key)\r\n      break;\r\n    default:\r\n      // Other error\r\n      console.error(result.error);\r\n  }\r\n}\r\n```\r\n\r\n## TypeScript Support\r\n\r\nFull TypeScript support with exported types:\r\n\r\n```typescript\r\nimport type {\r\n  License,\r\n  LicenseLimits,\r\n  ValidationResult,\r\n  ValidateOptions\r\n} from '@atlashub/license-validator';\r\n```\r\n\r\n## License\r\n\r\nMIT - Free to use in commercial and open-source projects.\r\n\r\n## Support\r\n\r\n- Issues: [GitHub Issues](https://github.com/atlashub/license-validator/issues)\r\n- Contact: license@atlashub.io\r\n","readmeFilename":"README.md"}