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

137 lines 4.5 kB
import { getLicenseKeyFromDB, saveLicenseKeyToDB, getConfig, setConfig, initializeDatabase } from '../storage/database.js'; export async function getLicenseKey() { try { // Ensure database is initialized await initializeDatabase(); return await getLicenseKeyFromDB(); } catch (error) { console.error('Error getting license key:', error); return null; } } export async function saveLicenseKey(licenseKey, email) { try { // Ensure database is initialized await initializeDatabase(); await saveLicenseKeyToDB(licenseKey, email); } catch (error) { console.error('Error saving license key:', error); throw error; } } export async function getCachedSubscription() { try { // Get cached subscription info from SQLite const cachedData = await getConfig('subscription_cache'); if (!cachedData) { return null; } const cache = JSON.parse(cachedData); // Check if cache is still valid (24 hours) const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours const cacheAge = Date.now() - new Date(cache.cachedAt).getTime(); if (cacheAge < CACHE_DURATION) { return cache.subscription; } } catch (error) { console.error('Error getting cached subscription:', error); } return null; } export async function cacheSubscription(subscription) { try { const cacheData = { subscription, cachedAt: new Date().toISOString() }; await setConfig('subscription_cache', JSON.stringify(cacheData)); } catch (error) { console.error('Error caching subscription:', error); throw error; } } export async function validateSubscription(licenseKey) { // First check cache const cached = await getCachedSubscription(); if (cached && !licenseKey) { return cached; } // Get license key const key = licenseKey || await getLicenseKey(); if (!key) { return { valid: false, error: 'No license key found. Run "hive-ai configure" to add your license key.' }; } try { // Import configurable endpoints (SECURITY: Remove hardcoded domains) const { getApiEndpoint } = await import('../config/endpoints.js'); // Call the Cloudflare API to validate subscription const response = await fetch(getApiEndpoint('subscription'), { method: 'POST', headers: { 'Authorization': `Bearer ${key}`, 'Content-Type': 'application/json' } }); if (!response.ok) { const error = await response.text(); return { valid: false, error: `Subscription validation failed: ${error}` }; } const data = await response.json(); const subscription = { valid: data.active, plan: data.plan, email: data.email, expiresAt: data.expiresAt, remainingConversations: data.remainingConversations }; // Cache the result await cacheSubscription(subscription); return subscription; } catch (error) { // Fallback to cached subscription if available if (cached) { console.warn('Failed to validate subscription online, using cached data'); return cached; } return { valid: false, error: `Failed to validate subscription: ${error}` }; } } export async function reportUsage(conversationId) { const licenseKey = await getLicenseKey(); if (!licenseKey) return; try { // Import configurable endpoints (SECURITY: Remove hardcoded domains) const { getApiEndpoint } = await import('../config/endpoints.js'); await fetch(getApiEndpoint('usage'), { method: 'POST', headers: { 'Authorization': `Bearer ${licenseKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ conversationId, timestamp: new Date().toISOString() }) }); } catch (error) { // Silently fail - don't interrupt the user experience console.error('Failed to report usage:', error); } } //# sourceMappingURL=validator.js.map