aura-security 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +446 -0
- package/deploy/AWS-DEPLOYMENT.md +358 -0
- package/deploy/terraform/main.tf +362 -0
- package/deploy/terraform/terraform.tfvars.example +6 -0
- package/dist/agents/base.d.ts +44 -0
- package/dist/agents/base.js +96 -0
- package/dist/agents/index.d.ts +14 -0
- package/dist/agents/index.js +17 -0
- package/dist/agents/policy/evaluator.d.ts +15 -0
- package/dist/agents/policy/evaluator.js +183 -0
- package/dist/agents/policy/index.d.ts +12 -0
- package/dist/agents/policy/index.js +15 -0
- package/dist/agents/policy/validator.d.ts +15 -0
- package/dist/agents/policy/validator.js +182 -0
- package/dist/agents/scanners/gitleaks.d.ts +14 -0
- package/dist/agents/scanners/gitleaks.js +155 -0
- package/dist/agents/scanners/grype.d.ts +14 -0
- package/dist/agents/scanners/grype.js +109 -0
- package/dist/agents/scanners/index.d.ts +15 -0
- package/dist/agents/scanners/index.js +27 -0
- package/dist/agents/scanners/npm-audit.d.ts +13 -0
- package/dist/agents/scanners/npm-audit.js +129 -0
- package/dist/agents/scanners/semgrep.d.ts +14 -0
- package/dist/agents/scanners/semgrep.js +131 -0
- package/dist/agents/scanners/trivy.d.ts +14 -0
- package/dist/agents/scanners/trivy.js +122 -0
- package/dist/agents/types.d.ts +137 -0
- package/dist/agents/types.js +91 -0
- package/dist/auditor/index.d.ts +3 -0
- package/dist/auditor/index.js +2 -0
- package/dist/auditor/pipeline.d.ts +19 -0
- package/dist/auditor/pipeline.js +240 -0
- package/dist/auditor/validator.d.ts +17 -0
- package/dist/auditor/validator.js +58 -0
- package/dist/aura/client.d.ts +29 -0
- package/dist/aura/client.js +125 -0
- package/dist/aura/index.d.ts +4 -0
- package/dist/aura/index.js +2 -0
- package/dist/aura/server.d.ts +45 -0
- package/dist/aura/server.js +343 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +1433 -0
- package/dist/client/index.d.ts +41 -0
- package/dist/client/index.js +170 -0
- package/dist/compliance/index.d.ts +40 -0
- package/dist/compliance/index.js +292 -0
- package/dist/database/index.d.ts +77 -0
- package/dist/database/index.js +395 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +762 -0
- package/dist/integrations/aura-scanner.d.ts +69 -0
- package/dist/integrations/aura-scanner.js +155 -0
- package/dist/integrations/aws-scanner.d.ts +63 -0
- package/dist/integrations/aws-scanner.js +624 -0
- package/dist/integrations/config.d.ts +69 -0
- package/dist/integrations/config.js +212 -0
- package/dist/integrations/github.d.ts +45 -0
- package/dist/integrations/github.js +201 -0
- package/dist/integrations/gitlab.d.ts +36 -0
- package/dist/integrations/gitlab.js +110 -0
- package/dist/integrations/index.d.ts +11 -0
- package/dist/integrations/index.js +11 -0
- package/dist/integrations/local-scanner.d.ts +146 -0
- package/dist/integrations/local-scanner.js +1654 -0
- package/dist/integrations/notifications.d.ts +99 -0
- package/dist/integrations/notifications.js +305 -0
- package/dist/integrations/scanners.d.ts +57 -0
- package/dist/integrations/scanners.js +217 -0
- package/dist/integrations/slop-scanner.d.ts +69 -0
- package/dist/integrations/slop-scanner.js +155 -0
- package/dist/integrations/webhook.d.ts +37 -0
- package/dist/integrations/webhook.js +256 -0
- package/dist/orchestrator/index.d.ts +72 -0
- package/dist/orchestrator/index.js +187 -0
- package/dist/output/index.d.ts +152 -0
- package/dist/output/index.js +399 -0
- package/dist/pipeline/index.d.ts +72 -0
- package/dist/pipeline/index.js +313 -0
- package/dist/sbom/index.d.ts +94 -0
- package/dist/sbom/index.js +298 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/input.schema.d.ts +87 -0
- package/dist/schemas/input.schema.js +44 -0
- package/dist/schemas/output.schema.d.ts +115 -0
- package/dist/schemas/output.schema.js +64 -0
- package/dist/serve-visualizer.d.ts +2 -0
- package/dist/serve-visualizer.js +78 -0
- package/dist/slop/client.d.ts +29 -0
- package/dist/slop/client.js +125 -0
- package/dist/slop/index.d.ts +4 -0
- package/dist/slop/index.js +2 -0
- package/dist/slop/server.d.ts +45 -0
- package/dist/slop/server.js +343 -0
- package/dist/types/events.d.ts +62 -0
- package/dist/types/events.js +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/visualizer/index.d.ts +4 -0
- package/dist/visualizer/index.js +181 -0
- package/dist/websocket/index.d.ts +88 -0
- package/dist/websocket/index.js +195 -0
- package/dist/zones/index.d.ts +7 -0
- package/dist/zones/index.js +7 -0
- package/dist/zones/manager.d.ts +101 -0
- package/dist/zones/manager.js +304 -0
- package/dist/zones/types.d.ts +78 -0
- package/dist/zones/types.js +33 -0
- package/package.json +84 -0
- package/visualizer/app.js +0 -0
- package/visualizer/index-minimal.html +1771 -0
- package/visualizer/index.html +2933 -0
- package/visualizer/landing.html +1328 -0
- package/visualizer/styles.css +0 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Database for aurasecurity
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent storage for:
|
|
5
|
+
* - Audit history
|
|
6
|
+
* - Configuration settings
|
|
7
|
+
* - Scan results
|
|
8
|
+
* - Notification history
|
|
9
|
+
*/
|
|
10
|
+
import Database from 'better-sqlite3';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
13
|
+
// ============ DEFAULT SETTINGS ============
|
|
14
|
+
const DEFAULT_SETTINGS = {
|
|
15
|
+
// AWS Settings
|
|
16
|
+
'aws.enabled': 'false',
|
|
17
|
+
'aws.region': 'us-east-1',
|
|
18
|
+
'aws.accessKeyId': '',
|
|
19
|
+
'aws.secretAccessKey': '',
|
|
20
|
+
'aws.services': 'iam,s3,ec2,lambda,rds',
|
|
21
|
+
// Slack Settings
|
|
22
|
+
'slack.enabled': 'false',
|
|
23
|
+
'slack.webhookUrl': '',
|
|
24
|
+
'slack.channel': '',
|
|
25
|
+
'slack.notifyOn': 'critical,high',
|
|
26
|
+
// Discord Settings
|
|
27
|
+
'discord.enabled': 'false',
|
|
28
|
+
'discord.webhookUrl': '',
|
|
29
|
+
'discord.notifyOn': 'critical,high',
|
|
30
|
+
// GitHub Settings
|
|
31
|
+
'github.enabled': 'false',
|
|
32
|
+
'github.token': '',
|
|
33
|
+
'github.createCheckRuns': 'true',
|
|
34
|
+
'github.commentOnPR': 'true',
|
|
35
|
+
// GitLab Settings
|
|
36
|
+
'gitlab.enabled': 'false',
|
|
37
|
+
'gitlab.token': '',
|
|
38
|
+
'gitlab.url': 'https://gitlab.com',
|
|
39
|
+
// Scanner Settings
|
|
40
|
+
'scanner.gitleaks': 'true',
|
|
41
|
+
'scanner.trivy': 'true',
|
|
42
|
+
'scanner.semgrep': 'true',
|
|
43
|
+
'scanner.npmAudit': 'true',
|
|
44
|
+
// Thresholds
|
|
45
|
+
'thresholds.failOnCritical': 'true',
|
|
46
|
+
'thresholds.failOnHigh': 'false',
|
|
47
|
+
'thresholds.maxCritical': '0',
|
|
48
|
+
'thresholds.maxHigh': '5',
|
|
49
|
+
// Server Settings
|
|
50
|
+
'server.port': '3000',
|
|
51
|
+
'server.visualizerPort': '8080',
|
|
52
|
+
};
|
|
53
|
+
// ============ DATABASE CLASS ============
|
|
54
|
+
export class AuditorDatabase {
|
|
55
|
+
db;
|
|
56
|
+
dbPath;
|
|
57
|
+
constructor(dbPath) {
|
|
58
|
+
// Default to .aura-security directory in user home
|
|
59
|
+
const dataDir = dbPath
|
|
60
|
+
? join(dbPath, '.aura-security')
|
|
61
|
+
: join(process.env.HOME || process.env.USERPROFILE || '.', '.aura-security');
|
|
62
|
+
if (!existsSync(dataDir)) {
|
|
63
|
+
mkdirSync(dataDir, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
this.dbPath = join(dataDir, 'auditor.db');
|
|
66
|
+
this.db = new Database(this.dbPath);
|
|
67
|
+
// Enable WAL mode for better concurrent access
|
|
68
|
+
this.db.pragma('journal_mode = WAL');
|
|
69
|
+
// Initialize tables
|
|
70
|
+
this.initTables();
|
|
71
|
+
console.log(`[DB] SQLite database initialized at: ${this.dbPath}`);
|
|
72
|
+
}
|
|
73
|
+
initTables() {
|
|
74
|
+
// Audits table
|
|
75
|
+
this.db.exec(`
|
|
76
|
+
CREATE TABLE IF NOT EXISTS audits (
|
|
77
|
+
id TEXT PRIMARY KEY,
|
|
78
|
+
type TEXT NOT NULL,
|
|
79
|
+
timestamp TEXT NOT NULL,
|
|
80
|
+
target TEXT NOT NULL,
|
|
81
|
+
critical INTEGER DEFAULT 0,
|
|
82
|
+
high INTEGER DEFAULT 0,
|
|
83
|
+
medium INTEGER DEFAULT 0,
|
|
84
|
+
low INTEGER DEFAULT 0,
|
|
85
|
+
data TEXT NOT NULL
|
|
86
|
+
)
|
|
87
|
+
`);
|
|
88
|
+
// Settings table
|
|
89
|
+
this.db.exec(`
|
|
90
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
91
|
+
key TEXT PRIMARY KEY,
|
|
92
|
+
value TEXT NOT NULL,
|
|
93
|
+
updated_at TEXT NOT NULL
|
|
94
|
+
)
|
|
95
|
+
`);
|
|
96
|
+
// Notifications table
|
|
97
|
+
this.db.exec(`
|
|
98
|
+
CREATE TABLE IF NOT EXISTS notifications (
|
|
99
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
100
|
+
type TEXT NOT NULL,
|
|
101
|
+
audit_id TEXT NOT NULL,
|
|
102
|
+
status TEXT NOT NULL,
|
|
103
|
+
message TEXT NOT NULL,
|
|
104
|
+
timestamp TEXT NOT NULL,
|
|
105
|
+
error TEXT,
|
|
106
|
+
FOREIGN KEY (audit_id) REFERENCES audits(id)
|
|
107
|
+
)
|
|
108
|
+
`);
|
|
109
|
+
// Create indexes
|
|
110
|
+
this.db.exec(`
|
|
111
|
+
CREATE INDEX IF NOT EXISTS idx_audits_timestamp ON audits(timestamp DESC);
|
|
112
|
+
CREATE INDEX IF NOT EXISTS idx_audits_type ON audits(type);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_audit ON notifications(audit_id);
|
|
114
|
+
`);
|
|
115
|
+
// Initialize default settings
|
|
116
|
+
const insertSetting = this.db.prepare(`
|
|
117
|
+
INSERT OR IGNORE INTO settings (key, value, updated_at) VALUES (?, ?, ?)
|
|
118
|
+
`);
|
|
119
|
+
const now = new Date().toISOString();
|
|
120
|
+
for (const [key, value] of Object.entries(DEFAULT_SETTINGS)) {
|
|
121
|
+
insertSetting.run(key, value, now);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// ============ AUDIT METHODS ============
|
|
125
|
+
saveAudit(type, target, result) {
|
|
126
|
+
const id = `${type}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
127
|
+
const timestamp = new Date().toISOString();
|
|
128
|
+
// Extract summary counts based on type
|
|
129
|
+
let critical = 0, high = 0, medium = 0, low = 0;
|
|
130
|
+
if (type === 'code') {
|
|
131
|
+
const r = result;
|
|
132
|
+
critical = r.secrets.filter(s => s.severity === 'critical').length +
|
|
133
|
+
r.packages.filter(p => p.severity === 'critical').length;
|
|
134
|
+
high = r.secrets.filter(s => s.severity === 'high').length +
|
|
135
|
+
r.packages.filter(p => p.severity === 'high').length;
|
|
136
|
+
medium = r.secrets.filter(s => s.severity === 'medium').length +
|
|
137
|
+
r.packages.filter(p => p.severity === 'medium').length;
|
|
138
|
+
low = r.secrets.filter(s => s.severity === 'low').length +
|
|
139
|
+
r.packages.filter(p => p.severity === 'low').length;
|
|
140
|
+
}
|
|
141
|
+
else if (type === 'aws') {
|
|
142
|
+
const r = result;
|
|
143
|
+
critical = r.summary.critical;
|
|
144
|
+
high = r.summary.high;
|
|
145
|
+
medium = r.summary.medium;
|
|
146
|
+
low = r.summary.low;
|
|
147
|
+
}
|
|
148
|
+
else if (type === 'audit') {
|
|
149
|
+
const r = result;
|
|
150
|
+
for (const event of r.events) {
|
|
151
|
+
if (event.payload?.severity === 'critical')
|
|
152
|
+
critical++;
|
|
153
|
+
else if (event.payload?.severity === 'high')
|
|
154
|
+
high++;
|
|
155
|
+
else if (event.payload?.severity === 'medium')
|
|
156
|
+
medium++;
|
|
157
|
+
else if (event.payload?.severity === 'low')
|
|
158
|
+
low++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const stmt = this.db.prepare(`
|
|
162
|
+
INSERT INTO audits (id, type, timestamp, target, critical, high, medium, low, data)
|
|
163
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
164
|
+
`);
|
|
165
|
+
stmt.run(id, type, timestamp, target, critical, high, medium, low, JSON.stringify(result));
|
|
166
|
+
console.log(`[DB] Saved audit: ${id} (${type})`);
|
|
167
|
+
return id;
|
|
168
|
+
}
|
|
169
|
+
getAudit(id) {
|
|
170
|
+
const stmt = this.db.prepare(`
|
|
171
|
+
SELECT id, type, timestamp, target, critical, high, medium, low, data
|
|
172
|
+
FROM audits WHERE id = ?
|
|
173
|
+
`);
|
|
174
|
+
const row = stmt.get(id);
|
|
175
|
+
if (!row)
|
|
176
|
+
return null;
|
|
177
|
+
return {
|
|
178
|
+
id: row.id,
|
|
179
|
+
type: row.type,
|
|
180
|
+
timestamp: row.timestamp,
|
|
181
|
+
target: row.target,
|
|
182
|
+
summary: {
|
|
183
|
+
critical: row.critical,
|
|
184
|
+
high: row.high,
|
|
185
|
+
medium: row.medium,
|
|
186
|
+
low: row.low,
|
|
187
|
+
},
|
|
188
|
+
data: row.data,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
getAudits(limit = 50, offset = 0, type) {
|
|
192
|
+
let query = `
|
|
193
|
+
SELECT id, type, timestamp, target, critical, high, medium, low, data
|
|
194
|
+
FROM audits
|
|
195
|
+
`;
|
|
196
|
+
const params = [];
|
|
197
|
+
if (type) {
|
|
198
|
+
query += ' WHERE type = ?';
|
|
199
|
+
params.push(type);
|
|
200
|
+
}
|
|
201
|
+
query += ' ORDER BY timestamp DESC LIMIT ? OFFSET ?';
|
|
202
|
+
params.push(limit, offset);
|
|
203
|
+
const stmt = this.db.prepare(query);
|
|
204
|
+
const rows = stmt.all(...params);
|
|
205
|
+
return rows.map(row => ({
|
|
206
|
+
id: row.id,
|
|
207
|
+
type: row.type,
|
|
208
|
+
timestamp: row.timestamp,
|
|
209
|
+
target: row.target,
|
|
210
|
+
summary: {
|
|
211
|
+
critical: row.critical,
|
|
212
|
+
high: row.high,
|
|
213
|
+
medium: row.medium,
|
|
214
|
+
low: row.low,
|
|
215
|
+
},
|
|
216
|
+
data: row.data,
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
getAuditCount(type) {
|
|
220
|
+
let query = 'SELECT COUNT(*) as count FROM audits';
|
|
221
|
+
const params = [];
|
|
222
|
+
if (type) {
|
|
223
|
+
query += ' WHERE type = ?';
|
|
224
|
+
params.push(type);
|
|
225
|
+
}
|
|
226
|
+
const stmt = this.db.prepare(query);
|
|
227
|
+
const row = stmt.get(...params);
|
|
228
|
+
return row.count;
|
|
229
|
+
}
|
|
230
|
+
deleteAudit(id) {
|
|
231
|
+
const stmt = this.db.prepare('DELETE FROM audits WHERE id = ?');
|
|
232
|
+
const result = stmt.run(id);
|
|
233
|
+
return result.changes > 0;
|
|
234
|
+
}
|
|
235
|
+
// ============ SETTINGS METHODS ============
|
|
236
|
+
getSetting(key) {
|
|
237
|
+
const stmt = this.db.prepare('SELECT value FROM settings WHERE key = ?');
|
|
238
|
+
const row = stmt.get(key);
|
|
239
|
+
return row ? row.value : null;
|
|
240
|
+
}
|
|
241
|
+
getSettings(prefix) {
|
|
242
|
+
let query = 'SELECT key, value FROM settings';
|
|
243
|
+
const params = [];
|
|
244
|
+
if (prefix) {
|
|
245
|
+
query += ' WHERE key LIKE ?';
|
|
246
|
+
params.push(`${prefix}%`);
|
|
247
|
+
}
|
|
248
|
+
const stmt = this.db.prepare(query);
|
|
249
|
+
const rows = stmt.all(...params);
|
|
250
|
+
const settings = {};
|
|
251
|
+
for (const row of rows) {
|
|
252
|
+
settings[row.key] = row.value;
|
|
253
|
+
}
|
|
254
|
+
return settings;
|
|
255
|
+
}
|
|
256
|
+
getAllSettings() {
|
|
257
|
+
return this.getSettings();
|
|
258
|
+
}
|
|
259
|
+
setSetting(key, value) {
|
|
260
|
+
const stmt = this.db.prepare(`
|
|
261
|
+
INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)
|
|
262
|
+
ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = ?
|
|
263
|
+
`);
|
|
264
|
+
const now = new Date().toISOString();
|
|
265
|
+
stmt.run(key, value, now, value, now);
|
|
266
|
+
}
|
|
267
|
+
setSettings(settings) {
|
|
268
|
+
const stmt = this.db.prepare(`
|
|
269
|
+
INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?)
|
|
270
|
+
ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = ?
|
|
271
|
+
`);
|
|
272
|
+
const now = new Date().toISOString();
|
|
273
|
+
const transaction = this.db.transaction(() => {
|
|
274
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
275
|
+
stmt.run(key, value, now, value, now);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
transaction();
|
|
279
|
+
}
|
|
280
|
+
// ============ NOTIFICATION METHODS ============
|
|
281
|
+
saveNotification(type, auditId, status, message, error) {
|
|
282
|
+
const stmt = this.db.prepare(`
|
|
283
|
+
INSERT INTO notifications (type, audit_id, status, message, timestamp, error)
|
|
284
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
285
|
+
`);
|
|
286
|
+
const result = stmt.run(type, auditId, status, message, new Date().toISOString(), error || null);
|
|
287
|
+
return result.lastInsertRowid;
|
|
288
|
+
}
|
|
289
|
+
recordNotification(auditId, channels, success, error) {
|
|
290
|
+
const timestamp = new Date().toISOString();
|
|
291
|
+
const stmt = this.db.prepare(`
|
|
292
|
+
INSERT INTO notifications (type, audit_id, status, message, timestamp, error)
|
|
293
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
294
|
+
`);
|
|
295
|
+
stmt.run(channels || 'unknown', auditId, success ? 'sent' : 'failed', success ? `Notification sent via ${channels}` : 'Notification failed', timestamp, error || null);
|
|
296
|
+
}
|
|
297
|
+
getNotifications(auditId, limit = 50) {
|
|
298
|
+
let query = `
|
|
299
|
+
SELECT id, type, audit_id, status, message, timestamp, error
|
|
300
|
+
FROM notifications
|
|
301
|
+
`;
|
|
302
|
+
const params = [];
|
|
303
|
+
if (auditId) {
|
|
304
|
+
query += ' WHERE audit_id = ?';
|
|
305
|
+
params.push(auditId);
|
|
306
|
+
}
|
|
307
|
+
query += ' ORDER BY timestamp DESC LIMIT ?';
|
|
308
|
+
params.push(limit);
|
|
309
|
+
const stmt = this.db.prepare(query);
|
|
310
|
+
const rows = stmt.all(...params);
|
|
311
|
+
return rows.map(row => ({
|
|
312
|
+
id: row.id,
|
|
313
|
+
type: row.type,
|
|
314
|
+
audit_id: row.audit_id,
|
|
315
|
+
status: row.status,
|
|
316
|
+
message: row.message,
|
|
317
|
+
timestamp: row.timestamp,
|
|
318
|
+
error: row.error,
|
|
319
|
+
}));
|
|
320
|
+
}
|
|
321
|
+
// ============ STATS METHODS ============
|
|
322
|
+
getStats() {
|
|
323
|
+
// Total audits
|
|
324
|
+
const totalStmt = this.db.prepare('SELECT COUNT(*) as count FROM audits');
|
|
325
|
+
const totalRow = totalStmt.get();
|
|
326
|
+
// By type
|
|
327
|
+
const typeStmt = this.db.prepare(`
|
|
328
|
+
SELECT type, COUNT(*) as count FROM audits GROUP BY type
|
|
329
|
+
`);
|
|
330
|
+
const typeRows = typeStmt.all();
|
|
331
|
+
const byType = {};
|
|
332
|
+
for (const row of typeRows) {
|
|
333
|
+
byType[row.type] = row.count;
|
|
334
|
+
}
|
|
335
|
+
// By day (last 30 days)
|
|
336
|
+
const dayStmt = this.db.prepare(`
|
|
337
|
+
SELECT DATE(timestamp) as date, COUNT(*) as count
|
|
338
|
+
FROM audits
|
|
339
|
+
WHERE timestamp >= DATE('now', '-30 days')
|
|
340
|
+
GROUP BY DATE(timestamp)
|
|
341
|
+
ORDER BY date DESC
|
|
342
|
+
`);
|
|
343
|
+
const dayRows = dayStmt.all();
|
|
344
|
+
const byDay = dayRows.map(row => ({ date: row.date, count: row.count }));
|
|
345
|
+
// Severity totals
|
|
346
|
+
const sevStmt = this.db.prepare(`
|
|
347
|
+
SELECT
|
|
348
|
+
SUM(critical) as critical,
|
|
349
|
+
SUM(high) as high,
|
|
350
|
+
SUM(medium) as medium,
|
|
351
|
+
SUM(low) as low
|
|
352
|
+
FROM audits
|
|
353
|
+
`);
|
|
354
|
+
const sevRow = sevStmt.get();
|
|
355
|
+
return {
|
|
356
|
+
totalAudits: totalRow.count,
|
|
357
|
+
byType,
|
|
358
|
+
byDay,
|
|
359
|
+
severityCounts: {
|
|
360
|
+
critical: sevRow.critical || 0,
|
|
361
|
+
high: sevRow.high || 0,
|
|
362
|
+
medium: sevRow.medium || 0,
|
|
363
|
+
low: sevRow.low || 0,
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
// ============ CLEANUP ============
|
|
368
|
+
close() {
|
|
369
|
+
this.db.close();
|
|
370
|
+
}
|
|
371
|
+
vacuum() {
|
|
372
|
+
this.db.exec('VACUUM');
|
|
373
|
+
}
|
|
374
|
+
deleteOldAudits(daysToKeep = 90) {
|
|
375
|
+
const stmt = this.db.prepare(`
|
|
376
|
+
DELETE FROM audits WHERE timestamp < DATE('now', '-' || ? || ' days')
|
|
377
|
+
`);
|
|
378
|
+
const result = stmt.run(daysToKeep);
|
|
379
|
+
return result.changes;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Singleton instance
|
|
383
|
+
let dbInstance = null;
|
|
384
|
+
export function getDatabase(dbPath) {
|
|
385
|
+
if (!dbInstance) {
|
|
386
|
+
dbInstance = new AuditorDatabase(dbPath);
|
|
387
|
+
}
|
|
388
|
+
return dbInstance;
|
|
389
|
+
}
|
|
390
|
+
export function closeDatabase() {
|
|
391
|
+
if (dbInstance) {
|
|
392
|
+
dbInstance.close();
|
|
393
|
+
dbInstance = null;
|
|
394
|
+
}
|
|
395
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export { AuraServer } from './aura/server.js';
|
|
2
|
+
export { AuraClient } from './aura/client.js';
|
|
3
|
+
export { AuditorPipeline } from './auditor/pipeline.js';
|
|
4
|
+
export { SchemaValidator, ValidationError } from './auditor/validator.js';
|
|
5
|
+
export * from './types/events.js';
|
|
6
|
+
export { AuditClient, createPullRequestEvent, createDeployEvent, createInfraChangeEvent } from './client/index.js';
|
|
7
|
+
export type { AuditClientConfig, AuditRequest, AuditResult, ServerInfo } from './client/index.js';
|
|
8
|
+
export { SecurityPipeline, SecretsDetectionStage, VulnerabilityScanStage, CriticalAssetStage, InfrastructureChangeStage, ProductionDeployStage } from './pipeline/index.js';
|
|
9
|
+
export type { PipelineContext, AnalysisStage, RuleDefinition, RuleResult } from './pipeline/index.js';
|
|
10
|
+
export { WebhookServer, defaultHandlers } from './integrations/webhook.js';
|
|
11
|
+
export { GitHubIntegration } from './integrations/github.js';
|
|
12
|
+
export { GitLabIntegration } from './integrations/gitlab.js';
|
|
13
|
+
export { SnykParser, TrivyParser, SemgrepParser, NpmAuditParser, getParser } from './integrations/scanners.js';
|
|
14
|
+
export { ConfigLoader, configLoader } from './integrations/config.js';
|
|
15
|
+
export type { AuditorConfig, ModuleConfig, IntegrationConfig } from './integrations/config.js';
|
|
16
|
+
export { LocalScanner, quickLocalScan, scanRemoteGit, isGitUrl } from './integrations/local-scanner.js';
|
|
17
|
+
export type { LocalScanConfig, LocalScanResult, SecretFinding, PackageFinding, SastFinding, DiscoveredService, DiscoveredModule, RemoteScanConfig, RemoteScanResult } from './integrations/local-scanner.js';
|
|
18
|
+
export { AWSScanner, scanAWS } from './integrations/aws-scanner.js';
|
|
19
|
+
export type { AWSScanConfig, AWSScanResult, AWSFinding } from './integrations/aws-scanner.js';
|
|
20
|
+
export { AuditorDatabase, getDatabase, closeDatabase } from './database/index.js';
|
|
21
|
+
export type { AuditRecord, SettingsRecord, NotificationRecord } from './database/index.js';
|
|
22
|
+
export { NotificationService, createNotificationFromAudit } from './integrations/notifications.js';
|
|
23
|
+
export type { NotificationConfig, NotificationPayload } from './integrations/notifications.js';
|
|
24
|
+
export { AuditorWebSocket, getWebSocketServer, closeWebSocketServer } from './websocket/index.js';
|
|
25
|
+
export type { WSMessage, AuditStartedPayload, AuditCompletedPayload, FindingPayload } from './websocket/index.js';
|