tops-bmad
Version:
CLI tool to install BMAD workflow files into any project with integrated Shai-Hulud 2.0 security scanning
106 lines (86 loc) • 3.27 kB
JavaScript
/**
* TOPS BMAD Security Scanner - Package Database Updater
*
* Updates the compromised packages database by merging organization-specific packages
*
* Usage:
* node update-package-db.js
*/
import { readFileSync, existsSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const dbPath = join(__dirname, '..', 'Shai-Hulud-2.0-Detector', 'compromised-packages.json');
const orgDbPath = join(__dirname, '..', 'config', 'organization-packages.json');
function loadDatabase() {
if (!existsSync(dbPath)) {
console.error('❌ Compromised packages database not found');
console.error(` Expected at: ${dbPath}`);
process.exit(1);
}
try {
return JSON.parse(readFileSync(dbPath, 'utf8'));
} catch (error) {
console.error('❌ Error reading database:', error.message);
process.exit(1);
}
}
function loadOrgDatabase() {
if (!existsSync(orgDbPath)) {
console.log('ℹ️ No organization-specific database found');
console.log(` Create ${orgDbPath} to add organization-specific packages`);
return {
version: '1.0.0',
lastUpdated: new Date().toISOString(),
packages: []
};
}
try {
return JSON.parse(readFileSync(orgDbPath, 'utf8'));
} catch (error) {
console.warn('⚠️ Error reading organization database:', error.message);
return {
version: '1.0.0',
lastUpdated: new Date().toISOString(),
packages: []
};
}
}
function main() {
console.log('📦 Updating package database...\n');
const masterDb = loadDatabase();
const orgDb = loadOrgDatabase();
console.log(`📊 Master database: ${masterDb.packages.length} packages`);
console.log(`📊 Organization database: ${orgDb.packages.length} packages`);
// Check for duplicates and new packages
const masterPackageNames = new Set(masterDb.packages.map(p => p.name));
const newPackages = [];
const duplicates = [];
for (const orgPkg of orgDb.packages) {
if (masterPackageNames.has(orgPkg.name)) {
duplicates.push(orgPkg.name);
} else {
newPackages.push(orgPkg);
}
}
if (duplicates.length > 0) {
console.log(`\n⚠️ Found ${duplicates.length} duplicate packages (already in master database):`);
duplicates.forEach(name => console.log(` - ${name}`));
}
if (newPackages.length > 0) {
console.log(`\n➕ Found ${newPackages.length} new organization-specific packages:`);
newPackages.forEach(pkg => console.log(` - ${pkg.name} (${pkg.severity})`));
} else {
console.log('\n✅ No new packages to add');
}
console.log(`\n📊 Total packages in master database: ${masterDb.packages.length}`);
console.log(`📊 Total organization packages: ${orgDb.packages.length}`);
console.log(`📊 New packages to add: ${newPackages.length}`);
console.log(`📊 Total after merge: ${masterDb.packages.length + newPackages.length}`);
console.log('\n✅ Database is up to date');
console.log('\n💡 Note: Organization-specific packages are tracked separately.');
console.log(' The scanner will check both databases during scans.');
}
main();