tlc-claude-code 1.4.8 → 1.4.9

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 (169) hide show
  1. package/package.json +1 -1
  2. package/server/index.js +229 -14
  3. package/server/lib/compliance/control-mapper.js +401 -0
  4. package/server/lib/compliance/control-mapper.test.js +117 -0
  5. package/server/lib/compliance/evidence-linker.js +296 -0
  6. package/server/lib/compliance/evidence-linker.test.js +121 -0
  7. package/server/lib/compliance/gdpr-checklist.js +416 -0
  8. package/server/lib/compliance/gdpr-checklist.test.js +131 -0
  9. package/server/lib/compliance/hipaa-checklist.js +277 -0
  10. package/server/lib/compliance/hipaa-checklist.test.js +101 -0
  11. package/server/lib/compliance/iso27001-checklist.js +287 -0
  12. package/server/lib/compliance/iso27001-checklist.test.js +99 -0
  13. package/server/lib/compliance/multi-framework-reporter.js +284 -0
  14. package/server/lib/compliance/multi-framework-reporter.test.js +127 -0
  15. package/server/lib/compliance/pci-dss-checklist.js +214 -0
  16. package/server/lib/compliance/pci-dss-checklist.test.js +95 -0
  17. package/server/lib/compliance/trust-centre.js +187 -0
  18. package/server/lib/compliance/trust-centre.test.js +93 -0
  19. package/server/lib/dashboard/api-server.js +155 -0
  20. package/server/lib/dashboard/api-server.test.js +155 -0
  21. package/server/lib/dashboard/health-api.js +199 -0
  22. package/server/lib/dashboard/health-api.test.js +122 -0
  23. package/server/lib/dashboard/notes-api.js +234 -0
  24. package/server/lib/dashboard/notes-api.test.js +134 -0
  25. package/server/lib/dashboard/router-api.js +176 -0
  26. package/server/lib/dashboard/router-api.test.js +132 -0
  27. package/server/lib/dashboard/tasks-api.js +289 -0
  28. package/server/lib/dashboard/tasks-api.test.js +161 -0
  29. package/server/lib/dashboard/tlc-introspection.js +197 -0
  30. package/server/lib/dashboard/tlc-introspection.test.js +138 -0
  31. package/server/lib/dashboard/version-api.js +222 -0
  32. package/server/lib/dashboard/version-api.test.js +112 -0
  33. package/server/lib/dashboard/websocket-server.js +104 -0
  34. package/server/lib/dashboard/websocket-server.test.js +118 -0
  35. package/server/lib/deploy/branch-classifier.js +163 -0
  36. package/server/lib/deploy/branch-classifier.test.js +164 -0
  37. package/server/lib/deploy/deployment-approval.js +299 -0
  38. package/server/lib/deploy/deployment-approval.test.js +296 -0
  39. package/server/lib/deploy/deployment-audit.js +374 -0
  40. package/server/lib/deploy/deployment-audit.test.js +307 -0
  41. package/server/lib/deploy/deployment-executor.js +335 -0
  42. package/server/lib/deploy/deployment-executor.test.js +329 -0
  43. package/server/lib/deploy/deployment-rules.js +163 -0
  44. package/server/lib/deploy/deployment-rules.test.js +188 -0
  45. package/server/lib/deploy/rollback-manager.js +379 -0
  46. package/server/lib/deploy/rollback-manager.test.js +321 -0
  47. package/server/lib/deploy/security-gates.js +236 -0
  48. package/server/lib/deploy/security-gates.test.js +222 -0
  49. package/server/lib/k8s/gitops-config.js +188 -0
  50. package/server/lib/k8s/gitops-config.test.js +59 -0
  51. package/server/lib/k8s/helm-generator.js +196 -0
  52. package/server/lib/k8s/helm-generator.test.js +59 -0
  53. package/server/lib/k8s/kustomize-generator.js +176 -0
  54. package/server/lib/k8s/kustomize-generator.test.js +58 -0
  55. package/server/lib/k8s/network-policy.js +114 -0
  56. package/server/lib/k8s/network-policy.test.js +53 -0
  57. package/server/lib/k8s/pod-security.js +114 -0
  58. package/server/lib/k8s/pod-security.test.js +55 -0
  59. package/server/lib/k8s/rbac-generator.js +132 -0
  60. package/server/lib/k8s/rbac-generator.test.js +57 -0
  61. package/server/lib/k8s/resource-manager.js +172 -0
  62. package/server/lib/k8s/resource-manager.test.js +60 -0
  63. package/server/lib/k8s/secrets-encryption.js +168 -0
  64. package/server/lib/k8s/secrets-encryption.test.js +49 -0
  65. package/server/lib/monitoring/alert-manager.js +238 -0
  66. package/server/lib/monitoring/alert-manager.test.js +106 -0
  67. package/server/lib/monitoring/health-check.js +226 -0
  68. package/server/lib/monitoring/health-check.test.js +176 -0
  69. package/server/lib/monitoring/incident-manager.js +230 -0
  70. package/server/lib/monitoring/incident-manager.test.js +98 -0
  71. package/server/lib/monitoring/log-aggregator.js +147 -0
  72. package/server/lib/monitoring/log-aggregator.test.js +89 -0
  73. package/server/lib/monitoring/metrics-collector.js +337 -0
  74. package/server/lib/monitoring/metrics-collector.test.js +172 -0
  75. package/server/lib/monitoring/status-page.js +214 -0
  76. package/server/lib/monitoring/status-page.test.js +105 -0
  77. package/server/lib/monitoring/uptime-monitor.js +194 -0
  78. package/server/lib/monitoring/uptime-monitor.test.js +109 -0
  79. package/server/lib/network/fail2ban-config.js +294 -0
  80. package/server/lib/network/fail2ban-config.test.js +275 -0
  81. package/server/lib/network/firewall-manager.js +252 -0
  82. package/server/lib/network/firewall-manager.test.js +254 -0
  83. package/server/lib/network/geoip-filter.js +282 -0
  84. package/server/lib/network/geoip-filter.test.js +264 -0
  85. package/server/lib/network/rate-limiter.js +229 -0
  86. package/server/lib/network/rate-limiter.test.js +293 -0
  87. package/server/lib/network/request-validator.js +351 -0
  88. package/server/lib/network/request-validator.test.js +345 -0
  89. package/server/lib/network/security-headers.js +251 -0
  90. package/server/lib/network/security-headers.test.js +283 -0
  91. package/server/lib/network/tls-config.js +210 -0
  92. package/server/lib/network/tls-config.test.js +248 -0
  93. package/server/lib/security/auth-security.js +369 -0
  94. package/server/lib/security/auth-security.test.js +448 -0
  95. package/server/lib/security/cis-benchmark.js +152 -0
  96. package/server/lib/security/cis-benchmark.test.js +137 -0
  97. package/server/lib/security/compose-templates.js +312 -0
  98. package/server/lib/security/compose-templates.test.js +229 -0
  99. package/server/lib/security/container-runtime.js +456 -0
  100. package/server/lib/security/container-runtime.test.js +503 -0
  101. package/server/lib/security/cors-validator.js +278 -0
  102. package/server/lib/security/cors-validator.test.js +310 -0
  103. package/server/lib/security/crypto-utils.js +253 -0
  104. package/server/lib/security/crypto-utils.test.js +409 -0
  105. package/server/lib/security/dockerfile-linter.js +459 -0
  106. package/server/lib/security/dockerfile-linter.test.js +483 -0
  107. package/server/lib/security/dockerfile-templates.js +278 -0
  108. package/server/lib/security/dockerfile-templates.test.js +164 -0
  109. package/server/lib/security/error-sanitizer.js +426 -0
  110. package/server/lib/security/error-sanitizer.test.js +331 -0
  111. package/server/lib/security/headers-generator.js +368 -0
  112. package/server/lib/security/headers-generator.test.js +398 -0
  113. package/server/lib/security/image-scanner.js +83 -0
  114. package/server/lib/security/image-scanner.test.js +106 -0
  115. package/server/lib/security/input-validator.js +352 -0
  116. package/server/lib/security/input-validator.test.js +330 -0
  117. package/server/lib/security/network-policy.js +174 -0
  118. package/server/lib/security/network-policy.test.js +164 -0
  119. package/server/lib/security/output-encoder.js +237 -0
  120. package/server/lib/security/output-encoder.test.js +276 -0
  121. package/server/lib/security/path-validator.js +359 -0
  122. package/server/lib/security/path-validator.test.js +293 -0
  123. package/server/lib/security/query-builder.js +421 -0
  124. package/server/lib/security/query-builder.test.js +318 -0
  125. package/server/lib/security/secret-detector.js +290 -0
  126. package/server/lib/security/secret-detector.test.js +354 -0
  127. package/server/lib/security/secrets-validator.js +137 -0
  128. package/server/lib/security/secrets-validator.test.js +120 -0
  129. package/server/lib/security-testing/dast-runner.js +154 -0
  130. package/server/lib/security-testing/dast-runner.test.js +62 -0
  131. package/server/lib/security-testing/dependency-scanner.js +172 -0
  132. package/server/lib/security-testing/dependency-scanner.test.js +64 -0
  133. package/server/lib/security-testing/pentest-runner.js +230 -0
  134. package/server/lib/security-testing/pentest-runner.test.js +60 -0
  135. package/server/lib/security-testing/sast-runner.js +136 -0
  136. package/server/lib/security-testing/sast-runner.test.js +62 -0
  137. package/server/lib/security-testing/secret-scanner.js +153 -0
  138. package/server/lib/security-testing/secret-scanner.test.js +66 -0
  139. package/server/lib/security-testing/security-gate.js +216 -0
  140. package/server/lib/security-testing/security-gate.test.js +115 -0
  141. package/server/lib/security-testing/security-reporter.js +303 -0
  142. package/server/lib/security-testing/security-reporter.test.js +114 -0
  143. package/server/lib/standards/audit-checker.js +546 -0
  144. package/server/lib/standards/audit-checker.test.js +415 -0
  145. package/server/lib/standards/cleanup-executor.js +452 -0
  146. package/server/lib/standards/cleanup-executor.test.js +293 -0
  147. package/server/lib/standards/refactor-stepper.js +425 -0
  148. package/server/lib/standards/refactor-stepper.test.js +298 -0
  149. package/server/lib/standards/standards-injector.js +167 -0
  150. package/server/lib/standards/standards-injector.test.js +232 -0
  151. package/server/lib/user-management.test.js +284 -0
  152. package/server/lib/vps/backup-manager.js +157 -0
  153. package/server/lib/vps/backup-manager.test.js +59 -0
  154. package/server/lib/vps/caddy-config.js +159 -0
  155. package/server/lib/vps/caddy-config.test.js +48 -0
  156. package/server/lib/vps/compose-orchestrator.js +219 -0
  157. package/server/lib/vps/compose-orchestrator.test.js +50 -0
  158. package/server/lib/vps/database-config.js +208 -0
  159. package/server/lib/vps/database-config.test.js +47 -0
  160. package/server/lib/vps/deploy-script.js +211 -0
  161. package/server/lib/vps/deploy-script.test.js +53 -0
  162. package/server/lib/vps/secrets-manager.js +148 -0
  163. package/server/lib/vps/secrets-manager.test.js +58 -0
  164. package/server/lib/vps/server-hardening.js +174 -0
  165. package/server/lib/vps/server-hardening.test.js +70 -0
  166. package/server/package-lock.json +19 -0
  167. package/server/package.json +1 -0
  168. package/server/templates/CLAUDE.md +37 -0
  169. package/server/templates/CODING-STANDARDS.md +408 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * PCI DSS v4.0 Compliance Checklist
3
+ * Payment Card Industry Data Security Standard requirements
4
+ */
5
+
6
+ // PCI DSS v4.0 Requirements
7
+ const REQUIREMENTS = [
8
+ // 12 main requirements
9
+ { id: 'req-1', name: 'Install and maintain network security controls', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
10
+ { id: 'req-2', name: 'Apply secure configurations to all system components', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
11
+ { id: 'req-3', name: 'Protect stored account data', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
12
+ { id: 'req-4', name: 'Protect cardholder data with strong cryptography during transmission', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
13
+ { id: 'req-5', name: 'Protect all systems and networks from malicious software', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
14
+ { id: 'req-6', name: 'Develop and maintain secure systems and software', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
15
+ { id: 'req-7', name: 'Restrict access to system components and cardholder data', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
16
+ { id: 'req-8', name: 'Identify users and authenticate access to system components', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
17
+ { id: 'req-9', name: 'Restrict physical access to cardholder data', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
18
+ { id: 'req-10', name: 'Log and monitor all access to system components and cardholder data', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
19
+ { id: 'req-11', name: 'Test security of systems and networks regularly', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
20
+ { id: 'req-12', name: 'Support information security with organizational policies and programs', level: 'requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: null },
21
+
22
+ // Sub-requirements for Requirement 1
23
+ { id: 'req-1.1', name: 'Processes and mechanisms for installing and maintaining network security controls are defined and understood', level: 'sub-requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: 'req-1' },
24
+ { id: 'req-1.2', name: 'Network security controls are configured and maintained', level: 'sub-requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: 'req-1' },
25
+ { id: 'req-1.3', name: 'Network access to and from the cardholder data environment is restricted', level: 'sub-requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'C-VT', 'D', 'P2PE'], parent: 'req-1' },
26
+
27
+ // Sub-requirements for Requirement 3
28
+ { id: 'req-3.4', name: 'PAN is rendered unreadable anywhere it is stored', level: 'sub-requirement', saqTypes: ['A', 'A-EP', 'B', 'B-IP', 'C', 'D', 'P2PE'], parent: 'req-3' }
29
+ ];
30
+
31
+ // Control mappings for technical implementations
32
+ const CONTROL_MAPPINGS = {
33
+ 'req-1.1': [
34
+ { type: 'firewall', description: 'Network firewall configuration', patterns: ['firewall', 'iptables', 'security-group'] },
35
+ { type: 'network-segmentation', description: 'Network segmentation controls', patterns: ['vlan', 'subnet', 'network-policy'] },
36
+ { type: 'documentation', description: 'Network security documentation', patterns: ['network-diagram', 'data-flow'] }
37
+ ],
38
+ 'req-1.2': [
39
+ { type: 'firewall', description: 'Firewall rule management', patterns: ['firewall-rules', 'ingress', 'egress'] },
40
+ { type: 'configuration', description: 'Secure configuration standards', patterns: ['config', 'settings'] }
41
+ ],
42
+ 'req-3.4': [
43
+ { type: 'encryption', description: 'Data encryption at rest', patterns: ['encrypt', 'aes', 'crypto'] },
44
+ { type: 'tokenization', description: 'PAN tokenization', patterns: ['token', 'mask', 'redact'] },
45
+ { type: 'hashing', description: 'One-way hashing', patterns: ['hash', 'sha256'] }
46
+ ]
47
+ };
48
+
49
+ // Requirement check logic
50
+ const REQUIREMENT_CHECKS = {
51
+ 'req-1.1': (evidence) => {
52
+ const gaps = [];
53
+ if (!evidence.hasFirewall) gaps.push('Firewall not detected');
54
+ if (!evidence.firewallConfig) gaps.push('Firewall configuration not provided');
55
+ return { passed: gaps.length === 0, gaps };
56
+ }
57
+ };
58
+
59
+ /**
60
+ * Create a PCI DSS checklist instance
61
+ * @param {Object} options - Configuration options
62
+ * @param {string} options.version - PCI DSS version (default: '4.0')
63
+ * @returns {Object} Checklist instance
64
+ */
65
+ export function createPciDssChecklist(options = {}) {
66
+ const version = options.version || '4.0';
67
+
68
+ return {
69
+ evaluate(evidence) {
70
+ const results = [];
71
+ const reqs = getRequirements();
72
+
73
+ for (const req of reqs) {
74
+ const result = checkRequirement(req.id, evidence);
75
+ results.push(result);
76
+ }
77
+
78
+ return {
79
+ version,
80
+ results,
81
+ compliant: results.every(r => r.status === 'compliant'),
82
+ score: (results.filter(r => r.status === 'compliant').length / results.length) * 100
83
+ };
84
+ },
85
+
86
+ getRequirements() {
87
+ return REQUIREMENTS.filter(r => r.id.startsWith('req-'));
88
+ }
89
+ };
90
+ }
91
+
92
+ /**
93
+ * Get PCI DSS requirements
94
+ * @param {Object} options - Filter options
95
+ * @param {boolean} options.includeSubRequirements - Include sub-requirements
96
+ * @param {string} options.saqType - Filter by SAQ type
97
+ * @returns {Array} Requirements list
98
+ */
99
+ export function getRequirements(options = {}) {
100
+ let reqs = [...REQUIREMENTS];
101
+
102
+ // Filter to main requirements unless sub-requirements requested
103
+ if (!options.includeSubRequirements) {
104
+ reqs = reqs.filter(r => r.level === 'requirement');
105
+ }
106
+
107
+ // Filter by SAQ type
108
+ if (options.saqType) {
109
+ reqs = reqs.filter(r => r.saqTypes.includes(options.saqType));
110
+ }
111
+
112
+ return reqs;
113
+ }
114
+
115
+ /**
116
+ * Check compliance with a specific requirement
117
+ * @param {string} requirementId - Requirement identifier
118
+ * @param {Object} evidence - Evidence for compliance check
119
+ * @returns {Object} Check result with status, gaps, and remediation
120
+ */
121
+ export function checkRequirement(requirementId, evidence) {
122
+ const requirement = REQUIREMENTS.find(r => r.id === requirementId);
123
+ const checkFn = REQUIREMENT_CHECKS[requirementId];
124
+
125
+ let status = 'non-compliant';
126
+ let gaps = [];
127
+
128
+ if (checkFn) {
129
+ const result = checkFn(evidence);
130
+ status = result.passed ? 'compliant' : 'non-compliant';
131
+ gaps = result.gaps;
132
+ } else {
133
+ // Default check - look for related evidence
134
+ gaps = ['Evidence not provided or check not implemented'];
135
+ }
136
+
137
+ const remediation = getRemediationGuidance(requirementId, gaps);
138
+
139
+ return {
140
+ requirementId,
141
+ requirementName: requirement?.name || 'Unknown requirement',
142
+ status,
143
+ gaps,
144
+ remediation
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Get remediation guidance for a requirement
150
+ * @param {string} requirementId - Requirement identifier
151
+ * @param {Array} gaps - Identified gaps
152
+ * @returns {string} Remediation guidance
153
+ */
154
+ function getRemediationGuidance(requirementId, gaps) {
155
+ const guidanceMap = {
156
+ 'req-1.1': 'Implement and document network security controls including firewalls, security groups, and network segmentation.',
157
+ 'req-1.2': 'Configure firewall rules to restrict inbound and outbound traffic to only necessary communications.',
158
+ 'req-3.4': 'Implement encryption, truncation, masking, or hashing to render PAN unreadable.',
159
+ };
160
+
161
+ return guidanceMap[requirementId] || 'Review PCI DSS v4.0 documentation for requirement details and implement appropriate controls.';
162
+ }
163
+
164
+ /**
165
+ * Generate a gap analysis report
166
+ * @param {Array} status - Array of requirement check results
167
+ * @returns {string} Formatted gap report
168
+ */
169
+ export function generateGapReport(status) {
170
+ // Sort by priority - critical first
171
+ const sorted = [...status].sort((a, b) => {
172
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
173
+ const aPriority = priorityOrder[a.priority] ?? 2;
174
+ const bPriority = priorityOrder[b.priority] ?? 2;
175
+ return aPriority - bPriority;
176
+ });
177
+
178
+ let report = '# PCI DSS Gap Analysis Report\n\n';
179
+ report += '## Summary\n\n';
180
+
181
+ const compliant = sorted.filter(s => s.status === 'compliant').length;
182
+ const nonCompliant = sorted.filter(s => s.status === 'non-compliant').length;
183
+
184
+ report += `- Compliant: ${compliant}\n`;
185
+ report += `- Non-Compliant: ${nonCompliant}\n\n`;
186
+
187
+ report += '## Gap Analysis\n\n';
188
+
189
+ for (const item of sorted) {
190
+ if (item.status === 'non-compliant') {
191
+ report += `### ${item.requirementId}\n\n`;
192
+ report += `**Status:** Non-Compliant\n`;
193
+ report += `**Priority:** ${item.priority || 'medium'}\n`;
194
+ if (item.gaps && item.gaps.length > 0) {
195
+ report += `**Gaps:**\n`;
196
+ for (const gap of item.gaps) {
197
+ report += `- ${gap}\n`;
198
+ }
199
+ }
200
+ report += '\n';
201
+ }
202
+ }
203
+
204
+ return report;
205
+ }
206
+
207
+ /**
208
+ * Map PCI DSS requirement to technical controls
209
+ * @param {string} requirementId - Requirement identifier
210
+ * @returns {Array} Technical control mappings
211
+ */
212
+ export function mapToControls(requirementId) {
213
+ return CONTROL_MAPPINGS[requirementId] || [];
214
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * PCI DSS Checklist Tests
3
+ */
4
+ import { describe, it, expect, vi } from 'vitest';
5
+ import { createPciDssChecklist, getRequirements, checkRequirement, generateGapReport, mapToControls } from './pci-dss-checklist.js';
6
+
7
+ describe('pci-dss-checklist', () => {
8
+ describe('createPciDssChecklist', () => {
9
+ it('creates PCI DSS checklist', () => {
10
+ const checklist = createPciDssChecklist();
11
+ expect(checklist.evaluate).toBeDefined();
12
+ expect(checklist.getRequirements).toBeDefined();
13
+ });
14
+
15
+ it('supports PCI DSS v4.0', () => {
16
+ const checklist = createPciDssChecklist({ version: '4.0' });
17
+ const reqs = checklist.getRequirements();
18
+ expect(reqs.some(r => r.id.startsWith('req-'))).toBe(true);
19
+ });
20
+ });
21
+
22
+ describe('getRequirements', () => {
23
+ it('returns all PCI DSS requirements', () => {
24
+ const reqs = getRequirements();
25
+ expect(reqs.length).toBeGreaterThan(0);
26
+ // PCI DSS has 12 main requirements
27
+ expect(reqs.filter(r => r.level === 'requirement').length).toBe(12);
28
+ });
29
+
30
+ it('includes sub-requirements', () => {
31
+ const reqs = getRequirements({ includeSubRequirements: true });
32
+ expect(reqs.some(r => r.parent)).toBe(true);
33
+ });
34
+
35
+ it('filters by SAQ type', () => {
36
+ const reqs = getRequirements({ saqType: 'A' });
37
+ expect(reqs.every(r => r.saqTypes.includes('A'))).toBe(true);
38
+ });
39
+ });
40
+
41
+ describe('checkRequirement', () => {
42
+ it('checks requirement compliance', () => {
43
+ const evidence = { hasFirewall: true, firewallConfig: { rules: [] } };
44
+ const result = checkRequirement('req-1.1', evidence);
45
+ expect(result.requirementId).toBe('req-1.1');
46
+ expect(result.status).toBeDefined();
47
+ });
48
+
49
+ it('returns evidence gaps', () => {
50
+ const evidence = {};
51
+ const result = checkRequirement('req-1.1', evidence);
52
+ expect(result.gaps.length).toBeGreaterThan(0);
53
+ });
54
+
55
+ it('provides remediation guidance', () => {
56
+ const result = checkRequirement('req-1.1', {});
57
+ expect(result.remediation).toBeDefined();
58
+ });
59
+ });
60
+
61
+ describe('generateGapReport', () => {
62
+ it('generates gap analysis report', () => {
63
+ const status = [
64
+ { requirementId: 'req-1.1', status: 'compliant' },
65
+ { requirementId: 'req-1.2', status: 'non-compliant', gaps: ['Missing firewall docs'] }
66
+ ];
67
+ const report = generateGapReport(status);
68
+ expect(report).toContain('Gap Analysis');
69
+ expect(report).toContain('req-1.2');
70
+ });
71
+
72
+ it('prioritizes critical gaps', () => {
73
+ const status = [
74
+ { requirementId: 'req-3.4', status: 'non-compliant', priority: 'critical' },
75
+ { requirementId: 'req-1.2', status: 'non-compliant', priority: 'medium' }
76
+ ];
77
+ const report = generateGapReport(status);
78
+ const criticalPos = report.indexOf('req-3.4');
79
+ const mediumPos = report.indexOf('req-1.2');
80
+ expect(criticalPos).toBeLessThan(mediumPos);
81
+ });
82
+ });
83
+
84
+ describe('mapToControls', () => {
85
+ it('maps PCI DSS to technical controls', () => {
86
+ const controls = mapToControls('req-1.1');
87
+ expect(controls.some(c => c.type === 'firewall')).toBe(true);
88
+ });
89
+
90
+ it('maps to code patterns', () => {
91
+ const controls = mapToControls('req-3.4');
92
+ expect(controls.some(c => c.type === 'encryption')).toBe(true);
93
+ });
94
+ });
95
+ });
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Trust Centre Core Functionality
3
+ * Central hub for compliance framework management
4
+ */
5
+
6
+ // Available frameworks with metadata
7
+ const FRAMEWORKS = [
8
+ { id: 'pci-dss', name: 'PCI DSS', version: '4.0', controlCount: 12, description: 'Payment Card Industry Data Security Standard' },
9
+ { id: 'hipaa', name: 'HIPAA', version: '2013', controlCount: 54, description: 'Health Insurance Portability and Accountability Act' },
10
+ { id: 'iso27001', name: 'ISO 27001', version: '2022', controlCount: 93, description: 'Information Security Management System' },
11
+ { id: 'gdpr', name: 'GDPR', version: '2018', controlCount: 99, description: 'General Data Protection Regulation' },
12
+ { id: 'soc2', name: 'SOC 2', version: 'Type II', controlCount: 64, description: 'Service Organization Control 2' }
13
+ ];
14
+
15
+ // Framework control details
16
+ const FRAMEWORK_DETAILS = {
17
+ 'pci-dss': {
18
+ id: 'pci-dss',
19
+ name: 'Payment Card Industry Data Security Standard',
20
+ version: '4.0',
21
+ controls: [
22
+ { id: 'req-1', name: 'Install and maintain network security controls' },
23
+ { id: 'req-2', name: 'Apply secure configurations' },
24
+ { id: 'req-3', name: 'Protect stored account data' },
25
+ { id: 'req-4', name: 'Protect cardholder data with strong cryptography' },
26
+ { id: 'req-5', name: 'Protect systems from malicious software' },
27
+ { id: 'req-6', name: 'Develop and maintain secure systems' },
28
+ { id: 'req-7', name: 'Restrict access to cardholder data' },
29
+ { id: 'req-8', name: 'Identify users and authenticate access' },
30
+ { id: 'req-9', name: 'Restrict physical access to cardholder data' },
31
+ { id: 'req-10', name: 'Log and monitor all access' },
32
+ { id: 'req-11', name: 'Test security of systems regularly' },
33
+ { id: 'req-12', name: 'Support information security with policies' }
34
+ ]
35
+ },
36
+ 'hipaa': {
37
+ id: 'hipaa',
38
+ name: 'Health Insurance Portability and Accountability Act',
39
+ version: '2013',
40
+ controls: [
41
+ { id: 'admin-1', name: 'Security Management Process' },
42
+ { id: 'admin-2', name: 'Assigned Security Responsibility' },
43
+ { id: 'physical-1', name: 'Facility Access Controls' },
44
+ { id: 'technical-1', name: 'Access Control' },
45
+ { id: 'technical-2', name: 'Audit Controls' },
46
+ { id: 'technical-3', name: 'Integrity Controls' },
47
+ { id: 'technical-4', name: 'Transmission Security' }
48
+ ]
49
+ },
50
+ 'iso27001': {
51
+ id: 'iso27001',
52
+ name: 'ISO/IEC 27001:2022',
53
+ version: '2022',
54
+ controls: [
55
+ { id: 'A.5.1', name: 'Policies for information security' },
56
+ { id: 'A.5.2', name: 'Information security roles and responsibilities' },
57
+ { id: 'A.6.1', name: 'Screening' },
58
+ { id: 'A.7.1', name: 'Physical security perimeters' },
59
+ { id: 'A.8.1', name: 'User endpoint devices' }
60
+ ]
61
+ },
62
+ 'gdpr': {
63
+ id: 'gdpr',
64
+ name: 'General Data Protection Regulation',
65
+ version: '2018',
66
+ controls: [
67
+ { id: 'art-5', name: 'Principles relating to processing' },
68
+ { id: 'art-6', name: 'Lawfulness of processing' },
69
+ { id: 'art-7', name: 'Conditions for consent' }
70
+ ]
71
+ },
72
+ 'soc2': {
73
+ id: 'soc2',
74
+ name: 'SOC 2 Type II',
75
+ version: 'Type II',
76
+ controls: [
77
+ { id: 'cc-1', name: 'Control Environment' },
78
+ { id: 'cc-2', name: 'Communication and Information' }
79
+ ]
80
+ }
81
+ };
82
+
83
+ /**
84
+ * Create a trust centre instance
85
+ * @param {Object} options - Configuration options
86
+ * @param {boolean} options.defaults - Whether to initialize with default frameworks
87
+ * @returns {Object} Trust centre instance
88
+ */
89
+ export function createTrustCentre(options = {}) {
90
+ const frameworks = options.defaults
91
+ ? ['pci-dss', 'hipaa', 'iso27001', 'gdpr']
92
+ : [];
93
+
94
+ return {
95
+ getStatus() {
96
+ return {
97
+ frameworks: frameworks.map(id => {
98
+ const fw = FRAMEWORKS.find(f => f.id === id);
99
+ return { id, name: fw?.name, compliant: false, score: 0 };
100
+ }),
101
+ overallScore: 0
102
+ };
103
+ },
104
+
105
+ addFramework(frameworkId) {
106
+ if (!frameworks.includes(frameworkId)) {
107
+ frameworks.push(frameworkId);
108
+ }
109
+ },
110
+
111
+ listFrameworks() {
112
+ return [...frameworks];
113
+ },
114
+
115
+ generateReport() {
116
+ return {
117
+ generatedAt: new Date().toISOString(),
118
+ frameworks: frameworks.map(id => ({
119
+ id,
120
+ status: 'pending',
121
+ score: 0
122
+ })),
123
+ summary: 'Trust centre compliance report'
124
+ };
125
+ }
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Get compliance status for a framework
131
+ * @param {Object} options - Options including framework and controls
132
+ * @returns {Object} Compliance status
133
+ */
134
+ export function getComplianceStatus({ framework, controls }) {
135
+ const compliantCount = controls.filter(c => c.status === 'compliant').length;
136
+ const totalCount = controls.length;
137
+ const score = totalCount > 0 ? (compliantCount / totalCount) * 100 : 0;
138
+
139
+ return {
140
+ framework,
141
+ compliant: compliantCount === totalCount && totalCount > 0,
142
+ score,
143
+ controlsAssessed: totalCount,
144
+ controlsCompliant: compliantCount
145
+ };
146
+ }
147
+
148
+ /**
149
+ * List available compliance frameworks
150
+ * @returns {Array} List of framework metadata
151
+ */
152
+ export function listFrameworks() {
153
+ return FRAMEWORKS.map(f => ({
154
+ id: f.id,
155
+ name: f.name,
156
+ version: f.version,
157
+ controlCount: f.controlCount,
158
+ description: f.description
159
+ }));
160
+ }
161
+
162
+ /**
163
+ * Get detailed information about a framework
164
+ * @param {string} frameworkId - Framework identifier
165
+ * @returns {Object} Framework details including controls
166
+ */
167
+ export function getFrameworkDetails(frameworkId) {
168
+ const details = FRAMEWORK_DETAILS[frameworkId];
169
+ if (!details) {
170
+ throw new Error(`Unknown framework: ${frameworkId}`);
171
+ }
172
+ return details;
173
+ }
174
+
175
+ /**
176
+ * Calculate overall compliance score from multiple frameworks
177
+ * @param {Array} scores - Array of framework scores with optional weights
178
+ * @returns {number} Weighted overall score
179
+ */
180
+ export function calculateOverallScore(scores) {
181
+ if (scores.length === 0) return 0;
182
+
183
+ const totalWeight = scores.reduce((sum, s) => sum + (s.weight || 1), 0);
184
+ const weightedSum = scores.reduce((sum, s) => sum + s.score * (s.weight || 1), 0);
185
+
186
+ return weightedSum / totalWeight;
187
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Trust Centre Tests
3
+ */
4
+ import { describe, it, expect, vi } from 'vitest';
5
+ import { createTrustCentre, getComplianceStatus, listFrameworks, getFrameworkDetails, calculateOverallScore } from './trust-centre.js';
6
+
7
+ describe('trust-centre', () => {
8
+ describe('createTrustCentre', () => {
9
+ it('creates trust centre instance', () => {
10
+ const centre = createTrustCentre();
11
+ expect(centre.getStatus).toBeDefined();
12
+ expect(centre.addFramework).toBeDefined();
13
+ expect(centre.generateReport).toBeDefined();
14
+ });
15
+
16
+ it('initializes with default frameworks', () => {
17
+ const centre = createTrustCentre({ defaults: true });
18
+ const frameworks = centre.listFrameworks();
19
+ expect(frameworks).toContain('pci-dss');
20
+ expect(frameworks).toContain('hipaa');
21
+ expect(frameworks).toContain('iso27001');
22
+ expect(frameworks).toContain('gdpr');
23
+ });
24
+ });
25
+
26
+ describe('getComplianceStatus', () => {
27
+ it('returns compliance status for framework', () => {
28
+ const status = getComplianceStatus({ framework: 'pci-dss', controls: [] });
29
+ expect(status.framework).toBe('pci-dss');
30
+ expect(status.compliant).toBeDefined();
31
+ expect(status.score).toBeDefined();
32
+ });
33
+
34
+ it('calculates score from controls', () => {
35
+ const controls = [
36
+ { id: 'req-1', status: 'compliant' },
37
+ { id: 'req-2', status: 'compliant' },
38
+ { id: 'req-3', status: 'non-compliant' }
39
+ ];
40
+ const status = getComplianceStatus({ framework: 'custom', controls });
41
+ expect(status.score).toBeCloseTo(66.67, 1);
42
+ });
43
+ });
44
+
45
+ describe('listFrameworks', () => {
46
+ it('lists available frameworks', () => {
47
+ const frameworks = listFrameworks();
48
+ expect(frameworks.length).toBeGreaterThan(0);
49
+ expect(frameworks[0].id).toBeDefined();
50
+ expect(frameworks[0].name).toBeDefined();
51
+ });
52
+
53
+ it('includes framework metadata', () => {
54
+ const frameworks = listFrameworks();
55
+ const pci = frameworks.find(f => f.id === 'pci-dss');
56
+ expect(pci.version).toBeDefined();
57
+ expect(pci.controlCount).toBeDefined();
58
+ });
59
+ });
60
+
61
+ describe('getFrameworkDetails', () => {
62
+ it('returns framework details', () => {
63
+ const details = getFrameworkDetails('pci-dss');
64
+ expect(details.id).toBe('pci-dss');
65
+ expect(details.name).toBeDefined();
66
+ expect(details.controls).toBeDefined();
67
+ });
68
+
69
+ it('throws for unknown framework', () => {
70
+ expect(() => getFrameworkDetails('unknown')).toThrow();
71
+ });
72
+ });
73
+
74
+ describe('calculateOverallScore', () => {
75
+ it('calculates weighted overall score', () => {
76
+ const scores = [
77
+ { framework: 'pci-dss', score: 80, weight: 2 },
78
+ { framework: 'hipaa', score: 90, weight: 1 }
79
+ ];
80
+ const overall = calculateOverallScore(scores);
81
+ expect(overall).toBeCloseTo(83.33, 1);
82
+ });
83
+
84
+ it('handles equal weights', () => {
85
+ const scores = [
86
+ { framework: 'pci-dss', score: 80 },
87
+ { framework: 'hipaa', score: 90 }
88
+ ];
89
+ const overall = calculateOverallScore(scores);
90
+ expect(overall).toBe(85);
91
+ });
92
+ });
93
+ });