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.
- package/package.json +1 -1
- package/server/index.js +229 -14
- package/server/lib/compliance/control-mapper.js +401 -0
- package/server/lib/compliance/control-mapper.test.js +117 -0
- package/server/lib/compliance/evidence-linker.js +296 -0
- package/server/lib/compliance/evidence-linker.test.js +121 -0
- package/server/lib/compliance/gdpr-checklist.js +416 -0
- package/server/lib/compliance/gdpr-checklist.test.js +131 -0
- package/server/lib/compliance/hipaa-checklist.js +277 -0
- package/server/lib/compliance/hipaa-checklist.test.js +101 -0
- package/server/lib/compliance/iso27001-checklist.js +287 -0
- package/server/lib/compliance/iso27001-checklist.test.js +99 -0
- package/server/lib/compliance/multi-framework-reporter.js +284 -0
- package/server/lib/compliance/multi-framework-reporter.test.js +127 -0
- package/server/lib/compliance/pci-dss-checklist.js +214 -0
- package/server/lib/compliance/pci-dss-checklist.test.js +95 -0
- package/server/lib/compliance/trust-centre.js +187 -0
- package/server/lib/compliance/trust-centre.test.js +93 -0
- package/server/lib/dashboard/api-server.js +155 -0
- package/server/lib/dashboard/api-server.test.js +155 -0
- package/server/lib/dashboard/health-api.js +199 -0
- package/server/lib/dashboard/health-api.test.js +122 -0
- package/server/lib/dashboard/notes-api.js +234 -0
- package/server/lib/dashboard/notes-api.test.js +134 -0
- package/server/lib/dashboard/router-api.js +176 -0
- package/server/lib/dashboard/router-api.test.js +132 -0
- package/server/lib/dashboard/tasks-api.js +289 -0
- package/server/lib/dashboard/tasks-api.test.js +161 -0
- package/server/lib/dashboard/tlc-introspection.js +197 -0
- package/server/lib/dashboard/tlc-introspection.test.js +138 -0
- package/server/lib/dashboard/version-api.js +222 -0
- package/server/lib/dashboard/version-api.test.js +112 -0
- package/server/lib/dashboard/websocket-server.js +104 -0
- package/server/lib/dashboard/websocket-server.test.js +118 -0
- package/server/lib/deploy/branch-classifier.js +163 -0
- package/server/lib/deploy/branch-classifier.test.js +164 -0
- package/server/lib/deploy/deployment-approval.js +299 -0
- package/server/lib/deploy/deployment-approval.test.js +296 -0
- package/server/lib/deploy/deployment-audit.js +374 -0
- package/server/lib/deploy/deployment-audit.test.js +307 -0
- package/server/lib/deploy/deployment-executor.js +335 -0
- package/server/lib/deploy/deployment-executor.test.js +329 -0
- package/server/lib/deploy/deployment-rules.js +163 -0
- package/server/lib/deploy/deployment-rules.test.js +188 -0
- package/server/lib/deploy/rollback-manager.js +379 -0
- package/server/lib/deploy/rollback-manager.test.js +321 -0
- package/server/lib/deploy/security-gates.js +236 -0
- package/server/lib/deploy/security-gates.test.js +222 -0
- package/server/lib/k8s/gitops-config.js +188 -0
- package/server/lib/k8s/gitops-config.test.js +59 -0
- package/server/lib/k8s/helm-generator.js +196 -0
- package/server/lib/k8s/helm-generator.test.js +59 -0
- package/server/lib/k8s/kustomize-generator.js +176 -0
- package/server/lib/k8s/kustomize-generator.test.js +58 -0
- package/server/lib/k8s/network-policy.js +114 -0
- package/server/lib/k8s/network-policy.test.js +53 -0
- package/server/lib/k8s/pod-security.js +114 -0
- package/server/lib/k8s/pod-security.test.js +55 -0
- package/server/lib/k8s/rbac-generator.js +132 -0
- package/server/lib/k8s/rbac-generator.test.js +57 -0
- package/server/lib/k8s/resource-manager.js +172 -0
- package/server/lib/k8s/resource-manager.test.js +60 -0
- package/server/lib/k8s/secrets-encryption.js +168 -0
- package/server/lib/k8s/secrets-encryption.test.js +49 -0
- package/server/lib/monitoring/alert-manager.js +238 -0
- package/server/lib/monitoring/alert-manager.test.js +106 -0
- package/server/lib/monitoring/health-check.js +226 -0
- package/server/lib/monitoring/health-check.test.js +176 -0
- package/server/lib/monitoring/incident-manager.js +230 -0
- package/server/lib/monitoring/incident-manager.test.js +98 -0
- package/server/lib/monitoring/log-aggregator.js +147 -0
- package/server/lib/monitoring/log-aggregator.test.js +89 -0
- package/server/lib/monitoring/metrics-collector.js +337 -0
- package/server/lib/monitoring/metrics-collector.test.js +172 -0
- package/server/lib/monitoring/status-page.js +214 -0
- package/server/lib/monitoring/status-page.test.js +105 -0
- package/server/lib/monitoring/uptime-monitor.js +194 -0
- package/server/lib/monitoring/uptime-monitor.test.js +109 -0
- package/server/lib/network/fail2ban-config.js +294 -0
- package/server/lib/network/fail2ban-config.test.js +275 -0
- package/server/lib/network/firewall-manager.js +252 -0
- package/server/lib/network/firewall-manager.test.js +254 -0
- package/server/lib/network/geoip-filter.js +282 -0
- package/server/lib/network/geoip-filter.test.js +264 -0
- package/server/lib/network/rate-limiter.js +229 -0
- package/server/lib/network/rate-limiter.test.js +293 -0
- package/server/lib/network/request-validator.js +351 -0
- package/server/lib/network/request-validator.test.js +345 -0
- package/server/lib/network/security-headers.js +251 -0
- package/server/lib/network/security-headers.test.js +283 -0
- package/server/lib/network/tls-config.js +210 -0
- package/server/lib/network/tls-config.test.js +248 -0
- package/server/lib/security/auth-security.js +369 -0
- package/server/lib/security/auth-security.test.js +448 -0
- package/server/lib/security/cis-benchmark.js +152 -0
- package/server/lib/security/cis-benchmark.test.js +137 -0
- package/server/lib/security/compose-templates.js +312 -0
- package/server/lib/security/compose-templates.test.js +229 -0
- package/server/lib/security/container-runtime.js +456 -0
- package/server/lib/security/container-runtime.test.js +503 -0
- package/server/lib/security/cors-validator.js +278 -0
- package/server/lib/security/cors-validator.test.js +310 -0
- package/server/lib/security/crypto-utils.js +253 -0
- package/server/lib/security/crypto-utils.test.js +409 -0
- package/server/lib/security/dockerfile-linter.js +459 -0
- package/server/lib/security/dockerfile-linter.test.js +483 -0
- package/server/lib/security/dockerfile-templates.js +278 -0
- package/server/lib/security/dockerfile-templates.test.js +164 -0
- package/server/lib/security/error-sanitizer.js +426 -0
- package/server/lib/security/error-sanitizer.test.js +331 -0
- package/server/lib/security/headers-generator.js +368 -0
- package/server/lib/security/headers-generator.test.js +398 -0
- package/server/lib/security/image-scanner.js +83 -0
- package/server/lib/security/image-scanner.test.js +106 -0
- package/server/lib/security/input-validator.js +352 -0
- package/server/lib/security/input-validator.test.js +330 -0
- package/server/lib/security/network-policy.js +174 -0
- package/server/lib/security/network-policy.test.js +164 -0
- package/server/lib/security/output-encoder.js +237 -0
- package/server/lib/security/output-encoder.test.js +276 -0
- package/server/lib/security/path-validator.js +359 -0
- package/server/lib/security/path-validator.test.js +293 -0
- package/server/lib/security/query-builder.js +421 -0
- package/server/lib/security/query-builder.test.js +318 -0
- package/server/lib/security/secret-detector.js +290 -0
- package/server/lib/security/secret-detector.test.js +354 -0
- package/server/lib/security/secrets-validator.js +137 -0
- package/server/lib/security/secrets-validator.test.js +120 -0
- package/server/lib/security-testing/dast-runner.js +154 -0
- package/server/lib/security-testing/dast-runner.test.js +62 -0
- package/server/lib/security-testing/dependency-scanner.js +172 -0
- package/server/lib/security-testing/dependency-scanner.test.js +64 -0
- package/server/lib/security-testing/pentest-runner.js +230 -0
- package/server/lib/security-testing/pentest-runner.test.js +60 -0
- package/server/lib/security-testing/sast-runner.js +136 -0
- package/server/lib/security-testing/sast-runner.test.js +62 -0
- package/server/lib/security-testing/secret-scanner.js +153 -0
- package/server/lib/security-testing/secret-scanner.test.js +66 -0
- package/server/lib/security-testing/security-gate.js +216 -0
- package/server/lib/security-testing/security-gate.test.js +115 -0
- package/server/lib/security-testing/security-reporter.js +303 -0
- package/server/lib/security-testing/security-reporter.test.js +114 -0
- package/server/lib/standards/audit-checker.js +546 -0
- package/server/lib/standards/audit-checker.test.js +415 -0
- package/server/lib/standards/cleanup-executor.js +452 -0
- package/server/lib/standards/cleanup-executor.test.js +293 -0
- package/server/lib/standards/refactor-stepper.js +425 -0
- package/server/lib/standards/refactor-stepper.test.js +298 -0
- package/server/lib/standards/standards-injector.js +167 -0
- package/server/lib/standards/standards-injector.test.js +232 -0
- package/server/lib/user-management.test.js +284 -0
- package/server/lib/vps/backup-manager.js +157 -0
- package/server/lib/vps/backup-manager.test.js +59 -0
- package/server/lib/vps/caddy-config.js +159 -0
- package/server/lib/vps/caddy-config.test.js +48 -0
- package/server/lib/vps/compose-orchestrator.js +219 -0
- package/server/lib/vps/compose-orchestrator.test.js +50 -0
- package/server/lib/vps/database-config.js +208 -0
- package/server/lib/vps/database-config.test.js +47 -0
- package/server/lib/vps/deploy-script.js +211 -0
- package/server/lib/vps/deploy-script.test.js +53 -0
- package/server/lib/vps/secrets-manager.js +148 -0
- package/server/lib/vps/secrets-manager.test.js +58 -0
- package/server/lib/vps/server-hardening.js +174 -0
- package/server/lib/vps/server-hardening.test.js +70 -0
- package/server/package-lock.json +19 -0
- package/server/package.json +1 -0
- package/server/templates/CLAUDE.md +37 -0
- 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
|
+
});
|