tlc-claude-code 1.4.7 → 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 (170) hide show
  1. package/docker-compose.dev.yml +6 -3
  2. package/package.json +1 -1
  3. package/server/index.js +229 -14
  4. package/server/lib/compliance/control-mapper.js +401 -0
  5. package/server/lib/compliance/control-mapper.test.js +117 -0
  6. package/server/lib/compliance/evidence-linker.js +296 -0
  7. package/server/lib/compliance/evidence-linker.test.js +121 -0
  8. package/server/lib/compliance/gdpr-checklist.js +416 -0
  9. package/server/lib/compliance/gdpr-checklist.test.js +131 -0
  10. package/server/lib/compliance/hipaa-checklist.js +277 -0
  11. package/server/lib/compliance/hipaa-checklist.test.js +101 -0
  12. package/server/lib/compliance/iso27001-checklist.js +287 -0
  13. package/server/lib/compliance/iso27001-checklist.test.js +99 -0
  14. package/server/lib/compliance/multi-framework-reporter.js +284 -0
  15. package/server/lib/compliance/multi-framework-reporter.test.js +127 -0
  16. package/server/lib/compliance/pci-dss-checklist.js +214 -0
  17. package/server/lib/compliance/pci-dss-checklist.test.js +95 -0
  18. package/server/lib/compliance/trust-centre.js +187 -0
  19. package/server/lib/compliance/trust-centre.test.js +93 -0
  20. package/server/lib/dashboard/api-server.js +155 -0
  21. package/server/lib/dashboard/api-server.test.js +155 -0
  22. package/server/lib/dashboard/health-api.js +199 -0
  23. package/server/lib/dashboard/health-api.test.js +122 -0
  24. package/server/lib/dashboard/notes-api.js +234 -0
  25. package/server/lib/dashboard/notes-api.test.js +134 -0
  26. package/server/lib/dashboard/router-api.js +176 -0
  27. package/server/lib/dashboard/router-api.test.js +132 -0
  28. package/server/lib/dashboard/tasks-api.js +289 -0
  29. package/server/lib/dashboard/tasks-api.test.js +161 -0
  30. package/server/lib/dashboard/tlc-introspection.js +197 -0
  31. package/server/lib/dashboard/tlc-introspection.test.js +138 -0
  32. package/server/lib/dashboard/version-api.js +222 -0
  33. package/server/lib/dashboard/version-api.test.js +112 -0
  34. package/server/lib/dashboard/websocket-server.js +104 -0
  35. package/server/lib/dashboard/websocket-server.test.js +118 -0
  36. package/server/lib/deploy/branch-classifier.js +163 -0
  37. package/server/lib/deploy/branch-classifier.test.js +164 -0
  38. package/server/lib/deploy/deployment-approval.js +299 -0
  39. package/server/lib/deploy/deployment-approval.test.js +296 -0
  40. package/server/lib/deploy/deployment-audit.js +374 -0
  41. package/server/lib/deploy/deployment-audit.test.js +307 -0
  42. package/server/lib/deploy/deployment-executor.js +335 -0
  43. package/server/lib/deploy/deployment-executor.test.js +329 -0
  44. package/server/lib/deploy/deployment-rules.js +163 -0
  45. package/server/lib/deploy/deployment-rules.test.js +188 -0
  46. package/server/lib/deploy/rollback-manager.js +379 -0
  47. package/server/lib/deploy/rollback-manager.test.js +321 -0
  48. package/server/lib/deploy/security-gates.js +236 -0
  49. package/server/lib/deploy/security-gates.test.js +222 -0
  50. package/server/lib/k8s/gitops-config.js +188 -0
  51. package/server/lib/k8s/gitops-config.test.js +59 -0
  52. package/server/lib/k8s/helm-generator.js +196 -0
  53. package/server/lib/k8s/helm-generator.test.js +59 -0
  54. package/server/lib/k8s/kustomize-generator.js +176 -0
  55. package/server/lib/k8s/kustomize-generator.test.js +58 -0
  56. package/server/lib/k8s/network-policy.js +114 -0
  57. package/server/lib/k8s/network-policy.test.js +53 -0
  58. package/server/lib/k8s/pod-security.js +114 -0
  59. package/server/lib/k8s/pod-security.test.js +55 -0
  60. package/server/lib/k8s/rbac-generator.js +132 -0
  61. package/server/lib/k8s/rbac-generator.test.js +57 -0
  62. package/server/lib/k8s/resource-manager.js +172 -0
  63. package/server/lib/k8s/resource-manager.test.js +60 -0
  64. package/server/lib/k8s/secrets-encryption.js +168 -0
  65. package/server/lib/k8s/secrets-encryption.test.js +49 -0
  66. package/server/lib/monitoring/alert-manager.js +238 -0
  67. package/server/lib/monitoring/alert-manager.test.js +106 -0
  68. package/server/lib/monitoring/health-check.js +226 -0
  69. package/server/lib/monitoring/health-check.test.js +176 -0
  70. package/server/lib/monitoring/incident-manager.js +230 -0
  71. package/server/lib/monitoring/incident-manager.test.js +98 -0
  72. package/server/lib/monitoring/log-aggregator.js +147 -0
  73. package/server/lib/monitoring/log-aggregator.test.js +89 -0
  74. package/server/lib/monitoring/metrics-collector.js +337 -0
  75. package/server/lib/monitoring/metrics-collector.test.js +172 -0
  76. package/server/lib/monitoring/status-page.js +214 -0
  77. package/server/lib/monitoring/status-page.test.js +105 -0
  78. package/server/lib/monitoring/uptime-monitor.js +194 -0
  79. package/server/lib/monitoring/uptime-monitor.test.js +109 -0
  80. package/server/lib/network/fail2ban-config.js +294 -0
  81. package/server/lib/network/fail2ban-config.test.js +275 -0
  82. package/server/lib/network/firewall-manager.js +252 -0
  83. package/server/lib/network/firewall-manager.test.js +254 -0
  84. package/server/lib/network/geoip-filter.js +282 -0
  85. package/server/lib/network/geoip-filter.test.js +264 -0
  86. package/server/lib/network/rate-limiter.js +229 -0
  87. package/server/lib/network/rate-limiter.test.js +293 -0
  88. package/server/lib/network/request-validator.js +351 -0
  89. package/server/lib/network/request-validator.test.js +345 -0
  90. package/server/lib/network/security-headers.js +251 -0
  91. package/server/lib/network/security-headers.test.js +283 -0
  92. package/server/lib/network/tls-config.js +210 -0
  93. package/server/lib/network/tls-config.test.js +248 -0
  94. package/server/lib/security/auth-security.js +369 -0
  95. package/server/lib/security/auth-security.test.js +448 -0
  96. package/server/lib/security/cis-benchmark.js +152 -0
  97. package/server/lib/security/cis-benchmark.test.js +137 -0
  98. package/server/lib/security/compose-templates.js +312 -0
  99. package/server/lib/security/compose-templates.test.js +229 -0
  100. package/server/lib/security/container-runtime.js +456 -0
  101. package/server/lib/security/container-runtime.test.js +503 -0
  102. package/server/lib/security/cors-validator.js +278 -0
  103. package/server/lib/security/cors-validator.test.js +310 -0
  104. package/server/lib/security/crypto-utils.js +253 -0
  105. package/server/lib/security/crypto-utils.test.js +409 -0
  106. package/server/lib/security/dockerfile-linter.js +459 -0
  107. package/server/lib/security/dockerfile-linter.test.js +483 -0
  108. package/server/lib/security/dockerfile-templates.js +278 -0
  109. package/server/lib/security/dockerfile-templates.test.js +164 -0
  110. package/server/lib/security/error-sanitizer.js +426 -0
  111. package/server/lib/security/error-sanitizer.test.js +331 -0
  112. package/server/lib/security/headers-generator.js +368 -0
  113. package/server/lib/security/headers-generator.test.js +398 -0
  114. package/server/lib/security/image-scanner.js +83 -0
  115. package/server/lib/security/image-scanner.test.js +106 -0
  116. package/server/lib/security/input-validator.js +352 -0
  117. package/server/lib/security/input-validator.test.js +330 -0
  118. package/server/lib/security/network-policy.js +174 -0
  119. package/server/lib/security/network-policy.test.js +164 -0
  120. package/server/lib/security/output-encoder.js +237 -0
  121. package/server/lib/security/output-encoder.test.js +276 -0
  122. package/server/lib/security/path-validator.js +359 -0
  123. package/server/lib/security/path-validator.test.js +293 -0
  124. package/server/lib/security/query-builder.js +421 -0
  125. package/server/lib/security/query-builder.test.js +318 -0
  126. package/server/lib/security/secret-detector.js +290 -0
  127. package/server/lib/security/secret-detector.test.js +354 -0
  128. package/server/lib/security/secrets-validator.js +137 -0
  129. package/server/lib/security/secrets-validator.test.js +120 -0
  130. package/server/lib/security-testing/dast-runner.js +154 -0
  131. package/server/lib/security-testing/dast-runner.test.js +62 -0
  132. package/server/lib/security-testing/dependency-scanner.js +172 -0
  133. package/server/lib/security-testing/dependency-scanner.test.js +64 -0
  134. package/server/lib/security-testing/pentest-runner.js +230 -0
  135. package/server/lib/security-testing/pentest-runner.test.js +60 -0
  136. package/server/lib/security-testing/sast-runner.js +136 -0
  137. package/server/lib/security-testing/sast-runner.test.js +62 -0
  138. package/server/lib/security-testing/secret-scanner.js +153 -0
  139. package/server/lib/security-testing/secret-scanner.test.js +66 -0
  140. package/server/lib/security-testing/security-gate.js +216 -0
  141. package/server/lib/security-testing/security-gate.test.js +115 -0
  142. package/server/lib/security-testing/security-reporter.js +303 -0
  143. package/server/lib/security-testing/security-reporter.test.js +114 -0
  144. package/server/lib/standards/audit-checker.js +546 -0
  145. package/server/lib/standards/audit-checker.test.js +415 -0
  146. package/server/lib/standards/cleanup-executor.js +452 -0
  147. package/server/lib/standards/cleanup-executor.test.js +293 -0
  148. package/server/lib/standards/refactor-stepper.js +425 -0
  149. package/server/lib/standards/refactor-stepper.test.js +298 -0
  150. package/server/lib/standards/standards-injector.js +167 -0
  151. package/server/lib/standards/standards-injector.test.js +232 -0
  152. package/server/lib/user-management.test.js +284 -0
  153. package/server/lib/vps/backup-manager.js +157 -0
  154. package/server/lib/vps/backup-manager.test.js +59 -0
  155. package/server/lib/vps/caddy-config.js +159 -0
  156. package/server/lib/vps/caddy-config.test.js +48 -0
  157. package/server/lib/vps/compose-orchestrator.js +219 -0
  158. package/server/lib/vps/compose-orchestrator.test.js +50 -0
  159. package/server/lib/vps/database-config.js +208 -0
  160. package/server/lib/vps/database-config.test.js +47 -0
  161. package/server/lib/vps/deploy-script.js +211 -0
  162. package/server/lib/vps/deploy-script.test.js +53 -0
  163. package/server/lib/vps/secrets-manager.js +148 -0
  164. package/server/lib/vps/secrets-manager.test.js +58 -0
  165. package/server/lib/vps/server-hardening.js +174 -0
  166. package/server/lib/vps/server-hardening.test.js +70 -0
  167. package/server/package-lock.json +19 -0
  168. package/server/package.json +1 -0
  169. package/server/templates/CLAUDE.md +37 -0
  170. package/server/templates/CODING-STANDARDS.md +408 -0
@@ -0,0 +1,277 @@
1
+ /**
2
+ * HIPAA Compliance Checklist
3
+ * Health Insurance Portability and Accountability Act safeguards
4
+ */
5
+
6
+ // HIPAA Safeguards
7
+ const SAFEGUARDS = [
8
+ // Administrative Safeguards
9
+ { id: 'security-management', name: 'Security Management Process', category: 'administrative', type: 'required', section: '164.308(a)(1)' },
10
+ { id: 'assigned-security', name: 'Assigned Security Responsibility', category: 'administrative', type: 'required', section: '164.308(a)(2)' },
11
+ { id: 'workforce-security', name: 'Workforce Security', category: 'administrative', type: 'addressable', section: '164.308(a)(3)' },
12
+ { id: 'info-access-mgmt', name: 'Information Access Management', category: 'administrative', type: 'required', section: '164.308(a)(4)' },
13
+ { id: 'security-training', name: 'Security Awareness and Training', category: 'administrative', type: 'addressable', section: '164.308(a)(5)' },
14
+ { id: 'security-incident', name: 'Security Incident Procedures', category: 'administrative', type: 'required', section: '164.308(a)(6)' },
15
+ { id: 'contingency-plan', name: 'Contingency Plan', category: 'administrative', type: 'required', section: '164.308(a)(7)' },
16
+ { id: 'evaluation', name: 'Evaluation', category: 'administrative', type: 'required', section: '164.308(a)(8)' },
17
+ { id: 'baa', name: 'Business Associate Contracts', category: 'administrative', type: 'required', section: '164.308(b)(1)' },
18
+
19
+ // Physical Safeguards
20
+ { id: 'facility-access', name: 'Facility Access Controls', category: 'physical', type: 'addressable', section: '164.310(a)(1)' },
21
+ { id: 'workstation-use', name: 'Workstation Use', category: 'physical', type: 'required', section: '164.310(b)' },
22
+ { id: 'workstation-security', name: 'Workstation Security', category: 'physical', type: 'required', section: '164.310(c)' },
23
+ { id: 'device-media', name: 'Device and Media Controls', category: 'physical', type: 'required', section: '164.310(d)(1)' },
24
+
25
+ // Technical Safeguards
26
+ { id: 'access-control', name: 'Access Control', category: 'technical', type: 'required', section: '164.312(a)(1)' },
27
+ { id: 'audit-controls', name: 'Audit Controls', category: 'technical', type: 'required', section: '164.312(b)' },
28
+ { id: 'integrity', name: 'Integrity', category: 'technical', type: 'addressable', section: '164.312(c)(1)' },
29
+ { id: 'person-auth', name: 'Person or Entity Authentication', category: 'technical', type: 'required', section: '164.312(d)' },
30
+ { id: 'transmission-security', name: 'Transmission Security', category: 'technical', type: 'addressable', section: '164.312(e)(1)' },
31
+ { id: 'encryption', name: 'Encryption', category: 'technical', type: 'addressable', section: '164.312(e)(2)' }
32
+ ];
33
+
34
+ // PHI data element patterns
35
+ const PHI_PATTERNS = {
36
+ ssn: { element: 'ssn', description: 'Social Security Number', sensitivity: 'high' },
37
+ 'patient.ssn': { element: 'ssn', description: 'Patient Social Security Number', sensitivity: 'high' },
38
+ dateOfBirth: { element: 'dateOfBirth', description: 'Date of Birth', sensitivity: 'medium' },
39
+ 'patient.dateOfBirth': { element: 'dateOfBirth', description: 'Patient Date of Birth', sensitivity: 'medium' },
40
+ medicalRecord: { element: 'medicalRecord', description: 'Medical Record', sensitivity: 'high' },
41
+ diagnosis: { element: 'diagnosis', description: 'Diagnosis Information', sensitivity: 'high' },
42
+ treatment: { element: 'treatment', description: 'Treatment Information', sensitivity: 'high' },
43
+ prescription: { element: 'prescription', description: 'Prescription Information', sensitivity: 'high' },
44
+ healthPlan: { element: 'healthPlan', description: 'Health Plan Information', sensitivity: 'medium' },
45
+ 'patient.name': { element: 'name', description: 'Patient Name', sensitivity: 'medium' },
46
+ 'patient.address': { element: 'address', description: 'Patient Address', sensitivity: 'medium' },
47
+ 'patient.phone': { element: 'phone', description: 'Patient Phone', sensitivity: 'medium' },
48
+ 'patient.email': { element: 'email', description: 'Patient Email', sensitivity: 'medium' }
49
+ };
50
+
51
+ // Safeguard check implementations
52
+ const SAFEGUARD_CHECKS = {
53
+ 'access-control': (evidence) => {
54
+ return evidence.accessControls?.enabled === true;
55
+ },
56
+ 'encryption': (evidence) => {
57
+ return evidence.encryption?.atRest === true && evidence.encryption?.inTransit === true;
58
+ },
59
+ 'audit-controls': (evidence) => {
60
+ if (!evidence.auditLogs?.enabled) return false;
61
+ // Check retention period (HIPAA requires 6 years)
62
+ const retention = evidence.auditLogs.retention;
63
+ if (retention) {
64
+ const years = parseInt(retention);
65
+ return years >= 6;
66
+ }
67
+ return false;
68
+ }
69
+ };
70
+
71
+ /**
72
+ * Create a HIPAA checklist instance
73
+ * @returns {Object} Checklist instance
74
+ */
75
+ export function createHipaaChecklist() {
76
+ return {
77
+ evaluate(evidence) {
78
+ const results = [];
79
+ const safeguards = getSafeguards();
80
+
81
+ for (const safeguard of safeguards) {
82
+ const result = checkSafeguard(safeguard.id, evidence);
83
+ results.push(result);
84
+ }
85
+
86
+ return {
87
+ results,
88
+ compliant: results.every(r => r.implemented || r.safeguard?.type === 'addressable'),
89
+ score: (results.filter(r => r.implemented).length / results.length) * 100
90
+ };
91
+ },
92
+
93
+ getSafeguards() {
94
+ return getSafeguards();
95
+ },
96
+
97
+ getCategories() {
98
+ return ['administrative', 'physical', 'technical'];
99
+ }
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Get HIPAA safeguards
105
+ * @param {Object} options - Filter options
106
+ * @param {string} options.category - Filter by category
107
+ * @returns {Array} Safeguards list
108
+ */
109
+ export function getSafeguards(options = {}) {
110
+ let safeguards = [...SAFEGUARDS];
111
+
112
+ if (options.category) {
113
+ safeguards = safeguards.filter(s => s.category === options.category);
114
+ }
115
+
116
+ return safeguards;
117
+ }
118
+
119
+ /**
120
+ * Check implementation of a specific safeguard
121
+ * @param {string} safeguardId - Safeguard identifier
122
+ * @param {Object} evidence - Evidence for compliance check
123
+ * @returns {Object} Check result
124
+ */
125
+ export function checkSafeguard(safeguardId, evidence) {
126
+ const safeguard = SAFEGUARDS.find(s => s.id === safeguardId);
127
+ const checkFn = SAFEGUARD_CHECKS[safeguardId];
128
+
129
+ let implemented = false;
130
+
131
+ if (checkFn) {
132
+ implemented = checkFn(evidence);
133
+ }
134
+
135
+ return {
136
+ safeguardId,
137
+ safeguardName: safeguard?.name || 'Unknown safeguard',
138
+ category: safeguard?.category,
139
+ type: safeguard?.type,
140
+ implemented,
141
+ safeguard
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Generate Business Associate Agreement template
147
+ * @param {Object} options - BAA options
148
+ * @param {string} options.coveredEntity - Covered entity name
149
+ * @param {string} options.businessAssociate - Business associate name
150
+ * @returns {string} BAA template
151
+ */
152
+ export function generateBaaTemplate(options = {}) {
153
+ const coveredEntity = options.coveredEntity || '[COVERED ENTITY]';
154
+ const businessAssociate = options.businessAssociate || '[BUSINESS ASSOCIATE]';
155
+ const date = new Date().toISOString().split('T')[0];
156
+
157
+ return `# Business Associate Agreement
158
+
159
+ **Effective Date:** ${date}
160
+
161
+ **Between:**
162
+ - Covered Entity: ${coveredEntity}
163
+ - Business Associate: ${businessAssociate}
164
+
165
+ ## Recitals
166
+
167
+ This Business Associate Agreement ("BAA") is entered into by and between ${coveredEntity} ("Covered Entity") and ${businessAssociate} ("Business Associate") to ensure compliance with the Health Insurance Portability and Accountability Act of 1996 ("HIPAA").
168
+
169
+ ## Article I: Definitions
170
+
171
+ Terms used herein shall have the same meaning as defined in 45 CFR Parts 160 and 164.
172
+
173
+ ## Article II: Obligations of Business Associate
174
+
175
+ ### 2.1 Permitted Uses and Disclosures
176
+
177
+ Business Associate agrees to not use or disclose PHI other than as permitted or required by this Agreement or as Required by Law.
178
+
179
+ The permitted uses and disclosures of PHI are limited to:
180
+ - Treatment, payment, and health care operations
181
+ - Functions, activities, or services specified in the underlying agreement
182
+ - As required by law
183
+
184
+ ### 2.2 Safeguards
185
+
186
+ Business Associate agrees to use appropriate safeguards to prevent use or disclosure of PHI other than as provided for by this Agreement.
187
+
188
+ Required safeguards include:
189
+ - Administrative safeguards (policies and procedures)
190
+ - Physical safeguards (facility access controls)
191
+ - Technical safeguards (access controls, encryption)
192
+
193
+ ### 2.3 Breach Notification
194
+
195
+ Business Associate agrees to report to Covered Entity any breach notification requirements under 45 CFR 164.410.
196
+
197
+ In the event of a breach:
198
+ - Notification within 60 days of discovery
199
+ - Description of PHI involved
200
+ - Recommended mitigation steps
201
+
202
+ ## Article III: Termination
203
+
204
+ This Agreement may be terminated:
205
+ - Upon termination of the underlying agreement
206
+ - Upon breach of material terms
207
+ - As required by law
208
+
209
+ ## Signatures
210
+
211
+ _________________________
212
+ ${coveredEntity}
213
+ Covered Entity
214
+
215
+ _________________________
216
+ ${businessAssociate}
217
+ Business Associate
218
+ `;
219
+ }
220
+
221
+ /**
222
+ * Assess PHI handling in code patterns
223
+ * @param {Array} codePatterns - Array of code patterns to analyze
224
+ * @returns {Object} Assessment result
225
+ */
226
+ export function assessPhiHandling(codePatterns) {
227
+ const dataElements = new Set();
228
+ const findings = [];
229
+ const recommendations = [];
230
+
231
+ for (const pattern of codePatterns) {
232
+ const patternStr = pattern.pattern || '';
233
+
234
+ // Check against known PHI patterns
235
+ for (const [key, info] of Object.entries(PHI_PATTERNS)) {
236
+ if (patternStr.toLowerCase().includes(key.toLowerCase())) {
237
+ dataElements.add(info.element);
238
+ findings.push({
239
+ file: pattern.file,
240
+ pattern: patternStr,
241
+ element: info.element,
242
+ description: info.description,
243
+ sensitivity: info.sensitivity
244
+ });
245
+ }
246
+ }
247
+ }
248
+
249
+ // Generate recommendations based on findings
250
+ if (findings.some(f => f.sensitivity === 'high')) {
251
+ recommendations.push('Implement encryption at rest for high-sensitivity PHI data');
252
+ recommendations.push('Use encryption in transit (TLS 1.2+) for all PHI transmissions');
253
+ recommendations.push('Implement access controls with role-based permissions');
254
+ }
255
+
256
+ if (dataElements.has('ssn')) {
257
+ recommendations.push('Consider tokenization for SSN storage');
258
+ recommendations.push('Implement audit logging for SSN access');
259
+ }
260
+
261
+ if (dataElements.has('medicalRecord')) {
262
+ recommendations.push('Implement audit logging for medical record access');
263
+ recommendations.push('Ensure minimum necessary access principle');
264
+ }
265
+
266
+ if (recommendations.length === 0 && findings.length > 0) {
267
+ recommendations.push('Review data handling practices for HIPAA compliance');
268
+ recommendations.push('Document PHI data flows');
269
+ }
270
+
271
+ return {
272
+ phiIdentified: dataElements.size > 0,
273
+ dataElements: Array.from(dataElements),
274
+ findings,
275
+ recommendations
276
+ };
277
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * HIPAA Checklist Tests
3
+ */
4
+ import { describe, it, expect, vi } from 'vitest';
5
+ import { createHipaaChecklist, getSafeguards, checkSafeguard, generateBaaTemplate, assessPhiHandling } from './hipaa-checklist.js';
6
+
7
+ describe('hipaa-checklist', () => {
8
+ describe('createHipaaChecklist', () => {
9
+ it('creates HIPAA checklist', () => {
10
+ const checklist = createHipaaChecklist();
11
+ expect(checklist.evaluate).toBeDefined();
12
+ expect(checklist.getSafeguards).toBeDefined();
13
+ });
14
+
15
+ it('covers all safeguard categories', () => {
16
+ const checklist = createHipaaChecklist();
17
+ const categories = checklist.getCategories();
18
+ expect(categories).toContain('administrative');
19
+ expect(categories).toContain('physical');
20
+ expect(categories).toContain('technical');
21
+ });
22
+ });
23
+
24
+ describe('getSafeguards', () => {
25
+ it('returns all HIPAA safeguards', () => {
26
+ const safeguards = getSafeguards();
27
+ expect(safeguards.length).toBeGreaterThan(0);
28
+ });
29
+
30
+ it('filters by category', () => {
31
+ const technical = getSafeguards({ category: 'technical' });
32
+ expect(technical.every(s => s.category === 'technical')).toBe(true);
33
+ });
34
+
35
+ it('distinguishes required vs addressable', () => {
36
+ const safeguards = getSafeguards();
37
+ expect(safeguards.some(s => s.type === 'required')).toBe(true);
38
+ expect(safeguards.some(s => s.type === 'addressable')).toBe(true);
39
+ });
40
+ });
41
+
42
+ describe('checkSafeguard', () => {
43
+ it('checks safeguard implementation', () => {
44
+ const evidence = { accessControls: { enabled: true } };
45
+ const result = checkSafeguard('access-control', evidence);
46
+ expect(result.safeguardId).toBe('access-control');
47
+ expect(result.implemented).toBeDefined();
48
+ });
49
+
50
+ it('checks encryption requirements', () => {
51
+ const evidence = { encryption: { atRest: true, inTransit: true } };
52
+ const result = checkSafeguard('encryption', evidence);
53
+ expect(result.implemented).toBe(true);
54
+ });
55
+
56
+ it('validates audit controls', () => {
57
+ const evidence = { auditLogs: { enabled: true, retention: '6years' } };
58
+ const result = checkSafeguard('audit-controls', evidence);
59
+ expect(result.implemented).toBe(true);
60
+ });
61
+ });
62
+
63
+ describe('generateBaaTemplate', () => {
64
+ it('generates Business Associate Agreement template', () => {
65
+ const baa = generateBaaTemplate({ coveredEntity: 'Hospital', businessAssociate: 'TLC Inc' });
66
+ expect(baa).toContain('Business Associate Agreement');
67
+ expect(baa).toContain('Hospital');
68
+ expect(baa).toContain('TLC Inc');
69
+ });
70
+
71
+ it('includes required provisions', () => {
72
+ const baa = generateBaaTemplate({});
73
+ expect(baa).toContain('permitted uses');
74
+ expect(baa).toContain('safeguards');
75
+ expect(baa).toContain('breach notification');
76
+ });
77
+ });
78
+
79
+ describe('assessPhiHandling', () => {
80
+ it('assesses PHI data handling', () => {
81
+ const codePatterns = [
82
+ { file: 'patient.js', pattern: 'patient.ssn' },
83
+ { file: 'records.js', pattern: 'medicalRecord' }
84
+ ];
85
+ const assessment = assessPhiHandling(codePatterns);
86
+ expect(assessment.phiIdentified).toBe(true);
87
+ expect(assessment.dataElements.length).toBeGreaterThan(0);
88
+ });
89
+
90
+ it('identifies PHI data elements', () => {
91
+ const codePatterns = [{ file: 'test.js', pattern: 'patient.dateOfBirth' }];
92
+ const assessment = assessPhiHandling(codePatterns);
93
+ expect(assessment.dataElements).toContain('dateOfBirth');
94
+ });
95
+
96
+ it('suggests protection measures', () => {
97
+ const assessment = assessPhiHandling([{ file: 'test.js', pattern: 'ssn' }]);
98
+ expect(assessment.recommendations.length).toBeGreaterThan(0);
99
+ });
100
+ });
101
+ });
@@ -0,0 +1,287 @@
1
+ /**
2
+ * ISO 27001:2022 Compliance Checklist
3
+ * Information Security Management System controls
4
+ */
5
+
6
+ // ISO 27001:2022 Annex A Controls
7
+ const CONTROLS = [
8
+ // Organizational controls (A.5)
9
+ { id: 'A.5.1', name: 'Policies for information security', theme: 'organizational', purpose: 'To provide management direction and support for information security' },
10
+ { id: 'A.5.2', name: 'Information security roles and responsibilities', theme: 'organizational', purpose: 'To establish a defined and approved information security organizational structure' },
11
+ { id: 'A.5.3', name: 'Segregation of duties', theme: 'organizational', purpose: 'To reduce the risk of fraud and error' },
12
+ { id: 'A.5.4', name: 'Management responsibilities', theme: 'organizational', purpose: 'To ensure all personnel support information security' },
13
+ { id: 'A.5.5', name: 'Contact with authorities', theme: 'organizational', purpose: 'To maintain appropriate contacts with relevant authorities' },
14
+ { id: 'A.5.6', name: 'Contact with special interest groups', theme: 'organizational', purpose: 'To maintain appropriate contacts with special interest groups' },
15
+ { id: 'A.5.7', name: 'Threat intelligence', theme: 'organizational', purpose: 'To provide awareness of the threat environment' },
16
+ { id: 'A.5.8', name: 'Information security in project management', theme: 'organizational', purpose: 'To ensure information security is integrated into project management' },
17
+ { id: 'A.5.9', name: 'Inventory of information and other associated assets', theme: 'organizational', purpose: 'To identify and manage information assets' },
18
+ { id: 'A.5.10', name: 'Acceptable use of information and other associated assets', theme: 'organizational', purpose: 'To ensure information assets are appropriately used' },
19
+ { id: 'A.5.11', name: 'Return of assets', theme: 'organizational', purpose: 'To protect assets when employment ends' },
20
+ { id: 'A.5.12', name: 'Classification of information', theme: 'organizational', purpose: 'To ensure information is classified appropriately' },
21
+ { id: 'A.5.13', name: 'Labelling of information', theme: 'organizational', purpose: 'To facilitate information classification' },
22
+ { id: 'A.5.14', name: 'Information transfer', theme: 'organizational', purpose: 'To maintain security during information transfer' },
23
+ { id: 'A.5.15', name: 'Access control', theme: 'organizational', purpose: 'To ensure authorized access to information' },
24
+ { id: 'A.5.16', name: 'Identity management', theme: 'organizational', purpose: 'To enable unique identification of individuals' },
25
+ { id: 'A.5.17', name: 'Authentication information', theme: 'organizational', purpose: 'To prevent unauthorized disclosure of authentication information' },
26
+ { id: 'A.5.18', name: 'Access rights', theme: 'organizational', purpose: 'To ensure access rights are authorized, reviewed, and removed' },
27
+
28
+ // People controls (A.6)
29
+ { id: 'A.6.1', name: 'Screening', theme: 'people', purpose: 'To ensure personnel are suitable and trustworthy' },
30
+ { id: 'A.6.2', name: 'Terms and conditions of employment', theme: 'people', purpose: 'To ensure personnel understand their responsibilities' },
31
+ { id: 'A.6.3', name: 'Information security awareness, education and training', theme: 'people', purpose: 'To ensure personnel are aware of security requirements' },
32
+ { id: 'A.6.4', name: 'Disciplinary process', theme: 'people', purpose: 'To ensure there are consequences for security violations' },
33
+ { id: 'A.6.5', name: 'Responsibilities after termination or change of employment', theme: 'people', purpose: 'To protect organizational interests during employment changes' },
34
+ { id: 'A.6.6', name: 'Confidentiality or non-disclosure agreements', theme: 'people', purpose: 'To protect confidential information' },
35
+ { id: 'A.6.7', name: 'Remote working', theme: 'people', purpose: 'To protect information when working remotely' },
36
+ { id: 'A.6.8', name: 'Information security event reporting', theme: 'people', purpose: 'To provide timely reporting of security events' },
37
+
38
+ // Physical controls (A.7)
39
+ { id: 'A.7.1', name: 'Physical security perimeters', theme: 'physical', purpose: 'To prevent unauthorized physical access' },
40
+ { id: 'A.7.2', name: 'Physical entry', theme: 'physical', purpose: 'To protect areas by appropriate entry controls' },
41
+ { id: 'A.7.3', name: 'Securing offices, rooms and facilities', theme: 'physical', purpose: 'To prevent unauthorized physical access' },
42
+ { id: 'A.7.4', name: 'Physical security monitoring', theme: 'physical', purpose: 'To detect and deter unauthorized access' },
43
+ { id: 'A.7.5', name: 'Protecting against physical and environmental threats', theme: 'physical', purpose: 'To protect against environmental damage' },
44
+ { id: 'A.7.6', name: 'Working in secure areas', theme: 'physical', purpose: 'To protect information in secure areas' },
45
+ { id: 'A.7.7', name: 'Clear desk and clear screen', theme: 'physical', purpose: 'To reduce risks from unattended workspaces' },
46
+ { id: 'A.7.8', name: 'Equipment siting and protection', theme: 'physical', purpose: 'To protect equipment from environmental threats' },
47
+ { id: 'A.7.9', name: 'Security of assets off-premises', theme: 'physical', purpose: 'To protect assets outside organizational premises' },
48
+ { id: 'A.7.10', name: 'Storage media', theme: 'physical', purpose: 'To prevent unauthorized disclosure from storage media' },
49
+ { id: 'A.7.11', name: 'Supporting utilities', theme: 'physical', purpose: 'To prevent loss or damage from utility failures' },
50
+ { id: 'A.7.12', name: 'Cabling security', theme: 'physical', purpose: 'To protect cabling from interception or damage' },
51
+ { id: 'A.7.13', name: 'Equipment maintenance', theme: 'physical', purpose: 'To ensure continued availability and integrity' },
52
+ { id: 'A.7.14', name: 'Secure disposal or re-use of equipment', theme: 'physical', purpose: 'To prevent information leakage from disposed equipment' },
53
+
54
+ // Technological controls (A.8)
55
+ { id: 'A.8.1', name: 'User endpoint devices', theme: 'technological', purpose: 'To protect information on endpoint devices' },
56
+ { id: 'A.8.2', name: 'Privileged access rights', theme: 'technological', purpose: 'To restrict and manage privileged access' },
57
+ { id: 'A.8.3', name: 'Information access restriction', theme: 'technological', purpose: 'To prevent unauthorized access to information' },
58
+ { id: 'A.8.4', name: 'Access to source code', theme: 'technological', purpose: 'To prevent unauthorized access to source code' },
59
+ { id: 'A.8.5', name: 'Secure authentication', theme: 'technological', purpose: 'To implement secure authentication mechanisms' },
60
+ { id: 'A.8.6', name: 'Capacity management', theme: 'technological', purpose: 'To ensure adequate resource capacity' },
61
+ { id: 'A.8.7', name: 'Protection against malware', theme: 'technological', purpose: 'To protect against malware' },
62
+ { id: 'A.8.8', name: 'Management of technical vulnerabilities', theme: 'technological', purpose: 'To prevent exploitation of vulnerabilities' },
63
+ { id: 'A.8.9', name: 'Configuration management', theme: 'technological', purpose: 'To ensure secure configurations' },
64
+ { id: 'A.8.10', name: 'Information deletion', theme: 'technological', purpose: 'To ensure secure deletion of information' },
65
+ { id: 'A.8.11', name: 'Data masking', theme: 'technological', purpose: 'To limit exposure of sensitive data' },
66
+ { id: 'A.8.12', name: 'Data leakage prevention', theme: 'technological', purpose: 'To prevent unauthorized data disclosure' },
67
+ { id: 'A.8.13', name: 'Information backup', theme: 'technological', purpose: 'To maintain backup copies of information' },
68
+ { id: 'A.8.14', name: 'Redundancy of information processing facilities', theme: 'technological', purpose: 'To ensure availability of processing facilities' },
69
+ { id: 'A.8.15', name: 'Logging', theme: 'technological', purpose: 'To record events for investigation' },
70
+ { id: 'A.8.16', name: 'Monitoring activities', theme: 'technological', purpose: 'To detect anomalous behavior' },
71
+ { id: 'A.8.17', name: 'Clock synchronization', theme: 'technological', purpose: 'To ensure consistent timestamps' },
72
+ { id: 'A.8.18', name: 'Use of privileged utility programs', theme: 'technological', purpose: 'To restrict use of privileged utilities' },
73
+ { id: 'A.8.19', name: 'Installation of software on operational systems', theme: 'technological', purpose: 'To control software installation' },
74
+ { id: 'A.8.20', name: 'Networks security', theme: 'technological', purpose: 'To protect network infrastructure' },
75
+ { id: 'A.8.21', name: 'Security of network services', theme: 'technological', purpose: 'To ensure security of network services' },
76
+ { id: 'A.8.22', name: 'Segregation of networks', theme: 'technological', purpose: 'To segregate network segments' },
77
+ { id: 'A.8.23', name: 'Web filtering', theme: 'technological', purpose: 'To restrict access to external websites' },
78
+ { id: 'A.8.24', name: 'Use of cryptography', theme: 'technological', purpose: 'To ensure proper use of cryptography' },
79
+ { id: 'A.8.25', name: 'Secure development life cycle', theme: 'technological', purpose: 'To establish secure development practices' },
80
+ { id: 'A.8.26', name: 'Application security requirements', theme: 'technological', purpose: 'To identify security requirements' },
81
+ { id: 'A.8.27', name: 'Secure system architecture and engineering principles', theme: 'technological', purpose: 'To establish secure design principles' },
82
+ { id: 'A.8.28', name: 'Secure coding', theme: 'technological', purpose: 'To apply secure coding practices' },
83
+ { id: 'A.8.29', name: 'Security testing in development and acceptance', theme: 'technological', purpose: 'To test security during development' },
84
+ { id: 'A.8.30', name: 'Outsourced development', theme: 'technological', purpose: 'To manage security of outsourced development' },
85
+ { id: 'A.8.31', name: 'Separation of development, test and production environments', theme: 'technological', purpose: 'To separate environments' },
86
+ { id: 'A.8.32', name: 'Change management', theme: 'technological', purpose: 'To control changes' },
87
+ { id: 'A.8.33', name: 'Test information', theme: 'technological', purpose: 'To protect test information' },
88
+ { id: 'A.8.34', name: 'Protection of information systems during audit testing', theme: 'technological', purpose: 'To minimize impact of audit testing' }
89
+ ];
90
+
91
+ // Control check implementations
92
+ const CONTROL_CHECKS = {
93
+ 'A.5.1': (evidence) => {
94
+ const implemented = evidence.policies?.informationSecurity === true;
95
+ return {
96
+ implemented,
97
+ effectiveness: implemented ? 'full' : 'none',
98
+ missingEvidence: implemented ? [] : ['Information security policy document']
99
+ };
100
+ },
101
+ 'A.5.15': (evidence) => {
102
+ const ac = evidence.accessControl;
103
+ const implemented = ac?.implemented === true;
104
+ const tested = ac?.tested === true;
105
+ const documented = ac?.documented === true;
106
+
107
+ let effectiveness = 'none';
108
+ if (implemented && tested && documented) effectiveness = 'full';
109
+ else if (implemented && (tested || documented)) effectiveness = 'partial';
110
+ else if (implemented) effectiveness = 'limited';
111
+
112
+ const missing = [];
113
+ if (!implemented) missing.push('Access control implementation');
114
+ if (!tested) missing.push('Access control testing evidence');
115
+ if (!documented) missing.push('Access control documentation');
116
+
117
+ return {
118
+ implemented,
119
+ effectiveness,
120
+ missingEvidence: missing
121
+ };
122
+ }
123
+ };
124
+
125
+ // Control to technical implementation mappings
126
+ const CONTROL_MAPPINGS = {
127
+ 'A.8.24': [
128
+ { type: 'encryption', description: 'Data encryption implementation', patterns: ['encrypt', 'aes', 'crypto', 'tls'] },
129
+ { type: 'key-management', description: 'Cryptographic key management', patterns: ['key-vault', 'kms', 'secret'] }
130
+ ],
131
+ 'A.8.3': [
132
+ { type: 'access-control', description: 'Information access restriction', patterns: ['rbac', 'acl', 'permission', 'authorize'] },
133
+ { type: 'authentication', description: 'User authentication', patterns: ['auth', 'login', 'session'] }
134
+ ]
135
+ };
136
+
137
+ /**
138
+ * Create an ISO 27001 checklist instance
139
+ * @param {Object} options - Configuration options
140
+ * @param {string} options.version - ISO 27001 version (default: '2022')
141
+ * @returns {Object} Checklist instance
142
+ */
143
+ export function createIso27001Checklist(options = {}) {
144
+ const version = options.version || '2022';
145
+
146
+ return {
147
+ evaluate(evidence) {
148
+ const results = [];
149
+ const controls = getControls();
150
+
151
+ for (const control of controls) {
152
+ const result = checkControl(control.id, evidence);
153
+ results.push(result);
154
+ }
155
+
156
+ return {
157
+ version,
158
+ results,
159
+ compliant: results.every(r => r.implemented),
160
+ score: (results.filter(r => r.implemented).length / results.length) * 100
161
+ };
162
+ },
163
+
164
+ getControls() {
165
+ return getControls();
166
+ }
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Get ISO 27001 controls
172
+ * @param {Object} options - Filter options
173
+ * @param {string} options.groupBy - Group by 'theme' or return flat list
174
+ * @returns {Array|Object} Controls list or grouped object
175
+ */
176
+ export function getControls(options = {}) {
177
+ if (options.groupBy === 'theme') {
178
+ const grouped = {
179
+ organizational: [],
180
+ people: [],
181
+ physical: [],
182
+ technological: []
183
+ };
184
+
185
+ for (const control of CONTROLS) {
186
+ grouped[control.theme].push(control);
187
+ }
188
+
189
+ return grouped;
190
+ }
191
+
192
+ return [...CONTROLS];
193
+ }
194
+
195
+ /**
196
+ * Check implementation of a specific control
197
+ * @param {string} controlId - Control identifier (e.g., 'A.5.1')
198
+ * @param {Object} evidence - Evidence for compliance check
199
+ * @returns {Object} Check result
200
+ */
201
+ export function checkControl(controlId, evidence) {
202
+ const control = CONTROLS.find(c => c.id === controlId);
203
+ const checkFn = CONTROL_CHECKS[controlId];
204
+
205
+ let implemented = false;
206
+ let effectiveness = 'none';
207
+ let missingEvidence = ['Evidence not provided'];
208
+
209
+ if (checkFn) {
210
+ const result = checkFn(evidence);
211
+ implemented = result.implemented;
212
+ effectiveness = result.effectiveness;
213
+ missingEvidence = result.missingEvidence;
214
+ }
215
+
216
+ return {
217
+ controlId,
218
+ controlName: control?.name || 'Unknown control',
219
+ theme: control?.theme,
220
+ purpose: control?.purpose,
221
+ implemented,
222
+ effectiveness,
223
+ missingEvidence
224
+ };
225
+ }
226
+
227
+ /**
228
+ * Generate Statement of Applicability
229
+ * @param {Array} assessments - Array of control assessments
230
+ * @returns {string} SoA document
231
+ */
232
+ export function generateSoa(assessments) {
233
+ const date = new Date().toISOString().split('T')[0];
234
+
235
+ let soa = `# Statement of Applicability
236
+
237
+ **Document Date:** ${date}
238
+ **ISO 27001:2022**
239
+
240
+ ## Purpose
241
+
242
+ This Statement of Applicability (SoA) documents the applicability and implementation status of ISO 27001:2022 Annex A controls.
243
+
244
+ ## Control Assessment
245
+
246
+ | Control ID | Control Name | Applicable | Implemented | Justification |
247
+ |------------|--------------|------------|-------------|---------------|
248
+ `;
249
+
250
+ for (const assessment of assessments) {
251
+ const control = CONTROLS.find(c => c.id === assessment.controlId);
252
+ const name = control?.name || 'Unknown';
253
+ const applicable = assessment.applicable ? 'Yes' : 'No';
254
+ const implemented = assessment.implemented ? 'Yes' : 'No';
255
+ const justification = assessment.justification || '-';
256
+
257
+ soa += `| ${assessment.controlId} | ${name} | ${applicable} | ${implemented} | ${justification} |\n`;
258
+ }
259
+
260
+ soa += `
261
+ ## Summary
262
+
263
+ - **Total Controls:** ${assessments.length}
264
+ - **Applicable:** ${assessments.filter(a => a.applicable).length}
265
+ - **Not Applicable:** ${assessments.filter(a => !a.applicable).length}
266
+ - **Implemented:** ${assessments.filter(a => a.implemented).length}
267
+
268
+ ## Approval
269
+
270
+ _________________________
271
+ Information Security Manager
272
+
273
+ _________________________
274
+ Management Representative
275
+ `;
276
+
277
+ return soa;
278
+ }
279
+
280
+ /**
281
+ * Map Annex A control to technical implementations
282
+ * @param {string} controlId - Control identifier
283
+ * @returns {Array} Technical implementation mappings
284
+ */
285
+ export function mapAnnexAControls(controlId) {
286
+ return CONTROL_MAPPINGS[controlId] || [];
287
+ }