Added NVD lookup features and optional NVD API key in .env file

This commit is contained in:
2026-02-02 10:50:38 -07:00
parent 260ae48f77
commit da109a6f8b
7 changed files with 855 additions and 11 deletions

View File

@@ -17,6 +17,7 @@ const createAuthRouter = require('./routes/auth');
const createUsersRouter = require('./routes/users');
const createAuditLogRouter = require('./routes/auditLog');
const logAudit = require('./helpers/auditLog');
const createNvdLookupRouter = require('./routes/nvdLookup');
const app = express();
const PORT = process.env.PORT || 3001;
@@ -56,6 +57,9 @@ app.use('/api/users', createUsersRouter(db, requireAuth, requireRole, logAudit))
// Audit log routes (admin only)
app.use('/api/audit-logs', createAuditLogRouter(db, requireAuth, requireRole));
// NVD lookup routes (authenticated users)
app.use('/api/nvd', createNvdLookupRouter(db, requireAuth));
// Simple storage - upload to temp directory first
const storage = multer.diskStorage({
destination: (req, file, cb) => {
@@ -125,6 +129,14 @@ app.get('/api/cves', requireAuth(db), (req, res) => {
});
});
// Get distinct CVE IDs for NVD sync (authenticated users)
app.get('/api/cves/distinct-ids', requireAuth(db), (req, res) => {
db.all('SELECT DISTINCT cve_id FROM cves ORDER BY cve_id', [], (err, rows) => {
if (err) return res.status(500).json({ error: err.message });
res.json(rows.map(r => r.cve_id));
});
});
// Check if CVE exists and get its status - UPDATED FOR MULTI-VENDOR (authenticated users)
app.get('/api/cves/check/:cveId', requireAuth(db), (req, res) => {
const { cveId } = req.params;
@@ -262,6 +274,73 @@ app.patch('/api/cves/:cveId/status', requireAuth(db), requireRole('editor', 'adm
});
});
// Bulk sync CVE data from NVD (editor or admin)
app.post('/api/cves/nvd-sync', requireAuth(db), requireRole('editor', 'admin'), (req, res) => {
const { updates } = req.body;
if (!Array.isArray(updates) || updates.length === 0) {
return res.status(400).json({ error: 'No updates provided' });
}
let updated = 0;
const errors = [];
let completed = 0;
db.serialize(() => {
updates.forEach((entry) => {
const fields = [];
const values = [];
if (entry.description !== null && entry.description !== undefined) {
fields.push('description = ?');
values.push(entry.description);
}
if (entry.severity !== null && entry.severity !== undefined) {
fields.push('severity = ?');
values.push(entry.severity);
}
if (entry.published_date !== null && entry.published_date !== undefined) {
fields.push('published_date = ?');
values.push(entry.published_date);
}
if (fields.length === 0) {
completed++;
if (completed === updates.length) sendResponse();
return;
}
fields.push('updated_at = CURRENT_TIMESTAMP');
values.push(entry.cve_id);
db.run(
`UPDATE cves SET ${fields.join(', ')} WHERE cve_id = ?`,
values,
function(err) {
if (err) {
errors.push({ cve_id: entry.cve_id, error: err.message });
} else {
updated += this.changes;
}
completed++;
if (completed === updates.length) sendResponse();
}
);
});
});
function sendResponse() {
logAudit(db, {
userId: req.user.id,
username: req.user.username,
action: 'cve_nvd_sync',
entityType: 'cve',
entityId: null,
details: { count: updated, cve_ids: updates.map(u => u.cve_id) },
ipAddress: req.ip
});
const result = { message: 'NVD sync completed', updated };
if (errors.length > 0) result.errors = errors;
res.json(result);
}
});
// ========== DOCUMENT ENDPOINTS ==========
// Get documents for a CVE - FILTER BY VENDOR (authenticated users)