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.
- package/docker-compose.dev.yml +6 -3
- 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,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firewall Manager - UFW rules generation and management
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* UFW policy constants
|
|
7
|
+
*/
|
|
8
|
+
export const UFW_POLICIES = {
|
|
9
|
+
ALLOW: 'allow',
|
|
10
|
+
DENY: 'deny',
|
|
11
|
+
REJECT: 'reject',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate UFW enable command
|
|
16
|
+
* @param {Object} options - Options
|
|
17
|
+
* @param {boolean} options.force - Include --force flag
|
|
18
|
+
* @returns {string} UFW enable command
|
|
19
|
+
*/
|
|
20
|
+
export function generateUfwEnableCommand(options = {}) {
|
|
21
|
+
const { force = false } = options;
|
|
22
|
+
if (force) {
|
|
23
|
+
return 'ufw --force enable';
|
|
24
|
+
}
|
|
25
|
+
return 'ufw enable';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Set default policy
|
|
30
|
+
* @param {Object} options - Options
|
|
31
|
+
* @param {string} options.direction - 'incoming' or 'outgoing'
|
|
32
|
+
* @param {string} options.policy - 'allow', 'deny', or 'reject'
|
|
33
|
+
* @returns {string} UFW default policy command
|
|
34
|
+
*/
|
|
35
|
+
export function setDefaultPolicy(options) {
|
|
36
|
+
const { direction, policy } = options;
|
|
37
|
+
return `ufw default ${policy} ${direction}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generate allow rule for port
|
|
42
|
+
* @param {Object} options - Options
|
|
43
|
+
* @param {number|string} options.port - Port number, range, or service name
|
|
44
|
+
* @param {string} options.protocol - Protocol (tcp, udp)
|
|
45
|
+
* @returns {string} UFW allow rule
|
|
46
|
+
*/
|
|
47
|
+
export function allowPort(options) {
|
|
48
|
+
const { port, protocol } = options;
|
|
49
|
+
if (protocol) {
|
|
50
|
+
return `ufw allow ${port}/${protocol}`;
|
|
51
|
+
}
|
|
52
|
+
return `ufw allow ${port}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Generate allow rule for IP
|
|
57
|
+
* @param {Object} options - Options
|
|
58
|
+
* @param {string} options.ip - IP address or CIDR range
|
|
59
|
+
* @param {number} options.port - Port number (optional)
|
|
60
|
+
* @returns {string} UFW allow from IP rule
|
|
61
|
+
*/
|
|
62
|
+
export function allowFromIp(options) {
|
|
63
|
+
const { ip, port } = options;
|
|
64
|
+
if (port) {
|
|
65
|
+
return `ufw allow from ${ip} to any port ${port}`;
|
|
66
|
+
}
|
|
67
|
+
return `ufw allow from ${ip}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Generate deny rule for port
|
|
72
|
+
* @param {Object} options - Options
|
|
73
|
+
* @param {number|string} options.port - Port number
|
|
74
|
+
* @param {string} options.protocol - Protocol (tcp, udp)
|
|
75
|
+
* @returns {string} UFW deny rule
|
|
76
|
+
*/
|
|
77
|
+
export function denyPort(options) {
|
|
78
|
+
const { port, protocol } = options;
|
|
79
|
+
if (protocol) {
|
|
80
|
+
return `ufw deny ${port}/${protocol}`;
|
|
81
|
+
}
|
|
82
|
+
return `ufw deny ${port}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Validate UFW rule syntax
|
|
87
|
+
* @param {string} rule - UFW rule to validate
|
|
88
|
+
* @returns {Object} Validation result with valid and error properties
|
|
89
|
+
*/
|
|
90
|
+
export function validateRule(rule) {
|
|
91
|
+
// Check for port numbers
|
|
92
|
+
const portMatch = rule.match(/(?:port\s+|allow\s+|deny\s+)(\d+)/);
|
|
93
|
+
if (portMatch) {
|
|
94
|
+
const port = parseInt(portMatch[1], 10);
|
|
95
|
+
if (port < 1 || port > 65535) {
|
|
96
|
+
return { valid: false, error: 'Invalid port number' };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check for IP addresses
|
|
101
|
+
const ipMatch = rule.match(/from\s+([\d.]+(?:\/\d+)?)/);
|
|
102
|
+
if (ipMatch) {
|
|
103
|
+
const ipPart = ipMatch[1];
|
|
104
|
+
const [ip, cidr] = ipPart.split('/');
|
|
105
|
+
|
|
106
|
+
// Validate IP octets
|
|
107
|
+
const octets = ip.split('.');
|
|
108
|
+
if (octets.length !== 4) {
|
|
109
|
+
return { valid: false, error: 'Invalid IP address format' };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const octet of octets) {
|
|
113
|
+
const num = parseInt(octet, 10);
|
|
114
|
+
if (isNaN(num) || num < 0 || num > 255) {
|
|
115
|
+
return { valid: false, error: 'Invalid IP address' };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Validate CIDR if present
|
|
120
|
+
if (cidr !== undefined) {
|
|
121
|
+
const cidrNum = parseInt(cidr, 10);
|
|
122
|
+
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
|
123
|
+
return { valid: false, error: 'Invalid CIDR notation' };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return { valid: true };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Generate complete UFW rules configuration
|
|
133
|
+
* @param {Object} options - Options
|
|
134
|
+
* @param {number[]} options.allowPorts - Ports to allow
|
|
135
|
+
* @param {number} options.sshPort - SSH port
|
|
136
|
+
* @param {string[]} options.adminIps - Admin IP addresses
|
|
137
|
+
* @param {boolean} options.rateLimit - Enable rate limiting
|
|
138
|
+
* @param {string} options.format - Output format ('rules' or 'script')
|
|
139
|
+
* @returns {string} UFW rules or script
|
|
140
|
+
*/
|
|
141
|
+
export function generateUfwRules(options) {
|
|
142
|
+
const {
|
|
143
|
+
allowPorts = [],
|
|
144
|
+
sshPort = 22,
|
|
145
|
+
adminIps = [],
|
|
146
|
+
rateLimit = false,
|
|
147
|
+
format = 'rules',
|
|
148
|
+
} = options;
|
|
149
|
+
|
|
150
|
+
const lines = [];
|
|
151
|
+
|
|
152
|
+
if (format === 'script') {
|
|
153
|
+
lines.push('#!/bin/bash');
|
|
154
|
+
lines.push('');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Default policies
|
|
158
|
+
lines.push('ufw default deny incoming');
|
|
159
|
+
lines.push('ufw default allow outgoing');
|
|
160
|
+
|
|
161
|
+
// SSH rule
|
|
162
|
+
if (rateLimit) {
|
|
163
|
+
lines.push(`ufw limit ${sshPort}`);
|
|
164
|
+
} else {
|
|
165
|
+
lines.push(`ufw allow ${sshPort}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Allowed ports
|
|
169
|
+
for (const port of allowPorts) {
|
|
170
|
+
lines.push(`ufw allow ${port}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Admin IPs
|
|
174
|
+
for (const ip of adminIps) {
|
|
175
|
+
lines.push(`ufw allow from ${ip}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return lines.join('\n');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Create a firewall manager instance
|
|
183
|
+
* @param {Object} options - Initial options
|
|
184
|
+
* @returns {Object} Firewall manager object
|
|
185
|
+
*/
|
|
186
|
+
export function createFirewallManager(options = {}) {
|
|
187
|
+
const { sshPort = 22 } = options;
|
|
188
|
+
const rules = [];
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
/**
|
|
192
|
+
* Generate rules using the current configuration
|
|
193
|
+
*/
|
|
194
|
+
generateRules(opts = {}) {
|
|
195
|
+
return generateUfwRules({ ...opts, sshPort });
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Add an allow port rule
|
|
200
|
+
*/
|
|
201
|
+
allowPort(opts) {
|
|
202
|
+
const rule = allowPort(opts);
|
|
203
|
+
rules.push(rule);
|
|
204
|
+
return rule;
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Add a deny port rule
|
|
209
|
+
*/
|
|
210
|
+
denyPort(opts) {
|
|
211
|
+
const rule = denyPort(opts);
|
|
212
|
+
rules.push(rule);
|
|
213
|
+
return rule;
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Add an allow from IP rule
|
|
218
|
+
*/
|
|
219
|
+
allowFromIp(opts) {
|
|
220
|
+
const rule = allowFromIp(opts);
|
|
221
|
+
rules.push(rule);
|
|
222
|
+
return rule;
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Validate a rule
|
|
227
|
+
*/
|
|
228
|
+
validate(rule) {
|
|
229
|
+
return validateRule(rule);
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get all added rules
|
|
234
|
+
*/
|
|
235
|
+
getRules() {
|
|
236
|
+
return [...rules];
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Generate complete configuration
|
|
241
|
+
*/
|
|
242
|
+
generateConfig() {
|
|
243
|
+
const lines = [
|
|
244
|
+
'ufw default deny incoming',
|
|
245
|
+
'ufw default allow outgoing',
|
|
246
|
+
`ufw allow ${sshPort}`,
|
|
247
|
+
...rules,
|
|
248
|
+
];
|
|
249
|
+
return lines.join('\n');
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firewall Manager Tests
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import {
|
|
6
|
+
generateUfwRules,
|
|
7
|
+
generateUfwEnableCommand,
|
|
8
|
+
setDefaultPolicy,
|
|
9
|
+
allowPort,
|
|
10
|
+
allowFromIp,
|
|
11
|
+
denyPort,
|
|
12
|
+
validateRule,
|
|
13
|
+
UFW_POLICIES,
|
|
14
|
+
createFirewallManager,
|
|
15
|
+
} from './firewall-manager.js';
|
|
16
|
+
|
|
17
|
+
describe('firewall-manager', () => {
|
|
18
|
+
describe('UFW_POLICIES', () => {
|
|
19
|
+
it('defines policy constants', () => {
|
|
20
|
+
expect(UFW_POLICIES.ALLOW).toBe('allow');
|
|
21
|
+
expect(UFW_POLICIES.DENY).toBe('deny');
|
|
22
|
+
expect(UFW_POLICIES.REJECT).toBe('reject');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('generateUfwEnableCommand', () => {
|
|
27
|
+
it('generates enable command', () => {
|
|
28
|
+
const command = generateUfwEnableCommand();
|
|
29
|
+
|
|
30
|
+
expect(command).toContain('ufw');
|
|
31
|
+
expect(command).toContain('enable');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('includes force flag', () => {
|
|
35
|
+
const command = generateUfwEnableCommand({ force: true });
|
|
36
|
+
|
|
37
|
+
expect(command).toContain('--force');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('setDefaultPolicy', () => {
|
|
42
|
+
it('sets default deny incoming', () => {
|
|
43
|
+
const command = setDefaultPolicy({
|
|
44
|
+
direction: 'incoming',
|
|
45
|
+
policy: 'deny',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
expect(command).toContain('default deny incoming');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('sets default allow outgoing', () => {
|
|
52
|
+
const command = setDefaultPolicy({
|
|
53
|
+
direction: 'outgoing',
|
|
54
|
+
policy: 'allow',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(command).toContain('default allow outgoing');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('allowPort', () => {
|
|
62
|
+
it('generates allow rule for port', () => {
|
|
63
|
+
const rule = allowPort({ port: 443 });
|
|
64
|
+
|
|
65
|
+
expect(rule).toContain('allow');
|
|
66
|
+
expect(rule).toContain('443');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('supports protocol specification', () => {
|
|
70
|
+
const rule = allowPort({ port: 443, protocol: 'tcp' });
|
|
71
|
+
|
|
72
|
+
expect(rule).toContain('443/tcp');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('supports port ranges', () => {
|
|
76
|
+
const rule = allowPort({ port: '3000:3010' });
|
|
77
|
+
|
|
78
|
+
expect(rule).toContain('3000:3010');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('supports named services', () => {
|
|
82
|
+
const rule = allowPort({ port: 'ssh' });
|
|
83
|
+
|
|
84
|
+
expect(rule).toContain('ssh');
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('allowFromIp', () => {
|
|
89
|
+
it('generates allow rule for IP', () => {
|
|
90
|
+
const rule = allowFromIp({
|
|
91
|
+
ip: '192.168.1.100',
|
|
92
|
+
port: 22,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
expect(rule).toContain('from 192.168.1.100');
|
|
96
|
+
expect(rule).toContain('22');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('supports CIDR notation', () => {
|
|
100
|
+
const rule = allowFromIp({
|
|
101
|
+
ip: '10.0.0.0/8',
|
|
102
|
+
port: 22,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
expect(rule).toContain('from 10.0.0.0/8');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('supports any destination', () => {
|
|
109
|
+
const rule = allowFromIp({
|
|
110
|
+
ip: '192.168.1.100',
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
expect(rule).toContain('from 192.168.1.100');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('denyPort', () => {
|
|
118
|
+
it('generates deny rule for port', () => {
|
|
119
|
+
const rule = denyPort({ port: 23 });
|
|
120
|
+
|
|
121
|
+
expect(rule).toContain('deny');
|
|
122
|
+
expect(rule).toContain('23');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('supports protocol specification', () => {
|
|
126
|
+
const rule = denyPort({ port: 23, protocol: 'tcp' });
|
|
127
|
+
|
|
128
|
+
expect(rule).toContain('23/tcp');
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('validateRule', () => {
|
|
133
|
+
it('validates correct rule syntax', () => {
|
|
134
|
+
const result = validateRule('ufw allow 443/tcp');
|
|
135
|
+
|
|
136
|
+
expect(result.valid).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('rejects invalid port numbers', () => {
|
|
140
|
+
const result = validateRule('ufw allow 99999');
|
|
141
|
+
|
|
142
|
+
expect(result.valid).toBe(false);
|
|
143
|
+
expect(result.error).toContain('port');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('rejects invalid IP addresses', () => {
|
|
147
|
+
const result = validateRule('ufw allow from 999.999.999.999');
|
|
148
|
+
|
|
149
|
+
expect(result.valid).toBe(false);
|
|
150
|
+
expect(result.error).toContain('IP');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('validates CIDR notation', () => {
|
|
154
|
+
const validResult = validateRule('ufw allow from 10.0.0.0/8');
|
|
155
|
+
expect(validResult.valid).toBe(true);
|
|
156
|
+
|
|
157
|
+
const invalidResult = validateRule('ufw allow from 10.0.0.0/33');
|
|
158
|
+
expect(invalidResult.valid).toBe(false);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('generateUfwRules', () => {
|
|
163
|
+
it('generates complete UFW configuration', () => {
|
|
164
|
+
const rules = generateUfwRules({
|
|
165
|
+
allowPorts: [80, 443],
|
|
166
|
+
sshPort: 22,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
expect(rules).toContain('default deny incoming');
|
|
170
|
+
expect(rules).toContain('default allow outgoing');
|
|
171
|
+
expect(rules).toContain('allow 80');
|
|
172
|
+
expect(rules).toContain('allow 443');
|
|
173
|
+
expect(rules).toContain('allow 22');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('supports custom SSH port', () => {
|
|
177
|
+
const rules = generateUfwRules({
|
|
178
|
+
allowPorts: [80, 443],
|
|
179
|
+
sshPort: 2222,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect(rules).toContain('allow 2222');
|
|
183
|
+
expect(rules).not.toContain('allow 22/tcp');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('includes IP allowlist for admin', () => {
|
|
187
|
+
const rules = generateUfwRules({
|
|
188
|
+
allowPorts: [80, 443],
|
|
189
|
+
sshPort: 22,
|
|
190
|
+
adminIps: ['192.168.1.100', '10.0.0.50'],
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
expect(rules).toContain('from 192.168.1.100');
|
|
194
|
+
expect(rules).toContain('from 10.0.0.50');
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('supports rate limiting', () => {
|
|
198
|
+
const rules = generateUfwRules({
|
|
199
|
+
allowPorts: [80, 443],
|
|
200
|
+
sshPort: 22,
|
|
201
|
+
rateLimit: true,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(rules).toContain('limit');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('generates script format', () => {
|
|
208
|
+
const rules = generateUfwRules({
|
|
209
|
+
allowPorts: [80, 443],
|
|
210
|
+
sshPort: 22,
|
|
211
|
+
format: 'script',
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(rules).toContain('#!/bin/bash');
|
|
215
|
+
expect(rules).toContain('ufw');
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('createFirewallManager', () => {
|
|
220
|
+
it('creates manager with methods', () => {
|
|
221
|
+
const manager = createFirewallManager();
|
|
222
|
+
|
|
223
|
+
expect(manager.generateRules).toBeDefined();
|
|
224
|
+
expect(manager.allowPort).toBeDefined();
|
|
225
|
+
expect(manager.denyPort).toBeDefined();
|
|
226
|
+
expect(manager.allowFromIp).toBeDefined();
|
|
227
|
+
expect(manager.validate).toBeDefined();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('tracks added rules', () => {
|
|
231
|
+
const manager = createFirewallManager();
|
|
232
|
+
|
|
233
|
+
manager.allowPort({ port: 80 });
|
|
234
|
+
manager.allowPort({ port: 443 });
|
|
235
|
+
|
|
236
|
+
const rules = manager.getRules();
|
|
237
|
+
expect(rules.length).toBe(2);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('generates complete config', () => {
|
|
241
|
+
const manager = createFirewallManager({
|
|
242
|
+
sshPort: 22,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
manager.allowPort({ port: 80 });
|
|
246
|
+
manager.allowPort({ port: 443 });
|
|
247
|
+
|
|
248
|
+
const config = manager.generateConfig();
|
|
249
|
+
expect(config).toContain('80');
|
|
250
|
+
expect(config).toContain('443');
|
|
251
|
+
expect(config).toContain('22');
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
});
|