guardrail-compliance 1.0.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/dist/audit/emitter.d.ts +97 -0
- package/dist/audit/emitter.d.ts.map +1 -0
- package/dist/audit/emitter.js +197 -0
- package/dist/audit/events.d.ts +304 -0
- package/dist/audit/events.d.ts.map +1 -0
- package/dist/audit/events.js +267 -0
- package/dist/audit/index.d.ts +11 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +51 -0
- package/dist/audit/storage.d.ts +93 -0
- package/dist/audit/storage.d.ts.map +1 -0
- package/dist/audit/storage.js +337 -0
- package/dist/automation/__tests__/compliance-scheduler.test.d.ts +2 -0
- package/dist/automation/__tests__/compliance-scheduler.test.d.ts.map +1 -0
- package/dist/automation/__tests__/compliance-scheduler.test.js +140 -0
- package/dist/automation/audit-logger.d.ts +129 -0
- package/dist/automation/audit-logger.d.ts.map +1 -0
- package/dist/automation/audit-logger.js +473 -0
- package/dist/automation/compliance-scheduler-fixed.d.ts +1 -0
- package/dist/automation/compliance-scheduler-fixed.d.ts.map +1 -0
- package/dist/automation/compliance-scheduler-fixed.js +1 -0
- package/dist/automation/compliance-scheduler.d.ts +83 -0
- package/dist/automation/compliance-scheduler.d.ts.map +1 -0
- package/dist/automation/compliance-scheduler.js +414 -0
- package/dist/automation/dashboard.d.ts +194 -0
- package/dist/automation/dashboard.d.ts.map +1 -0
- package/dist/automation/dashboard.js +768 -0
- package/dist/automation/email-service.d.ts +69 -0
- package/dist/automation/email-service.d.ts.map +1 -0
- package/dist/automation/email-service.js +218 -0
- package/dist/automation/evidence-collector.d.ts +140 -0
- package/dist/automation/evidence-collector.d.ts.map +1 -0
- package/dist/automation/evidence-collector.js +682 -0
- package/dist/automation/index.d.ts +8 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js +24 -0
- package/dist/automation/pdf-exporter.d.ts +90 -0
- package/dist/automation/pdf-exporter.d.ts.map +1 -0
- package/dist/automation/pdf-exporter.js +381 -0
- package/dist/automation/reporting-engine.d.ts +116 -0
- package/dist/automation/reporting-engine.d.ts.map +1 -0
- package/dist/automation/reporting-engine.js +329 -0
- package/dist/container/index.d.ts +4 -0
- package/dist/container/index.d.ts.map +1 -0
- package/dist/container/index.js +19 -0
- package/dist/container/kubernetes.d.ts +94 -0
- package/dist/container/kubernetes.d.ts.map +1 -0
- package/dist/container/kubernetes.js +268 -0
- package/dist/container/rules.d.ts +27 -0
- package/dist/container/rules.d.ts.map +1 -0
- package/dist/container/rules.js +216 -0
- package/dist/container/scanner.d.ts +50 -0
- package/dist/container/scanner.d.ts.map +1 -0
- package/dist/container/scanner.js +143 -0
- package/dist/frameworks/engine.d.ts +108 -0
- package/dist/frameworks/engine.d.ts.map +1 -0
- package/dist/frameworks/engine.js +206 -0
- package/dist/frameworks/gdpr.d.ts +6 -0
- package/dist/frameworks/gdpr.d.ts.map +1 -0
- package/dist/frameworks/gdpr.js +198 -0
- package/dist/frameworks/hipaa.d.ts +6 -0
- package/dist/frameworks/hipaa.d.ts.map +1 -0
- package/dist/frameworks/hipaa.js +183 -0
- package/dist/frameworks/index.d.ts +8 -0
- package/dist/frameworks/index.d.ts.map +1 -0
- package/dist/frameworks/index.js +30 -0
- package/dist/frameworks/iso27001.d.ts +63 -0
- package/dist/frameworks/iso27001.d.ts.map +1 -0
- package/dist/frameworks/iso27001.js +331 -0
- package/dist/frameworks/nist.d.ts +62 -0
- package/dist/frameworks/nist.d.ts.map +1 -0
- package/dist/frameworks/nist.js +424 -0
- package/dist/frameworks/pci.d.ts +6 -0
- package/dist/frameworks/pci.d.ts.map +1 -0
- package/dist/frameworks/pci.js +201 -0
- package/dist/frameworks/soc2.d.ts +7 -0
- package/dist/frameworks/soc2.d.ts.map +1 -0
- package/dist/frameworks/soc2.js +248 -0
- package/dist/iac/drift-detector.d.ts +64 -0
- package/dist/iac/drift-detector.d.ts.map +1 -0
- package/dist/iac/drift-detector.js +134 -0
- package/dist/iac/index.d.ts +4 -0
- package/dist/iac/index.d.ts.map +1 -0
- package/dist/iac/index.js +19 -0
- package/dist/iac/rules.d.ts +17 -0
- package/dist/iac/rules.d.ts.map +1 -0
- package/dist/iac/rules.js +385 -0
- package/dist/iac/scanner.d.ts +104 -0
- package/dist/iac/scanner.d.ts.map +1 -0
- package/dist/iac/scanner.js +343 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/pii/data-flow.d.ts +58 -0
- package/dist/pii/data-flow.d.ts.map +1 -0
- package/dist/pii/data-flow.js +154 -0
- package/dist/pii/detector.d.ts +60 -0
- package/dist/pii/detector.d.ts.map +1 -0
- package/dist/pii/detector.js +267 -0
- package/dist/pii/index.d.ts +4 -0
- package/dist/pii/index.d.ts.map +1 -0
- package/dist/pii/index.js +19 -0
- package/dist/pii/patterns.d.ts +36 -0
- package/dist/pii/patterns.d.ts.map +1 -0
- package/dist/pii/patterns.js +108 -0
- package/dist/policy/index.d.ts +5 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +20 -0
- package/dist/policy/opa-engine.d.ts +121 -0
- package/dist/policy/opa-engine.d.ts.map +1 -0
- package/dist/policy/opa-engine.js +423 -0
- package/package.json +31 -0
- package/src/audit/emitter.ts +383 -0
- package/src/audit/events.ts +351 -0
- package/src/audit/index.ts +35 -0
- package/src/audit/storage.ts +394 -0
- package/src/automation/__tests__/compliance-scheduler.test.ts +183 -0
- package/src/automation/audit-logger.ts +629 -0
- package/src/automation/compliance-scheduler-fixed.ts +0 -0
- package/src/automation/compliance-scheduler.ts +516 -0
- package/src/automation/dashboard.ts +947 -0
- package/src/automation/email-service.ts +230 -0
- package/src/automation/evidence-collector.ts +866 -0
- package/src/automation/index.ts +8 -0
- package/src/automation/pdf-exporter.ts +434 -0
- package/src/automation/reporting-engine.ts +462 -0
- package/src/container/index.ts +3 -0
- package/src/container/kubernetes.ts +379 -0
- package/src/container/rules.ts +244 -0
- package/src/container/scanner.ts +202 -0
- package/src/frameworks/engine.ts +298 -0
- package/src/frameworks/gdpr.ts +204 -0
- package/src/frameworks/hipaa.ts +209 -0
- package/src/frameworks/index.ts +23 -0
- package/src/frameworks/iso27001.ts +398 -0
- package/src/frameworks/nist.ts +518 -0
- package/src/frameworks/pci.ts +226 -0
- package/src/frameworks/soc2.ts +281 -0
- package/src/iac/drift-detector.ts +197 -0
- package/src/iac/index.ts +3 -0
- package/src/iac/rules.ts +420 -0
- package/src/iac/scanner.ts +445 -0
- package/src/index.ts +17 -0
- package/src/pii/data-flow.ts +216 -0
- package/src/pii/detector.ts +327 -0
- package/src/pii/index.ts +3 -0
- package/src/pii/patterns.ts +128 -0
- package/src/policy/index.ts +5 -0
- package/src/policy/opa-engine.ts +504 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.complianceScheduler = exports.ComplianceScheduler = void 0;
|
|
4
|
+
const database_1 = require("@guardrail/database");
|
|
5
|
+
const engine_1 = require("../frameworks/engine");
|
|
6
|
+
const evidence_collector_1 = require("./evidence-collector");
|
|
7
|
+
const reporting_engine_1 = require("./reporting-engine");
|
|
8
|
+
const email_service_1 = require("./email-service");
|
|
9
|
+
/**
|
|
10
|
+
* Compliance Scheduler
|
|
11
|
+
*
|
|
12
|
+
* Manages scheduled compliance checks and notifications
|
|
13
|
+
*/
|
|
14
|
+
class ComplianceScheduler {
|
|
15
|
+
jobs = new Map();
|
|
16
|
+
executions = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* Initialize scheduler and load existing schedules
|
|
19
|
+
*/
|
|
20
|
+
async initialize() {
|
|
21
|
+
const schedules = await database_1.prisma.complianceSchedule.findMany({
|
|
22
|
+
where: { enabled: true },
|
|
23
|
+
});
|
|
24
|
+
for (const schedule of schedules) {
|
|
25
|
+
await this.scheduleJob(schedule);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create or update a schedule
|
|
30
|
+
*/
|
|
31
|
+
async upsertSchedule(schedule) {
|
|
32
|
+
if (!this.isValidCron(schedule.frequency)) {
|
|
33
|
+
throw new Error("Invalid cron expression");
|
|
34
|
+
}
|
|
35
|
+
let dbSchedule;
|
|
36
|
+
try {
|
|
37
|
+
dbSchedule = await database_1.prisma.complianceSchedule.upsert({
|
|
38
|
+
where: {
|
|
39
|
+
id: `${schedule.projectId}_${schedule.frameworkId}`,
|
|
40
|
+
},
|
|
41
|
+
update: {
|
|
42
|
+
schedule: schedule.frequency,
|
|
43
|
+
enabled: schedule.enabled,
|
|
44
|
+
},
|
|
45
|
+
create: {
|
|
46
|
+
projectId: schedule.projectId,
|
|
47
|
+
frameworkId: schedule.frameworkId,
|
|
48
|
+
schedule: schedule.frequency,
|
|
49
|
+
enabled: schedule.enabled,
|
|
50
|
+
nextRun: new Date(),
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.warn("Could not upsert schedule in database:", error);
|
|
56
|
+
// Create a mock schedule object for in-memory operation
|
|
57
|
+
dbSchedule = {
|
|
58
|
+
id: `sched_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
59
|
+
...schedule,
|
|
60
|
+
lastRun: null,
|
|
61
|
+
nextRun: new Date(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (schedule.enabled) {
|
|
65
|
+
await this.scheduleJob(dbSchedule);
|
|
66
|
+
}
|
|
67
|
+
return dbSchedule.id;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Remove a schedule
|
|
71
|
+
*/
|
|
72
|
+
async removeSchedule(projectId, frameworkId) {
|
|
73
|
+
const jobKey = `${projectId}:${frameworkId}`;
|
|
74
|
+
if (this.jobs.has(jobKey)) {
|
|
75
|
+
this.jobs.get(jobKey).stop();
|
|
76
|
+
this.jobs.delete(jobKey);
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
await database_1.prisma.complianceSchedule.deleteMany({
|
|
80
|
+
where: {
|
|
81
|
+
projectId,
|
|
82
|
+
frameworkId,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.warn("Could not delete schedule from database:", error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Run a compliance check
|
|
92
|
+
*/
|
|
93
|
+
async runCheck(projectId, frameworkId, options) {
|
|
94
|
+
const executionId = `exec_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
95
|
+
const result = {
|
|
96
|
+
scheduleId: `${projectId}:${frameworkId}`,
|
|
97
|
+
executionId,
|
|
98
|
+
startTime: new Date(),
|
|
99
|
+
endTime: new Date(),
|
|
100
|
+
status: "running",
|
|
101
|
+
};
|
|
102
|
+
this.executions.set(executionId, result);
|
|
103
|
+
try {
|
|
104
|
+
// Get project details
|
|
105
|
+
const project = await database_1.prisma.project.findUnique({
|
|
106
|
+
where: { id: projectId },
|
|
107
|
+
});
|
|
108
|
+
if (!project) {
|
|
109
|
+
throw new Error(`Project ${projectId} not found`);
|
|
110
|
+
}
|
|
111
|
+
// Run compliance assessment
|
|
112
|
+
const assessment = await engine_1.complianceAutomationEngine.assess(project.path || "", frameworkId, projectId);
|
|
113
|
+
// Collect evidence if requested
|
|
114
|
+
let evidence = null;
|
|
115
|
+
if (options?.collectEvidence !== false) {
|
|
116
|
+
evidence = await evidence_collector_1.evidenceCollector.collectForAssessment(projectId, frameworkId, assessment);
|
|
117
|
+
}
|
|
118
|
+
// Generate report if requested
|
|
119
|
+
let report = null;
|
|
120
|
+
if (options?.generateReport) {
|
|
121
|
+
report = await reporting_engine_1.reportingEngine.generateReport({
|
|
122
|
+
projectId,
|
|
123
|
+
frameworkId,
|
|
124
|
+
type: "compliance",
|
|
125
|
+
format: "json",
|
|
126
|
+
includeEvidence: !!evidence,
|
|
127
|
+
includeRecommendations: true,
|
|
128
|
+
includeCharts: false,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Update result
|
|
132
|
+
result.result = {
|
|
133
|
+
assessment,
|
|
134
|
+
evidence,
|
|
135
|
+
report,
|
|
136
|
+
};
|
|
137
|
+
result.status = "completed";
|
|
138
|
+
result.endTime = new Date();
|
|
139
|
+
// Send notifications if requested
|
|
140
|
+
if (options?.notifyOnCompletion) {
|
|
141
|
+
setTimeout(() => {
|
|
142
|
+
this.sendNotifications(projectId, frameworkId, result);
|
|
143
|
+
}, 1000);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
result.status = "failed";
|
|
148
|
+
result.error = error instanceof Error ? error.message : "Unknown error";
|
|
149
|
+
result.endTime = new Date();
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get execution status
|
|
155
|
+
*/
|
|
156
|
+
getExecutionStatus(executionId) {
|
|
157
|
+
return this.executions.get(executionId);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get all schedules
|
|
161
|
+
*/
|
|
162
|
+
async getSchedules(projectId) {
|
|
163
|
+
const schedules = await database_1.prisma.complianceSchedule.findMany({
|
|
164
|
+
where: projectId ? { projectId } : undefined,
|
|
165
|
+
orderBy: { nextRun: "asc" },
|
|
166
|
+
});
|
|
167
|
+
return schedules.map((s) => ({
|
|
168
|
+
id: s.id,
|
|
169
|
+
projectId: s.projectId,
|
|
170
|
+
frameworkId: s.frameworkId,
|
|
171
|
+
frequency: s.schedule,
|
|
172
|
+
enabled: s.enabled,
|
|
173
|
+
lastRun: s.lastRun || undefined,
|
|
174
|
+
nextRun: s.nextRun || undefined,
|
|
175
|
+
notifications: s.notifications || undefined,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Schedule a job
|
|
180
|
+
*/
|
|
181
|
+
async scheduleJob(schedule) {
|
|
182
|
+
const jobKey = `${schedule.projectId}:${schedule.frameworkId}`;
|
|
183
|
+
// Remove existing job if any
|
|
184
|
+
if (this.jobs.has(jobKey)) {
|
|
185
|
+
this.jobs.get(jobKey).stop();
|
|
186
|
+
}
|
|
187
|
+
// Create new cron job
|
|
188
|
+
// const job = new CronJob(schedule.schedule, async () => {
|
|
189
|
+
// await this.executeScheduledCheck(schedule);
|
|
190
|
+
// }, null, true, 'UTC');
|
|
191
|
+
// this.jobs.set(jobKey, job);
|
|
192
|
+
// Update next run time
|
|
193
|
+
try {
|
|
194
|
+
await database_1.prisma.complianceSchedule.update({
|
|
195
|
+
where: { id: schedule.id },
|
|
196
|
+
data: { nextRun: new Date() },
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
console.warn("Could not update next run time in database:", error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Execute a scheduled check - currently unused
|
|
204
|
+
/*
|
|
205
|
+
private async executeScheduledCheck(schedule: any): Promise<void> {
|
|
206
|
+
try {
|
|
207
|
+
const result = await this.runCheck(
|
|
208
|
+
schedule.projectId,
|
|
209
|
+
schedule.frameworkId,
|
|
210
|
+
{
|
|
211
|
+
collectEvidence: true,
|
|
212
|
+
generateReport: true,
|
|
213
|
+
notifyOnCompletion: true
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Update last run time
|
|
218
|
+
try {
|
|
219
|
+
await prisma.complianceSchedule.update({
|
|
220
|
+
where: { id: schedule.id },
|
|
221
|
+
data: { lastRun: new Date() }
|
|
222
|
+
});
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.warn('Could not update last run time in database:', error);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Check for compliance failures and send alerts
|
|
228
|
+
if (result.result?.assessment?.summary?.score < 70) {
|
|
229
|
+
await this.sendAlert(schedule, result);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.error(`Scheduled check failed for ${schedule.projectId}:${schedule.frameworkId}:`, error);
|
|
234
|
+
await this.sendErrorAlert(schedule, error);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
*/
|
|
238
|
+
/**
|
|
239
|
+
* Send notifications for completed checks
|
|
240
|
+
*/
|
|
241
|
+
async sendNotifications(projectId, frameworkId, result) {
|
|
242
|
+
try {
|
|
243
|
+
const schedule = await database_1.prisma.complianceSchedule.findFirst({
|
|
244
|
+
where: {
|
|
245
|
+
projectId,
|
|
246
|
+
frameworkId,
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
if (!schedule?.notifications)
|
|
250
|
+
return;
|
|
251
|
+
const notifications = schedule.notifications;
|
|
252
|
+
// Send email notifications
|
|
253
|
+
if (notifications.email?.length) {
|
|
254
|
+
const score = result.result?.assessment?.summary?.score;
|
|
255
|
+
const status = result.status === "completed" ? "completed" : "failed";
|
|
256
|
+
const emailResult = await email_service_1.emailService.sendComplianceNotification(notifications.email, projectId, frameworkId, {
|
|
257
|
+
status,
|
|
258
|
+
score,
|
|
259
|
+
summary: result.error || undefined,
|
|
260
|
+
});
|
|
261
|
+
if (!emailResult.success) {
|
|
262
|
+
console.error(`Failed to send compliance email to ${notifications.email.join(", ")}: ${emailResult.error}`);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
console.log(`Sent compliance check email to ${notifications.email.join(", ")} (messageId: ${emailResult.messageId})`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Send Slack notifications
|
|
269
|
+
if (notifications.slack) {
|
|
270
|
+
try {
|
|
271
|
+
const score = result.result?.assessment?.summary?.score || 0;
|
|
272
|
+
const status = score >= 90 ? "passed" : score >= 70 ? "warning" : "failed";
|
|
273
|
+
const statusIcon = status === "passed" ? "✅" : status === "warning" ? "⚠️" : "❌";
|
|
274
|
+
const slackPayload = {
|
|
275
|
+
blocks: [
|
|
276
|
+
{
|
|
277
|
+
type: "header",
|
|
278
|
+
text: {
|
|
279
|
+
type: "plain_text",
|
|
280
|
+
text: `${statusIcon} Compliance Check ${status.toUpperCase()}`,
|
|
281
|
+
emoji: true,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
type: "section",
|
|
286
|
+
fields: [
|
|
287
|
+
{
|
|
288
|
+
type: "mrkdwn",
|
|
289
|
+
text: `*Project:*\n${projectId}`,
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
type: "mrkdwn",
|
|
293
|
+
text: `*Framework:*\n${frameworkId}`,
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
type: "section",
|
|
299
|
+
fields: [
|
|
300
|
+
{
|
|
301
|
+
type: "mrkdwn",
|
|
302
|
+
text: `*Score:*\n${score}%`,
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
type: "mrkdwn",
|
|
306
|
+
text: `*Status:*\n${status}`,
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
type: "section",
|
|
312
|
+
text: {
|
|
313
|
+
type: "mrkdwn",
|
|
314
|
+
text: `Check completed at ${new Date().toLocaleString()}`,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
};
|
|
319
|
+
await fetch(notifications.slack, {
|
|
320
|
+
method: "POST",
|
|
321
|
+
headers: { "Content-Type": "application/json" },
|
|
322
|
+
body: JSON.stringify(slackPayload),
|
|
323
|
+
});
|
|
324
|
+
console.log(`Sending Slack notification to ${notifications.slack}`);
|
|
325
|
+
}
|
|
326
|
+
catch (slackError) {
|
|
327
|
+
console.error("Failed to send Slack notification:", slackError);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// Send webhook notifications
|
|
331
|
+
if (notifications.webhook) {
|
|
332
|
+
console.log(`Sending webhook notification to ${notifications.webhook}`);
|
|
333
|
+
try {
|
|
334
|
+
const response = await fetch(notifications.webhook, {
|
|
335
|
+
method: "POST",
|
|
336
|
+
headers: {
|
|
337
|
+
"Content-Type": "application/json",
|
|
338
|
+
},
|
|
339
|
+
body: JSON.stringify(result),
|
|
340
|
+
});
|
|
341
|
+
if (!response.ok) {
|
|
342
|
+
console.error(`Failed to send webhook notification: ${response.status} ${response.statusText}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (webhookError) {
|
|
346
|
+
console.error("Error sending webhook notification:", webhookError);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
console.error("Failed to send notifications:", error);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/*
|
|
355
|
+
private async sendAlert(schedule: any, result: ComplianceExecutionResult): Promise<void> {
|
|
356
|
+
const score = result.result?.assessment?.summary?.score || 0;
|
|
357
|
+
const message = `Compliance check failed for project ${schedule.projectId} (${schedule.frameworkId}). Score: ${score}%`;
|
|
358
|
+
|
|
359
|
+
await auditLogger.logEvent({
|
|
360
|
+
type: 'compliance_failure',
|
|
361
|
+
category: 'compliance',
|
|
362
|
+
projectId: schedule.projectId,
|
|
363
|
+
timestamp: new Date(),
|
|
364
|
+
severity: 'high',
|
|
365
|
+
source: 'scheduler',
|
|
366
|
+
details: {
|
|
367
|
+
action: 'Compliance check failed',
|
|
368
|
+
framework: schedule.frameworkId,
|
|
369
|
+
score,
|
|
370
|
+
message
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
await this.sendNotifications(schedule.projectId, schedule.frameworkId, result);
|
|
375
|
+
}
|
|
376
|
+
*/
|
|
377
|
+
/*
|
|
378
|
+
private async sendErrorAlert(schedule: any, error: any): Promise<void> {
|
|
379
|
+
await auditLogger.logEvent({
|
|
380
|
+
type: 'compliance_error',
|
|
381
|
+
category: 'system',
|
|
382
|
+
projectId: schedule.projectId,
|
|
383
|
+
timestamp: new Date(),
|
|
384
|
+
severity: 'critical',
|
|
385
|
+
source: 'scheduler',
|
|
386
|
+
details: {
|
|
387
|
+
action: 'Compliance check error',
|
|
388
|
+
framework: schedule.frameworkId,
|
|
389
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
*/
|
|
394
|
+
/**
|
|
395
|
+
* Validate cron expression
|
|
396
|
+
*/
|
|
397
|
+
isValidCron(cron) {
|
|
398
|
+
// Basic validation - should be more sophisticated
|
|
399
|
+
const parts = cron.split(" ");
|
|
400
|
+
return parts.length === 5;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Stop all jobs
|
|
404
|
+
*/
|
|
405
|
+
stopAll() {
|
|
406
|
+
for (const job of this.jobs.values()) {
|
|
407
|
+
job.stop();
|
|
408
|
+
}
|
|
409
|
+
this.jobs.clear();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
exports.ComplianceScheduler = ComplianceScheduler;
|
|
413
|
+
// Export singleton instance
|
|
414
|
+
exports.complianceScheduler = new ComplianceScheduler();
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
interface DashboardData {
|
|
2
|
+
projectId: string;
|
|
3
|
+
overview: {
|
|
4
|
+
overallScore: number;
|
|
5
|
+
status: "compliant" | "partial" | "non-compliant";
|
|
6
|
+
lastAssessment: Date;
|
|
7
|
+
nextAssessment?: Date;
|
|
8
|
+
totalControls: number;
|
|
9
|
+
activeFrameworks: string[];
|
|
10
|
+
};
|
|
11
|
+
trends: {
|
|
12
|
+
scores: Array<{
|
|
13
|
+
date: Date;
|
|
14
|
+
score: number;
|
|
15
|
+
framework: string;
|
|
16
|
+
}>;
|
|
17
|
+
violations: Array<{
|
|
18
|
+
date: Date;
|
|
19
|
+
count: number;
|
|
20
|
+
severity: string;
|
|
21
|
+
}>;
|
|
22
|
+
remediation: Array<{
|
|
23
|
+
date: Date;
|
|
24
|
+
completed: number;
|
|
25
|
+
pending: number;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
alerts: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
type: "violation" | "deadline" | "score_drop" | "system";
|
|
31
|
+
severity: "low" | "medium" | "high" | "critical";
|
|
32
|
+
message: string;
|
|
33
|
+
timestamp: Date;
|
|
34
|
+
acknowledged: boolean;
|
|
35
|
+
}>;
|
|
36
|
+
frameworkStatus: Array<{
|
|
37
|
+
frameworkId: string;
|
|
38
|
+
score: number;
|
|
39
|
+
status: string;
|
|
40
|
+
lastRun: Date;
|
|
41
|
+
nextRun?: Date;
|
|
42
|
+
gaps: number;
|
|
43
|
+
}>;
|
|
44
|
+
recentActivity: Array<{
|
|
45
|
+
type: string;
|
|
46
|
+
description: string;
|
|
47
|
+
timestamp: Date;
|
|
48
|
+
user?: string;
|
|
49
|
+
}>;
|
|
50
|
+
upcomingTasks: Array<{
|
|
51
|
+
id: string;
|
|
52
|
+
type: "assessment" | "remediation" | "review";
|
|
53
|
+
title: string;
|
|
54
|
+
dueDate: Date;
|
|
55
|
+
priority: "low" | "medium" | "high" | "critical";
|
|
56
|
+
assignedTo?: string;
|
|
57
|
+
}>;
|
|
58
|
+
}
|
|
59
|
+
interface AlertConfig {
|
|
60
|
+
id: string;
|
|
61
|
+
projectId: string;
|
|
62
|
+
type: "score_threshold" | "violation_detected" | "deadline_approaching" | "system_error";
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
threshold?: number;
|
|
65
|
+
recipients: {
|
|
66
|
+
email?: string[];
|
|
67
|
+
slack?: string;
|
|
68
|
+
webhook?: string;
|
|
69
|
+
};
|
|
70
|
+
conditions: any;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Compliance Dashboard and Alerting System
|
|
74
|
+
*
|
|
75
|
+
* Provides real-time compliance monitoring, dashboards,
|
|
76
|
+
* and intelligent alerting for compliance issues
|
|
77
|
+
*/
|
|
78
|
+
export declare class ComplianceDashboard {
|
|
79
|
+
private alertConfigs;
|
|
80
|
+
private alertIntervals;
|
|
81
|
+
/**
|
|
82
|
+
* Get dashboard data for a project
|
|
83
|
+
*/
|
|
84
|
+
getDashboardData(projectId: string): Promise<DashboardData>;
|
|
85
|
+
/**
|
|
86
|
+
* Configure alerts for a project
|
|
87
|
+
*/
|
|
88
|
+
configureAlerts(config: AlertConfig): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Trigger manual compliance check
|
|
91
|
+
*/
|
|
92
|
+
triggerCheck(projectId: string, frameworkId: string, userId?: string): Promise<string>;
|
|
93
|
+
/**
|
|
94
|
+
* Acknowledge an alert
|
|
95
|
+
*/
|
|
96
|
+
acknowledgeAlert(alertId: string, userId: string): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Get compliance metrics for widgets
|
|
99
|
+
*/
|
|
100
|
+
getWidgetData(projectId: string, widgetType: "score" | "trends" | "violations" | "remediation"): Promise<any>;
|
|
101
|
+
/**
|
|
102
|
+
* Export dashboard data
|
|
103
|
+
*/
|
|
104
|
+
exportData(projectId: string, format: "json" | "csv", _dateRange?: {
|
|
105
|
+
start: Date;
|
|
106
|
+
end: Date;
|
|
107
|
+
}): Promise<string>;
|
|
108
|
+
/**
|
|
109
|
+
* Build overview section
|
|
110
|
+
*/
|
|
111
|
+
private buildOverview;
|
|
112
|
+
/**
|
|
113
|
+
* Get compliance trends
|
|
114
|
+
*/
|
|
115
|
+
private getTrends;
|
|
116
|
+
/**
|
|
117
|
+
* Get active alerts
|
|
118
|
+
*/
|
|
119
|
+
private getActiveAlerts;
|
|
120
|
+
/**
|
|
121
|
+
* Build framework status
|
|
122
|
+
*/
|
|
123
|
+
private buildFrameworkStatus;
|
|
124
|
+
/**
|
|
125
|
+
* Get recent activity
|
|
126
|
+
*/
|
|
127
|
+
private getRecentActivity;
|
|
128
|
+
/**
|
|
129
|
+
* Get upcoming tasks
|
|
130
|
+
*/
|
|
131
|
+
private getUpcomingTasks;
|
|
132
|
+
/**
|
|
133
|
+
* Start alert monitoring
|
|
134
|
+
*/
|
|
135
|
+
private startAlertMonitoring;
|
|
136
|
+
/**
|
|
137
|
+
* Stop alert monitoring
|
|
138
|
+
*/
|
|
139
|
+
private stopAlertMonitoring;
|
|
140
|
+
/**
|
|
141
|
+
* Check alert conditions
|
|
142
|
+
*/
|
|
143
|
+
private checkAlertConditions;
|
|
144
|
+
/**
|
|
145
|
+
* Check score threshold
|
|
146
|
+
*/
|
|
147
|
+
private checkScoreThreshold;
|
|
148
|
+
/**
|
|
149
|
+
* Check for violations
|
|
150
|
+
*/
|
|
151
|
+
private checkViolations;
|
|
152
|
+
/**
|
|
153
|
+
* Check approaching deadlines
|
|
154
|
+
*/
|
|
155
|
+
private checkDeadlines;
|
|
156
|
+
/**
|
|
157
|
+
* Check for system errors
|
|
158
|
+
*/
|
|
159
|
+
private checkSystemErrors;
|
|
160
|
+
/**
|
|
161
|
+
* Create an alert
|
|
162
|
+
*/
|
|
163
|
+
private createAlert;
|
|
164
|
+
/**
|
|
165
|
+
* Get violation trends
|
|
166
|
+
*/
|
|
167
|
+
private getViolationTrends;
|
|
168
|
+
/**
|
|
169
|
+
* Get remediation trends
|
|
170
|
+
*/
|
|
171
|
+
private getRemediationTrends;
|
|
172
|
+
/**
|
|
173
|
+
* Widget data getters
|
|
174
|
+
*/
|
|
175
|
+
private getScoreWidget;
|
|
176
|
+
private getTrendsWidget;
|
|
177
|
+
private getViolationsWidget;
|
|
178
|
+
private getRemediationWidget;
|
|
179
|
+
/**
|
|
180
|
+
* Calculate trend direction
|
|
181
|
+
*/
|
|
182
|
+
private calculateTrend;
|
|
183
|
+
/**
|
|
184
|
+
* Convert dashboard data to CSV
|
|
185
|
+
*/
|
|
186
|
+
private convertToCSV;
|
|
187
|
+
/**
|
|
188
|
+
* Shutdown dashboard monitoring
|
|
189
|
+
*/
|
|
190
|
+
shutdown(): Promise<void>;
|
|
191
|
+
}
|
|
192
|
+
export declare const complianceDashboard: ComplianceDashboard;
|
|
193
|
+
export {};
|
|
194
|
+
//# sourceMappingURL=dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/automation/dashboard.ts"],"names":[],"mappings":"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"}
|