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.
Files changed (149) hide show
  1. package/dist/audit/emitter.d.ts +97 -0
  2. package/dist/audit/emitter.d.ts.map +1 -0
  3. package/dist/audit/emitter.js +197 -0
  4. package/dist/audit/events.d.ts +304 -0
  5. package/dist/audit/events.d.ts.map +1 -0
  6. package/dist/audit/events.js +267 -0
  7. package/dist/audit/index.d.ts +11 -0
  8. package/dist/audit/index.d.ts.map +1 -0
  9. package/dist/audit/index.js +51 -0
  10. package/dist/audit/storage.d.ts +93 -0
  11. package/dist/audit/storage.d.ts.map +1 -0
  12. package/dist/audit/storage.js +337 -0
  13. package/dist/automation/__tests__/compliance-scheduler.test.d.ts +2 -0
  14. package/dist/automation/__tests__/compliance-scheduler.test.d.ts.map +1 -0
  15. package/dist/automation/__tests__/compliance-scheduler.test.js +140 -0
  16. package/dist/automation/audit-logger.d.ts +129 -0
  17. package/dist/automation/audit-logger.d.ts.map +1 -0
  18. package/dist/automation/audit-logger.js +473 -0
  19. package/dist/automation/compliance-scheduler-fixed.d.ts +1 -0
  20. package/dist/automation/compliance-scheduler-fixed.d.ts.map +1 -0
  21. package/dist/automation/compliance-scheduler-fixed.js +1 -0
  22. package/dist/automation/compliance-scheduler.d.ts +83 -0
  23. package/dist/automation/compliance-scheduler.d.ts.map +1 -0
  24. package/dist/automation/compliance-scheduler.js +414 -0
  25. package/dist/automation/dashboard.d.ts +194 -0
  26. package/dist/automation/dashboard.d.ts.map +1 -0
  27. package/dist/automation/dashboard.js +768 -0
  28. package/dist/automation/email-service.d.ts +69 -0
  29. package/dist/automation/email-service.d.ts.map +1 -0
  30. package/dist/automation/email-service.js +218 -0
  31. package/dist/automation/evidence-collector.d.ts +140 -0
  32. package/dist/automation/evidence-collector.d.ts.map +1 -0
  33. package/dist/automation/evidence-collector.js +682 -0
  34. package/dist/automation/index.d.ts +8 -0
  35. package/dist/automation/index.d.ts.map +1 -0
  36. package/dist/automation/index.js +24 -0
  37. package/dist/automation/pdf-exporter.d.ts +90 -0
  38. package/dist/automation/pdf-exporter.d.ts.map +1 -0
  39. package/dist/automation/pdf-exporter.js +381 -0
  40. package/dist/automation/reporting-engine.d.ts +116 -0
  41. package/dist/automation/reporting-engine.d.ts.map +1 -0
  42. package/dist/automation/reporting-engine.js +329 -0
  43. package/dist/container/index.d.ts +4 -0
  44. package/dist/container/index.d.ts.map +1 -0
  45. package/dist/container/index.js +19 -0
  46. package/dist/container/kubernetes.d.ts +94 -0
  47. package/dist/container/kubernetes.d.ts.map +1 -0
  48. package/dist/container/kubernetes.js +268 -0
  49. package/dist/container/rules.d.ts +27 -0
  50. package/dist/container/rules.d.ts.map +1 -0
  51. package/dist/container/rules.js +216 -0
  52. package/dist/container/scanner.d.ts +50 -0
  53. package/dist/container/scanner.d.ts.map +1 -0
  54. package/dist/container/scanner.js +143 -0
  55. package/dist/frameworks/engine.d.ts +108 -0
  56. package/dist/frameworks/engine.d.ts.map +1 -0
  57. package/dist/frameworks/engine.js +206 -0
  58. package/dist/frameworks/gdpr.d.ts +6 -0
  59. package/dist/frameworks/gdpr.d.ts.map +1 -0
  60. package/dist/frameworks/gdpr.js +198 -0
  61. package/dist/frameworks/hipaa.d.ts +6 -0
  62. package/dist/frameworks/hipaa.d.ts.map +1 -0
  63. package/dist/frameworks/hipaa.js +183 -0
  64. package/dist/frameworks/index.d.ts +8 -0
  65. package/dist/frameworks/index.d.ts.map +1 -0
  66. package/dist/frameworks/index.js +30 -0
  67. package/dist/frameworks/iso27001.d.ts +63 -0
  68. package/dist/frameworks/iso27001.d.ts.map +1 -0
  69. package/dist/frameworks/iso27001.js +331 -0
  70. package/dist/frameworks/nist.d.ts +62 -0
  71. package/dist/frameworks/nist.d.ts.map +1 -0
  72. package/dist/frameworks/nist.js +424 -0
  73. package/dist/frameworks/pci.d.ts +6 -0
  74. package/dist/frameworks/pci.d.ts.map +1 -0
  75. package/dist/frameworks/pci.js +201 -0
  76. package/dist/frameworks/soc2.d.ts +7 -0
  77. package/dist/frameworks/soc2.d.ts.map +1 -0
  78. package/dist/frameworks/soc2.js +248 -0
  79. package/dist/iac/drift-detector.d.ts +64 -0
  80. package/dist/iac/drift-detector.d.ts.map +1 -0
  81. package/dist/iac/drift-detector.js +134 -0
  82. package/dist/iac/index.d.ts +4 -0
  83. package/dist/iac/index.d.ts.map +1 -0
  84. package/dist/iac/index.js +19 -0
  85. package/dist/iac/rules.d.ts +17 -0
  86. package/dist/iac/rules.d.ts.map +1 -0
  87. package/dist/iac/rules.js +385 -0
  88. package/dist/iac/scanner.d.ts +104 -0
  89. package/dist/iac/scanner.d.ts.map +1 -0
  90. package/dist/iac/scanner.js +343 -0
  91. package/dist/index.d.ts +7 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +28 -0
  94. package/dist/pii/data-flow.d.ts +58 -0
  95. package/dist/pii/data-flow.d.ts.map +1 -0
  96. package/dist/pii/data-flow.js +154 -0
  97. package/dist/pii/detector.d.ts +60 -0
  98. package/dist/pii/detector.d.ts.map +1 -0
  99. package/dist/pii/detector.js +267 -0
  100. package/dist/pii/index.d.ts +4 -0
  101. package/dist/pii/index.d.ts.map +1 -0
  102. package/dist/pii/index.js +19 -0
  103. package/dist/pii/patterns.d.ts +36 -0
  104. package/dist/pii/patterns.d.ts.map +1 -0
  105. package/dist/pii/patterns.js +108 -0
  106. package/dist/policy/index.d.ts +5 -0
  107. package/dist/policy/index.d.ts.map +1 -0
  108. package/dist/policy/index.js +20 -0
  109. package/dist/policy/opa-engine.d.ts +121 -0
  110. package/dist/policy/opa-engine.d.ts.map +1 -0
  111. package/dist/policy/opa-engine.js +423 -0
  112. package/package.json +31 -0
  113. package/src/audit/emitter.ts +383 -0
  114. package/src/audit/events.ts +351 -0
  115. package/src/audit/index.ts +35 -0
  116. package/src/audit/storage.ts +394 -0
  117. package/src/automation/__tests__/compliance-scheduler.test.ts +183 -0
  118. package/src/automation/audit-logger.ts +629 -0
  119. package/src/automation/compliance-scheduler-fixed.ts +0 -0
  120. package/src/automation/compliance-scheduler.ts +516 -0
  121. package/src/automation/dashboard.ts +947 -0
  122. package/src/automation/email-service.ts +230 -0
  123. package/src/automation/evidence-collector.ts +866 -0
  124. package/src/automation/index.ts +8 -0
  125. package/src/automation/pdf-exporter.ts +434 -0
  126. package/src/automation/reporting-engine.ts +462 -0
  127. package/src/container/index.ts +3 -0
  128. package/src/container/kubernetes.ts +379 -0
  129. package/src/container/rules.ts +244 -0
  130. package/src/container/scanner.ts +202 -0
  131. package/src/frameworks/engine.ts +298 -0
  132. package/src/frameworks/gdpr.ts +204 -0
  133. package/src/frameworks/hipaa.ts +209 -0
  134. package/src/frameworks/index.ts +23 -0
  135. package/src/frameworks/iso27001.ts +398 -0
  136. package/src/frameworks/nist.ts +518 -0
  137. package/src/frameworks/pci.ts +226 -0
  138. package/src/frameworks/soc2.ts +281 -0
  139. package/src/iac/drift-detector.ts +197 -0
  140. package/src/iac/index.ts +3 -0
  141. package/src/iac/rules.ts +420 -0
  142. package/src/iac/scanner.ts +445 -0
  143. package/src/index.ts +17 -0
  144. package/src/pii/data-flow.ts +216 -0
  145. package/src/pii/detector.ts +327 -0
  146. package/src/pii/index.ts +3 -0
  147. package/src/pii/patterns.ts +128 -0
  148. package/src/policy/index.ts +5 -0
  149. package/src/policy/opa-engine.ts +504 -0
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ /**
3
+ * Audit Trail Storage
4
+ *
5
+ * Hash-chained JSONL storage with adapter interface for future extensibility.
6
+ * Default: Local file storage at .guardrail/audit/audit.log.jsonl
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.ServerStorageAdapter = exports.LocalJSONLStorage = void 0;
43
+ exports.createStorageAdapter = createStorageAdapter;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const readline = __importStar(require("readline"));
47
+ const events_1 = require("./events");
48
+ // Genesis hash (used as prevHash for first event)
49
+ const GENESIS_HASH = '0'.repeat(64);
50
+ /**
51
+ * Local JSONL file storage adapter
52
+ */
53
+ class LocalJSONLStorage {
54
+ filePath;
55
+ lastHash = GENESIS_HASH;
56
+ initialized = false;
57
+ constructor(basePath = process.cwd()) {
58
+ const auditDir = path.join(basePath, '.guardrail', 'audit');
59
+ this.filePath = path.join(auditDir, 'audit.log.jsonl');
60
+ }
61
+ async ensureDir() {
62
+ const dir = path.dirname(this.filePath);
63
+ if (!fs.existsSync(dir)) {
64
+ fs.mkdirSync(dir, { recursive: true });
65
+ }
66
+ }
67
+ async initialize() {
68
+ if (this.initialized)
69
+ return;
70
+ await this.ensureDir();
71
+ // Read last hash from existing log
72
+ if (fs.existsSync(this.filePath)) {
73
+ const events = await this.tail(1);
74
+ if (events.length > 0 && events[0]) {
75
+ this.lastHash = events[0].hash;
76
+ }
77
+ }
78
+ this.initialized = true;
79
+ }
80
+ async append(event) {
81
+ await this.initialize();
82
+ const line = JSON.stringify(event) + '\n';
83
+ fs.appendFileSync(this.filePath, line, 'utf8');
84
+ this.lastHash = event.hash;
85
+ }
86
+ async getLastHash() {
87
+ await this.initialize();
88
+ return this.lastHash;
89
+ }
90
+ async read(options = {}) {
91
+ await this.initialize();
92
+ if (!fs.existsSync(this.filePath)) {
93
+ return [];
94
+ }
95
+ const events = [];
96
+ const fileStream = fs.createReadStream(this.filePath);
97
+ const rl = readline.createInterface({
98
+ input: fileStream,
99
+ crlfDelay: Infinity,
100
+ });
101
+ let index = 0;
102
+ const offset = options.offset ?? 0;
103
+ const limit = options.limit ?? Infinity;
104
+ for await (const line of rl) {
105
+ if (!line.trim())
106
+ continue;
107
+ try {
108
+ const event = JSON.parse(line);
109
+ // Apply filters
110
+ if (options.startDate && new Date(event.timestamp) < options.startDate)
111
+ continue;
112
+ if (options.endDate && new Date(event.timestamp) > options.endDate)
113
+ continue;
114
+ if (options.surface && event.surface !== options.surface)
115
+ continue;
116
+ if (options.category && event.category !== options.category)
117
+ continue;
118
+ if (options.action && event.action !== options.action)
119
+ continue;
120
+ if (options.actorId && event.actor.id !== options.actorId)
121
+ continue;
122
+ if (options.result && event.result !== options.result)
123
+ continue;
124
+ // Apply pagination
125
+ if (index >= offset && events.length < limit) {
126
+ events.push(event);
127
+ }
128
+ index++;
129
+ if (events.length >= limit)
130
+ break;
131
+ }
132
+ catch (e) {
133
+ // Skip malformed lines
134
+ console.error(`Skipping malformed audit event: ${e}`);
135
+ }
136
+ }
137
+ return events;
138
+ }
139
+ async tail(count) {
140
+ await this.initialize();
141
+ if (!fs.existsSync(this.filePath)) {
142
+ return [];
143
+ }
144
+ // Read all events and return last N
145
+ const allEvents = [];
146
+ const fileStream = fs.createReadStream(this.filePath);
147
+ const rl = readline.createInterface({
148
+ input: fileStream,
149
+ crlfDelay: Infinity,
150
+ });
151
+ for await (const line of rl) {
152
+ if (!line.trim())
153
+ continue;
154
+ try {
155
+ const event = JSON.parse(line);
156
+ allEvents.push(event);
157
+ }
158
+ catch (e) {
159
+ // Skip malformed lines
160
+ }
161
+ }
162
+ return allEvents.slice(-count);
163
+ }
164
+ async validateChain() {
165
+ await this.initialize();
166
+ const result = {
167
+ valid: true,
168
+ totalEvents: 0,
169
+ validEvents: 0,
170
+ invalidEvents: 0,
171
+ brokenLinks: [],
172
+ tamperedEvents: [],
173
+ };
174
+ if (!fs.existsSync(this.filePath)) {
175
+ return result;
176
+ }
177
+ const fileStream = fs.createReadStream(this.filePath);
178
+ const rl = readline.createInterface({
179
+ input: fileStream,
180
+ crlfDelay: Infinity,
181
+ });
182
+ let expectedPrevHash = GENESIS_HASH;
183
+ let index = 0;
184
+ for await (const line of rl) {
185
+ if (!line.trim())
186
+ continue;
187
+ try {
188
+ const event = JSON.parse(line);
189
+ result.totalEvents++;
190
+ // Validate hash chain
191
+ if (event.prevHash !== expectedPrevHash) {
192
+ result.valid = false;
193
+ result.invalidEvents++;
194
+ result.brokenLinks.push({
195
+ index,
196
+ eventId: event.id,
197
+ expectedPrevHash,
198
+ actualPrevHash: event.prevHash,
199
+ });
200
+ }
201
+ else if (!(0, events_1.verifyEventHash)(event)) {
202
+ // Validate event hash
203
+ result.valid = false;
204
+ result.invalidEvents++;
205
+ result.tamperedEvents.push({
206
+ index,
207
+ eventId: event.id,
208
+ reason: 'Event hash does not match content',
209
+ });
210
+ }
211
+ else {
212
+ result.validEvents++;
213
+ }
214
+ expectedPrevHash = event.hash;
215
+ index++;
216
+ }
217
+ catch (e) {
218
+ result.totalEvents++;
219
+ result.invalidEvents++;
220
+ result.tamperedEvents.push({
221
+ index,
222
+ eventId: 'unknown',
223
+ reason: `Malformed JSON: ${e}`,
224
+ });
225
+ index++;
226
+ }
227
+ }
228
+ return result;
229
+ }
230
+ async export(format, options = {}) {
231
+ const events = await this.read({
232
+ startDate: options.startDate,
233
+ endDate: options.endDate,
234
+ });
235
+ if (format === 'json') {
236
+ return JSON.stringify(events, null, 2);
237
+ }
238
+ // CSV export
239
+ const headers = [
240
+ 'id',
241
+ 'timestamp',
242
+ 'actor_id',
243
+ 'actor_type',
244
+ 'actor_name',
245
+ 'surface',
246
+ 'category',
247
+ 'action',
248
+ 'target_type',
249
+ 'target_path',
250
+ 'tier',
251
+ 'result',
252
+ 'hash',
253
+ ];
254
+ if (options.includeMetadata) {
255
+ headers.push('metadata');
256
+ }
257
+ const rows = events.map(event => {
258
+ const row = [
259
+ event.id,
260
+ event.timestamp,
261
+ event.actor.id,
262
+ event.actor.type,
263
+ event.actor.name ?? '',
264
+ event.surface,
265
+ event.category,
266
+ event.action,
267
+ event.target.type,
268
+ event.target.path ?? '',
269
+ event.tier,
270
+ event.result,
271
+ event.hash,
272
+ ];
273
+ if (options.includeMetadata) {
274
+ row.push(JSON.stringify(event.metadata ?? {}));
275
+ }
276
+ return row.map(v => `"${String(v).replace(/"/g, '""')}"`).join(',');
277
+ });
278
+ return [headers.join(','), ...rows].join('\n');
279
+ }
280
+ async clear() {
281
+ if (fs.existsSync(this.filePath)) {
282
+ fs.unlinkSync(this.filePath);
283
+ }
284
+ this.lastHash = GENESIS_HASH;
285
+ this.initialized = false;
286
+ }
287
+ getFilePath() {
288
+ return this.filePath;
289
+ }
290
+ }
291
+ exports.LocalJSONLStorage = LocalJSONLStorage;
292
+ /**
293
+ * Server storage adapter (placeholder for future implementation)
294
+ */
295
+ class ServerStorageAdapter {
296
+ apiUrl;
297
+ apiKey;
298
+ constructor(apiUrl, apiKey) {
299
+ this.apiUrl = apiUrl;
300
+ this.apiKey = apiKey;
301
+ }
302
+ async append(_event) {
303
+ // TODO: Implement server storage
304
+ void this.apiUrl;
305
+ void this.apiKey;
306
+ throw new Error('Server storage not yet implemented');
307
+ }
308
+ async getLastHash() {
309
+ throw new Error('Server storage not yet implemented');
310
+ }
311
+ async read(_options) {
312
+ throw new Error('Server storage not yet implemented');
313
+ }
314
+ async tail(_count) {
315
+ throw new Error('Server storage not yet implemented');
316
+ }
317
+ async validateChain() {
318
+ throw new Error('Server storage not yet implemented');
319
+ }
320
+ async export(_format, _options) {
321
+ throw new Error('Server storage not yet implemented');
322
+ }
323
+ async clear() {
324
+ throw new Error('Server storage not yet implemented');
325
+ }
326
+ }
327
+ exports.ServerStorageAdapter = ServerStorageAdapter;
328
+ /**
329
+ * Factory function to create storage adapter based on configuration
330
+ */
331
+ function createStorageAdapter(config) {
332
+ const type = config?.type ?? 'local';
333
+ if (type === 'server' && config?.apiUrl && config?.apiKey) {
334
+ return new ServerStorageAdapter(config.apiUrl, config.apiKey);
335
+ }
336
+ return new LocalJSONLStorage(config?.basePath);
337
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compliance-scheduler.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compliance-scheduler.test.d.ts","sourceRoot":"","sources":["../../../src/automation/__tests__/compliance-scheduler.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const compliance_scheduler_1 = require("../compliance-scheduler");
4
+ const globals_1 = require("@jest/globals");
5
+ // Create mocks for the dependencies
6
+ globals_1.jest.mock("@guardrail/database", () => ({
7
+ prisma: {
8
+ complianceSchedule: {
9
+ findMany: globals_1.jest.fn().mockResolvedValue([]),
10
+ upsert: globals_1.jest.fn(),
11
+ deleteMany: globals_1.jest.fn(),
12
+ update: globals_1.jest.fn(),
13
+ findFirst: globals_1.jest
14
+ .fn()
15
+ .mockImplementation(async ({ where }) => {
16
+ if (where.projectId === "test-project" &&
17
+ where.frameworkId === "test-framework") {
18
+ return {
19
+ id: "test-id",
20
+ projectId: "test-project",
21
+ frameworkId: "test-framework",
22
+ enabled: true,
23
+ schedule: "0 0 * * *",
24
+ notifications: {
25
+ slack: "https://hooks.slack.com/services/test/webhook",
26
+ email: ["test@example.com"],
27
+ },
28
+ };
29
+ }
30
+ return null;
31
+ }),
32
+ },
33
+ project: {
34
+ findUnique: globals_1.jest
35
+ .fn()
36
+ .mockResolvedValue({ id: "test-project", path: "/tmp" }),
37
+ },
38
+ },
39
+ }));
40
+ globals_1.jest.mock("../../frameworks/engine", () => ({
41
+ complianceAutomationEngine: {
42
+ // Return structure matching result.result.assessment.summary.score
43
+ assess: globals_1.jest.fn().mockResolvedValue({
44
+ summary: { score: 85 },
45
+ details: {},
46
+ }),
47
+ },
48
+ }));
49
+ globals_1.jest.mock("../reporting-engine", () => ({
50
+ reportingEngine: {
51
+ generateReport: globals_1.jest
52
+ .fn()
53
+ .mockResolvedValue({ id: "report-1" }),
54
+ },
55
+ }));
56
+ globals_1.jest.mock("../email-service", () => ({
57
+ emailService: {
58
+ sendComplianceNotification: globals_1.jest
59
+ .fn()
60
+ .mockResolvedValue({
61
+ success: true,
62
+ messageId: "test-message-id",
63
+ }),
64
+ },
65
+ }));
66
+ (0, globals_1.describe)("ComplianceScheduler Slack Integration", () => {
67
+ beforeEach(() => {
68
+ globals_1.jest.useFakeTimers();
69
+ });
70
+ afterEach(() => {
71
+ globals_1.jest.useRealTimers();
72
+ });
73
+ (0, globals_1.it)("should send Slack notification", async () => {
74
+ // Mock fetch
75
+ const fetchMock = globals_1.jest.fn().mockResolvedValue({
76
+ ok: true,
77
+ json: () => Promise.resolve({}),
78
+ });
79
+ global.fetch = fetchMock;
80
+ // Spy on console.log to check current behavior
81
+ const consoleSpy = globals_1.jest.spyOn(console, "log");
82
+ const scheduler = new compliance_scheduler_1.ComplianceScheduler();
83
+ // Create a mock result
84
+ const mockResult = {
85
+ scheduleId: "test-schedule",
86
+ executionId: "test-execution",
87
+ startTime: new Date(),
88
+ endTime: new Date(),
89
+ status: "completed",
90
+ result: {
91
+ assessment: {
92
+ summary: { score: 85 },
93
+ },
94
+ },
95
+ };
96
+ // Call sendNotifications directly
97
+ await scheduler.sendNotifications("test-project", "test-framework", mockResult);
98
+ (0, globals_1.expect)(fetchMock).toHaveBeenCalledWith("https://hooks.slack.com/services/test/webhook", globals_1.expect.objectContaining({
99
+ method: "POST",
100
+ headers: { "Content-Type": "application/json" },
101
+ body: globals_1.expect.stringContaining("Compliance Check WARNING"), // Score is 85, so warning
102
+ }));
103
+ // Verify block structure in body
104
+ const callArgs = fetchMock.mock.calls[0];
105
+ if (callArgs && callArgs.length > 1) {
106
+ const body = JSON.parse(callArgs[1].body);
107
+ (0, globals_1.expect)(body.blocks).toBeDefined();
108
+ // Check for score in fields instead of text
109
+ (0, globals_1.expect)(body.blocks.some((b) => b.fields &&
110
+ b.fields.some((f) => f.text && f.text.includes("85%")))).toBe(true);
111
+ }
112
+ // Check if console log was called
113
+ (0, globals_1.expect)(consoleSpy).toHaveBeenCalledWith(globals_1.expect.stringContaining("Sending Slack notification to https://hooks.slack.com/services/test/webhook"));
114
+ });
115
+ (0, globals_1.it)("should handle Slack errors gracefully", async () => {
116
+ // Mock fetch error
117
+ const fetchMock = globals_1.jest
118
+ .fn()
119
+ .mockRejectedValue(new Error("Network error"));
120
+ global.fetch = fetchMock;
121
+ const consoleErrorSpy = globals_1.jest.spyOn(console, "error");
122
+ const scheduler = new compliance_scheduler_1.ComplianceScheduler();
123
+ // Create a mock result
124
+ const mockResult = {
125
+ scheduleId: "test-schedule",
126
+ executionId: "test-execution",
127
+ startTime: new Date(),
128
+ endTime: new Date(),
129
+ status: "completed",
130
+ result: {
131
+ assessment: {
132
+ summary: { score: 85 },
133
+ },
134
+ },
135
+ };
136
+ // Call sendNotifications directly
137
+ await scheduler.sendNotifications("test-project", "test-framework", mockResult);
138
+ (0, globals_1.expect)(consoleErrorSpy).toHaveBeenCalledWith("Failed to send Slack notification:", globals_1.expect.any(Error));
139
+ });
140
+ });
@@ -0,0 +1,129 @@
1
+ interface AuditEvent {
2
+ id?: string;
3
+ type: string;
4
+ category: 'compliance' | 'security' | 'access' | 'data' | 'system';
5
+ projectId?: string;
6
+ frameworkId?: string;
7
+ userId?: string;
8
+ sessionId?: string;
9
+ timestamp: Date;
10
+ metadata?: any;
11
+ details?: any;
12
+ severity: 'low' | 'medium' | 'high' | 'critical';
13
+ source: string;
14
+ correlationId?: string;
15
+ ipAddress?: string;
16
+ userAgent?: string;
17
+ }
18
+ interface AuditQuery {
19
+ projectId?: string;
20
+ frameworkId?: string;
21
+ userId?: string;
22
+ type?: string;
23
+ category?: string;
24
+ severity?: string;
25
+ startDate?: Date;
26
+ endDate?: Date;
27
+ limit?: number;
28
+ offset?: number;
29
+ orderBy?: 'timestamp' | 'severity' | 'type';
30
+ orderDirection?: 'asc' | 'desc';
31
+ }
32
+ interface AuditTrail {
33
+ events: AuditEvent[];
34
+ summary: {
35
+ totalEvents: number;
36
+ byType: Record<string, number>;
37
+ byCategory: Record<string, number>;
38
+ bySeverity: Record<string, number>;
39
+ timeRange: {
40
+ start: Date;
41
+ end: Date;
42
+ };
43
+ };
44
+ metadata: {
45
+ hasMore: boolean;
46
+ totalCount: number;
47
+ query: AuditQuery;
48
+ };
49
+ }
50
+ /**
51
+ * Comprehensive Audit Trail Logger
52
+ *
53
+ * Provides tamper-proof logging of all compliance-related activities
54
+ * with chain of custody verification and evidence preservation
55
+ */
56
+ export declare class AuditLogger {
57
+ private readonly sequenceCounters;
58
+ /**
59
+ * Log an audit event
60
+ */
61
+ logEvent(event: AuditEvent): Promise<string>;
62
+ /**
63
+ * Log compliance check start
64
+ */
65
+ logComplianceCheckStart(projectId: string, frameworkId: string, executionId: string, metadata?: any): Promise<string>;
66
+ /**
67
+ * Log compliance check completion
68
+ */
69
+ logComplianceCheckComplete(projectId: string, frameworkId: string, executionId: string, result: any, metadata?: any): Promise<string>;
70
+ /**
71
+ * Log evidence collection
72
+ */
73
+ logEvidenceCollection(projectId: string, frameworkId: string, collectionId: string, artifactCount: number, metadata?: any): Promise<string>;
74
+ /**
75
+ * Log compliance violation
76
+ */
77
+ logViolation(projectId: string, frameworkId: string, controlId: string, violation: any, severity?: 'medium' | 'high' | 'critical'): Promise<string>;
78
+ /**
79
+ * Log remediation action
80
+ */
81
+ logRemediation(projectId: string, frameworkId: string, controlId: string, action: string, userId?: string): Promise<string>;
82
+ /**
83
+ * Log access to compliance data
84
+ */
85
+ logAccess(projectId: string, userId: string, action: string, resource: string, metadata?: any): Promise<string>;
86
+ /**
87
+ * Query audit trail
88
+ */
89
+ query(query: AuditQuery): Promise<AuditTrail>;
90
+ /**
91
+ * Get audit trail for a specific time period
92
+ */
93
+ getAuditTrail(projectId: string, startDate: Date, endDate: Date): Promise<AuditTrail>;
94
+ /**
95
+ * Verify audit trail integrity
96
+ */
97
+ verifyIntegrity(projectId?: string): Promise<{
98
+ valid: boolean;
99
+ totalEvents: number;
100
+ violations: Array<{
101
+ eventId: string;
102
+ sequenceNumber: number;
103
+ issue: string;
104
+ }>;
105
+ }>;
106
+ /**
107
+ * Store audit event in database
108
+ */
109
+ private storeEvent;
110
+ /**
111
+ * Calculate hash for event
112
+ */
113
+ private calculateHash;
114
+ /**
115
+ * Determine severity based on compliance result
116
+ */
117
+ private determineSeverity;
118
+ /**
119
+ * Log to external systems for redundancy
120
+ */
121
+ private logToExternalSystems;
122
+ /**
123
+ * Generate summary statistics
124
+ */
125
+ private generateSummary;
126
+ }
127
+ export declare const auditLogger: AuditLogger;
128
+ export {};
129
+ //# sourceMappingURL=audit-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.d.ts","sourceRoot":"","sources":["../../src/automation/audit-logger.ts"],"names":[],"mappings":"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"}