UNPKG

@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
/** * 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