@interopio/desktop-cli
Version:
io.Connect Desktop Seed Repository CLI Tools
208 lines • 9.55 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.licenseCommand = void 0;
const commander_1 = require("commander");
const utils_1 = require("../utils");
const license_validator_1 = require("../services/license-validator");
const chalk_1 = __importDefault(require("chalk"));
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
exports.licenseCommand = new commander_1.Command('license')
.description('Manage and validate licenses');
// License validate command
exports.licenseCommand
.command('validate')
.description('Validate the current license')
.action(async () => {
try {
const validator = new license_validator_1.LicenseValidator();
const isValid = await validator.validate();
if (isValid) {
utils_1.Logger.success('License is valid');
}
else {
utils_1.Logger.error('License validation failed');
process.exit(1);
}
}
catch (error) {
utils_1.Logger.error(`License validation error: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
}
});
// License info command
exports.licenseCommand
.command('info')
.description('Display license information')
.action(async () => {
try {
const validator = new license_validator_1.LicenseValidator();
const license = await validator.getLicenseInfo();
if (!license) {
utils_1.Logger.error('No license found');
process.exit(1);
}
console.log('\nLicense Information:');
console.log('───────────────────────────────────────');
console.log(`ID: ${chalk_1.default.cyan(license.id)}`);
console.log(`Type: ${chalk_1.default.green(license.type)}`);
if (license.organization) {
console.log(`Organization: ${chalk_1.default.blue(license.organization)}`);
}
if (license.maxUsers) {
console.log(`Max Users: ${chalk_1.default.yellow(license.maxUsers)}`);
}
if (license.expiresAt) {
const expirationDate = new Date(license.expiresAt);
const now = new Date();
const isExpired = expirationDate < now;
const status = isExpired ? chalk_1.default.red('EXPIRED') : chalk_1.default.green('Valid');
console.log(`Expires: ${expirationDate.toLocaleDateString()} (${status})`);
if (!isExpired) {
const daysUntilExpiration = Math.ceil((expirationDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
console.log(`Days remaining: ${chalk_1.default.yellow(daysUntilExpiration)}`);
}
}
else {
console.log(`Expires: ${chalk_1.default.green('Never')}`);
}
console.log(`\nFeatures: ${license.features.join(', ')}`);
console.log(`Allowed Components: ${license.allowedComponents.join(', ')}`);
console.log('');
}
catch (error) {
utils_1.Logger.error(`Failed to get license info: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
}
});
// License check-components command
exports.licenseCommand
.command('check-components')
.description('Check which components are allowed by the current license')
.action(async () => {
try {
const validator = new license_validator_1.LicenseValidator();
const license = await validator.getLicenseInfo();
if (!license) {
utils_1.Logger.error('No license found');
process.exit(1);
}
console.log('\nComponent License Status:');
console.log('────────────────────────────────────────');
// Check common components
const commonComponents = ['iocd', 'bbg-v2', 'teams-adapter', 'excel-adapter', 'symphony-adapter'];
for (const component of commonComponents) {
const hasAccess = await validator.validateComponentAccess(component);
const status = hasAccess ? chalk_1.default.green('✓ Allowed') : chalk_1.default.red('✗ Not allowed');
console.log(`${chalk_1.default.cyan(component)}: ${status}`);
}
console.log('');
}
catch (error) {
utils_1.Logger.error(`Failed to check component licenses: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
}
});
// License decode command (for JWT tokens)
exports.licenseCommand
.command('decode')
.description('Decode JWT license token and show payload (without verification)')
.option('--verify', 'Verify JWT signature using public key')
.action(async (options) => {
try {
const licensePath = path_1.default.join(process.cwd(), 'license.json');
if (!(await fs_extra_1.default.pathExists(licensePath))) {
utils_1.Logger.error('No license.json file found');
process.exit(1);
}
const rawData = await fs_extra_1.default.readFile(licensePath, 'utf8');
const licenseData = JSON.parse(rawData);
let token = null;
// Extract JWT token
if (typeof licenseData === 'string' && isJWTFormat(licenseData)) {
token = licenseData;
}
else if (typeof licenseData === 'object') {
const tokenFields = ['token', 'jwt', 'license_token', 'licenseToken'];
for (const field of tokenFields) {
if (licenseData[field] && isJWTFormat(licenseData[field])) {
token = licenseData[field];
break;
}
}
}
if (!token) {
utils_1.Logger.error('No JWT token found in license.json');
console.log('\nExpected format:');
console.log('{"token": "your.jwt.token"}');
console.log('or');
console.log('"your.jwt.token"');
process.exit(1);
}
console.log('\nJWT License Token Information:');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
// Decode without verification first
try {
const decoded = jsonwebtoken_1.default.decode(token, { complete: true });
if (!decoded) {
utils_1.Logger.error('Failed to decode JWT token');
process.exit(1);
}
console.log(chalk_1.default.bold('\nHeader:'));
console.log(JSON.stringify(decoded.header, null, 2));
console.log(chalk_1.default.bold('\nPayload:'));
console.log(JSON.stringify(decoded.payload, null, 2));
// Show expiration information
const payload = decoded.payload;
if (payload.exp) {
const expDate = new Date(payload.exp * 1000);
const now = new Date();
const isExpired = expDate < now;
console.log(chalk_1.default.bold('\nExpiration:'));
console.log(`Expires: ${expDate.toISOString()}`);
console.log(`Status: ${isExpired ? chalk_1.default.red('EXPIRED') : chalk_1.default.green('VALID')}`);
if (!isExpired) {
const daysLeft = Math.ceil((expDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
console.log(`Days remaining: ${daysLeft}`);
}
}
// If verification is requested
if (options.verify) {
console.log(chalk_1.default.bold('\nSignature Verification:'));
try {
const validator = new license_validator_1.LicenseValidator();
const verifiedLicense = await validator.getLicenseInfo();
if (verifiedLicense) {
console.log(chalk_1.default.green('✓ Signature is valid'));
console.log(chalk_1.default.bold('\nVerified License Data:'));
console.log(JSON.stringify(verifiedLicense, null, 2));
}
}
catch (verifyError) {
console.log(chalk_1.default.red('✗ Signature verification failed'));
console.log(`Error: ${verifyError instanceof Error ? verifyError.message : String(verifyError)}`);
}
}
else {
console.log(chalk_1.default.yellow('\nNote: Use --verify to check signature validity'));
}
}
catch (decodeError) {
utils_1.Logger.error(`Failed to decode JWT: ${decodeError instanceof Error ? decodeError.message : String(decodeError)}`);
process.exit(1);
}
}
catch (error) {
utils_1.Logger.error(`Failed to decode license: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
}
});
function isJWTFormat(token) {
const parts = token.split('.');
return parts.length === 3 && parts.every(part => part.length > 0);
}
//# sourceMappingURL=license.js.map