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