Phase 1: Add ESLint/Prettier config + baseline auto-fixes

This commit is contained in:
Krystie
2026-03-22 11:00:25 +01:00
parent 41a0cdee7e
commit e2c67a8fe8
90 changed files with 4008 additions and 3066 deletions

View File

@@ -30,7 +30,7 @@ function validateDNSRecord(data) {
if (!subdomainRegex.test(data.subdomain)) {
errors.push({
field: 'subdomain',
message: 'Invalid subdomain format. Use only letters, numbers, and hyphens (1-63 chars)'
message: 'Invalid subdomain format. Use only letters, numbers, and hyphens (1-63 chars)',
});
}
@@ -80,7 +80,7 @@ function validateDNSRecord(data) {
subdomain: data.subdomain.toLowerCase().trim(),
domain: data.domain ? data.domain.toLowerCase().trim() : null,
ip: data.ip.trim(),
ttl: data.ttl ? parseInt(data.ttl, 10) : 3600
ttl: data.ttl ? parseInt(data.ttl, 10) : 3600,
};
}
@@ -99,7 +99,7 @@ function validateDockerDeployment(data) {
if (!nameRegex.test(data.name)) {
errors.push({
field: 'name',
message: 'Invalid container name. Use only letters, numbers, underscores, periods, and hyphens'
message: 'Invalid container name. Use only letters, numbers, underscores, periods, and hyphens',
});
}
@@ -119,7 +119,7 @@ function validateDockerDeployment(data) {
if (!imageRegex.test(data.image)) {
errors.push({
field: 'image',
message: 'Invalid Docker image format'
message: 'Invalid Docker image format',
});
}
@@ -146,7 +146,7 @@ function validateDockerDeployment(data) {
if (!portRegex.test(port)) {
errors.push({
field: `ports[${index}]`,
message: 'Invalid port format. Use "host:container" or "host:container/protocol"'
message: 'Invalid port format. Use "host:container" or "host:container/protocol"',
});
} else {
const [, hostPort, containerPort] = port.match(portRegex);
@@ -193,7 +193,7 @@ function validateDockerDeployment(data) {
if (!envKeyRegex.test(key)) {
errors.push({
field: `environment.${key}`,
message: 'Invalid environment variable name'
message: 'Invalid environment variable name',
});
}
@@ -201,7 +201,7 @@ function validateDockerDeployment(data) {
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
errors.push({
field: `environment.${key}`,
message: 'Environment variable value must be string, number, or boolean'
message: 'Environment variable value must be string, number, or boolean',
});
}
});
@@ -219,7 +219,7 @@ function validateDockerDeployment(data) {
image: data.image.trim(),
ports: data.ports || [],
volumes: data.volumes || [],
environment: data.environment || {}
environment: data.environment || {},
};
}
@@ -248,7 +248,7 @@ function validateFilePath(filePath, allowedBasePaths = []) {
'C:\\Windows',
'C:\\Program Files',
'/var/run',
'/var/lib/docker'
'/var/lib/docker',
];
const lowerPath = normalized.toLowerCase();
@@ -284,7 +284,7 @@ function validateVolumePath(volume, index) {
if (!match) {
errors.push({
field: `volumes[${index}]`,
message: 'Invalid volume format. Use "host:container" or "host:container:mode"'
message: 'Invalid volume format. Use "host:container" or "host:container:mode"',
});
return errors;
}
@@ -297,7 +297,7 @@ function validateVolumePath(volume, index) {
} catch (error) {
errors.push({
field: `volumes[${index}].hostPath`,
message: `Invalid host path: ${error.message}`
message: `Invalid host path: ${error.message}`,
});
}
@@ -305,7 +305,7 @@ function validateVolumePath(volume, index) {
if (containerPath.includes('..') || !path.isAbsolute(containerPath)) {
errors.push({
field: `volumes[${index}].containerPath`,
message: 'Container path must be absolute and not contain ..'
message: 'Container path must be absolute and not contain ..',
});
}
@@ -313,7 +313,7 @@ function validateVolumePath(volume, index) {
if (mode && !['ro', 'rw', 'z', 'Z'].includes(mode)) {
errors.push({
field: `volumes[${index}].mode`,
message: 'Invalid volume mode. Use ro, rw, z, or Z'
message: 'Invalid volume mode. Use ro, rw, z, or Z',
});
}
@@ -333,7 +333,7 @@ function validateURL(url, options = {}) {
require_protocol: options.requireProtocol !== false,
require_valid_protocol: true,
allow_underscores: false,
...options
...options,
};
if (!validator.isURL(url, validatorOptions)) {
@@ -451,7 +451,7 @@ function isPrivateIP(ip) {
/^169\.254\./,
/^::1$/,
/^fc00:/,
/^fe80:/
/^fe80:/,
];
return privateRanges.some(range => range.test(ip));
@@ -496,7 +496,7 @@ async function validateSecurePath(requestedPath, allowedRoots, auditLogger = nul
auditLogger.logSecurityEvent('path_traversal_blocked', {
requestedPath,
reason: 'null_byte_detected',
severity: 'high'
severity: 'high',
});
}
throw new ValidationError('Invalid path - null byte detected', 'path');
@@ -510,7 +510,7 @@ async function validateSecurePath(requestedPath, allowedRoots, auditLogger = nul
/\.\%2f/i, // .%2F (encoded ./)
/%2e\./i, // %2E.
/\.\\/, // .\ (Windows)
/%5c/i // URL encoded backslash
/%5c/i, // URL encoded backslash
];
if (suspiciousPatterns.some(pattern => pattern.test(requestedPath)) ||
@@ -520,7 +520,7 @@ async function validateSecurePath(requestedPath, allowedRoots, auditLogger = nul
requestedPath,
decodedPath,
reason: 'traversal_sequence_detected',
severity: 'high'
severity: 'high',
});
}
throw new ValidationError('Path traversal detected', 'path');
@@ -581,7 +581,7 @@ async function validateSecurePath(requestedPath, allowedRoots, auditLogger = nul
realPath,
allowedRoots,
reason: 'outside_allowed_roots',
severity: 'critical'
severity: 'critical',
});
}
throw new ValidationError('Access denied - path is outside allowed directories', 'path');
@@ -602,5 +602,5 @@ module.exports = {
sanitizeString,
isValidPort,
isPrivateIP,
validateSecurePath
validateSecurePath,
};