@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
JavaScript
/**
* 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();