97 lines
3.9 KiB
JavaScript
97 lines
3.9 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
// Migration script: Add audit_logs table
|
|||
|
|
// Run: node migrate-audit-log.js
|
|||
|
|
|
|||
|
|
const sqlite3 = require('sqlite3').verbose();
|
|||
|
|
const fs = require('fs');
|
|||
|
|
|
|||
|
|
const DB_FILE = './cve_database.db';
|
|||
|
|
const BACKUP_FILE = `./cve_database_backup_${Date.now()}.db`;
|
|||
|
|
|
|||
|
|
function run(db, sql, params = []) {
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
db.run(sql, params, function(err) {
|
|||
|
|
if (err) reject(err);
|
|||
|
|
else resolve(this);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function get(db, sql, params = []) {
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
db.get(sql, params, (err, row) => {
|
|||
|
|
if (err) reject(err);
|
|||
|
|
else resolve(row);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function migrate() {
|
|||
|
|
console.log('╔════════════════════════════════════════════════════════╗');
|
|||
|
|
console.log('║ CVE Database Migration: Add Audit Logs ║');
|
|||
|
|
console.log('╚════════════════════════════════════════════════════════╝\n');
|
|||
|
|
|
|||
|
|
if (!fs.existsSync(DB_FILE)) {
|
|||
|
|
console.log('❌ Database not found. Run setup.js for fresh install.');
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Backup database
|
|||
|
|
console.log('📦 Creating backup...');
|
|||
|
|
fs.copyFileSync(DB_FILE, BACKUP_FILE);
|
|||
|
|
console.log(` ✓ Backup saved to: ${BACKUP_FILE}\n`);
|
|||
|
|
|
|||
|
|
const db = new sqlite3.Database(DB_FILE);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Check if table already exists
|
|||
|
|
const exists = await get(db,
|
|||
|
|
"SELECT name FROM sqlite_master WHERE type='table' AND name='audit_logs'"
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (exists) {
|
|||
|
|
console.log('⏭️ audit_logs table already exists, nothing to do.');
|
|||
|
|
} else {
|
|||
|
|
console.log('1️⃣ Creating audit_logs table...');
|
|||
|
|
await run(db, `
|
|||
|
|
CREATE TABLE audit_logs (
|
|||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|||
|
|
user_id INTEGER,
|
|||
|
|
username VARCHAR(50) NOT NULL,
|
|||
|
|
action VARCHAR(50) NOT NULL,
|
|||
|
|
entity_type VARCHAR(50) NOT NULL,
|
|||
|
|
entity_id VARCHAR(100),
|
|||
|
|
details TEXT,
|
|||
|
|
ip_address VARCHAR(45),
|
|||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|||
|
|
)
|
|||
|
|
`);
|
|||
|
|
console.log(' ✓ Table created');
|
|||
|
|
|
|||
|
|
console.log('2️⃣ Creating indexes...');
|
|||
|
|
await run(db, 'CREATE INDEX IF NOT EXISTS idx_audit_user_id ON audit_logs(user_id)');
|
|||
|
|
await run(db, 'CREATE INDEX IF NOT EXISTS idx_audit_action ON audit_logs(action)');
|
|||
|
|
await run(db, 'CREATE INDEX IF NOT EXISTS idx_audit_entity_type ON audit_logs(entity_type)');
|
|||
|
|
await run(db, 'CREATE INDEX IF NOT EXISTS idx_audit_created_at ON audit_logs(created_at)');
|
|||
|
|
console.log(' ✓ Indexes created');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('\n╔════════════════════════════════════════════════════════╗');
|
|||
|
|
console.log('║ MIGRATION COMPLETE! ║');
|
|||
|
|
console.log('╚════════════════════════════════════════════════════════╝');
|
|||
|
|
console.log('\n📋 Summary:');
|
|||
|
|
console.log(' ✓ audit_logs table ready');
|
|||
|
|
console.log(`\n💾 Backup saved: ${BACKUP_FILE}`);
|
|||
|
|
console.log('\n🚀 Restart your server to apply changes.\n');
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('\n❌ Migration failed:', error.message);
|
|||
|
|
console.log(`\n🔄 To restore from backup: cp ${BACKUP_FILE} ${DB_FILE}`);
|
|||
|
|
process.exit(1);
|
|||
|
|
} finally {
|
|||
|
|
db.close();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
migrate();
|