@hivetechs/hive-ai
Version:
Real-time streaming AI consensus platform with HTTP+SSE MCP integration for Claude Code, VS Code, Cursor, and Windsurf - powered by OpenRouter's unified API
487 lines • 16.4 kB
JavaScript
/**
* License Gating System - Protects Premium Features
*
* This module handles license validation and feature access control.
* Free tier provides basic tools, premium tier unlocks advanced features.
*/
import { getApiEndpoint } from '../config/endpoints.js';
export var FeatureTier;
(function (FeatureTier) {
FeatureTier["FREE"] = "free";
FeatureTier["PREMIUM"] = "premium";
})(FeatureTier || (FeatureTier = {}));
export class LicenseGate {
static instance;
licenseCache = null;
cacheExpiry = 0;
static getInstance() {
if (!LicenseGate.instance) {
LicenseGate.instance = new LicenseGate();
}
return LicenseGate.instance;
}
/**
* Check if user has a valid license for the requested feature
* ALL features now require a license key (free, trial, or premium)
*/
async checkFeatureAccess(feature) {
const license = await this.validateLicense();
// ALL features require a valid license now
if (!license.valid) {
throw new NoLicenseError(feature);
}
// Define feature tiers
const freeFeatures = [
'setup_wizard',
'configure_provider',
'test_providers',
'help',
'browse_models',
'single_model_query',
'basic_analytics'
];
const premiumFeatures = [
'consensus_query',
'multi_model_query',
'dashboard',
'analytics',
'export_data',
'cost_tracking',
'benchmarking',
'advanced_features'
];
// Check if user's license tier allows this feature
if (freeFeatures.includes(feature)) {
// Free features available to all license types (free, trial, premium)
return license;
}
else if (premiumFeatures.includes(feature)) {
// Premium features require premium or trial license
if (license.tier === FeatureTier.FREE) {
throw new PremiumFeatureError(feature);
}
return license;
}
// Default: require license but allow if valid
return license;
}
/**
* Validate license with Cloudflare Workers backend
*/
async validateLicense() {
// Check cache first
if (this.licenseCache && Date.now() < this.cacheExpiry) {
return this.licenseCache;
}
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return this.createFreeLicense();
}
try {
// Validate against 2025 security best practices endpoint
const response = await fetch(`${getApiEndpoint('general')}/v1/session/validate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'User-Agent': 'HiveClient/1.0'
},
body: JSON.stringify({
client_id: 'hive-tools',
session_token: licenseKey,
fingerprint: this.getDeviceFingerprint(),
version: this.getVersion(),
nonce: Date.now()
})
});
if (!response.ok) {
// Invalid license key provided - reject
console.warn('License validation failed - invalid key');
return this.createFreeLicense();
}
const license = await response.json();
// Ensure the license is marked as valid
license.valid = true;
// Map subscription tier to feature tier
if (license.tier === 'free') {
license.tier = FeatureTier.FREE;
}
else {
// All paid tiers (basic, standard, premium, team) get premium features
license.tier = FeatureTier.PREMIUM;
}
// Cache for 1 hour
this.licenseCache = license;
this.cacheExpiry = Date.now() + (60 * 60 * 1000);
return license;
}
catch (error) {
console.warn('License validation error - network or API issue:', error);
return this.createFreeLicense();
}
}
getLicenseKey() {
// Check environment variables first
if (process.env.HIVE_TOOLS_LICENSE) {
return process.env.HIVE_TOOLS_LICENSE;
}
// Check config file - use process.env.HOME directly since require doesn't work in ES modules
try {
const homedir = process.env.HOME || process.env.USERPROFILE || '/tmp';
// Try reading the license file with hardcoded paths
const paths = [
`${homedir}/.hive-ai/license.json`,
`${homedir}/.hive-ai/config.json`,
`${homedir}/.hive-tools/license.key`
];
for (const filePath of paths) {
try {
// Use eval to access require in a way that bypasses ES module restrictions
const fs = new Function('return require("fs")')();
if (fs.existsSync(filePath)) {
const content = fs.readFileSync(filePath, 'utf8');
if (filePath.endsWith('.json')) {
const data = JSON.parse(content);
return data.licenseKey;
}
else {
return content.trim();
}
}
}
catch (fileError) {
// Continue to next path
continue;
}
}
}
catch (error) {
// Ignore file read errors
}
return null;
}
createFreeLicense() {
// Free tier requires a valid license key - users must sign up
// Return invalid license to force sign-up
return {
valid: false,
tier: FeatureTier.FREE,
features: [],
message: 'Free license key required. Get yours at https://hivetechs.io/pricing'
};
}
createValidFreeLicense() {
// Valid free license for users who have signed up
return {
valid: true,
tier: FeatureTier.FREE,
features: [
'setup_wizard',
'configure_provider',
'test_providers',
'help',
'single_model_query',
'basic_analytics'
],
dailyLimit: 10,
user_id: 'free-user',
subscription_status: 'free',
max_devices: 1,
active_devices: 1
};
}
getVersion() {
try {
const fs = new Function('return require("fs")')();
const path = new Function('return require("path")')();
const currentDir = new Function('return __dirname')();
const packagePath = path.join(currentDir, '..', '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
return packageJson.version;
}
catch {
return '1.0.0';
}
}
getDeviceFingerprint() {
try {
const os = new Function('return require("os")')();
const crypto = new Function('return require("crypto")')();
// Create device fingerprint from system info
const fingerprint = {
platform: os.platform(),
arch: os.arch(),
hostname: os.hostname(),
user: os.userInfo().username
};
// Hash the fingerprint for privacy
const hash = crypto.createHash('sha256');
hash.update(JSON.stringify(fingerprint));
return hash.digest('hex').substring(0, 16);
}
catch {
return 'unknown-device';
}
}
/**
* Store license key securely
*/
async storeLicenseKey(licenseKey) {
const fs = new Function('return require("fs")')();
const os = new Function('return require("os")')();
const path = new Function('return require("path")')();
const configDir = path.join(os.homedir(), '.hive-tools');
const configPath = path.join(configDir, 'license.key');
// Create directory if it doesn't exist
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
// Store license key
fs.writeFileSync(configPath, licenseKey);
fs.chmodSync(configPath, 0o600); // Read-only for owner
// Clear cache to force revalidation
this.licenseCache = null;
this.cacheExpiry = 0;
}
/**
* Get detailed subscription information
*/
async getSubscriptionDetails() {
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return {
tier: 'free',
status: 'No subscription',
daily_limit: 10,
monthly_limit: 100,
expires_at: null,
trial_days_remaining: 0
};
}
try {
const response = await fetch(`${getApiEndpoint('subscription')}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${licenseKey}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
return await response.json();
}
else {
return this.getDefaultSubscription();
}
}
catch (error) {
console.warn('Failed to get subscription details:', error);
return this.getDefaultSubscription();
}
}
/**
* Get usage statistics
*/
async getUsageStatistics(period = 'month') {
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return {
daily_used: 0,
monthly_used: 0,
credits_remaining: 0
};
}
try {
const response = await fetch(`${getApiEndpoint('usage')}?period=${period}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${licenseKey}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
return await response.json();
}
else {
return this.getDefaultUsage();
}
}
catch (error) {
console.warn('Failed to get usage statistics:', error);
return this.getDefaultUsage();
}
}
/**
* Get account details
*/
async getAccountDetails() {
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return {
email: 'not-configured@example.com',
user_id: 'free-user',
created_at: new Date().toISOString(),
status: 'free',
subscription_tier: 'free',
max_devices: 1,
active_devices: 1
};
}
try {
const response = await fetch(`${getApiEndpoint('general')}/account`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${licenseKey}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
return await response.json();
}
else {
return this.getDefaultAccount();
}
}
catch (error) {
console.warn('Failed to get account details:', error);
return this.getDefaultAccount();
}
}
/**
* Get registered devices
*/
async getRegisteredDevices() {
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return [];
}
try {
const response = await fetch(`${getApiEndpoint('general')}/devices`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${licenseKey}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
return data.devices || [];
}
else {
return [];
}
}
catch (error) {
console.warn('Failed to get devices:', error);
return [];
}
}
/**
* Update email address
*/
async updateEmail(email) {
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return { success: false, error: 'No license key configured' };
}
try {
const response = await fetch(`${getApiEndpoint('general')}/account/email`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${licenseKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ email })
});
if (response.ok) {
return { success: true };
}
else {
const error = await response.text();
return { success: false, error };
}
}
catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
}
/**
* Remove device
*/
async removeDevice(deviceId) {
const licenseKey = this.getLicenseKey();
if (!licenseKey) {
return { success: false, error: 'No license key configured' };
}
try {
const response = await fetch(`${getApiEndpoint('general')}/devices/${deviceId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${licenseKey}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
return { success: true };
}
else {
const error = await response.text();
return { success: false, error };
}
}
catch (error) {
return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
}
}
getDefaultSubscription() {
return {
tier: 'free',
status: 'Active',
daily_limit: 10,
monthly_limit: 100,
expires_at: null,
trial_days_remaining: 0
};
}
getDefaultUsage() {
return {
daily_used: 0,
monthly_used: 0,
credits_remaining: 0
};
}
getDefaultAccount() {
return {
email: 'not-configured@example.com',
user_id: 'free-user',
created_at: new Date().toISOString(),
status: 'free',
subscription_tier: 'free',
max_devices: 1,
active_devices: 1
};
}
}
export class NoLicenseError extends Error {
constructor(feature) {
super(`🔑 License required to use '${feature}'. Get your FREE license at hivetechs.io/pricing`);
this.name = 'NoLicenseError';
}
}
export class PremiumFeatureError extends Error {
constructor(feature) {
super(`🔒 Premium feature '${feature}' requires a premium license. Upgrade at hivetechs.io/pricing`);
this.name = 'PremiumFeatureError';
}
}
/**
* Decorator for protecting premium MCP tools
*/
export function requiresPremium(target, propertyName, descriptor) {
const method = descriptor.value;
descriptor.value = async function (...args) {
const licenseGate = LicenseGate.getInstance();
await licenseGate.checkFeatureAccess(propertyName);
return method.apply(this, args);
};
return descriptor;
}
//# sourceMappingURL=license-gate.js.map