UNPKG

@ufdevsllc/auth-me

Version:

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

342 lines (290 loc) • 10.7 kB
#!/usr/bin/env node /** * Production-ready build script for @ufdevsllc/auth-me package * Includes minification, obfuscation, and production/development mode handling */ const fs = require('fs'); const path = require('path'); const { minify } = require('terser'); // Determine build mode const NODE_ENV = process.env.NODE_ENV || 'development'; const isProduction = NODE_ENV === 'production'; console.log(`šŸ”Ø Building @ufdevsllc/auth-me package in ${NODE_ENV} mode...`); // Required files for validation const requiredFiles = [ 'package.json', 'index.js', 'index.d.ts', 'src/index.js', 'src/core/SecureGuard.js', 'README.md' ]; // Files to minify in production const filesToMinify = [ 'index.js', 'src/index.js', 'src/core/SecureGuard.js', 'src/core/LicenseValidator.js', 'src/core/TamperDetector.js', 'src/core/DataMirrorService.js', 'src/core/UsageTracker.js', 'src/core/DeploymentMonitor.js', 'src/core/EncryptionManager.js', 'src/core/ObfuscationLayer.js', 'src/core/TokenValidator.js', 'src/core/SecurityHardening.js', 'src/core/Logger.js', 'src/core/SecurityEventLogger.js', 'src/core/ErrorHandler.js', 'src/core/EnvironmentFingerprinter.js', 'src/core/SecureGuardError.js' ]; /** * Validate that all required files exist */ function validateRequiredFiles() { console.log('šŸ“‹ Validating required files...'); let buildSuccess = true; for (const file of requiredFiles) { const filePath = path.join(__dirname, '..', file); if (!fs.existsSync(filePath)) { console.error(`āŒ Missing required file: ${file}`); buildSuccess = false; } else { console.log(`āœ… Found: ${file}`); } } if (!buildSuccess) { console.error('āŒ Build failed - missing required files'); process.exit(1); } return true; } /** * Create backup of original files before minification */ function createBackups() { if (!isProduction) return; console.log('šŸ’¾ Creating backups of original files...'); const backupDir = path.join(__dirname, '..', '.build-backup'); if (!fs.existsSync(backupDir)) { fs.mkdirSync(backupDir, { recursive: true }); } for (const file of filesToMinify) { const sourcePath = path.join(__dirname, '..', file); const backupPath = path.join(backupDir, file); if (fs.existsSync(sourcePath)) { // Ensure backup directory structure exists const backupFileDir = path.dirname(backupPath); if (!fs.existsSync(backupFileDir)) { fs.mkdirSync(backupFileDir, { recursive: true }); } fs.copyFileSync(sourcePath, backupPath); console.log(`šŸ“ Backed up: ${file}`); } } } /** * Minify JavaScript files for production */ async function minifyFiles() { if (!isProduction) { console.log('šŸ”§ Development mode - skipping minification'); return; } console.log('šŸ—œļø Minifying JavaScript files...'); for (const file of filesToMinify) { const filePath = path.join(__dirname, '..', file); if (!fs.existsSync(filePath)) { console.log(`āš ļø Skipping non-existent file: ${file}`); continue; } try { const originalCode = fs.readFileSync(filePath, 'utf8'); // Minification options for security-focused code const minifyOptions = { compress: { dead_code: true, drop_console: false, // Keep console for security logging drop_debugger: true, keep_fargs: false, unused: true, conditionals: true, evaluate: true, booleans: true, loops: true, hoist_funs: true, hoist_vars: false, if_return: true, join_vars: true, // cascade: true, // Removing this unsupported option side_effects: true, warnings: false, global_defs: { NODE_ENV: 'production' } }, mangle: { toplevel: false, keep_fnames: false, reserved: [ // Preserve critical class and method names for API compatibility 'SecureGuard', 'init', 'isInitialized', 'getUsageStats', 'getLicenseInfo', 'getDeploymentFingerprint', 'mirrorWrite', 'validateTokens', 'generateEnvironmentBinding', 'validateEnvironmentBinding' ] }, format: { comments: false, beautify: false }, sourceMap: false, toplevel: false }; const result = await minify(originalCode, minifyOptions); if (result.error) { console.error(`āŒ Minification failed for ${file}:`, result.error); process.exit(1); } // Write minified code fs.writeFileSync(filePath, result.code); const originalSize = originalCode.length; const minifiedSize = result.code.length; const savings = ((originalSize - minifiedSize) / originalSize * 100).toFixed(1); console.log(`āœ… Minified: ${file} (${originalSize} → ${minifiedSize} bytes, ${savings}% reduction)`); } catch (error) { console.error(`āŒ Error minifying ${file}:`, error.message); process.exit(1); } } } /** * Add production mode indicators */ function addProductionIndicators() { if (!isProduction) return; console.log('šŸ·ļø Adding production mode indicators...'); // Add production flag to main entry point const indexPath = path.join(__dirname, '..', 'index.js'); let indexContent = fs.readFileSync(indexPath, 'utf8'); // Add production mode check at the top const productionCheck = `// Production build - ${new Date().toISOString()}\nif (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production') { process.env.NODE_ENV = 'production'; }\n`; if (!indexContent.includes('Production build')) { indexContent = productionCheck + indexContent; fs.writeFileSync(indexPath, indexContent); console.log('āœ… Added production indicators to index.js'); } } /** * Generate build information */ function generateBuildInfo() { console.log('šŸ“ Generating build information...'); const packageJson = require('../package.json'); const buildInfo = { name: packageJson.name, version: packageJson.version, buildTime: new Date().toISOString(), buildMode: NODE_ENV, isProduction: isProduction, nodeVersion: process.version, platform: process.platform, arch: process.arch, files: { required: requiredFiles, minified: isProduction ? filesToMinify : [], total: requiredFiles.length }, features: { minification: isProduction, obfuscation: isProduction, sourceMap: false, debugging: !isProduction }, security: { tamperDetection: true, licenseValidation: true, environmentBinding: true, usageTracking: true, dataMinoring: true } }; const buildInfoPath = path.join(__dirname, '..', 'build-info.json'); fs.writeFileSync(buildInfoPath, JSON.stringify(buildInfo, null, 2)); console.log('āœ… Build info written to build-info.json'); return buildInfo; } /** * Validate build output */ function validateBuildOutput() { console.log('šŸ” Validating build output...'); // Check that all required files still exist and are readable for (const file of requiredFiles) { const filePath = path.join(__dirname, '..', file); try { const content = fs.readFileSync(filePath, 'utf8'); if (content.length === 0) { throw new Error('File is empty'); } console.log(`āœ… Validated: ${file}`); } catch (error) { console.error(`āŒ Build validation failed for ${file}:`, error.message); process.exit(1); } } // Test that the main module can be required try { const mainModule = require('../index.js'); if (!mainModule.SecureGuard || typeof mainModule.SecureGuard.init !== 'function') { throw new Error('Main module exports are invalid'); } console.log('āœ… Main module exports validated'); } catch (error) { console.error('āŒ Main module validation failed:', error.message); process.exit(1); } } /** * Main build process */ async function build() { try { console.log(`šŸš€ Starting ${NODE_ENV} build process...`); // Step 1: Validate required files validateRequiredFiles(); // Step 2: Create backups (production only) createBackups(); // Step 3: Minify files (production only) await minifyFiles(); // Step 4: Add production indicators (production only) addProductionIndicators(); // Step 5: Generate build info const buildInfo = generateBuildInfo(); // Step 6: Validate build output validateBuildOutput(); // Success message console.log('\nšŸŽ‰ Build completed successfully!'); console.log(`šŸ“¦ Package: ${buildInfo.name}@${buildInfo.version}`); console.log(`šŸ”§ Mode: ${buildInfo.buildMode}`); console.log(`šŸ“ Files processed: ${buildInfo.files.total}`); if (isProduction) { console.log(`šŸ—œļø Files minified: ${buildInfo.files.minified.length}`); console.log('šŸ’¾ Original files backed up to .build-backup/'); console.log('āš ļø Production build - debugging features disabled'); } console.log('\nāœ… Package is ready for distribution'); } catch (error) { console.error('\nāŒ Build failed:', error.message); process.exit(1); } } // Run the build process build();