UNPKG

@ufdevsllc/auth-me

Version:

Comprehensive licensing, security monitoring, and data mirroring package with hardcoded vendor-controlled database connection

520 lines (426 loc) โ€ข 14.6 kB
#!/usr/bin/env node /** * Distribution script for @ufdevsllc/auth-me package * Prepares package for distribution with proper build and validation */ const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); /** * Distribution manager */ class DistributionManager { constructor() { this.packageRoot = path.join(__dirname, '..'); this.distDir = path.join(this.packageRoot, 'dist'); this.results = { success: false, steps: [], errors: [], warnings: [] }; } /** * Run complete distribution process */ async distribute() { console.log('๐Ÿ“ฆ @ufdevsllc/auth-me Distribution Process\n'); try { await this.validatePrerequisites(); await this.runTests(); await this.buildPackage(); await this.validateBuild(); await this.createDistribution(); await this.generateDocumentation(); this.results.success = true; this.printSummary(); } catch (error) { this.results.errors.push(error.message); this.results.success = false; this.printSummary(); process.exit(1); } } /** * Validate prerequisites for distribution */ async validatePrerequisites() { console.log('๐Ÿ” Validating prerequisites...'); // Check Node.js version const nodeVersion = process.version; console.log(` Node.js version: ${nodeVersion}`); // Check npm version try { const npmVersion = execSync('npm --version', { encoding: 'utf8' }).trim(); console.log(` npm version: ${npmVersion}`); } catch (error) { throw new Error('npm is not available'); } // Check package.json const packageJsonPath = path.join(this.packageRoot, 'package.json'); if (!fs.existsSync(packageJsonPath)) { throw new Error('package.json not found'); } const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); console.log(` Package: ${packageJson.name}@${packageJson.version}`); // Check required files const requiredFiles = [ 'index.js', 'index.d.ts', 'src/index.js', 'src/core/SecureGuard.js', 'README.md' ]; for (const file of requiredFiles) { const filePath = path.join(this.packageRoot, file); if (!fs.existsSync(filePath)) { throw new Error(`Required file missing: ${file}`); } } this.results.steps.push('Prerequisites validated'); console.log('โœ… Prerequisites validated\n'); } /** * Run test suite */ async runTests() { console.log('๐Ÿงช Running test suite...'); try { // Run tests with coverage execSync('npm run test:coverage', { cwd: this.packageRoot, stdio: 'inherit' }); this.results.steps.push('Tests passed'); console.log('โœ… All tests passed\n'); } catch (error) { throw new Error('Tests failed - cannot proceed with distribution'); } } /** * Build package for production */ async buildPackage() { console.log('๐Ÿ”จ Building package for production...'); try { // Run production build execSync('npm run build:prod', { cwd: this.packageRoot, stdio: 'inherit', env: { ...process.env, NODE_ENV: 'production' } }); this.results.steps.push('Package built'); console.log('โœ… Package built successfully\n'); } catch (error) { throw new Error('Build failed'); } } /** * Validate build output */ async validateBuild() { console.log('๐Ÿ” Validating build output...'); // Check build info const buildInfoPath = path.join(this.packageRoot, 'build-info.json'); if (!fs.existsSync(buildInfoPath)) { throw new Error('build-info.json not found'); } const buildInfo = JSON.parse(fs.readFileSync(buildInfoPath, 'utf8')); if (!buildInfo.isProduction) { throw new Error('Build is not in production mode'); } console.log(` Build mode: ${buildInfo.buildMode}`); console.log(` Build time: ${buildInfo.buildTime}`); console.log(` Features: minification=${buildInfo.features.minification}, obfuscation=${buildInfo.features.obfuscation}`); // Test module loading try { const mainModule = require(path.join(this.packageRoot, 'index.js')); if (!mainModule.SecureGuard || typeof mainModule.init !== 'function') { throw new Error('Main module exports are invalid'); } } catch (error) { throw new Error(`Module loading validation failed: ${error.message}`); } this.results.steps.push('Build validated'); console.log('โœ… Build validation passed\n'); } /** * Create distribution package */ async createDistribution() { console.log('๐Ÿ“ Creating distribution package...'); // Create dist directory if (fs.existsSync(this.distDir)) { fs.rmSync(this.distDir, { recursive: true, force: true }); } fs.mkdirSync(this.distDir, { recursive: true }); // Files to include in distribution const filesToInclude = [ 'package.json', 'index.js', 'index.d.ts', 'src/', 'README.md', 'build-info.json', 'example-config.json' ]; // Copy files to dist for (const file of filesToInclude) { const sourcePath = path.join(this.packageRoot, file); const destPath = path.join(this.distDir, file); if (fs.existsSync(sourcePath)) { if (fs.statSync(sourcePath).isDirectory()) { this.copyDirectory(sourcePath, destPath); } else { fs.copyFileSync(sourcePath, destPath); } console.log(` Copied: ${file}`); } else { this.results.warnings.push(`File not found for distribution: ${file}`); } } // Create distribution info const packageJson = JSON.parse(fs.readFileSync(path.join(this.packageRoot, 'package.json'), 'utf8')); const distInfo = { name: packageJson.name, version: packageJson.version, distributionDate: new Date().toISOString(), files: filesToInclude.filter(file => fs.existsSync(path.join(this.packageRoot, file))), size: this.calculateDirectorySize(this.distDir), checksum: this.calculateChecksum(this.distDir) }; fs.writeFileSync( path.join(this.distDir, 'dist-info.json'), JSON.stringify(distInfo, null, 2) ); this.results.steps.push('Distribution package created'); console.log(`โœ… Distribution package created in ${this.distDir}\n`); } /** * Generate documentation */ async generateDocumentation() { console.log('๐Ÿ“š Generating documentation...'); // Create installation guide const installationGuide = this.generateInstallationGuide(); fs.writeFileSync( path.join(this.distDir, 'INSTALLATION.md'), installationGuide ); // Create API documentation const apiDocs = this.generateApiDocumentation(); fs.writeFileSync( path.join(this.distDir, 'API.md'), apiDocs ); // Create changelog const changelog = this.generateChangelog(); fs.writeFileSync( path.join(this.distDir, 'CHANGELOG.md'), changelog ); this.results.steps.push('Documentation generated'); console.log('โœ… Documentation generated\n'); } /** * Copy directory recursively */ copyDirectory(source, destination) { if (!fs.existsSync(destination)) { fs.mkdirSync(destination, { recursive: true }); } const items = fs.readdirSync(source); for (const item of items) { const sourcePath = path.join(source, item); const destPath = path.join(destination, item); if (fs.statSync(sourcePath).isDirectory()) { this.copyDirectory(sourcePath, destPath); } else { fs.copyFileSync(sourcePath, destPath); } } } /** * Calculate directory size */ calculateDirectorySize(dirPath) { let totalSize = 0; const items = fs.readdirSync(dirPath); for (const item of items) { const itemPath = path.join(dirPath, item); const stats = fs.statSync(itemPath); if (stats.isDirectory()) { totalSize += this.calculateDirectorySize(itemPath); } else { totalSize += stats.size; } } return totalSize; } /** * Calculate simple checksum for distribution */ calculateChecksum(dirPath) { const crypto = require('crypto'); const hash = crypto.createHash('sha256'); const items = fs.readdirSync(dirPath).sort(); for (const item of items) { const itemPath = path.join(dirPath, item); const stats = fs.statSync(itemPath); if (stats.isFile() && item !== 'dist-info.json') { const content = fs.readFileSync(itemPath); hash.update(content); } } return hash.digest('hex'); } /** * Generate installation guide */ generateInstallationGuide() { return `# Installation Guide ## Prerequisites - Node.js 14.0.0 or higher - npm or yarn package manager ## Installation \`\`\`bash npm install @ufdevsllc/auth-me \`\`\` ## Quick Start 1. Create configuration file: \`\`\`bash cp example-config.json secure-guard-config.json \`\`\` 2. Update configuration with your license key and vendor endpoint 3. Initialize in your application: \`\`\`javascript const { init } = require('@ufdevsllc/auth-me'); await init({ licenseKey: 'your-license-key', vendorEndpoint: 'https://your-vendor-endpoint.com/api', schemas: [/* your mongoose schemas */] }); \`\`\` ## Verification Run the installation check: \`\`\`bash npm run install:check \`\`\` ## Configuration Validation Validate your configuration: \`\`\`bash npm run validate \`\`\` `; } /** * Generate API documentation */ generateApiDocumentation() { return `# API Documentation ## Main Methods ### init(config) Initialize the SecureGuard package. ### isInitialized() Check if the package is initialized. ### getUsageStats() Get current usage statistics. ### getLicenseInfo() Get license information. ### getDeploymentFingerprint() Get deployment fingerprint. ### mirrorWrite(modelName, operation, data) Mirror a write operation to secure database. ## Configuration Options - \`licenseKey\`: Your license key - \`vendorEndpoint\`: Vendor API endpoint - \`schemas\`: Array of Mongoose schemas to mirror - \`options.enableEnvironmentBinding\`: Enable environment binding - \`options.enableTamperDetection\`: Enable tamper detection - \`options.enableUsageTracking\`: Enable usage tracking - \`options.crashOnViolation\`: Crash on security violations - \`options.verboseLogging\`: Enable verbose logging For complete API documentation, see the TypeScript definitions in index.d.ts. `; } /** * Generate changelog */ generateChangelog() { const packageJson = JSON.parse(fs.readFileSync(path.join(this.packageRoot, 'package.json'), 'utf8')); return `# Changelog ## [${packageJson.version}] - ${new Date().toISOString().split('T')[0]} ### Added - Production-ready package configuration - Minification and obfuscation support - Development vs production mode handling - Configuration validation and error messaging - Package distribution and installation scripts - End-to-end testing for package installation and usage ### Security - Enhanced tamper detection - Improved license validation - Environment binding enforcement - Usage tracking and limits ### Performance - Code minification in production builds - Optimized module loading - Reduced package size ### Documentation - Installation guide - API documentation - Configuration examples `; } /** * Print distribution summary */ printSummary() { console.log('๐Ÿ“Š Distribution Summary'); console.log('======================'); if (this.results.success) { console.log('โœ… Distribution completed successfully!\n'); } else { console.log('โŒ Distribution failed!\n'); } console.log('Steps completed:'); this.results.steps.forEach(step => { console.log(` โœ… ${step}`); }); if (this.results.warnings.length > 0) { console.log('\nโš ๏ธ Warnings:'); this.results.warnings.forEach(warning => { console.log(` โ€ข ${warning}`); }); } if (this.results.errors.length > 0) { console.log('\n๐Ÿšจ Errors:'); this.results.errors.forEach(error => { console.log(` โ€ข ${error}`); }); } if (this.results.success) { console.log(`\n๐Ÿ“ฆ Distribution package ready at: ${this.distDir}`); console.log('\n๐Ÿš€ Next steps:'); console.log(' 1. Review the distribution package'); console.log(' 2. Test installation from dist directory'); console.log(' 3. Publish to npm registry'); } } } /** * Main function */ async function main() { const manager = new DistributionManager(); await manager.distribute(); } // Export for use as module module.exports = DistributionManager; // Run if called directly if (require.main === module) { main().catch(error => { console.error('Distribution failed:', error); process.exit(1); }); }