@moontra/moonui-pro
Version:
Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components
336 lines (279 loc) • 11.5 kB
JavaScript
import https from 'https';
import fs from 'fs';
import path from 'path';
import os from 'os';
import crypto from 'crypto';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// ANSI color codes for console output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
cyan: '\x1b[36m',
gray: '\x1b[90m'
};
const log = (message, color = '') => {
console.log(`${color}${message}${colors.reset}`);
};
const getDeviceFingerprint = () => {
// Create a unique device fingerprint using multiple system attributes
const hostname = os.hostname();
const username = os.userInfo().username;
const platform = os.platform();
const arch = os.arch();
const cpus = os.cpus();
const cpuModel = cpus[0]?.model || 'unknown';
const cpuCount = cpus.length;
const homeDir = os.homedir();
// Combine all attributes for a unique device ID
const deviceString = `${hostname}|${username}|${platform}|${arch}|${cpuModel}|${cpuCount}|${homeDir}`;
return crypto.createHash('sha256').update(deviceString).digest('hex');
};
const getAuthConfig = () => {
try {
const authPath = path.join(os.homedir(), '.moonui', 'auth.encrypted');
if (!fs.existsSync(authPath)) {
return null;
}
// Read encrypted auth
const encryptedData = fs.readFileSync(authPath, 'utf-8');
const parts = encryptedData.split('.');
if (parts.length !== 3) {
// Encrypted format: iv.encrypted.signature
return null;
}
const [ivHex, encrypted, signature] = parts;
const iv = Buffer.from(ivHex, 'hex');
// Get device-specific key using same fingerprint method
const deviceFingerprint = getDeviceFingerprint();
const key = crypto.createHash('sha256').update(deviceFingerprint).digest();
// Verify signature
const hmac = crypto.createHmac('sha256', key);
hmac.update(encrypted);
const computedSignature = hmac.digest('hex');
if (computedSignature !== signature) {
return null;
}
// Decrypt
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
const cache = JSON.parse(decrypted);
// Verify device matches
if (cache.deviceId && cache.deviceId !== deviceFingerprint) {
log('❌ Device mismatch detected!', colors.red + colors.bright);
log(' This license is registered to a different device', colors.red);
log(' MoonUI Pro licenses are single-device only', colors.yellow);
return null;
}
// Extract token from cache
const auth = cache.token || cache;
// Check if expired
if (new Date(auth.expiresAt) < new Date()) {
return null;
}
return auth;
} catch (error) {
// Silent fail - will show auth required message
return null;
}
};
const validateAuth = async (token) => {
return new Promise((resolve) => {
const API_BASE = process.env.MOONUI_API_BASE || 'moonui.dev';
const options = {
hostname: API_BASE.replace('https://', '').replace('http://', ''),
port: 443,
path: '/api/auth/validate',
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'User-Agent': 'moonui-pro-postinstall/2.0.0'
},
timeout: 10000
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
if (res.statusCode === 200) {
const result = JSON.parse(data);
resolve({ valid: true, ...result });
} else {
resolve({ valid: false, error: 'INVALID_TOKEN', message: 'Authentication token is invalid' });
}
} catch (error) {
resolve({ valid: false, error: 'PARSE_ERROR', message: 'Invalid response from server' });
}
});
});
req.on('error', (error) => {
resolve({ valid: false, error: 'NETWORK_ERROR', message: 'Could not connect to auth server' });
});
req.on('timeout', () => {
resolve({ valid: false, error: 'TIMEOUT', message: 'Auth validation timeout' });
});
req.end();
});
};
const checkEnvironmentAuth = () => {
// Check for auth token in environment variables
const envToken = process.env.MOONUI_AUTH_TOKEN || process.env.MOONUI_ACCESS_TOKEN;
if (envToken) {
log('🔑 Found auth token in environment variables', colors.blue);
return envToken;
}
return null;
};
const main = async () => {
log('', ''); // Empty line
log('🌙 MoonUI Pro Installation', colors.cyan + colors.bright);
log('═'.repeat(50), colors.gray);
// Check for development bypass
if (process.env.MOONUI_DEV_MODE === 'true' || process.env.MOONUI_SKIP_AUTH === 'true') {
log('🔧 Development Mode Enabled', colors.yellow + colors.bright);
log(' Authentication bypassed for local development', colors.yellow);
log(' This mode should only be used during development', colors.gray);
log('', '');
log('✅ MoonUI Pro ready for development!', colors.green);
log('═'.repeat(50), colors.gray);
return;
}
// Check if running on localhost (development)
const isLocalDev = process.env.NODE_ENV === 'development' ||
process.cwd().includes('moonui') ||
fs.existsSync(path.join(process.cwd(), '.moonui-dev'));
if (isLocalDev && !process.env.MOONUI_FORCE_AUTH) {
log('🚀 Local Development Detected', colors.blue + colors.bright);
log(' Running in development mode without auth', colors.blue);
log(' To enable auth checks: MOONUI_FORCE_AUTH=true npm install', colors.gray);
log('', '');
log('✅ MoonUI Pro ready for development!', colors.green);
log('═'.repeat(50), colors.gray);
return;
}
// Check if this is a CI environment
const isCI = process.env.CI || process.env.CONTINUOUS_INTEGRATION || process.env.GITHUB_ACTIONS;
if (isCI) {
log('🤖 CI Environment detected', colors.blue);
const envToken = checkEnvironmentAuth();
if (!envToken) {
log('⚠️ No auth token found in CI environment', colors.yellow);
log(' Set MOONUI_AUTH_TOKEN environment variable for CI builds', colors.gray);
log(' Get your token by running: moonui whoami --token', colors.gray);
return;
}
// Validate CI auth
log('🔍 Validating CI authentication...', colors.blue);
const validation = await validateAuth(envToken);
if (validation.valid) {
log('✅ CI Authentication successful!', colors.green);
log(` Plan: ${validation.user?.plan || 'N/A'}`, colors.blue);
return;
} else {
log('❌ CI Authentication failed!', colors.red);
log(` Error: ${validation.message}`, colors.red);
process.exit(1);
}
}
// Regular installation - check for existing auth
const authConfig = getAuthConfig();
if (!authConfig || !authConfig.accessToken) {
log('🔐 MoonUI Pro Authentication Required', colors.yellow + colors.bright);
log('', '');
log('This package requires authentication with a MoonUI Pro account.', colors.yellow);
log('', '');
log('📋 Next Steps:', colors.blue + colors.bright);
log(' 1. Install MoonUI CLI: npm install -g @moontra/moonui-cli', colors.blue);
log(' 2. Login to your account: moonui login', colors.blue);
log(' 3. Or set environment variable: MOONUI_AUTH_TOKEN=<your-token>', colors.blue);
log('', '');
log('📖 Documentation: https://moonui.dev/docs/authentication', colors.gray);
log('🔧 Get your account: https://moonui.dev/pricing', colors.gray);
log('', '');
process.exit(1);
}
// Check if Pro access
const hasPro = authConfig.user?.plan === 'pro_monthly' ||
authConfig.user?.plan === 'pro_annual' ||
authConfig.user?.plan === 'pro_lifetime' ||
authConfig.user?.features?.includes('pro_components');
if (!hasPro) {
log('❌ MoonUI Pro Access Required', colors.red + colors.bright);
log('', '');
log('Your account does not have access to Pro components.', colors.red);
log(`Current plan: ${authConfig.user?.plan || 'free'}`, colors.yellow);
log('', '');
log('📋 Upgrade your account:', colors.blue + colors.bright);
log(' Visit: https://moonui.dev/pricing', colors.blue);
log('', '');
process.exit(1);
}
// Validate existing auth
log('🔍 Validating authentication...', colors.blue);
const validation = await validateAuth(authConfig.accessToken);
if (validation.valid) {
log('✅ Authentication successful!', colors.green + colors.bright);
log(` Plan: ${validation.user?.plan || authConfig.user?.plan}`, colors.blue);
log(` Account: ${authConfig.user?.email || 'N/A'}`, colors.blue);
if (validation.expiresAt) {
const expiryDate = new Date(validation.expiresAt);
const daysLeft = Math.ceil((expiryDate - new Date()) / (1000 * 60 * 60 * 24));
if (daysLeft > 0) {
log(` Expires: ${expiryDate.toLocaleDateString()} (${daysLeft} days)`, colors.blue);
} else {
log(` Status: EXPIRED on ${expiryDate.toLocaleDateString()}`, colors.red);
}
} else {
log(' Expires: Never (Lifetime)', colors.green);
}
if (validation.downloadLimit) {
const { current, max, period } = validation.downloadLimit;
const percentage = Math.round((current / max) * 100);
const warningColor = percentage > 80 ? colors.yellow : colors.blue;
log(` Usage: ${current}/${max} downloads this ${period} (${percentage}%)`, warningColor);
}
log('', '');
log('🚀 Ready to use MoonUI Pro components!', colors.green);
log(' Documentation: https://moonui.dev/docs/components', colors.gray);
} else {
log('❌ Authentication failed!', colors.red + colors.bright);
log(` Error: ${validation.message}`, colors.red);
log('', '');
if (validation.error === 'INVALID_TOKEN') {
log('🔧 Troubleshooting:', colors.yellow + colors.bright);
log(' • Your session may have expired', colors.yellow);
log(' • Run: moonui login', colors.yellow);
log(' • Contact support: support@moonui.dev', colors.yellow);
} else if (validation.error === 'NETWORK_ERROR') {
log('🌐 Network Issue:', colors.yellow + colors.bright);
log(' • Auth validation requires internet connection', colors.yellow);
log(' • Components will work offline after initial validation', colors.yellow);
log(' • Retry: npm install --force', colors.yellow);
}
log('', '');
log('📖 Auth Guide: https://moonui.dev/docs/authentication', colors.gray);
// Don't fail installation for network issues, only for invalid auth
if (validation.error === 'INVALID_TOKEN') {
process.exit(1);
}
}
log('═'.repeat(50), colors.gray);
log('', '');
};
// Run postinstall script
main().catch((error) => {
log('❌ Postinstall script failed:', colors.red);
log(` ${error.message}`, colors.red);
log('', '');
log('📖 If this persists, see: https://moonui.dev/docs/troubleshooting', colors.gray);
});